[clang] Enable C++11-style attributes in all language modes

This also ignores and deprecates the `-fdouble-square-bracket-attributes` command line flag, which seems to not be used anywhere. At least a code search exclusively found mentions of it in documentation: https://sourcegraph.com/search?q=context:global+-fdouble-square-bracket-attributes+-file:clang/*+-file:test/Sema/*+-file:test/Parser/*+-file:test/AST/*+-file:test/Preprocessor/*+-file:test/Misc/*+archived:yes&patternType=standard&sm=0&groupBy=repo

RFC: https://discourse.llvm.org/t/rfc-enable-c-11-c2x-attributes-in-all-standard-modes-as-an-extension-and-remove-fdouble-square-bracket-attributes

This enables `[[]]` attributes in all C and C++ language modes without warning by default. `-Wc++-extensions` does warn. GCC has enabled this extension in all C modes since GCC 10.

Reviewed By: aaron.ballman, MaskRay

Spies: #clang-vendors, beanz, JDevlieghere, Michael137, MaskRay, sstefan1, jplehr, cfe-commits, lldb-commits, dmgreen, jdoerfert, wenlei, wlei

Differential Revision: https://reviews.llvm.org/D151683
This commit is contained in:
Nikolas Klauser 2023-07-22 09:33:55 -07:00
parent 1d0759e6c3
commit 874217f99b
48 changed files with 104 additions and 121 deletions

View File

