[cfe-commits] r131109 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/DeclSpec.h lib/Sema/SemaDecl.cpp test/SemaCXX/anonymous-union.cpp

Douglas Gregor dgregor at apple.com
Mon May 9 16:05:33 PDT 2011


Author: dgregor
Date: Mon May  9 18:05:33 2011
New Revision: 131109

URL: http://llvm.org/viewvc/llvm-project?rev=131109&view=rev
Log:
Ignore const/volatile/restrict qualifiers on anonymous structs and
unions. Fixes PR8326.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/anonymous-union.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131109&r1=131108&r2=131109&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May  9 18:05:33 2011
@@ -758,7 +758,9 @@
   "static data member %0 not allowed in %select{anonymous struct|union}1">; 
 def err_union_member_of_reference_type : Error<
   "union member %0 has reference type %1">;
-
+def ext_anonymous_struct_union_qualified : Extension<
+  "anonymous %select{struct|union}0 cannot be '%select{const|volatile|"
+  "restrict}1'">;
 def err_different_return_type_for_overriding_virtual_function : Error<
   "virtual function %0 has a different return type (%1) than the "
   "function it overrides (which has return type %2)">;

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=131109&r1=131108&r2=131109&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon May  9 18:05:33 2011
@@ -462,6 +462,14 @@
   SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; }
   SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; }
 
+  /// \brief Clear out all of the type qualifiers.
+  void ClearTypeQualifiers() {
+    TypeQualifiers = 0;
+    TQ_constLoc = SourceLocation();
+    TQ_restrictLoc = SourceLocation();
+    TQ_volatileLoc = SourceLocation();
+  }
+
   // function-specifier
   bool isInlineSpecified() const { return FS_inline_specified; }
   SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131109&r1=131108&r2=131109&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May  9 18:05:33 2011
@@ -2489,6 +2489,24 @@
                              PrevSpec, DiagID, getLangOptions());
     }
 
+    // Ignore const/volatile/restrict qualifiers.
+    if (DS.getTypeQualifiers()) {
+      if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
+        Diag(DS.getConstSpecLoc(), diag::ext_anonymous_struct_union_qualified)
+          << Record->isUnion() << 0 
+          << FixItHint::CreateRemoval(DS.getConstSpecLoc());
+      if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile)
+        Diag(DS.getVolatileSpecLoc(), diag::ext_anonymous_struct_union_qualified)
+          << Record->isUnion() << 1
+          << FixItHint::CreateRemoval(DS.getVolatileSpecLoc());
+      if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict)
+        Diag(DS.getRestrictSpecLoc(), diag::ext_anonymous_struct_union_qualified)
+          << Record->isUnion() << 2 
+          << FixItHint::CreateRemoval(DS.getRestrictSpecLoc());
+
+      DS.ClearTypeQualifiers();
+    }
+
     // C++ [class.union]p2:
     //   The member-specification of an anonymous union shall only
     //   define non-static data members. [Note: nested types and

Modified: cfe/trunk/test/SemaCXX/anonymous-union.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/anonymous-union.cpp?rev=131109&r1=131108&r2=131109&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/anonymous-union.cpp (original)
+++ cfe/trunk/test/SemaCXX/anonymous-union.cpp Mon May  9 18:05:33 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
 struct X {
   union {
     float f3;
@@ -17,7 +17,7 @@
 
   void test_unqual_references();
 
-  struct {
+  struct { // expected-warning{{anonymous structs are a GNU extension}}
     int a;
     float b;
   };
@@ -125,7 +125,7 @@
 // <rdar://problem/7987650>
 namespace test4 {
   class A {
-    struct {
+    struct { // expected-warning{{anonymous structs are a GNU extension}}
       int s0; // expected-note {{declared private here}}
       double s1; // expected-note {{declared private here}}
       union {
@@ -136,7 +136,7 @@
     union {
       int u0; // expected-note {{declared private here}}
       double u1; // expected-note {{declared private here}}
-      struct {
+      struct { // expected-warning{{anonymous structs are a GNU extension}}
         int us0; // expected-note {{declared private here}}
         double us1; // expected-note {{declared private here}}
       };
@@ -175,3 +175,25 @@
         };
     }
 }
+
+namespace PR8326 {
+  template <class T>
+  class Foo {
+  public:
+    Foo()
+      : x(0)
+      , y(1){
+    }
+  
+  private:
+    const union { // expected-warning{{anonymous union cannot be 'const'}}
+      struct { // expected-warning{{anonymous structs are a GNU extension}}
+        T x;
+        T y;
+      };
+      T v[2];
+    };
+  };
+
+  Foo<int> baz;
+}





More information about the cfe-commits mailing list