https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/147308
>From 8f1c383f8f84fb636af4a78e0ff504830f9272f5 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Mon, 7 Jul 2025 17:20:48 +0300 Subject: [PATCH 1/8] [Clang] disallow operator in attribute argument lists --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/Basic/DiagnosticParseKinds.td | 2 ++ clang/lib/Parse/ParseDecl.cpp | 7 +++++++ clang/test/Parser/cxx0x-attributes.cpp | 5 +++++ 4 files changed, 15 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a6be59f1d6bd7..b8032ee9c03da 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -673,6 +673,7 @@ Improvements to Clang's diagnostics false positives in exception-heavy code, though only simple patterns are currently recognized. +- Clang now rejects ``#`` operators in attribute argument lists. (#GH147217) Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 6c30da376dafb..b39e2a7359c22 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -830,6 +830,8 @@ def err_ms_property_expected_comma_or_rparen : Error< "expected ',' or ')' at end of property accessor list">; def err_ms_property_initializer : Error< "property declaration cannot have a default member initializer">; +def err_invalid_attribute_argument + : Error<"'%0' is not allowed in attribute argument lists">; def err_assume_attr_expects_cond_expr : Error< "use of this expression in an %0 attribute requires parentheses">; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 7e739e09b15e8..059636653723c 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -488,6 +488,13 @@ unsigned Parser::ParseAttributeArgsCommon( bool AttributeHasVariadicIdentifierArg = attributeHasVariadicIdentifierArg(*AttrName, Form.getSyntax(), ScopeName); + if (Tok.is(tok::hash) || Tok.is(tok::hashhash)) { + Diag(Tok.getLocation(), diag::err_invalid_attribute_argument) + << PP.getSpelling(Tok); + SkipUntil(tok::r_paren, StopAtSemi); + return 0; + } + // Interpret "kw_this" as an identifier if the attributed requests it. if (ChangeKWThisToIdent && Tok.is(tok::kw_this)) Tok.setKind(tok::identifier); diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index 372a373a49ec5..d343cd4f3a93e 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -477,3 +477,8 @@ namespace P2361 { } alignas(int) struct AlignAsAttribute {}; // expected-error {{misplaced attributes; expected attributes here}} + +namespace GH147217 { + [[clang::annotate(#)]] void a(); // expected-error {{'#' is not allowed in attribute argument lists}} + [[clang::annotate(##)]] void b(); // expected-error {{'##' is not allowed in attribute argument lists}} +} >From 962f703e11a25f6ddf9b0ba5ac045456d5167242 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Mon, 7 Jul 2025 18:49:55 +0300 Subject: [PATCH 2/8] update diagnostic message --- clang/include/clang/Basic/DiagnosticParseKinds.td | 2 +- clang/test/Parser/cxx0x-attributes.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index b39e2a7359c22..d53ef7a93bfda 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -831,7 +831,7 @@ def err_ms_property_expected_comma_or_rparen : Error< def err_ms_property_initializer : Error< "property declaration cannot have a default member initializer">; def err_invalid_attribute_argument - : Error<"'%0' is not allowed in attribute argument lists">; + : Error<"'%0' is not allowed in an attribute argument list">; def err_assume_attr_expects_cond_expr : Error< "use of this expression in an %0 attribute requires parentheses">; diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index d343cd4f3a93e..f5a3039c4470c 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -479,6 +479,8 @@ namespace P2361 { alignas(int) struct AlignAsAttribute {}; // expected-error {{misplaced attributes; expected attributes here}} namespace GH147217 { - [[clang::annotate(#)]] void a(); // expected-error {{'#' is not allowed in attribute argument lists}} - [[clang::annotate(##)]] void b(); // expected-error {{'##' is not allowed in attribute argument lists}} + [[clang::annotate(#)]] void a(); // expected-error {{'#' is not allowed in an attribute argument list}} + [[clang::annotate(##)]] void b(); // expected-error {{'##' is not allowed in an attribute argument list}} + [[clang::annotate(%:)]] void c(); // expected-error {{'%:' is not allowed in an attribute argument list}} + [[clang::annotate(%:%:)]] void d(); // expected-error {{'%:%:' is not allowed in an attribute argument list}} } >From a697990d1fc6aa021c4b63bc0b3ad1efe55cec5b Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Mon, 7 Jul 2025 18:51:30 +0300 Subject: [PATCH 3/8] disallow and operators in C++ mode only --- clang/lib/Parse/ParseDecl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 059636653723c..495aa778b0d7f 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -488,7 +488,7 @@ unsigned Parser::ParseAttributeArgsCommon( bool AttributeHasVariadicIdentifierArg = attributeHasVariadicIdentifierArg(*AttrName, Form.getSyntax(), ScopeName); - if (Tok.is(tok::hash) || Tok.is(tok::hashhash)) { + if (getLangOpts().CPlusPlus && Tok.isOneOf(tok::hash, tok::hashhash)) { Diag(Tok.getLocation(), diag::err_invalid_attribute_argument) << PP.getSpelling(Tok); SkipUntil(tok::r_paren, StopAtSemi); >From ac38e4d2b4432af6c1eb6f69a76394c205c3eea7 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Wed, 9 Jul 2025 00:41:52 +0300 Subject: [PATCH 4/8] update release notes --- clang/docs/ReleaseNotes.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 554f89cc498c2..a7adb8919e5b4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -678,7 +678,10 @@ Improvements to Clang's diagnostics - Clang now accepts ``@tparam`` comments on variable template partial specializations. (#GH144775) -- Clang now rejects ``#`` operators in attribute argument lists. (#GH147217) +- Clang rejects the ``#`` and ``##`` preprocessor tokens in an attribute + argument list in C++. The operators can be used in macro replacement lists + with the usual preprocessor semantics. What is rejected are non-preprocessor + uses of the tokens. The same restrictions do not apply in C. (#GH147217) Improvements to Clang's time-trace ---------------------------------- >From 9204a36843d27fa23a522aacee3a6a16d9388970 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Wed, 9 Jul 2025 00:42:59 +0300 Subject: [PATCH 5/8] handle preprocessor tokens in unknown attributes --- clang/lib/Parse/ParseDecl.cpp | 7 --- clang/lib/Parse/ParseDeclCXX.cpp | 21 +++++++ .../cxx0x-attributes-preprocessor-tokens.cpp | 58 +++++++++++++++++++ clang/test/Parser/cxx0x-attributes.cpp | 7 --- 4 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 495aa778b0d7f..7e739e09b15e8 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -488,13 +488,6 @@ unsigned Parser::ParseAttributeArgsCommon( bool AttributeHasVariadicIdentifierArg = attributeHasVariadicIdentifierArg(*AttrName, Form.getSyntax(), ScopeName); - if (getLangOpts().CPlusPlus && Tok.isOneOf(tok::hash, tok::hashhash)) { - Diag(Tok.getLocation(), diag::err_invalid_attribute_argument) - << PP.getSpelling(Tok); - SkipUntil(tok::r_paren, StopAtSemi); - return 0; - } - // Interpret "kw_this" as an identifier if the attributed requests it. if (ChangeKWThisToIdent && Tok.is(tok::kw_this)) Tok.setKind(tok::identifier); diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 6b0564dca6f45..57555a287382b 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4523,6 +4523,27 @@ bool Parser::ParseCXX11AttributeArgs( Form = ParsedAttr::Form::Microsoft(); } + if (LO.CPlusPlus) { + TentativeParsingAction TPA(*this); + bool HasInvalidArgument = false; + while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof)) { + if (Tok.isOneOf(tok::hash, tok::hashhash)) { + Diag(Tok.getLocation(), diag::err_invalid_attribute_argument) + << PP.getSpelling(Tok); + HasInvalidArgument = true; + } + ConsumeAnyToken(); + } + + if (HasInvalidArgument) { + SkipUntil(tok::r_paren); + TPA.Commit(); + return true; + } + + TPA.Revert(); + } + // If the attribute isn't known, we will not attempt to parse any // arguments. if (Form.getSyntax() != ParsedAttr::AS_Microsoft && diff --git a/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp b/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp new file mode 100644 index 0000000000000..23a9d597e5dd8 --- /dev/null +++ b/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -E %s | FileCheck %s +// RUN: %clang_cc1 -x c -fsyntax-only -verify=c %s +// RUN: %clang_cc1 -x c -E %s | FileCheck %s + +#define ATTR_STR(X) [[clang::annotate(#X)]] +#define ATTR_PASTE(X, Y) [[clang::annotate("test", X ## Y)]] + +[[clang::assume(#)]] void f1(); // c-error {{expected expression}} \ + // expected-error {{'#' is not allowed in an attribute argument list}} + +[[clang::assume(##)]] void f2(); // c-error {{expected expression}} \ + // expected-error {{'##' is not allowed in an attribute argument list}} + +[[clang::assume(1#2#3)]] void f3(); // c-error {{use of this expression in an 'assume' attribute requires parentheses}} \ + // c-error {{expected ')'}} \ + // c-note {{to match this '('}} \ + // expected-error {{'#' is not allowed in an attribute argument list}} \ + // expected-error {{'#' is not allowed in an attribute argument list}} + +[[unknown::unknown(#)]] void f4(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ + // expected-error {{'#' is not allowed in an attribute argument list}} + +[[unknown::unknown(##)]] void f5(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ + // expected-error {{'##' is not allowed in an attribute argument list}} + +[[unknown::unknown(1#2#3)]] void f6(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ + // expected-error {{'#' is not allowed in an attribute argument list}} \ + // expected-error {{'#' is not allowed in an attribute argument list}} + +[[clang::assume(%:)]] void f7(); // c-error {{expected expression}} \ + // expected-error {{'%:' is not allowed in an attribute argument list}} + + +[[clang::assume(%:%:)]] void f8(); // c-error {{expected expression}} \ + // expected-error {{'%:%:' is not allowed in an attribute argument list}} + +[[clang::assume(1%:2%:3)]] void f9(); // c-error {{use of this expression in an 'assume' attribute requires parentheses}} \ + // c-error {{expected ')'}} \ + // c-note {{to match this '('}} \ + // expected-error {{'%:' is not allowed in an attribute argument list}} \ + // expected-error {{'%:' is not allowed in an attribute argument list}} + +[[unknown::unknown(%:)]] void f10(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ + // expected-error {{'%:' is not allowed in an attribute argument list}} + +[[unknown::unknown(%:%:)]] void f11(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ + // expected-error {{'%:%:' is not allowed in an attribute argument list}} + +[[unknown::unknown(1%:2%:3)]] void f12(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ + // expected-error {{'%:' is not allowed in an attribute argument list}} \ + // expected-error {{'%:' is not allowed in an attribute argument list}} + +ATTR_STR(stringify) void f13(); +// CHECK: {{\[\[}}clang{{::}}annotate("stringify"){{\]\]}} void f13(); + +ATTR_PASTE(1, 2) void f14(); +// CHECK: {{\[\[}}clang{{::}}annotate("test", 12){{\]\]}} void f14(); diff --git a/clang/test/Parser/cxx0x-attributes.cpp b/clang/test/Parser/cxx0x-attributes.cpp index f5a3039c4470c..372a373a49ec5 100644 --- a/clang/test/Parser/cxx0x-attributes.cpp +++ b/clang/test/Parser/cxx0x-attributes.cpp @@ -477,10 +477,3 @@ namespace P2361 { } alignas(int) struct AlignAsAttribute {}; // expected-error {{misplaced attributes; expected attributes here}} - -namespace GH147217 { - [[clang::annotate(#)]] void a(); // expected-error {{'#' is not allowed in an attribute argument list}} - [[clang::annotate(##)]] void b(); // expected-error {{'##' is not allowed in an attribute argument list}} - [[clang::annotate(%:)]] void c(); // expected-error {{'%:' is not allowed in an attribute argument list}} - [[clang::annotate(%:%:)]] void d(); // expected-error {{'%:%:' is not allowed in an attribute argument list}} -} >From 4e429b015dd0bf2a23eb203ef4ea2d33788ad63c Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Wed, 30 Jul 2025 16:43:04 +0300 Subject: [PATCH 6/8] update release notes --- clang/docs/ReleaseNotes.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 911188aed8b78..e0ce5959d89eb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -684,10 +684,11 @@ Improvements to Clang's diagnostics - Clang now tries to avoid printing file paths that contain ``..``, instead preferring the canonical file path if it ends up being shorter. -- Clang rejects the ``#`` and ``##`` preprocessor tokens in an attribute +- Clang now rejects the ``#`` and ``##`` preprocessor tokens in an attribute argument list in C++. The operators can be used in macro replacement lists - with the usual preprocessor semantics. What is rejected are non-preprocessor - uses of the tokens. The same restrictions do not apply in C. (#GH147217) + with the usual preprocessor semantics, however non-preprocessor use of + tokens are now rejected in C++. Compilation in C mode is unchanged, and + still permits these tokens to be used. (#GH147217) Improvements to Clang's time-trace ---------------------------------- >From b495eed9f6f9db8782a2b4b3d4790e9deadf97f5 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Mon, 4 Aug 2025 14:49:26 +0300 Subject: [PATCH 7/8] change diagnostic category from error to extension --- clang/docs/ReleaseNotes.rst | 10 +++++----- clang/include/clang/Basic/DiagnosticParseKinds.td | 4 ++-- clang/lib/Parse/ParseDeclCXX.cpp | 2 +- .../Parser/cxx0x-attributes-preprocessor-tokens.cpp | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d73e8ec090034..0dc39e10b0dba 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -124,11 +124,11 @@ Improvements to Clang's diagnostics Added a new warning in this group for the case where the attribute is missing/implicit on an override of a virtual method. -- Clang now rejects the ``#`` and ``##`` preprocessor tokens in an attribute - argument list in C++. The operators can be used in macro replacement lists - with the usual preprocessor semantics, however non-preprocessor use of - tokens are now rejected in C++. Compilation in C mode is unchanged, and - still permits these tokens to be used. (#GH147217) +- Clang now diagnoses the use of ``#`` and ``##`` preprocessor tokens in + attribute argument lists in C++ when ``-pedantic`` is enabled. The operators + can be used in macro replacement lists with the usual preprocessor semantics, + however, non-preprocessor use of tokens now triggers a pedantic warning in C++. + Compilation in C mode is unchanged, and still permits these tokens to be used. (#GH147217) Improvements to Clang's time-trace ---------------------------------- diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 817d2980291d4..394804c85a9f1 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -830,8 +830,8 @@ def err_ms_property_expected_comma_or_rparen : Error< "expected ',' or ')' at end of property accessor list">; def err_ms_property_initializer : Error< "property declaration cannot have a default member initializer">; -def err_invalid_attribute_argument - : Error<"'%0' is not allowed in an attribute argument list">; +def ext_invalid_attribute_argument + : Extension<"'%0' is not allowed in an attribute argument list">; def err_assume_attr_expects_cond_expr : Error< "use of this expression in an %0 attribute requires parentheses">; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 6360db0174243..cce3b247d31ad 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -4517,7 +4517,7 @@ bool Parser::ParseCXX11AttributeArgs( bool HasInvalidArgument = false; while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof)) { if (Tok.isOneOf(tok::hash, tok::hashhash)) { - Diag(Tok.getLocation(), diag::err_invalid_attribute_argument) + Diag(Tok.getLocation(), diag::ext_invalid_attribute_argument) << PP.getSpelling(Tok); HasInvalidArgument = true; } diff --git a/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp b/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp index 23a9d597e5dd8..054b0c679240f 100644 --- a/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp +++ b/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -E %s | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -pedantic-errors -verify %s +// RUN: %clang_cc1 -pedantic-errors -E %s | FileCheck %s // RUN: %clang_cc1 -x c -fsyntax-only -verify=c %s // RUN: %clang_cc1 -x c -E %s | FileCheck %s >From 7bbd74158d79296ee509093591d26e8e580cd930 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Mon, 4 Aug 2025 15:58:23 +0300 Subject: [PATCH 8/8] add new diagnostic group --- .../clang/Basic/DiagnosticParseKinds.td | 3 +- .../cxx0x-attributes-preprocessor-tokens.cpp | 36 +++++++++---------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index fbef6254b25ce..3a6a9e582c7ca 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -831,7 +831,8 @@ def err_ms_property_expected_comma_or_rparen : Error< def err_ms_property_initializer : Error< "property declaration cannot have a default member initializer">; def ext_invalid_attribute_argument - : Extension<"'%0' is not allowed in an attribute argument list">; + : Extension<"'%0' is not allowed in an attribute argument list">, + InGroup<DiagGroup<"attribute-preprocessor-tokens">>; def err_assume_attr_expects_cond_expr : Error< "use of this expression in an %0 attribute requires parentheses">; diff --git a/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp b/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp index 054b0c679240f..6605d2486aa03 100644 --- a/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp +++ b/clang/test/Parser/cxx0x-attributes-preprocessor-tokens.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -pedantic-errors -verify %s -// RUN: %clang_cc1 -pedantic-errors -E %s | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -Wattribute-preprocessor-tokens -verify %s +// RUN: %clang_cc1 -Wattribute-preprocessor-tokens -E %s | FileCheck %s // RUN: %clang_cc1 -x c -fsyntax-only -verify=c %s // RUN: %clang_cc1 -x c -E %s | FileCheck %s @@ -7,49 +7,49 @@ #define ATTR_PASTE(X, Y) [[clang::annotate("test", X ## Y)]] [[clang::assume(#)]] void f1(); // c-error {{expected expression}} \ - // expected-error {{'#' is not allowed in an attribute argument list}} + // expected-warning {{'#' is not allowed in an attribute argument list}} [[clang::assume(##)]] void f2(); // c-error {{expected expression}} \ - // expected-error {{'##' is not allowed in an attribute argument list}} + // expected-warning {{'##' is not allowed in an attribute argument list}} [[clang::assume(1#2#3)]] void f3(); // c-error {{use of this expression in an 'assume' attribute requires parentheses}} \ // c-error {{expected ')'}} \ // c-note {{to match this '('}} \ - // expected-error {{'#' is not allowed in an attribute argument list}} \ - // expected-error {{'#' is not allowed in an attribute argument list}} + // expected-warning {{'#' is not allowed in an attribute argument list}} \ + // expected-warning {{'#' is not allowed in an attribute argument list}} [[unknown::unknown(#)]] void f4(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ - // expected-error {{'#' is not allowed in an attribute argument list}} + // expected-warning {{'#' is not allowed in an attribute argument list}} [[unknown::unknown(##)]] void f5(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ - // expected-error {{'##' is not allowed in an attribute argument list}} + // expected-warning {{'##' is not allowed in an attribute argument list}} [[unknown::unknown(1#2#3)]] void f6(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ - // expected-error {{'#' is not allowed in an attribute argument list}} \ - // expected-error {{'#' is not allowed in an attribute argument list}} + // expected-warning {{'#' is not allowed in an attribute argument list}} \ + // expected-warning {{'#' is not allowed in an attribute argument list}} [[clang::assume(%:)]] void f7(); // c-error {{expected expression}} \ - // expected-error {{'%:' is not allowed in an attribute argument list}} + // expected-warning {{'%:' is not allowed in an attribute argument list}} [[clang::assume(%:%:)]] void f8(); // c-error {{expected expression}} \ - // expected-error {{'%:%:' is not allowed in an attribute argument list}} + // expected-warning {{'%:%:' is not allowed in an attribute argument list}} [[clang::assume(1%:2%:3)]] void f9(); // c-error {{use of this expression in an 'assume' attribute requires parentheses}} \ // c-error {{expected ')'}} \ // c-note {{to match this '('}} \ - // expected-error {{'%:' is not allowed in an attribute argument list}} \ - // expected-error {{'%:' is not allowed in an attribute argument list}} + // expected-warning {{'%:' is not allowed in an attribute argument list}} \ + // expected-warning {{'%:' is not allowed in an attribute argument list}} [[unknown::unknown(%:)]] void f10(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ - // expected-error {{'%:' is not allowed in an attribute argument list}} + // expected-warning {{'%:' is not allowed in an attribute argument list}} [[unknown::unknown(%:%:)]] void f11(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ - // expected-error {{'%:%:' is not allowed in an attribute argument list}} + // expected-warning {{'%:%:' is not allowed in an attribute argument list}} [[unknown::unknown(1%:2%:3)]] void f12(); // c-warning {{unknown attribute 'unknown::unknown' ignored}} \ - // expected-error {{'%:' is not allowed in an attribute argument list}} \ - // expected-error {{'%:' is not allowed in an attribute argument list}} + // expected-warning {{'%:' is not allowed in an attribute argument list}} \ + // expected-warning {{'%:' is not allowed in an attribute argument list}} ATTR_STR(stringify) void f13(); // CHECK: {{\[\[}}clang{{::}}annotate("stringify"){{\]\]}} void f13(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits