]> granicus.if.org Git - clang/commitdiff
Support GCC's bug^Wextension allowing class array members to be initalized by a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Feb 2012 22:38:09 +0000 (22:38 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Feb 2012 22:38:09 +0000 (22:38 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Initialization.h
lib/Sema/SemaInit.cpp
test/Misc/warning-flags.c
test/SemaCXX/cxx0x-initializer-aggregates.cpp

index 8e502ed77aa599a191d229bafd0d252ddaa2d71c..95514017dcdeab96798555ff29220831c6acdbf9 100644 (file)
@@ -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<GNU>;
+def ext_array_init_parens : ExtWarn<
+  "parenthesized initialization of a member array is a GNU extension">,
+  InGroup<GNU>;
 def warn_deprecated_string_literal_conversion : Warning<
   "conversion from string literal to %0 is deprecated">, InGroup<DeprecatedWritableStr>;
 def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
index b66c2b4598959e965cddedc818a7d135a585be2c..a36b5e6bd80ce869c5d7ebc5c4617ba42f99cc53 100644 (file)
@@ -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);
 
index da6892e230d790b62ccb5d5416d97ba914ad1c83..b6d55aae8062df69c62257533c26bd7acdae924b 100644 (file)
@@ -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<InitListExpr>(Initializer)) {
+      TryListInitialization(S, Entity, Kind, cast<InitListExpr>(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;
index e9e75c925957ad9fc056460e72a501b690b90828..6621f08fcf7c1333f30243a30099875fe005fba4 100644 (file)
@@ -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
index 4ee3cd3f6bf956e16c4cc626619494dec6ae73c9..b5fa5fe143c4b4d2d4077b8145d17b6adb918840 100644 (file)
@@ -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}}
 }