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. 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: 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}}