From: Richard Smith Date: Wed, 15 Feb 2012 22:38:09 +0000 (+0000) Subject: Support GCC's bug^Wextension allowing class array members to be initalized by a X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0f163e964289bc18e9bc1ec37a6a01018ba62640;p=clang Support GCC's bug^Wextension allowing class array members to be initalized by a parenthesized braced-init-list in the base/member initialization list. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150625 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 8e502ed77a..95514017dc 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -3550,7 +3550,10 @@ def err_array_init_non_constant_array : Error< "cannot initialize array of type %0 with non-constant array of type %1">; def ext_array_init_copy : Extension< "initialization of an array of type %0 from a compound literal of type %1 is " - "a GNU extension">; + "a GNU extension">, InGroup; +def ext_array_init_parens : ExtWarn< + "parenthesized initialization of a member array is a GNU extension">, + InGroup; def warn_deprecated_string_literal_conversion : Warning< "conversion from string literal to %0 is deprecated">, InGroup; def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">; diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index b66c2b4598..a36b5e6bd8 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -592,6 +592,9 @@ public: /// \brief Array initialization (from an array rvalue). /// This is a GNU C extension. SK_ArrayInit, + /// \brief Array initialization from a parenthesized initializer list. + /// This is a GNU C++ extension. + SK_ParenthesizedArrayInit, /// \brief Pass an object by indirect copy-and-restore. SK_PassByIndirectCopyRestore, /// \brief Pass an object by indirect restore. @@ -912,6 +915,9 @@ public: /// \brief Add an array initialization step. void AddArrayInitStep(QualType T); + /// \brief Add a parenthesized array initialization step. + void AddParenthesizedArrayInitStep(QualType T); + /// \brief Add a step to pass an object by indirect copy-restore. void AddPassByIndirectCopyRestoreStep(QualType T, bool shouldCopy); diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index da6892e230..b6d55aae80 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2417,6 +2417,7 @@ void InitializationSequence::Step::Destroy() { case SK_StringInit: case SK_ObjCObjectConversion: case SK_ArrayInit: + case SK_ParenthesizedArrayInit: case SK_PassByIndirectCopyRestore: case SK_PassByIndirectRestore: case SK_ProduceObjCObject: @@ -2618,6 +2619,13 @@ void InitializationSequence::AddArrayInitStep(QualType T) { Steps.push_back(S); } +void InitializationSequence::AddParenthesizedArrayInitStep(QualType T) { + Step S; + S.Kind = SK_ParenthesizedArrayInit; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::AddPassByIndirectCopyRestoreStep(QualType type, bool shouldCopy) { Step s; @@ -4058,6 +4066,15 @@ InitializationSequence::InitializationSequence(Sema &S, else { AddArrayInitStep(DestType); } + } + // Note: as a GNU C++ extension, we allow initialization of a + // class member from a parenthesized initializer list. + else if (S.getLangOptions().CPlusPlus && + Entity.getKind() == InitializedEntity::EK_Member && + Initializer && isa(Initializer)) { + TryListInitialization(S, Entity, Kind, cast(Initializer), + *this); + AddParenthesizedArrayInitStep(DestType); } else if (DestAT->getElementType()->isAnyCharacterType()) SetFailed(FK_ArrayNeedsInitListOrStringLiteral); else @@ -4787,6 +4804,7 @@ InitializationSequence::Perform(Sema &S, case SK_StringInit: case SK_ObjCObjectConversion: case SK_ArrayInit: + case SK_ParenthesizedArrayInit: case SK_PassByIndirectCopyRestore: case SK_PassByIndirectRestore: case SK_ProduceObjCObject: @@ -5213,6 +5231,13 @@ InitializationSequence::Perform(Sema &S, } break; + case SK_ParenthesizedArrayInit: + // Okay: we checked everything before creating this step. Note that + // this is a GNU extension. + S.Diag(Kind.getLocation(), diag::ext_array_init_parens) + << CurInit.get()->getSourceRange(); + break; + case SK_PassByIndirectCopyRestore: case SK_PassByIndirectRestore: checkIndirectCopyRestoreSource(S, CurInit.get()); @@ -5889,6 +5914,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "array initialization"; break; + case SK_ParenthesizedArrayInit: + OS << "parenthesized array initialization"; + break; + case SK_PassByIndirectCopyRestore: OS << "pass by indirect copy and restore"; break; diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c index e9e75c9259..6621f08fcf 100644 --- a/test/Misc/warning-flags.c +++ b/test/Misc/warning-flags.c @@ -17,9 +17,8 @@ This test serves two purposes: The list of warnings below should NEVER grow. It should gradually shrink to 0. -CHECK: Warnings without flags (258): +CHECK: Warnings without flags (257): CHECK-NEXT: ext_anonymous_struct_union_qualified -CHECK-NEXT: ext_array_init_copy CHECK-NEXT: ext_binary_literal CHECK-NEXT: ext_cast_fn_obj CHECK-NEXT: ext_delete_void_ptr_operand diff --git a/test/SemaCXX/cxx0x-initializer-aggregates.cpp b/test/SemaCXX/cxx0x-initializer-aggregates.cpp index 4ee3cd3f6b..b5fa5fe143 100644 --- a/test/SemaCXX/cxx0x-initializer-aggregates.cpp +++ b/test/SemaCXX/cxx0x-initializer-aggregates.cpp @@ -71,5 +71,5 @@ namespace aggregate { static_assert(sizeof(overloaded({1})) == sizeof(one), "bad overload"); } - struct C { int a[2]; C():a({1, 2}) { } }; // expected-error {{array initializer must be an initializer list}} + struct C { int a[2]; C():a({1, 2}) { } }; // expected-warning {{parenthesized initialization of a member array is a GNU extension}} }