[PATCH] D46112: Allow _Atomic to be specified on incomplete types

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 26 03:02:00 PDT 2018


aaron.ballman created this revision.
aaron.ballman added a reviewer: rsmith.

The C standard does not prohibit the _Atomic specifier on incomplete types, which turns out to be sometimes useful.

This addresses PR37237.

Note that C++ still requires checking if the type is complete in order to support member pointers under the Microsoft ABI (because that check completes some information on the type), which is a use case we have in test\SemaCXX\atomic-type.cpp.


https://reviews.llvm.org/D46112

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaType.cpp
  test/Sema/atomic-type.c


Index: test/Sema/atomic-type.c
===================================================================
--- test/Sema/atomic-type.c
+++ test/Sema/atomic-type.c
@@ -16,7 +16,10 @@
 extern _Atomic(int (*)(int(*)[10], int(*)[10])) mergetest;
 
 _Atomic(int()) error1; // expected-error {{_Atomic cannot be applied to function type}}
-_Atomic(struct ErrorS) error2; // expected-error {{_Atomic cannot be applied to incomplete type}} expected-note {{forward declaration}}
+_Atomic(struct ErrorS) error2;
 _Atomic(int[10]) error3; // expected-error {{_Atomic cannot be applied to array type}}
 _Atomic(const int) error4; // expected-error {{_Atomic cannot be applied to qualified type}}
 _Atomic(_Atomic(int)) error5; // expected-error {{_Atomic cannot be applied to atomic type}}
+
+void g(_Atomic void *ptr);
+void h(_Atomic struct Incomplete *ptr); // expected-warning {{declaration of 'struct Incomplete' will not be visible outside of this function}}
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -8007,25 +8007,21 @@
 
 QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {
   if (!T->isDependentType()) {
-    // FIXME: It isn't entirely clear whether incomplete atomic types
-    // are allowed or not; for simplicity, ban them for the moment.
-    if (RequireCompleteType(Loc, T, diag::err_atomic_specifier_bad_type, 0))
-      return QualType();
-
     int DisallowedKind = -1;
     if (T->isArrayType())
-      DisallowedKind = 1;
+      DisallowedKind = 0;
     else if (T->isFunctionType())
-      DisallowedKind = 2;
+      DisallowedKind = 1;
     else if (T->isReferenceType())
-      DisallowedKind = 3;
+      DisallowedKind = 2;
     else if (T->isAtomicType())
-      DisallowedKind = 4;
+      DisallowedKind = 3;
     else if (T.hasQualifiers())
-      DisallowedKind = 5;
-    else if (!T.isTriviallyCopyableType(Context))
+      DisallowedKind = 4;
+    else if (LangOpts.CPlusPlus && isCompleteType(Loc, T) &&
+             !T.isTriviallyCopyableType(Context))
       // Some other non-trivially-copyable type (probably a C++ class)
-      DisallowedKind = 6;
+      DisallowedKind = 5;
 
     if (DisallowedKind != -1) {
       Diag(Loc, diag::err_atomic_specifier_bad_type) << DisallowedKind << T;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5504,7 +5504,7 @@
   "incomplete result type %0 in function definition">;
 def err_atomic_specifier_bad_type : Error<
   "_Atomic cannot be applied to "
-  "%select{incomplete |array |function |reference |atomic |qualified |}0type "
+  "%select{array |function |reference |atomic |qualified |}0type "
   "%1 %select{||||||which is not trivially copyable}0">;
 
 // Expressions.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46112.144089.patch
Type: text/x-patch
Size: 2977 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180426/c820a9b7/attachment-0001.bin>


More information about the cfe-commits mailing list