]> granicus.if.org Git - clang/commitdiff
Don't warn about anonymous struct/union in C11.
authorHans Wennborg <hans@hanshq.net>
Fri, 3 Feb 2012 15:47:04 +0000 (15:47 +0000)
committerHans Wennborg <hans@hanshq.net>
Fri, 3 Feb 2012 15:47:04 +0000 (15:47 +0000)
Also, in C, call this a C11 extension rather than a GNU extension.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Sema/anonymous-struct-union-c11.c [new file with mode: 0644]
test/Sema/array-init.c

index 394f8b089d6d471ed9ae60b7cbc59d4c3b894448..05fc863c61cdd4e87db1acb1018b03205aed4bb2 100644 (file)
@@ -4570,9 +4570,11 @@ def ext_in_class_initializer_non_constant : Extension<
 
 // C++ anonymous unions and GNU anonymous structs/unions
 def ext_anonymous_union : Extension<
-  "anonymous unions are a GNU extension in C">, InGroup<GNU>;
-def ext_anonymous_struct : Extension<
+  "anonymous unions are a C11 extension">, InGroup<C11>;
+def ext_gnu_anonymous_struct : Extension<
   "anonymous structs are a GNU extension">, InGroup<GNU>;
+def ext_c11_anonymous_struct : Extension<
+  "anonymous structs are a C11 extension">, InGroup<C11>;
 def err_anonymous_union_not_static : Error<
   "anonymous unions at namespace or global scope must be declared 'static'">;
 def err_anonymous_union_with_storage_spec : Error<
index 8a0e461ec2b939d081895500010793f157c5aa1d..f6f97dddbcaeb646556c158963abd6f84d435924 100644 (file)
@@ -2679,18 +2679,20 @@ StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
 
 /// BuildAnonymousStructOrUnion - Handle the declaration of an
 /// anonymous structure or union. Anonymous unions are a C++ feature
-/// (C++ [class.union]) and a GNU C extension; anonymous structures
-/// are a GNU C and GNU C++ extension.
+/// (C++ [class.union]) and a C11 feature; anonymous structures
+/// are a C11 feature and GNU C++ extension.
 Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
                                              AccessSpecifier AS,
                                              RecordDecl *Record) {
   DeclContext *Owner = Record->getDeclContext();
 
   // Diagnose whether this anonymous struct/union is an extension.
-  if (Record->isUnion() && !getLangOptions().CPlusPlus)
+  if (Record->isUnion() && !getLangOptions().CPlusPlus && !getLangOptions().C11)
     Diag(Record->getLocation(), diag::ext_anonymous_union);
-  else if (!Record->isUnion())
-    Diag(Record->getLocation(), diag::ext_anonymous_struct);
+  else if (!Record->isUnion() && getLangOptions().CPlusPlus)
+    Diag(Record->getLocation(), diag::ext_gnu_anonymous_struct);
+  else if (!Record->isUnion() && !getLangOptions().C11)
+    Diag(Record->getLocation(), diag::ext_c11_anonymous_struct);
 
   // C and C++ require different kinds of checks for anonymous
   // structs/unions.
diff --git a/test/Sema/anonymous-struct-union-c11.c b/test/Sema/anonymous-struct-union-c11.c
new file mode 100644 (file)
index 0000000..229ee52
--- /dev/null
@@ -0,0 +1,19 @@
+// Check for warnings in non-C11 mode:
+// RUN: %clang_cc1 -fsyntax-only -verify -Wc11-extensions %s
+
+// Expect no warnings in C11 mode:
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Werror -std=c11 %s
+
+struct s {
+  int a;
+  struct { // expected-warning{{anonymous structs are a C11 extension}}
+    int b;
+  };
+};
+
+struct t {
+  int a;
+  union { // expected-warning{{anonymous unions are a C11 extension}}
+    int b;
+  };
+};
index bd1dfd2c06fdbc86b18f0077e2002c1e552b7c46..a979fb9e57c3f4cda9a1007cb4b9081f8a7adf82 100644 (file)
@@ -245,7 +245,7 @@ static void sppp_ipv6cp_up();
 const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct is a GNU extension}} \
 // expected-warning{{excess elements in struct initializer}}
 
-struct _Matrix { union { float m[4][4]; }; }; //expected-warning{{anonymous unions are a GNU extension in C}}
+struct _Matrix { union { float m[4][4]; }; }; //expected-warning{{anonymous unions are a C11 extension}}
 typedef struct _Matrix Matrix;
 void test_matrix() {
   const Matrix mat1 = {