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.
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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits