]> granicus.if.org Git - clang/commitdiff
[Sema] Fix parsing of anonymous union in language linkage specification
authorJan Korous <jkorous@apple.com>
Wed, 6 Jun 2018 05:16:34 +0000 (05:16 +0000)
committerJan Korous <jkorous@apple.com>
Wed, 6 Jun 2018 05:16:34 +0000 (05:16 +0000)
C++17 [dcl.link]p4:
A linkage specification does not establish a scope.

C++17 [class.union.anon]p2:
Namespace level anonymous unions shall be declared static.

Differential Revision: https://reviews.llvm.org/D45884

rdar://problem/37545925

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

lib/Sema/SemaDecl.cpp
test/SemaCXX/anonymous-union-export.cpp [new file with mode: 0644]
test/SemaCXX/anonymous-union.cpp

index 862da621491a7c65da60f4ac185ccd74244db01a..e1ee8ec079a5f91b9e6ac5eae43ead8c3bf5bed0 100644 (file)
@@ -4642,12 +4642,14 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
     unsigned DiagID;
     if (Record->isUnion()) {
       // C++ [class.union]p6:
+      // C++17 [class.union.anon]p2:
       //   Anonymous unions declared in a named namespace or in the
       //   global namespace shall be declared static.
+      DeclContext *OwnerScope = Owner->getRedeclContext();
       if (DS.getStorageClassSpec() != DeclSpec::SCS_static &&
-          (isa<TranslationUnitDecl>(Owner) ||
-           (isa<NamespaceDecl>(Owner) &&
-            cast<NamespaceDecl>(Owner)->getDeclName()))) {
+          (OwnerScope->isTranslationUnit() ||
+           (OwnerScope->isNamespace() &&
+            !cast<NamespaceDecl>(OwnerScope)->isAnonymousNamespace()))) {
         Diag(Record->getLocation(), diag::err_anonymous_union_not_static)
           << FixItHint::CreateInsertion(Record->getLocation(), "static ");
 
diff --git a/test/SemaCXX/anonymous-union-export.cpp b/test/SemaCXX/anonymous-union-export.cpp
new file mode 100644 (file)
index 0000000..270c0c3
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -std=c++17 -fmodules-ts -emit-obj -verify %s
+
+export module M;
+export {
+    union { bool a; }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+}
index 0b654266f75f788fea27cc55b2d3def1ba8c454b..5538ea47033535d08e6274adab1cd135d8567b7f 100644 (file)
@@ -80,6 +80,10 @@ union { // expected-error{{anonymous unions at namespace or global scope must be
   float float_val;
 };
 
+extern "C++" {
+union { }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+}
+
 static union {
   int int_val2; // expected-note{{previous definition is here}}
   float float_val2;