]> granicus.if.org Git - clang/commitdiff
Sema: Cleanup and simplify anonymous union diagnostics
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 2 Nov 2013 10:38:05 +0000 (10:38 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 2 Nov 2013 10:38:05 +0000 (10:38 +0000)
The determination of which diagnostics would be issued for certain
anonymous unions started to get a little ridiculous.  Clean this up by
inverting the condition-tree's logic from dialect -> issue to
issue -> diagnostic.

As part of this cleanup, move ext_c99_flexible_array_member from
DiagnosticParseKinds.td to DiagnosticSemaKinds.td because it's driven by
Sema, not Parse.

Also, the liberty was taken to edit ext_c99_flexible_array_member to
match other, similar, diagnostics.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@193919 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Sema/c89.c
test/SemaCXX/c99.cpp

index 932732402c53cbc6fcdfda003a260ce712e55e97..1df1713972af42863d19086d3a58731e0736ec8c 100644 (file)
@@ -73,8 +73,6 @@ def ext_c99_variable_decl_in_for_loop : Extension<
   "variable declaration in for loop is a C99-specific feature">, InGroup<C99>;
 def ext_c99_compound_literal : Extension<
   "compound literals are a C99-specific feature">, InGroup<C99>;
-def ext_c99_flexible_array_member : Extension<
-  "flexible array members are a C99-specific feature">, InGroup<C99>;
 def ext_enumerator_list_comma_c : Extension<
   "commas at the end of enumerator lists are a C99-specific "
   "feature">, InGroup<C99>;
index fea3fe996de351b9981202660fcd899cee6cabc3..ae2d9c9e779df6dcd86f37ed6fd7c8928d11ec9f 100644 (file)
@@ -3935,8 +3935,11 @@ def ext_variable_sized_type_in_struct : ExtWarn<
   "field %0 with variable sized type %1 not at the end of a struct or class is"
   " a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>;
 
-def err_flexible_array_empty_struct : Error<
-  "flexible array %0 not allowed in otherwise empty struct">;
+def ext_c99_flexible_array_member : Extension<
+  "flexible array members are a C99 feature">, InGroup<C99>;
+def err_flexible_array_empty_aggregate : Error<
+  "flexible array member %0 not allowed in otherwise empty "
+  "%select{struct|interface|union|class|enum}1 is not allowed">;
 def err_flexible_array_has_nonpod_type : Error<
   "flexible array member %0 of non-POD element type %1">;
 def ext_flexible_array_in_struct : Extension<
@@ -3951,6 +3954,8 @@ def ext_flexible_array_empty_aggregate_ms : Extension<
   "flexible array member %0 in otherwise empty "
   "%select{struct|interface|union|class|enum}1 is a Microsoft extension">,
   InGroup<Microsoft>;
+def err_flexible_array_union : Error<
+  "flexible array member %0 in a union is not allowed">;
 def ext_flexible_array_union_ms : Extension<
   "flexible array member %0 in a union is a Microsoft extension">,
   InGroup<Microsoft>;
index 6c8b36c6cc9e3c86905d57c6d7cd7add96b31b7c..101f4ce8988a315f7237c6f70511882e9645bd1b 100644 (file)
@@ -11822,40 +11822,29 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
       // Microsoft and g++ is more permissive regarding flexible array.
       // It will accept flexible array in union and also
       // as the sole element of a struct/class.
-      if (getLangOpts().MicrosoftExt) {
-        if (Record->isUnion())
-          Diag(FD->getLocation(), diag::ext_flexible_array_union_ms)
-            << FD->getDeclName();
-        else if (Fields.size() == 1)
-          Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms)
-            << FD->getDeclName() << Record->getTagKind();
-        else
-          Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
-            << FD->getDeclName() << Record->getTagKind();
-      } else if (getLangOpts().CPlusPlus) {
-        if (Record->isUnion())
-          Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
-            << FD->getDeclName();
-        else if (Fields.size() == 1)
-          Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu)
-            << FD->getDeclName() << Record->getTagKind();
-        else
-          Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
-            << FD->getDeclName() << Record->getTagKind();
-      } else if (!getLangOpts().C99) {
-        if (Record->isUnion())
-          Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
-            << FD->getDeclName();
-        else
-          Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
-            << FD->getDeclName() << Record->getTagKind();
-      } else if (NumNamedMembers < 1) {
-        Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
-          << FD->getDeclName();
-        FD->setInvalidDecl();
-        EnclosingDecl->setInvalidDecl();
-        continue;
-      }
+      unsigned DiagID = 0;
+      if (Record->isUnion())
+        DiagID = getLangOpts().MicrosoftExt
+                     ? diag::ext_flexible_array_union_ms
+                     : getLangOpts().CPlusPlus
+                           ? diag::ext_flexible_array_union_gnu
+                           : diag::err_flexible_array_union;
+      else if (Fields.size() == 1)
+        DiagID = getLangOpts().MicrosoftExt
+                     ? diag::ext_flexible_array_empty_aggregate_ms
+                     : getLangOpts().CPlusPlus
+                           ? diag::ext_flexible_array_empty_aggregate_gnu
+                           : NumNamedMembers < 1
+                                 ? diag::err_flexible_array_empty_aggregate
+                                 : 0;
+
+      if (DiagID)
+        Diag(FD->getLocation(), DiagID) << FD->getDeclName()
+                                        << Record->getTagKind();
+      if (!getLangOpts().C99)
+        Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
+          << FD->getDeclName() << Record->getTagKind();
+
       if (!FD->getType()->isDependentType() &&
           !Context.getBaseElementType(FD->getType()).isPODType(Context)) {
         Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type)
index 0c42ec291f04c271aea17fac2fcb163a601560bc..b746d383f3069f339fc8e7dd9e8e2e4bea82774d 100644 (file)
@@ -90,7 +90,7 @@ void test16() {
   printg("Hello, world!\n"); /* expected-warning {{implicit declaration of function 'printg'}} */
 }
 
-struct x { int x,y[]; }; /* expected-warning {{flexible array members are a C99-specific feature}} */
+struct x { int x,y[]; }; /* expected-warning {{flexible array members are a C99 feature}} */
 
 /* Duplicated type-qualifiers aren't allowed by C90 */
 const const int c_i; /* expected-warning {{duplicate 'const' declaration specifier}} */
index 3383d595f0ed36318a014c277183b8de5563c9be..7afcdd509f9d18091caac0ea86a2d595590cb5b8 100644 (file)
@@ -2,7 +2,7 @@
 void f1(int i[static 5]) { // expected-error{{C99}}
 }
 
-struct Point { int x; int y; int z[]; }; // expected-warning{{flexible array members are a C99-specific feature}}
+struct Point { int x; int y; int z[]; }; // expected-warning{{flexible array members are a C99 feature}}
 
 Point p1 = { .x = 17, // expected-warning{{designated initializers are a C99 feature}}
              y: 25 }; // expected-warning{{designated initializers are a C99 feature}} \