diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f44fef28b9f17..4e5c870e4177f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -298,6 +298,9 @@ Bug Fixes to C++ Support Fixes (`#82941 `_), (`#42411 `_), and (`#18121 `_). +- Clang now properly reports supported C++11 attributes when using + ``__has_cpp_attribute`` and parses attributes with arguments in C++03 + (`#82995 `_) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/test/Preprocessor/has_attribute.cpp b/clang/test/Preprocessor/has_attribute.cpp index 33546dbb175f6..00ec57615c84b 100644 --- a/clang/test/Preprocessor/has_attribute.cpp +++ b/clang/test/Preprocessor/has_attribute.cpp @@ -1,4 +1,6 @@ +// RUN: %clang_cc1 -triple i386-unknown-unknown -fms-compatibility -std=c++03 -E -P %s -o - | FileCheck %s --check-prefixes=CHECK,ITANIUM --implicit-check-not=: // RUN: %clang_cc1 -triple i386-unknown-unknown -fms-compatibility -std=c++11 -E -P %s -o - | FileCheck %s --check-prefixes=CHECK,ITANIUM --implicit-check-not=: +// RUN: %clang_cc1 -triple i386-windows -fms-compatibility -std=c++03 -E -P %s -o - | FileCheck %s --check-prefixes=CHECK,WINDOWS --implicit-check-not=: // RUN: %clang_cc1 -triple i386-windows -fms-compatibility -std=c++11 -E -P %s -o - | FileCheck %s --check-prefixes=CHECK,WINDOWS --implicit-check-not=: #define CXX11(x) x: __has_cpp_attribute(x) @@ -65,7 +67,7 @@ CXX11(unlikely) // CHECK: likely: 201803L // CHECK: maybe_unused: 201603L // ITANIUM: no_unique_address: 201803L -// WINDOWS: no_unique_address: 0 +// WINDOWS: no_unique_address: 0 // ITANIUM: msvc::no_unique_address: 0 // WINDOWS: msvc::no_unique_address: 201803L // CHECK: nodiscard: 201907L diff --git a/clang/test/SemaCXX/attr-declspec-ignored.cpp b/clang/test/SemaCXX/attr-declspec-ignored.cpp index dfea8cc4d47c8..98e0ffd1a1afd 100644 --- a/clang/test/SemaCXX/attr-declspec-ignored.cpp +++ b/clang/test/SemaCXX/attr-declspec-ignored.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -verify -fsyntax-only +// RUN: %clang_cc1 %s -std=c++03 -Wno-c++11-extensions -verify -fsyntax-only namespace test1 { __attribute__((visibility("hidden"))) __attribute__((aligned)) class A; // expected-warning{{attribute 'visibility' is ignored, place it after "class" to apply attribute to type declaration}} \ @@ -28,7 +29,7 @@ namespace test1 { // expected-warning{{attribute 'aligned' is ignored, place it after "enum class" to apply attribute to type declaration}} __attribute__((visibility("hidden"))) __attribute__((aligned)) enum struct ES {}; // expected-warning{{attribute 'visibility' is ignored, place it after "enum struct" to apply attribute to type declaration}} \ // expected-warning{{attribute 'aligned' is ignored, place it after "enum struct" to apply attribute to type declaration}} - + // Also test [[]] attribute syntax. (On a non-nested declaration, these // generate a hard "misplaced attributes" error, which we test for // elsewhere.) diff --git a/clang/test/SemaCXX/attr-gnu.cpp b/clang/test/SemaCXX/attr-gnu.cpp index c257c2b029127..941d01a2e611a 100644 --- a/clang/test/SemaCXX/attr-gnu.cpp +++ b/clang/test/SemaCXX/attr-gnu.cpp @@ -1,7 +1,8 @@ -// RUN: %clang_cc1 -std=gnu++17 -fsyntax-only -fms-compatibility -verify %s - -void f() { - // GNU-style attributes are prohibited in this position. +// RUN: %clang_cc1 -std=gnu++03 -fsyntax-only -fms-compatibility -Wno-c++11-extensions -Wno-c++17-extensions -verify %s +// RUN: %clang_cc1 -std=gnu++17 -fsyntax-only -fms-compatibility -verify %s + +void f() { + // GNU-style attributes are prohibited in this position. auto P = new int * __attribute__((vector_size(8))); // expected-error {{an attribute list cannot appear here}} \ // expected-error {{invalid vector element type 'int *'}} @@ -47,13 +48,13 @@ void tuTest1(Tu u); // expected-note {{candidate function not viable: no kn void tuTest2(Tu3 u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu3' for 1st argument}} void tu() { int x = 2; - tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}} - tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}} -} - -[[gnu::__const__]] int f2() { return 12; } -[[__gnu__::__const__]] int f3() { return 12; } -[[using __gnu__ : __const__]] int f4() { return 12; } - -static_assert(__has_cpp_attribute(gnu::__const__)); -static_assert(__has_cpp_attribute(__gnu__::__const__)); + tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}} + tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}} +} + +[[gnu::__const__]] int f2() { return 12; } +[[__gnu__::__const__]] int f3() { return 12; } +[[using __gnu__ : __const__]] int f4() { return 12; } + +static_assert(__has_cpp_attribute(gnu::__const__)); +static_assert(__has_cpp_attribute(__gnu__::__const__)); diff --git a/clang/test/SemaCXX/cxx03-cxx11-attr.cpp b/clang/test/SemaCXX/cxx03-cxx11-attr.cpp new file mode 100644 index 0000000000000..5a273c8fe2534 --- /dev/null +++ b/clang/test/SemaCXX/cxx03-cxx11-attr.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -std=c++03 -fsyntax-only %s + +// Ensure that __has_cpp_attribute and argument parsing work in C++03 + +#if !__has_cpp_attribute(nodiscard) +# error +#endif + +[[gnu::assume_aligned(4)]] void* g() { return __nullptr; } diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 935b9846990ee..eb5c34d15693d 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3576,10 +3576,6 @@ static void GenerateHasAttrSpellingStringSwitch( const Record *R = Attr->getValueAsDef("Target"); std::vector Arches = R->getValueAsListOfStrings("Arches"); GenerateTargetSpecificAttrChecks(R, Arches, Test, nullptr); - - // If this is the C++11 variety, also add in the LangOpts test. - if (Variety == "CXX11") - Test += " && LangOpts.CPlusPlus11"; } else if (!Attr->getValueAsListOfDefs("TargetSpecificSpellings").empty()) { // Add target checks if this spelling is target-specific. const std::vector TargetSpellings = @@ -3597,13 +3593,7 @@ static void GenerateHasAttrSpellingStringSwitch( } } } - - if (Variety == "CXX11") - Test += " && LangOpts.CPlusPlus11"; - } else if (Variety == "CXX11") - // C++11 mode should be checked against LangOpts, which is presumed to be - // present in the caller. - Test = "LangOpts.CPlusPlus11"; + } std::string TestStr = !Test.empty() ? Test + " ? " + llvm::itostr(Version) + " : 0"