[clang] [clang] fix skipped parsing of late parsed attributes (PR #153558)

via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 14 01:50:26 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Matheus Izvekov (mizvekov)

<details>
<summary>Changes</summary>

Fixes some situations where late parsed attributes on functions are skipped, such as:

* With function try blocks.
* Error recovery when parsing out-of-line constructor definitions
* When skipping parsing of function bodies with -skip-function-bodies

Also fixes memory leaks in those situations.

Fixes https://github.com/llvm/llvm-project/issues/153551

---
Full diff: https://github.com/llvm/llvm-project/pull/153558.diff


4 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/lib/Parse/Parser.cpp (+4-4) 
- (modified) clang/test/Frontend/skip-function-bodies.cpp (+4-2) 
- (added) clang/test/Parser/diagnose_if.cpp (+12) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 3462a099a5ebe..38ed7d7f6a6d3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -176,6 +176,9 @@ Bug Fixes to Attribute Support
 
 - ``[[nodiscard]]`` is now respected on Objective-C and Objective-C++ methods.
   (#GH141504)
+- Fixes some late parsed attributes, when applied to function definitions, not being parsed
+  in function try blocks, and some situations where parsing of the function body
+  is skipped, such as error recovery and code completion. (#GH153551)
 - Using ``[[gnu::cleanup(some_func)]]`` where some_func is annotated with
   ``[[gnu::error("some error")]]`` now correctly triggers an error. (#GH146520)
 
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index e57a789251a5b..7d190ea99dba0 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1418,6 +1418,10 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
     // parameter list was specified.
     CurTemplateDepthTracker.addDepth(1);
 
+  // Late attributes are parsed in the same scope as the function body.
+  if (LateParsedAttrs)
+    ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);
+
   if (SkipFunctionBodies && (!Res || Actions.canSkipFunctionBody(Res)) &&
       trySkippingFunctionBody()) {
     BodyScope.Exit();
@@ -1442,10 +1446,6 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D,
   } else
     Actions.ActOnDefaultCtorInitializers(Res);
 
-  // Late attributes are parsed in the same scope as the function body.
-  if (LateParsedAttrs)
-    ParseLexedAttributeList(*LateParsedAttrs, Res, false, true);
-
   return ParseFunctionStatementBody(Res, BodyScope);
 }
 
diff --git a/clang/test/Frontend/skip-function-bodies.cpp b/clang/test/Frontend/skip-function-bodies.cpp
index d0593b474bda2..4cfc4c5bfff3c 100644
--- a/clang/test/Frontend/skip-function-bodies.cpp
+++ b/clang/test/Frontend/skip-function-bodies.cpp
@@ -1,13 +1,15 @@
 // Trivial check to ensure skip-function-bodies flag is propagated.
 //
-// RUN: %clang_cc1 -verify -skip-function-bodies -pedantic-errors %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -verify -skip-function-bodies %s
 
 int f() {
   // normally this should emit some diags, but we're skipping it!
   this is garbage;
 }
 
+void g() __attribute__((__diagnose_if__(baz))) {}
+// expected-error at -1 {{use of undeclared identifier 'baz'}}
+
 // Make sure we only accept it as a cc1 arg.
 // RUN: not %clang -skip-function-bodies %s 2>&1 | FileCheck %s
 // CHECK: clang: error: unknown argument '-skip-function-bodies'; did you mean '-Xclang -skip-function-bodies'?
diff --git a/clang/test/Parser/diagnose_if.cpp b/clang/test/Parser/diagnose_if.cpp
new file mode 100644
index 0000000000000..52059804c9ef9
--- /dev/null
+++ b/clang/test/Parser/diagnose_if.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -fsyntax-only -fcxx-exceptions -verify
+
+void t1() __attribute__((__diagnose_if__(baz))) try {} catch(...) {}
+// expected-error at -1 {{use of undeclared identifier 'baz'}}
+
+struct A {
+  A();
+};
+
+A::A() __attribute__((__diagnose_if__(baz))) :;
+// expected-error at -1 {{expected class member or base class name}}
+// expected-error at -2 {{use of undeclared identifier 'baz'}}

``````````

</details>


https://github.com/llvm/llvm-project/pull/153558


More information about the cfe-commits mailing list