[clang] [Clang] fix crash parsing forbidden attribute args in pragma attributes (PR #182362)
Oleksandr Tarasiuk via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 19 12:20:52 PST 2026
https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/182362
Fixes #182122
---
This patch resolves a crash when parsing `#pragma clang attribute` arguments for attributes that forbid arguments. The root cause is that the `#pragma` attribute path doesn't pass `EndLoc` to
https://github.com/llvm/llvm-project/blob/413cafa4624eb37e586e266f44abd64896e1c598/clang/lib/Parse/ParsePragma.cpp#L1982-L1985
unlike the normal attribute parsing flow
https://github.com/llvm/llvm-project/blob/413cafa4624eb37e586e266f44abd64896e1c598/clang/lib/Parse/ParseDeclCXX.cpp#L4706
Without `EndLoc`, argument parsing cannot update the parsed end token
https://github.com/llvm/llvm-project/blob/413cafa4624eb37e586e266f44abd64896e1c598/clang/lib/Parse/ParseDecl.cpp#L621-L622
and `fix-it` gets an invalid end location
https://github.com/llvm/llvm-project/blob/0dafeb97a4687c29f5182fa0239c7fa39ee23091/clang/lib/Parse/ParseDeclCXX.cpp#L4537
This change makes the pragma path pass `EndLoc` the same way as the regular flow does, preventing the crash and preserving valid fix-it ranges.
>From 4faec39a5b899bdfc743011ccad7b134e99496ca Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Thu, 19 Feb 2026 22:03:09 +0200
Subject: [PATCH] [Clang] fix crash parsing forbidden attribute args in pragma
attributes
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Parse/ParsePragma.cpp | 3 ++-
clang/test/FixIt/fixit-pragma-attribute.cpp | 4 ++++
clang/test/Parser/pragma-attribute.cpp | 5 +++++
4 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6e9e5baea2921..533cde545b25b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -273,6 +273,7 @@ Bug Fixes in This Version
- Fixed an assertion failure when evaluating ``_Countof`` on invalid ``void``-typed operands. (#GH180893)
- Fixed a ``-Winvalid-noreturn`` false positive for unreachable ``try`` blocks following an unconditional ``throw``. (#GH174822)
- Fixed an assertion failure caused by error recovery while extending a nested name specifier with results from ordinary lookup. (#GH181470)
+- Fixed a crash when parsing ``#pragma clang attribute`` arguments for attributes that forbid arguments. (#GH182122)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index def2817c930b2..734d095d74cdf 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -1982,7 +1982,8 @@ void Parser::HandlePragmaAttribute() {
if ((Tok.is(tok::l_square) && NextToken().is(tok::l_square)) ||
Tok.isRegularKeywordAttribute()) {
// Parse the CXX11 style attribute.
- ParseCXX11AttributeSpecifier(Attrs);
+ SourceLocation EndLoc = Tok.getLocation();
+ ParseCXX11AttributeSpecifier(Attrs, &EndLoc);
} else if (Tok.is(tok::kw___attribute)) {
ConsumeToken();
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
diff --git a/clang/test/FixIt/fixit-pragma-attribute.cpp b/clang/test/FixIt/fixit-pragma-attribute.cpp
index ad233ef067915..ecfd6e60b253e 100644
--- a/clang/test/FixIt/fixit-pragma-attribute.cpp
+++ b/clang/test/FixIt/fixit-pragma-attribute.cpp
@@ -84,3 +84,7 @@
#pragma clang attribute push (__attribute__((objc_externally_retained)), apply_to)
// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:82-[[@LINE-1]]:82}:" = any(function, variable(unless(is_parameter)))"
+
+int x;
+#pragma clang attribute push ([[noreturn (x))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:42-[[@LINE-1]]:45}:""
diff --git a/clang/test/Parser/pragma-attribute.cpp b/clang/test/Parser/pragma-attribute.cpp
index eaf1a775c1c88..0ef630f1cc06f 100644
--- a/clang/test/Parser/pragma-attribute.cpp
+++ b/clang/test/Parser/pragma-attribute.cpp
@@ -217,3 +217,8 @@ _Pragma("clang attribute pop");
#pragma clang attribute push (__attribute__((disable_tail_calls,)), apply_to = function) // expected-error {{expected identifier that represents an attribute name}}
#pragma clang attribute push ([[clang::disable_tail_calls, noreturn]]) // expected-error {{expected ','}}
+
+int x;
+#pragma clang attribute push ([[noreturn (x)) // expected-error {{attribute 'noreturn' cannot have an argument list}} \
+ // expected-error {{expected ']'}} \
+ // expected-error {{expected ']'}}
More information about the cfe-commits
mailing list