[clang] [Clang][Parser] Reject unbalanced unknown attribute arguments (PR #220259)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 7 04:33:01 PDT 2026
https://github.com/nehaGautam07 updated https://github.com/llvm/llvm-project/pull/220259
>From a68ba345063247506807acaf2990ba1fc4aa749e Mon Sep 17 00:00:00 2001
From: neharaj <neharajgautam07 at gmail.com>
Date: Sat, 5 Sep 2026 11:52:10 +0000
Subject: [PATCH 1/6] [Clang][Parser] Reject unbalanced unknown attribute
arguments
---
clang/include/clang/Parse/Parser.h | 4 +++-
clang/lib/Parse/ParseDeclCXX.cpp | 5 ++++-
clang/lib/Parse/Parser.cpp | 6 ++++++
clang/test/Parser/cxx11-unbalanced-attr-args.cpp | 7 +++++++
4 files changed, 20 insertions(+), 2 deletions(-)
create mode 100644 clang/test/Parser/cxx11-unbalanced-attr-args.cpp
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index ae91153e34e3a98..4a1b330fc995e03 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -570,7 +570,9 @@ class Parser : public CodeCompletionHandler {
StopAtSemi = 1 << 0, ///< Stop skipping at semicolon
/// Stop skipping at specified token, but don't skip the token itself
StopBeforeMatch = 1 << 1,
- StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
+ StopAtCodeCompletion = 1 << 2, ///< Stop at code completion
+ /// Do not swallow an unmatched ')', ']', or '}'.
+ StopAtUnbalanced = 1 << 3
};
friend constexpr SkipUntilFlags operator|(SkipUntilFlags L,
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index d701cbaa43bdd63..0e67f83f76b3b11 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4581,7 +4581,10 @@ bool Parser::ParseCXX11AttributeArgs(
ScopeName, AttrName, getTargetInfo(), getLangOpts())) {
// Eat the left paren, then skip to the ending right paren.
ConsumeParen();
- SkipUntil(tok::r_paren);
+ if (!SkipUntil(tok::r_paren, StopAtUnbalanced)) {
+ Diag(Tok, diag::err_expected) << tok::r_paren;
+ SkipUntil(tok::r_paren, StopAtSemi);
+ }
return false;
}
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 84059a41238cce8..c67bb8503735cbe 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -394,16 +394,22 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
case tok::r_paren:
if (ParenCount && !isFirstTokenSkipped)
return false; // Matches something.
+ if (HasFlagsSet(Flags, StopAtUnbalanced))
+ return false;
ConsumeParen();
break;
case tok::r_square:
if (BracketCount && !isFirstTokenSkipped)
return false; // Matches something.
+ if (HasFlagsSet(Flags, StopAtUnbalanced))
+ return false;
ConsumeBracket();
break;
case tok::r_brace:
if (BraceCount && !isFirstTokenSkipped)
return false; // Matches something.
+ if (HasFlagsSet(Flags, StopAtUnbalanced))
+ return false;
ConsumeBrace();
break;
diff --git a/clang/test/Parser/cxx11-unbalanced-attr-args.cpp b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
new file mode 100644
index 000000000000000..ba132bca19c7240
--- /dev/null
+++ b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c -std=c23 %s
+
+[[X1(])]]; // expected-error {{expected ')'}} expected-warning {{unknown attribute 'X1' ignored}}
+[[X1(})]]; // expected-error {{expected ')'}} expected-warning {{unknown attribute 'X1' ignored}}
+[[X1]]; // expected-warning {{unknown attribute 'X1' ignored}}
+[[X1()]]; // expected-warning {{unknown attribute 'X1' ignored}}
\ No newline at end of file
>From 6756cc54b4e3e0ef9bc643d3847c9b89fb52fe1b Mon Sep 17 00:00:00 2001
From: neharaj <neharajgautam07 at gmail.com>
Date: Sun, 6 Sep 2026 11:25:33 +0000
Subject: [PATCH 2/6] Retrigger CI
>From f79dfafc594a56216daa053fbc65538a2c5682ee Mon Sep 17 00:00:00 2001
From: neharaj <neharajgautam07 at gmail.com>
Date: Thu, 10 Sep 2026 09:24:15 +0000
Subject: [PATCH 3/6] [Clang][Parser] Diagnose unbalanced attr args as a
pedantic warning
---
clang/include/clang/Basic/DiagnosticParseKinds.td | 2 ++
clang/lib/Parse/ParseDeclCXX.cpp | 2 +-
clang/test/Parser/cxx11-unbalanced-attr-args.cpp | 14 +++++++-------
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index a06d3c899453c18..ba8d0636a17c188 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -826,6 +826,8 @@ def err_using_attribute_ns_conflict : Error<
"attribute with scope specifier cannot follow default scope specifier">;
def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
def err_keyword_not_allowed : Error<"%0 cannot appear here">;
+def ext_unbalanced_attribute_args : ExtWarn<
+ "attribute argument list is not a balanced token sequence">, InGroup<Pedantic>;
def ext_cxx11_attr_placement : ExtWarn<
"ISO C++ does not allow %select{an attribute list|%0}1 to appear here">,
InGroup<DiagGroup<"cxx-attribute-extension">>;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 0e67f83f76b3b11..2b8b052721b8d16 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -4582,7 +4582,7 @@ bool Parser::ParseCXX11AttributeArgs(
// Eat the left paren, then skip to the ending right paren.
ConsumeParen();
if (!SkipUntil(tok::r_paren, StopAtUnbalanced)) {
- Diag(Tok, diag::err_expected) << tok::r_paren;
+ Diag(Tok, diag::ext_unbalanced_attribute_args);
SkipUntil(tok::r_paren, StopAtSemi);
}
return false;
diff --git a/clang/test/Parser/cxx11-unbalanced-attr-args.cpp b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
index ba132bca19c7240..a24e1cf46cdde1b 100644
--- a/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
+++ b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -x c -std=c23 %s
-
-[[X1(])]]; // expected-error {{expected ')'}} expected-warning {{unknown attribute 'X1' ignored}}
-[[X1(})]]; // expected-error {{expected ')'}} expected-warning {{unknown attribute 'X1' ignored}}
-[[X1]]; // expected-warning {{unknown attribute 'X1' ignored}}
-[[X1()]]; // expected-warning {{unknown attribute 'X1' ignored}}
\ No newline at end of file
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -x c -std=c23 %s
+
+[[X1(])]]; // expected-warning {{attribute argument list is not a balanced token sequence}} expected-warning {{unknown attribute 'X1' ignored}}
+[[X1(})]]; // expected-warning {{attribute argument list is not a balanced token sequence}} expected-warning {{unknown attribute 'X1' ignored}}
+[[X1]]; // expected-warning {{unknown attribute 'X1' ignored}}
+[[X1()]]; // expected-warning {{unknown attribute 'X1' ignored}}
>From bc93de7d3c8b2312099a42669129407bcccc66a5 Mon Sep 17 00:00:00 2001
From: neharaj <neharajgautam07 at gmail.com>
Date: Thu, 10 Sep 2026 12:08:49 +0000
Subject: [PATCH 4/6] [Clang][Parser] Put unbalanced attr-args warning in its
own group
---
clang/include/clang/Basic/DiagnosticParseKinds.td | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index ba8d0636a17c188..9b631b00569694c 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -827,7 +827,8 @@ def err_using_attribute_ns_conflict : Error<
def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
def err_keyword_not_allowed : Error<"%0 cannot appear here">;
def ext_unbalanced_attribute_args : ExtWarn<
- "attribute argument list is not a balanced token sequence">, InGroup<Pedantic>;
+ "attribute argument list is not a balanced token sequence">,
+ InGroup<DiagGroup<"unbalanced-attribute-args">>;
def ext_cxx11_attr_placement : ExtWarn<
"ISO C++ does not allow %select{an attribute list|%0}1 to appear here">,
InGroup<DiagGroup<"cxx-attribute-extension">>;
>From da966504a81e948fb4c395e1e01d892409f6ec92 Mon Sep 17 00:00:00 2001
From: neharaj <neharajgautam07 at gmail.com>
Date: Wed, 30 Sep 2026 06:18:21 +0000
Subject: [PATCH 5/6] clang: make unbalanced attribute args pedantic warning
---
clang/include/clang/Basic/DiagnosticParseKinds.td | 2 +-
clang/test/Parser/cxx11-unbalanced-attr-args.cpp | 12 ++++++++----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 9b631b00569694c..48c03e6b16468d7 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -826,7 +826,7 @@ def err_using_attribute_ns_conflict : Error<
"attribute with scope specifier cannot follow default scope specifier">;
def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
def err_keyword_not_allowed : Error<"%0 cannot appear here">;
-def ext_unbalanced_attribute_args : ExtWarn<
+def ext_unbalanced_attribute_args : Extension<
"attribute argument list is not a balanced token sequence">,
InGroup<DiagGroup<"unbalanced-attribute-args">>;
def ext_cxx11_attr_placement : ExtWarn<
diff --git a/clang/test/Parser/cxx11-unbalanced-attr-args.cpp b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
index a24e1cf46cdde1b..ec74c482fd6b203 100644
--- a/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
+++ b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
@@ -1,7 +1,11 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,pedantic -std=c++11 -pedantic %s
// RUN: %clang_cc1 -fsyntax-only -verify -x c -std=c23 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,pedantic -x c -std=c23 -pedantic %s
-[[X1(])]]; // expected-warning {{attribute argument list is not a balanced token sequence}} expected-warning {{unknown attribute 'X1' ignored}}
-[[X1(})]]; // expected-warning {{attribute argument list is not a balanced token sequence}} expected-warning {{unknown attribute 'X1' ignored}}
-[[X1]]; // expected-warning {{unknown attribute 'X1' ignored}}
-[[X1()]]; // expected-warning {{unknown attribute 'X1' ignored}}
+void test() {
+ [[X1(])]]; // expected-warning {{unknown attribute 'X1' ignored}} pedantic-warning {{attribute argument list is not a balanced token sequence}}
+ [[X1(})]]; // expected-warning {{unknown attribute 'X1' ignored}} pedantic-warning {{attribute argument list is not a balanced token sequence}}
+ [[X1]]; // expected-warning {{unknown attribute 'X1' ignored}}
+ [[X1()]]; // expected-warning {{unknown attribute 'X1' ignored}}
+}
>From e04271fc2d8b8e7d1d0bda2e9214957e8a9fb519 Mon Sep 17 00:00:00 2001
From: neharaj <neharajgautam07 at gmail.com>
Date: Wed, 7 Oct 2026 11:32:22 +0000
Subject: [PATCH 6/6] [Clang][Parser] Add tests for unbalanced attribute
arguments
---
.../Parser/cxx11-unbalanced-attr-args.cpp | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/clang/test/Parser/cxx11-unbalanced-attr-args.cpp b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
index ec74c482fd6b203..09416a92b838257 100644
--- a/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
+++ b/clang/test/Parser/cxx11-unbalanced-attr-args.cpp
@@ -9,3 +9,23 @@ void test() {
[[X1]]; // expected-warning {{unknown attribute 'X1' ignored}}
[[X1()]]; // expected-warning {{unknown attribute 'X1' ignored}}
}
+
+void test1() {
+ [[X1())]]; // expected-error {{expected ','}} expected-warning {{unknown attribute 'X1' ignored}}
+}
+
+void test2() {
+ [[X1([)]]; // expected-error {{expected ']'}} pedantic-warning {{attribute argument list is not a balanced token sequence}}
+} // expected-error {{expected statement}}
+
+void test3() {
+ [[X1({)]]; // expected-error {{expected ']'}} pedantic-warning {{attribute argument list is not a balanced token sequence}}
+} // expected-error {{expected statement}}
+
+void test4() {
+ [[X1(()]]; // expected-error {{expected ']'}} pedantic-warning {{attribute argument list is not a balanced token sequence}}
+} // expected-error {{expected statement}}
+
+void test5() {
+ [[X1([[[[[]]]])]]; // expected-warning {{unknown attribute 'X1' ignored}}
+}
More information about the cfe-commits
mailing list