@ -1429,15 +1429,15 @@ More information could be found `here <https://clang.llvm.org/docs/Modules.html>
Language Extensions Back-ported to Previous Standards Language Extensions Back-ported to Previous Standards
===================================================== =====================================================
====================================== ================================ ============= ============= ================================== ====================================== ================================ ============= =============
Feature Feature Test Macro Introduced In Backported To Required Flags Feature Feature Test Macro Introduced In Backported To
====================================== ================================ ============= ============= ================================== ====================================== ================================ ============= =============
variadic templates __cpp_variadic_templates C++11 C++03 variadic templates __cpp_variadic_templates C++11 C++03
Alias templates __cpp_alias_templates C++11 C++03 Alias templates __cpp_alias_templates C++11 C++03
Non-static data member initializers __cpp_nsdmi C++11 C++03 Non-static data member initializers __cpp_nsdmi C++11 C++03
Range-based ``for`` loop __cpp_range_based_for C++11 C++03 Range-based ``for`` loop __cpp_range_based_for C++11 C++03
RValue references __cpp_rvalue_references C++11 C++03 RValue references __cpp_rvalue_references C++11 C++03
Attributes __cpp_attributes C++11 C++03 -fdouble-square-bracket-attributes Attributes __cpp_attributes C++11 C++03
variable templates __cpp_variable_templates C++14 C++03 variable templates __cpp_variable_templates C++14 C++03
Binary literals __cpp_binary_literals C++14 C++03 Binary literals __cpp_binary_literals C++14 C++03
Relaxed constexpr __cpp_constexpr C++14 C++11 Relaxed constexpr __cpp_constexpr C++14 C++11
@ -1457,10 +1457,11 @@ Conditional ``explicit`` __cpp_conditional_explicit C++20
``using enum`` __cpp_using_enum C++20 C++03 ``using enum`` __cpp_using_enum C++20 C++03
``if consteval`` __cpp_if_consteval C++23 C++20 ``if consteval`` __cpp_if_consteval C++23 C++20
``static operator()`` __cpp_static_call_operator C++23 C++03 ``static operator()`` __cpp_static_call_operator C++23 C++03
-------------------------------------- -------------------------------- ------------- ------------- ---------------------------------- -------------------------------------- -------------------------------- ------------- -------------
Designated initializers (N494) C99 C89 Designated initializers (N494) C99 C89
Array & element qualification (N2607) C2x C89 Array & element qualification (N2607) C2x C89
====================================== ================================ ============= ============= ================================== Attributes (N2335) C2x C89
====================================== ================================ ============= =============
Type Trait Primitives Type Trait Primitives
===================== =====================

View File

@ -277,6 +277,9 @@ New Compiler Flags
Deprecated Compiler Flags Deprecated Compiler Flags
------------------------- -------------------------
- ``-fdouble-square-bracket-attributes`` has been deprecated. It is ignored now
and will be removed in Clang 18.
Modified Compiler Flags Modified Compiler Flags
----------------------- -----------------------

View File

@ -719,8 +719,17 @@ def warn_cxx14_compat_ns_enum_attribute : Warning<
def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">, def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">,
InGroup<CXX98Compat>, DefaultIgnore; InGroup<CXX98Compat>, DefaultIgnore;
def warn_cxx98_compat_attribute : Warning< def warn_cxx98_compat_attribute : Warning<
"C++11 attribute syntax is incompatible with C++98">, "[[]] attributes are incompatible with C++ standards before C++11">,
InGroup<CXX98Compat>, DefaultIgnore; InGroup<CXX98Compat>, DefaultIgnore;
def warn_ext_cxx11_attributes : Extension<
"[[]] attributes are a C++11 extension">,
InGroup<CXX11>;
def warn_pre_c2x_compat_attributes : Warning<
"[[]] attributes are incompatible with C standards before C2x">,
DefaultIgnore, InGroup<CPre2xCompat>;
def warn_ext_c2x_attributes : Extension<
"[[]] attributes are a C2x extension">,
InGroup<C2x>;
def err_cxx11_attribute_forbids_arguments : Error< def err_cxx11_attribute_forbids_arguments : Error<
"attribute %0 cannot have an argument list">; "attribute %0 cannot have an argument list">;
def err_attribute_requires_arguments : Error< def err_attribute_requires_arguments : Error<

View File

@ -245,6 +245,8 @@ EXTENSION(c_generic_selections, true)
EXTENSION(c_generic_selection_with_controlling_type, true) EXTENSION(c_generic_selection_with_controlling_type, true)
EXTENSION(c_static_assert, true) EXTENSION(c_static_assert, true)
EXTENSION(c_thread_local, PP.getTargetInfo().isTLSSupported()) EXTENSION(c_thread_local, PP.getTargetInfo().isTLSSupported())
// C2x features supported by other languages as extensions
EXTENSION(c_attributes, true)
// C++11 features supported by other languages as extensions. // C++11 features supported by other languages as extensions.
EXTENSION(cxx_atomic, LangOpts.CPlusPlus) EXTENSION(cxx_atomic, LangOpts.CPlusPlus)
EXTENSION(cxx_default_function_template_args, LangOpts.CPlusPlus) EXTENSION(cxx_default_function_template_args, LangOpts.CPlusPlus)

View File

@ -1267,9 +1267,7 @@ def fast : Flag<["-"], "fast">, Group<f_Group>;
def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>; def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>;
defm double_square_bracket_attributes : BoolFOption<"double-square-bracket-attributes", defm double_square_bracket_attributes : BoolFOption<"double-square-bracket-attributes",
LangOpts<"DoubleSquareBracketAttributes">, Default<!strconcat(cpp11.KeyPath, "||", c2x.KeyPath)>, LangOpts<"DoubleSquareBracketAttributes">, DefaultTrue, PosFlag<SetTrue>, NegFlag<SetFalse>>;
PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [], "Disable">,
BothFlags<[NoXarchOption, CC1Option], " '[[]]' attributes in all C and C++ language modes">>;
defm autolink : BoolFOption<"autolink", defm autolink : BoolFOption<"autolink",
CodeGenOpts<"Autolink">, DefaultTrue, CodeGenOpts<"Autolink">, DefaultTrue,

View File

@ -2712,12 +2712,6 @@ public:
private: private:
void ParseBlockId(SourceLocation CaretLoc); void ParseBlockId(SourceLocation CaretLoc);
/// Are [[]] attributes enabled?
bool standardAttributesAllowed() const {
const LangOptions &LO = getLangOpts();
return LO.DoubleSquareBracketAttributes;
}
/// Return true if the next token should be treated as a [[]] attribute, /// Return true if the next token should be treated as a [[]] attribute,
/// or as a keyword that behaves like one. The former is only true if /// or as a keyword that behaves like one. The former is only true if
/// [[]] attributes are enabled, whereas the latter is true whenever /// [[]] attributes are enabled, whereas the latter is true whenever
@ -2726,15 +2720,14 @@ private:
bool isAllowedCXX11AttributeSpecifier(bool Disambiguate = false, bool isAllowedCXX11AttributeSpecifier(bool Disambiguate = false,
bool OuterMightBeMessageSend = false) { bool OuterMightBeMessageSend = false) {
return (Tok.isRegularKeywordAttribute() || return (Tok.isRegularKeywordAttribute() ||
(standardAttributesAllowed() && isCXX11AttributeSpecifier(Disambiguate, OuterMightBeMessageSend));
isCXX11AttributeSpecifier(Disambiguate, OuterMightBeMessageSend)));
} }
// Check for the start of an attribute-specifier-seq in a context where an // Check for the start of an attribute-specifier-seq in a context where an
// attribute is not allowed. // attribute is not allowed.
bool CheckProhibitedCXX11Attribute() { bool CheckProhibitedCXX11Attribute() {
assert(Tok.is(tok::l_square)); assert(Tok.is(tok::l_square));
if (!standardAttributesAllowed() || NextToken().isNot(tok::l_square)) if (NextToken().isNot(tok::l_square))
return false; return false;
return DiagnoseProhibitedCXX11Attribute(); return DiagnoseProhibitedCXX11Attribute();
} }
@ -2742,13 +2735,10 @@ private:
bool DiagnoseProhibitedCXX11Attribute(); bool DiagnoseProhibitedCXX11Attribute();
void CheckMisplacedCXX11Attribute(ParsedAttributes &Attrs, void CheckMisplacedCXX11Attribute(ParsedAttributes &Attrs,
SourceLocation CorrectLocation) { SourceLocation CorrectLocation) {
if (!Tok.isRegularKeywordAttribute()) { if (!Tok.isRegularKeywordAttribute() &&
if (!standardAttributesAllowed()) (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) &&
return; Tok.isNot(tok::kw_alignas))
if ((Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square)) && return;
Tok.isNot(tok::kw_alignas))
return;
}
DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation); DiagnoseMisplacedCXX11Attribute(Attrs, CorrectLocation);
} }
void DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs, void DiagnoseMisplacedCXX11Attribute(ParsedAttributes &Attrs,

View File

@ -33,8 +33,7 @@ int clang::hasAttribute(AttributeCommonInfo::Syntax Syntax,
// attributes. We support those, but not through the typical attribute // attributes. We support those, but not through the typical attribute
// machinery that goes through TableGen. We support this in all OpenMP modes // machinery that goes through TableGen. We support this in all OpenMP modes
// so long as double square brackets are enabled. // so long as double square brackets are enabled.
if (LangOpts.OpenMP && LangOpts.DoubleSquareBracketAttributes && if (LangOpts.OpenMP && ScopeName == "omp")
ScopeName == "omp")
return (Name == "directive" || Name == "sequence") ? 1 : 0; return (Name == "directive" || Name == "sequence") ? 1 : 0;
int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts); int res = hasAttributeImpl(Syntax, Name, ScopeName, Target, LangOpts);

View File

@ -4224,9 +4224,7 @@ LexStart:
if (LangOpts.Digraphs && Char == '>') { if (LangOpts.Digraphs && Char == '>') {
Kind = tok::r_square; // ':>' -> ']' Kind = tok::r_square; // ':>' -> ']'
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
} else if ((LangOpts.CPlusPlus || } else if (Char == ':') {
LangOpts.DoubleSquareBracketAttributes) &&
Char == ':') {
Kind = tok::coloncolon; Kind = tok::coloncolon;
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result); CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
} else { } else {
@ -4443,8 +4441,7 @@ bool Lexer::LexDependencyDirectiveToken(Token &Result) {
Result.setLiteralData(TokPtr); Result.setLiteralData(TokPtr);
return true; return true;
} }
if (Result.is(tok::colon) && if (Result.is(tok::colon)) {
(LangOpts.CPlusPlus || LangOpts.DoubleSquareBracketAttributes)) {
// Convert consecutive colons to 'tok::coloncolon'. // Convert consecutive colons to 'tok::coloncolon'.
if (*BufferPtr == ':') { if (*BufferPtr == ':') {
assert(DepDirectives.front().Tokens[NextDepDirectiveTokenIndex].is( assert(DepDirectives.front().Tokens[NextDepDirectiveTokenIndex].is(

View File

@ -4506,7 +4506,13 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
"Not a double square bracket attribute list"); "Not a double square bracket attribute list");
SourceLocation OpenLoc = Tok.getLocation(); SourceLocation OpenLoc = Tok.getLocation();
Diag(OpenLoc, diag::warn_cxx98_compat_attribute); if (getLangOpts().CPlusPlus) {
Diag(OpenLoc, getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_attribute
: diag::warn_ext_cxx11_attributes);
} else {
Diag(OpenLoc, getLangOpts().C2x ? diag::warn_pre_c2x_compat_attributes
: diag::warn_ext_c2x_attributes);
}
ConsumeBracket(); ConsumeBracket();
checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin); checkCompoundToken(OpenLoc, tok::l_square, CompoundToken::AttrBegin);
@ -4621,8 +4627,6 @@ void Parser::ParseCXX11AttributeSpecifierInternal(ParsedAttributes &Attrs,
/// attribute-specifier-seq: /// attribute-specifier-seq:
/// attribute-specifier-seq[opt] attribute-specifier /// attribute-specifier-seq[opt] attribute-specifier
void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) { void Parser::ParseCXX11Attributes(ParsedAttributes &Attrs) {
assert(standardAttributesAllowed() || Tok.isRegularKeywordAttribute());
SourceLocation StartLoc = Tok.getLocation(); SourceLocation StartLoc = Tok.getLocation();
SourceLocation EndLoc = StartLoc; SourceLocation EndLoc = StartLoc;

View File

@ -1,12 +1,12 @@
// Test without serialization: // Test without serialization:
// RUN: %clang_cc1 -fdouble-square-bracket-attributes -triple x86_64-apple-macosx10.10.0 \ // RUN: %clang_cc1 -triple x86_64-apple-macosx10.10.0 \
// RUN: -ast-dump -ast-dump-filter Test %s \ // RUN: -ast-dump -ast-dump-filter Test %s \
// RUN: | FileCheck --strict-whitespace %s // RUN: | FileCheck --strict-whitespace %s
// //
// Test with serialization: // Test with serialization:
// RUN: %clang_cc1 -fdouble-square-bracket-attributes -triple x86_64-apple-macosx10.10.0 \ // RUN: %clang_cc1 -triple x86_64-apple-macosx10.10.0 \
// RUN: -emit-pch -o %t %s // RUN: -emit-pch -o %t %s
// RUN: %clang_cc1 -x objective-c -fdouble-square-bracket-attributes -triple x86_64-apple-macosx10.10.0 \ // RUN: %clang_cc1 -x objective-c -triple x86_64-apple-macosx10.10.0 \
// RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ // RUN: -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \ // RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN: | FileCheck --strict-whitespace %s // RUN: | FileCheck --strict-whitespace %s

View File

@ -1,12 +1,12 @@
// Test without serialization: // Test without serialization:
// RUN: %clang_cc1 -triple x86_64-pc-linux -fdouble-square-bracket-attributes \ // RUN: %clang_cc1 -triple x86_64-pc-linux \
// RUN: -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s \ // RUN: -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s \
// RUN: | FileCheck --strict-whitespace %s // RUN: | FileCheck --strict-whitespace %s
// //
// Test with serialization: // Test with serialization:
// RUN: %clang_cc1 -triple x86_64-pc-linux -fdouble-square-bracket-attributes \ // RUN: %clang_cc1 -triple x86_64-pc-linux \
// RUN: -Wno-deprecated-declarations -emit-pch -o %t %s // RUN: -Wno-deprecated-declarations -emit-pch -o %t %s
// RUN: %clang_cc1 -x c -triple x86_64-pc-linux -fdouble-square-bracket-attributes \ // RUN: %clang_cc1 -x c -triple x86_64-pc-linux \
// RUN: -Wno-deprecated-declarations -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \ // RUN: -Wno-deprecated-declarations -include-pch %t -ast-dump-all -ast-dump-filter Test /dev/null \
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \ // RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
// RUN: | FileCheck --strict-whitespace %s // RUN: | FileCheck --strict-whitespace %s

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 %s -ast-dump -fdouble-square-bracket-attributes | FileCheck %s // RUN: %clang_cc1 %s -ast-dump | FileCheck %s
// Verify that we print the [[clang::annotate_type]] attribute. // Verify that we print the [[clang::annotate_type]] attribute.
// FIXME: The arguments are currently not printed -- see also comments in // FIXME: The arguments are currently not printed -- see also comments in

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -DDOUBLE_BRACKET_ATTRS=1 -fdouble-square-bracket-attributes -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple %itanium_abi_triple -DDOUBLE_BRACKET_ATTRS=1 -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s
#if DOUBLE_BRACKET_ATTRS #if DOUBLE_BRACKET_ATTRS
#define __tag1 [[clang::btf_type_tag("tag1")]] #define __tag1 [[clang::btf_type_tag("tag1")]]

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -DDOUBLE_BRACKET_ATTRS=1 -fdouble-square-bracket-attributes -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple %itanium_abi_triple -DDOUBLE_BRACKET_ATTRS=1 -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s
#if DOUBLE_BRACKET_ATTRS #if DOUBLE_BRACKET_ATTRS
#define __tag1 [[clang::btf_type_tag("tag1")]] #define __tag1 [[clang::btf_type_tag("tag1")]]

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -Wno-unused-value -fdouble-square-bracket-attributes -verify %s // RUN: %clang_cc1 -Wno-unused-value -verify %s
#define NODEREF __attribute__((noderef)) #define NODEREF __attribute__((noderef))

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -std=c99 -fms-extensions -fdouble-square-bracket-attributes -Wno-pragma-pack %s // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -std=c99 -fms-extensions -Wno-pragma-pack %s
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -std=c99 -fms-extensions -fdouble-square-bracket-attributes -Wno-pragma-pack %s // RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp-simd -std=c99 -fms-extensions -Wno-pragma-pack %s
[[omp::directive(assumes)]]; // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism' clause for '#pragma omp assumes'}} [[omp::directive(assumes)]]; // expected-error {{expected at least one 'ext_', 'absent', 'contains', 'holds', 'no_openmp', 'no_openmp_routines', 'no_parallelism' clause for '#pragma omp assumes'}}
[[omp::directive(begin)]]; // expected-error {{expected an OpenMP directive}} [[omp::directive(begin)]]; // expected-error {{expected an OpenMP directive}}

View File

@ -7,13 +7,12 @@
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fsyntax-only -verify=off -Wno-openmp %s // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fsyntax-only -verify=off -Wno-openmp %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fsyntax-only -verify=off -Wno-openmp-51-extensions %s // RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fsyntax-only -verify=off -Wno-openmp-51-extensions %s
// RUN: %clang_cc1 -fopenmp -fsyntax-only -verify=pre -Wpre-openmp-51-compat -x c -fdouble-square-bracket-attributes %s // RUN: %clang_cc1 -fopenmp -fsyntax-only -verify=pre -Wpre-openmp-51-compat -x c -std=c2x %s
// RUN: %clang_cc1 -fopenmp -fsyntax-only -verify=off -x c -std=c2x %s // RUN-: %clang_cc1 -fopenmp -fsyntax-only -verify=off -x c -std=c2x %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -fsyntax-only -verify=ext -Wopenmp -x c -std=c2x %s // RUN-: %clang_cc1 -fopenmp -fopenmp-version=50 -fsyntax-only -verify=ext -Wopenmp -x c -std=c2x %s
// off-no-diagnostics // off-no-diagnostics
int x; int x;
[[omp::directive(threadprivate(x))]]; // pre-warning {{specifying OpenMP directives with [[]] is incompatible with OpenMP standards before OpenMP 5.1}} \ [[omp::directive(threadprivate(x))]]; // pre-warning {{specifying OpenMP directives with [[]] is incompatible with OpenMP standards before OpenMP 5.1}} \
// ext-warning {{specifying OpenMP directives with [[]] is an OpenMP 5.1 extension}} // ext-warning {{specifying OpenMP directives with [[]] is an OpenMP 5.1 extension}}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
#if !__has_extension(gnu_asm) #if !__has_extension(gnu_asm)
#error Extension 'gnu_asm' should be available by default #error Extension 'gnu_asm' should be available by default

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify=expected,notc2x -Wno-strict-prototypes %s // RUN: %clang_cc1 -fsyntax-only -verify=expected,notc2x -Wno-strict-prototypes %s
// RUN: %clang_cc1 -fsyntax-only -std=gnu2x -verify=expected,c2x %s // RUN: %clang_cc1 -fsyntax-only -std=gnu2x -verify=expected,c2x %s
enum [[]] E { enum [[]] E {

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
// expected-no-diagnostics // expected-no-diagnostics
enum __attribute__((deprecated)) E1 : int; // ok enum __attribute__((deprecated)) E1 : int; // ok

View File

@ -196,12 +196,9 @@ namespace PR15017 {
} }
// Ensure we produce at least some diagnostic for attributes in C++98. // Ensure we produce at least some diagnostic for attributes in C++98.
[[]] struct S; [[]] struct S; // expected-error {{misplaced attributes}}
#if __cplusplus <= 199711L #if __cplusplus < 201103L
// expected-error@-2 {{expected expression}} // expected-error@-2 {{[[]] attributes are a C++11 extension}}
// expected-error@-3 {{expected unqualified-id}}
#else
// expected-error@-5 {{misplaced attributes}}
#endif #endif
namespace test7 { namespace test7 {

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -triple x86_64-apple-macosx10.10.0 -verify %s // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.10.0 -verify %s
// expected-no-diagnostics // expected-no-diagnostics
@interface NSObject @interface NSObject

View File

@ -8,9 +8,6 @@ extern float groupshared f; // Ok, redeclaration?
// expected-warning@+1 {{'auto' type specifier is a C++11 extension}} // expected-warning@+1 {{'auto' type specifier is a C++11 extension}}
auto l = []() groupshared {}; auto l = []() groupshared {};
// NOTE: remove this error once [[]] attribute is supported except for hlsl202x.
// expected-error@+1 {{expected expression}}
float groupshared [[]] i = 12; float groupshared [[]] i = 12;
float groupshared const i2 = 12; float groupshared const i2 = 12;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fdouble-square-bracket-attributes -std=c11 -E -P %s -o - | FileCheck %s // RUN: %clang_cc1 -std=c11 -E -P %s -o - | FileCheck %s
// RUN: %clang_cc1 -std=c2x -E -P %s -o - | FileCheck %s // RUN: %clang_cc1 -std=c2x -E -P %s -o - | FileCheck %s
#define C2x(x) x: __has_c_attribute(x) #define C2x(x) x: __has_c_attribute(x)

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 %s -fsyntax-only -fdouble-square-bracket-attributes -verify // RUN: %clang_cc1 %s -fsyntax-only -verify
const char *some_function(); const char *some_function();

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 %s -fsyntax-only -fdouble-square-bracket-attributes -verify // RUN: %clang_cc1 %s -fsyntax-only -verify
void __attribute__((annotate("foo"))) foo(float *a) { void __attribute__((annotate("foo"))) foo(float *a) {
__attribute__((annotate("bar"))) int x; __attribute__((annotate("bar"))) int x;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fdouble-square-bracket-attributes -verify %s // RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -verify %s
[[clang::availability(macosx,introduced=10.4,deprecated=10.2)]] void f0(void); // expected-warning{{feature cannot be deprecated in macOS version 10.2 before it was introduced in version 10.4; attribute ignored}} [[clang::availability(macosx,introduced=10.4,deprecated=10.2)]] void f0(void); // expected-warning{{feature cannot be deprecated in macOS version 10.2 before it was introduced in version 10.4; attribute ignored}}
[[clang::availability(ios,obsoleted=2.1,deprecated=3.0)]] void f1(void); // expected-warning{{feature cannot be obsoleted in iOS version 2.1 before it was deprecated in version 3.0; attribute ignored}} [[clang::availability(ios,obsoleted=2.1,deprecated=3.0)]] void f1(void); // expected-warning{{feature cannot be obsoleted in iOS version 2.1 before it was deprecated in version 3.0; attribute ignored}}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fblocks -verify -fdouble-square-bracket-attributes %s // RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
template<class T> template<class T>
class Class { class Class {

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fblocks -verify -fdouble-square-bracket-attributes %s // RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
void threeClauses(void) __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration))); void threeClauses(void) __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 %s -fsyntax-only -fdouble-square-bracket-attributes -verify // RUN: %clang_cc1 %s -fsyntax-only -verify
void g(void) { void g(void) {
if (1) if (1)

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fdouble-square-bracket-attributes %s // RUN: %clang_cc1 -verify -fsyntax-only %s
struct [[clang::objc_bridge_related(NSParagraphStyle,,)]] TestBridgedRef; struct [[clang::objc_bridge_related(NSParagraphStyle,,)]] TestBridgedRef;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -fdouble-square-bracket-attributes -verify %s // RUN: %clang_cc1 -triple i386-apple-darwin9 -fsyntax-only -verify %s
__attribute((regparm(2))) int x0(void); __attribute((regparm(2))) int x0(void);
__attribute((regparm(1.0))) int x1(void); // expected-error{{'regparm' attribute requires an integer constant}} __attribute((regparm(1.0))) int x1(void); // expected-error{{'regparm' attribute requires an integer constant}}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
struct A {}; struct A {};

View File

@ -0,0 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c2x -Wpre-c2x-compat -verify=pre-c2x %s
// RUN: %clang_cc1 -fsyntax-only -std=c17 -Wc2x-extensions -verify=c2x-ext %s
[[]] void func(); // pre-c2x-warning {{[[]] attributes are incompatible with C standards before C2x}}
// c2x-ext-warning@-1 {{[[]] attributes are a C2x extension}}

View File

@ -1,7 +1,7 @@
// RUN: %clang_cc1 -verify=all,c2x -std=c2x -fsyntax-only %s // RUN: %clang_cc1 -verify=all,c2x -std=c2x -fsyntax-only %s
// RUN: %clang_cc1 -verify=all -std=c17 -fdouble-square-bracket-attributes -fsyntax-only %s // RUN: %clang_cc1 -verify=all -std=c17 -fsyntax-only %s
// RUN: %clang_cc1 -verify=none -Wno-deprecated-attributes -D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS -std=c2x -fsyntax-only %s // RUN: %clang_cc1 -verify=none -Wno-deprecated-attributes -D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS -std=c2x -fsyntax-only %s
// RUN: %clang_cc1 -verify=none -Wno-deprecated-attributes -D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS -std=c17 -fdouble-square-bracket-attributes -fsyntax-only %s // RUN: %clang_cc1 -verify=none -Wno-deprecated-attributes -D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS -std=c17 -fsyntax-only %s
// none-no-diagnostics // none-no-diagnostics
// Test preprocessor functionality. // Test preprocessor functionality.

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify -fdouble-square-bracket-attributes %s // RUN: %clang_cc1 -fsyntax-only -verify %s
int var __attribute__((internal_linkage)); int var __attribute__((internal_linkage));
int var2 __attribute__((internal_linkage,common)); // expected-error{{'common' and 'internal_linkage' attributes are not compatible}} \ int var2 __attribute__((internal_linkage,common)); // expected-error{{'common' and 'internal_linkage' attributes are not compatible}} \

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 %s -fenable-matrix -fdouble-square-bracket-attributes -pedantic -verify -triple=x86_64-apple-darwin9 // RUN: %clang_cc1 %s -fenable-matrix -pedantic -verify -triple=x86_64-apple-darwin9
typedef float sx5x10_t __attribute__((matrix_type(5, 10))); typedef float sx5x10_t __attribute__((matrix_type(5, 10)));
typedef int ix3x2_t __attribute__((matrix_type(3, 2))); typedef int ix3x2_t __attribute__((matrix_type(3, 2)));
@ -8,17 +8,17 @@ typedef unsigned ix3x3 __attribute__((matrix_type(3, 3)));
// Verify that we can use the [[]] spelling of the attribute. // Verify that we can use the [[]] spelling of the attribute.
// We intentionally use the same type alias name to check that both versions // We intentionally use the same type alias name to check that both versions
// define the same type. // define the same type.
typedef float [[clang::matrix_type(5, 10)]] sx5x10_t; typedef float [[clang::matrix_type(5, 10)]] sx5x10_t; // expected-warning {{[[]] attributes are a C2x extension}}
typedef int [[clang::matrix_type(3, 2)]] ix3x2_t; typedef int [[clang::matrix_type(3, 2)]] ix3x2_t; // expected-warning {{[[]] attributes are a C2x extension}}
[[clang::matrix_type(5, 10)]] typedef float sx5x10_t; [[clang::matrix_type(5, 10)]] typedef float sx5x10_t; // expected-warning {{[[]] attributes are a C2x extension}}
// expected-warning@-1 {{applying attribute 'matrix_type' to a declaration is deprecated; apply it to the type instead}} // expected-warning@-1 {{applying attribute 'matrix_type' to a declaration is deprecated; apply it to the type instead}}
[[clang::matrix_type(3, 2)]] typedef int ix3x2_t; [[clang::matrix_type(3, 2)]] typedef int ix3x2_t; // expected-warning {{[[]] attributes are a C2x extension}}
// expected-warning@-1 {{applying attribute 'matrix_type' to a declaration is deprecated; apply it to the type instead}} // expected-warning@-1 {{applying attribute 'matrix_type' to a declaration is deprecated; apply it to the type instead}}
// Attribute may not be used outside typedefs. // Attribute may not be used outside typedefs.
[[clang::matrix_type(3, 2)]] int ix3x2_var; [[clang::matrix_type(3, 2)]] int ix3x2_var; // expected-warning {{[[]] attributes are a C2x extension}}
// expected-error@-1 {{'matrix_type' attribute only applies to typedefs}} // expected-error@-1 {{'matrix_type' attribute only applies to typedefs}}
int [[clang::matrix_type(3, 2)]] ix3x2_var; int [[clang::matrix_type(3, 2)]] ix3x2_var; // expected-warning {{[[]] attributes are a C2x extension}}
// expected-error@-1 {{'matrix_type' attribute only applies to typedefs}} // expected-error@-1 {{'matrix_type' attribute only applies to typedefs}}
void transpose(sx5x10_t a, ix3x2_t b, dx3x3 c, int *d, int e) { void transpose(sx5x10_t a, ix3x2_t b, dx3x3 c, int *d, int e) {

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 %s -triple armv7 -target-feature +neon -fsyntax-only -fdouble-square-bracket-attributes -verify // RUN: %clang_cc1 %s -triple armv7 -target-feature +neon -fsyntax-only -verify
// RUN: %clang_cc1 %s -triple armv8 -target-feature +neon -fsyntax-only -fdouble-square-bracket-attributes -verify // RUN: %clang_cc1 %s -triple armv8 -target-feature +neon -fsyntax-only -verify
typedef float float32_t; typedef float float32_t;
typedef signed char poly8_t; typedef signed char poly8_t;

View File

@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -flax-vector-conversions=all -fdouble-square-bracket-attributes -Werror -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -flax-vector-conversions=all -Werror -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -flax-vector-conversions=all -fdouble-square-bracket-attributes -verify -fsyntax-only -DERROR_CHECK %s // RUN: %clang_cc1 -triple thumbv8.1m.main-none-none-eabi -target-feature +mve.fp -flax-vector-conversions=all -verify -fsyntax-only -DERROR_CHECK %s
typedef signed short int16_t; typedef signed short int16_t;
typedef signed int int32_t; typedef signed int int32_t;

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s -Wincompatible-pointer-types -Wno-strict-prototypes // RUN: %clang_cc1 -fsyntax-only -verify %s -Wincompatible-pointer-types -Wno-strict-prototypes
int var __attribute__((overloadable)); // expected-error{{'overloadable' attribute only applies to functions}} int var __attribute__((overloadable)); // expected-error{{'overloadable' attribute only applies to functions}}
void bad_attr_target(int) [[clang::overloadable]]; // expected-error{{'overloadable' attribute cannot be applied to types}} void bad_attr_target(int) [[clang::overloadable]]; // expected-error{{'overloadable' attribute cannot be applied to types}}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 %s -verify -fsyntax-only -fdouble-square-bracket-attributes -Weverything -Wno-unused-but-set-variable -triple x86_64-apple-darwin10 // RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -Wno-unused-but-set-variable -triple x86_64-apple-darwin10
// Test the compatibility of clang's vector extensions with gcc's vector // Test the compatibility of clang's vector extensions with gcc's vector
// extensions for C. Notably &&, ||, ?: and ! are not available. // extensions for C. Notably &&, ||, ?: and ! are not available.
@ -20,17 +20,14 @@ typedef int v4i32 __attribute((vector_size(16)));
// Verify that we can use the [[]] spelling of the attribute. // Verify that we can use the [[]] spelling of the attribute.
// We intentionally use the same type alias name to check that both versions // We intentionally use the same type alias name to check that both versions
// define the same type. // define the same type.
// FIXME: Warnings are nuisance warnings due to the `-Weverything` flag, but typedef long long v2i64 [[gnu::vector_size(16)]]; // expected-warning{{[[]] attributes are a C2x extension}}
// we shouldn't really be emitting them in C mode with the typedef int v2i32 [[gnu::vector_size(8)]]; // expected-warning{{[[]] attributes are a C2x extension}}
// `-fdouble-square-bracket-attributes` flag.
typedef long long v2i64 [[gnu::vector_size(16)]]; // expected-warning{{C++11 attribute syntax is incompatible with C++98}}
typedef int v2i32 [[gnu::vector_size(8)]]; // expected-warning{{C++11 attribute syntax is incompatible with C++98}}
// Check various positions where the [[]] spelling can or cannot be used. // Check various positions where the [[]] spelling can or cannot be used.
[[gnu::vector_size(16)]] typedef long long v2i64; // expected-warning{{C++11 attribute syntax is incompatible with C++98}} [[gnu::vector_size(16)]] typedef long long v2i64; // expected-warning{{[[]] attributes are a C2x extension}}
typedef long long [[gnu::vector_size(16)]] v2i64_ignored; typedef long long [[gnu::vector_size(16)]] v2i64_ignored;
// expected-warning@-1{{'vector_size' attribute ignored}} // expected-warning@-1{{'vector_size' attribute ignored}}
// expected-warning@-2{{C++11 attribute syntax is incompatible with C++98}} // expected-warning@-2{{[[]] attributes are a C2x extension}}
// FIXME: Contrary to the error message that we emit, GCC does actually allow // FIXME: Contrary to the error message that we emit, GCC does actually allow
// the attribute in the following position. Somewhat surprisingly, the attribute // the attribute in the following position. Somewhat surprisingly, the attribute
// is applied not to the pointer but to the base type, i.e. this declaration has // is applied not to the pointer but to the base type, i.e. this declaration has
@ -38,10 +35,10 @@ typedef long long [[gnu::vector_size(16)]] v2i64_ignored;
typedef long long *[[gnu::vector_size(16)]] v2i64_doesnt_work; typedef long long *[[gnu::vector_size(16)]] v2i64_doesnt_work;
// expected-error@-1{{invalid vector element type 'long long *'}} // expected-error@-1{{invalid vector element type 'long long *'}}
// expected-warning@-2{{GCC does not allow the 'vector_size' attribute to be written on a type}} // expected-warning@-2{{GCC does not allow the 'vector_size' attribute to be written on a type}}
// expected-warning@-3{{C++11 attribute syntax is incompatible with C++98}} // expected-warning@-3{{[[]] attributes are a C2x extension}}
// Verify that we can use the attribute outside of a typedef. // Verify that we can use the attribute outside of a typedef.
static int v2i32_var [[gnu::vector_size(8)]]; // expected-warning{{C++11 attribute syntax is incompatible with C++98}} static int v2i32_var [[gnu::vector_size(8)]]; // expected-warning{{[[]] attributes are a C2x extension}}
void arithmeticTest(void); void arithmeticTest(void);
void logicTest(void); void logicTest(void);

View File

@ -1,12 +0,0 @@
// RUN: %clang_cc1 -fsyntax-only -fno-double-square-bracket-attributes -verify -pedantic -std=c++11 -DERRORS %s
// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify -pedantic -std=c++11 %s
struct [[]] S {};
#ifdef ERRORS
// expected-error@-3 {{declaration of anonymous struct must be a definition}}
// expected-warning@-4 {{declaration does not declare anything}}
#else
// expected-no-diagnostics
#endif

View File

@ -24,7 +24,7 @@ template<int ...I> // expected-warning {{variadic templates are incompatible wi
class Variadic3 {}; class Variadic3 {};
alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}} alignas(8) int with_alignas; // expected-warning {{'alignas' is incompatible with C++98}}
int with_attribute [[ ]]; // expected-warning {{C++11 attribute syntax is incompatible with C++98}} int with_attribute [[ ]]; // expected-warning {{[[]] attributes are incompatible with C++ standards before C++11}}
void Literals() { void Literals() {
(void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}} (void)u8"str"; // expected-warning {{unicode literals are incompatible with C++98}}
@ -104,7 +104,7 @@ struct RefQualifier {
auto f() -> int; // expected-warning {{trailing return types are incompatible with C++98}} auto f() -> int; // expected-warning {{trailing return types are incompatible with C++98}}
#ifdef CXX14COMPAT #ifdef CXX14COMPAT
auto ff() { return 5; } // expected-warning {{'auto' type specifier is incompatible with C++98}} auto ff() { return 5; } // expected-warning {{'auto' type specifier is incompatible with C++98}}
// expected-warning@-1 {{return type deduction is incompatible with C++ standards before C++14}} // expected-warning@-1 {{return type deduction is incompatible with C++ standards before C++14}}
#endif #endif

View File

@ -7,3 +7,5 @@ unsigned long long ull1 = // expected-warning {{'long long' is a C++11 extension
enum struct E1 { A, B }; // expected-warning {{scoped enumerations are a C++11 extension}} enum struct E1 { A, B }; // expected-warning {{scoped enumerations are a C++11 extension}}
enum class E2 { C, D }; // expected-warning {{scoped enumerations are a C++11 extension}} enum class E2 { C, D }; // expected-warning {{scoped enumerations are a C++11 extension}}
[[]] void func(); // expected-warning {{[[]] attributes are a C++11 extension}}

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -fdouble-square-bracket-attributes -verify %s // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
static id __attribute((objc_gc(weak))) a; static id __attribute((objc_gc(weak))) a;
static id __attribute((objc_gc(strong))) b; static id __attribute((objc_gc(strong))) b;

View File

@ -157,7 +157,7 @@ TEST(Attr, AnnotateType) {
AST = buildASTFromCodeWithArgs(R"c( AST = buildASTFromCodeWithArgs(R"c(
__auto_type [[clang::annotate_type("auto")]] auto_var = 1; __auto_type [[clang::annotate_type("auto")]] auto_var = 1;
)c", )c",
{"-fdouble-square-bracket-attributes"}, {},
"input.c"); "input.c");
{ {

View File

@ -3394,14 +3394,10 @@ static void GenerateHasAttrSpellingStringSwitch(
// If this is the C++11 variety, also add in the LangOpts test. // If this is the C++11 variety, also add in the LangOpts test.
if (Variety == "CXX11") if (Variety == "CXX11")
Test += " && LangOpts.CPlusPlus11"; Test += " && LangOpts.CPlusPlus11";
else if (Variety == "C2x")
Test += " && LangOpts.DoubleSquareBracketAttributes";
} else if (Variety == "CXX11") } else if (Variety == "CXX11")
// C++11 mode should be checked against LangOpts, which is presumed to be // C++11 mode should be checked against LangOpts, which is presumed to be
// present in the caller. // present in the caller.
Test = "LangOpts.CPlusPlus11"; Test = "LangOpts.CPlusPlus11";
else if (Variety == "C2x")
Test = "LangOpts.DoubleSquareBracketAttributes";
std::string TestStr = !Test.empty() std::string TestStr = !Test.empty()
? Test + " ? " + llvm::itostr(Version) + " : 0" ? Test + " ? " + llvm::itostr(Version) + " : 0"

View File

@ -575,7 +575,6 @@ ClangExpressionParser::ClangExpressionParser(
// FIXME: We should ask the driver for the appropriate default flags. // FIXME: We should ask the driver for the appropriate default flags.
lang_opts.GNUMode = true; lang_opts.GNUMode = true;
lang_opts.GNUKeywords = true; lang_opts.GNUKeywords = true;
lang_opts.DoubleSquareBracketAttributes = true;
lang_opts.CPlusPlus11 = true; lang_opts.CPlusPlus11 = true;
// The Darwin libc expects this macro to be set. // The Darwin libc expects this macro to be set.