Author: Richard Smith Date: 2020-04-15T13:28:24-07:00 New Revision: 57acbaece1ace979e6a9382d9d517d48895b9ef7
URL: https://github.com/llvm/llvm-project/commit/57acbaece1ace979e6a9382d9d517d48895b9ef7 DIFF: https://github.com/llvm/llvm-project/commit/57acbaece1ace979e6a9382d9d517d48895b9ef7.diff LOG: Improve diagnostic when constant-evaluating a std::initializer_list with an unexpected form. Added: Modified: clang/lib/AST/ExprConstant.cpp clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 2eabf59acb94..5b3866d0a471 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -9338,24 +9338,30 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr( // Get a pointer to the first element of the array. Array.addArray(Info, E, ArrayType); + auto InvalidType = [&] { + Info.FFDiag(E, diag::note_constexpr_unsupported_layout) + << E->getType(); + return false; + }; + // FIXME: Perform the checks on the field types in SemaInit. RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl(); RecordDecl::field_iterator Field = Record->field_begin(); if (Field == Record->field_end()) - return Error(E); + return InvalidType(); // Start pointer. if (!Field->getType()->isPointerType() || !Info.Ctx.hasSameType(Field->getType()->getPointeeType(), ArrayType->getElementType())) - return Error(E); + return InvalidType(); // FIXME: What if the initializer_list type has base classes, etc? Result = APValue(APValue::UninitStruct(), 0, 2); Array.moveInto(Result.getStructField(0)); if (++Field == Record->field_end()) - return Error(E); + return InvalidType(); if (Field->getType()->isPointerType() && Info.Ctx.hasSameType(Field->getType()->getPointeeType(), @@ -9370,10 +9376,10 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr( // Length. Result.getStructField(1) = APValue(APSInt(ArrayType->getSize())); else - return Error(E); + return InvalidType(); if (++Field != Record->field_end()) - return Error(E); + return InvalidType(); return true; } diff --git a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp index b5d6bd68f1fb..9380330b41f3 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -365,3 +365,14 @@ namespace designated_init { static_assert(c.size() == 5, ""); static_assert(d.size() == 1, ""); } + +namespace weird_initlist { + struct weird {}; +} +template<> struct std::initializer_list<weird_initlist::weird> { int a, b, c; }; +namespace weird_initlist { + // We don't check the struct layout in Sema. + auto x = {weird{}, weird{}, weird{}, weird{}, weird{}}; + // ... but we do in constant evaluation. + constexpr auto y = {weird{}, weird{}, weird{}, weird{}, weird{}}; // expected-error {{constant}} expected-note {{type 'const std::initializer_list<weird_initlist::weird>' has unexpected layout}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits