From de229235b979e030b2d9dd1402f40d29e21571ad Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 6 Jun 2013 11:41:05 +0000 Subject: [PATCH] Implement DR1270: braces can be elided in all aggregate initialization, not just copy-list-initialization in a variable declaration. This effectively reverts r142147. llvm-svn: 183397 --- .../clang/Basic/DiagnosticSemaKinds.td | 3 -- clang/lib/Sema/SemaInit.cpp | 30 +++++-------------- .../SemaCXX/cxx0x-initializer-aggregates.cpp | 27 ++++++++--------- 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6e682e8954e5..32abf8a2a793 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3703,9 +3703,6 @@ def warn_anon_bitfield_width_exceeds_type_size : Warning< def warn_missing_braces : Warning< "suggest braces around initialization of subobject">, InGroup, DefaultIgnore; -def err_missing_braces : Error< - "cannot omit braces around initialization of subobject when using direct " - "list-initialization">; def err_redefinition_of_label : Error<"redefinition of label %0">; def err_undeclared_label_use : Error<"use of undeclared label %0">; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index e04d72d9fb83..60c67cd38bbe 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -236,7 +236,6 @@ class InitListChecker { Sema &SemaRef; bool hadError; bool VerifyOnly; // no diagnostics, no structure building - bool AllowBraceElision; llvm::DenseMap SyntacticToSemantic; InitListExpr *FullyStructuredList; @@ -327,8 +326,7 @@ class InitListChecker { public: InitListChecker(Sema &S, const InitializedEntity &Entity, - InitListExpr *IL, QualType &T, bool VerifyOnly, - bool AllowBraceElision); + InitListExpr *IL, QualType &T, bool VerifyOnly); bool HadError() { return hadError; } // @brief Retrieves the fully-structured initializer list used for @@ -559,8 +557,8 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity, InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, InitListExpr *IL, QualType &T, - bool VerifyOnly, bool AllowBraceElision) - : SemaRef(S), VerifyOnly(VerifyOnly), AllowBraceElision(AllowBraceElision) { + bool VerifyOnly) + : SemaRef(S), VerifyOnly(VerifyOnly) { hadError = false; unsigned newIndex = 0; @@ -645,10 +643,7 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity, StructuredSubobjectInitList, StructuredSubobjectInitIndex); - if (VerifyOnly) { - if (!AllowBraceElision && (T->isArrayType() || T->isRecordType())) - hadError = true; - } else { + if (!VerifyOnly) { StructuredSubobjectInitList->setType(T); unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1); @@ -663,8 +658,7 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity, // Complain about missing braces. if (T->isArrayType() || T->isRecordType()) { SemaRef.Diag(StructuredSubobjectInitList->getLocStart(), - AllowBraceElision ? diag::warn_missing_braces : - diag::err_missing_braces) + diag::warn_missing_braces) << StructuredSubobjectInitList->getSourceRange() << FixItHint::CreateInsertion( StructuredSubobjectInitList->getLocStart(), "{") @@ -672,8 +666,6 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity, SemaRef.PP.getLocForEndOfToken( StructuredSubobjectInitList->getLocEnd()), "}"); - if (!AllowBraceElision) - hadError = true; } } } @@ -3277,9 +3269,7 @@ static void TryListInitialization(Sema &S, } InitListChecker CheckInitList(S, Entity, InitList, - DestType, /*VerifyOnly=*/true, - Kind.getKind() != InitializationKind::IK_DirectList || - !S.getLangOpts().CPlusPlus11); + DestType, /*VerifyOnly=*/true); if (CheckInitList.HadError()) { Sequence.SetFailed(InitializationSequence::FK_ListInitializationFailed); return; @@ -5695,9 +5685,7 @@ InitializationSequence::Perform(Sema &S, InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(Ty); InitializedEntity InitEntity = IsTemporary ? TempEntity : Entity; InitListChecker PerformInitList(S, InitEntity, - InitList, Ty, /*VerifyOnly=*/false, - Kind.getKind() != InitializationKind::IK_DirectList || - !S.getLangOpts().CPlusPlus11); + InitList, Ty, /*VerifyOnly=*/false); if (PerformInitList.HadError()) return ExprError(); @@ -6381,9 +6369,7 @@ bool InitializationSequence::Diagnose(Sema &S, InitListExpr* InitList = cast(Args[0]); QualType DestType = Entity.getType(); InitListChecker DiagnoseInitList(S, Entity, InitList, - DestType, /*VerifyOnly=*/false, - Kind.getKind() != InitializationKind::IK_DirectList || - !S.getLangOpts().CPlusPlus11); + DestType, /*VerifyOnly=*/false); assert(DiagnoseInitList.HadError() && "Inconsistent init list check result."); break; diff --git a/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp index f53ac6dff930..0e9a97d5bb07 100644 --- a/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp +++ b/clang/test/SemaCXX/cxx0x-initializer-aggregates.cpp @@ -4,7 +4,6 @@ struct one { char c[1]; }; struct two { char c[2]; }; namespace aggregate { - // Direct list initialization does NOT allow braces to be elided! struct S { int ar[2]; struct T { @@ -20,25 +19,25 @@ namespace aggregate { }; void bracing() { - S s1 = { 1, 2, 3 ,4, 5, 6, 7, 8 }; // no-error - S s2{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced - S s3{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}} - S s4{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}} - S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}} + S s1 = { 1, 2, 3 ,4, 5, 6, 7, 8 }; + S s2{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; + S s3{ 1, 2, 3, 4, 5, 6 }; + S s4{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; + S s5{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; } void bracing_new() { - new S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced - new S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}} - new S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}} - new S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}} + new S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; + new S{ 1, 2, 3, 4, 5, 6 }; + new S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; + new S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; } void bracing_construct() { - (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; // completely braced - (void) S{ 1, 2, 3, 4, 5, 6 }; // expected-error 5 {{cannot omit braces}} - (void) S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; // expected-error 2 {{cannot omit braces}} - (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; // expected-error {{cannot omit braces}} + (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, { {7, 8} } }; + (void) S{ 1, 2, 3, 4, 5, 6 }; + (void) S{ {1, 2}, {3, 4}, {5, 6}, { {7, 8} } }; + (void) S{ {1, 2}, {3, 4}, { {5}, {6} }, {7, 8} }; } struct String {