[clang] [Debug Info] Fix a Verifier failure with redeclared nodebug functions (PR #218070)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 21 17:04:18 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Adrian Prantl (adrian-prantl)
<details>
<summary>Changes</summary>
When a forward-declard function is used before its definition, and the definition has a nodebug attribute on it, the existing heuristic in EmitFuncDeclForCallSite would fail, because it only saw the non-nodebug forward declaration, thus emitting a conflicting DISubprogram for the call site.
rdar://184780682
Assisted-by: claude
---
Full diff: https://github.com/llvm/llvm-project/pull/218070.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+7-2)
- (modified) clang/test/DebugInfo/Generic/attr-nodebug2.c (+19)
``````````diff
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 37ee3765fd7c4..091a403043b61 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -5166,13 +5166,18 @@ void CGDebugInfo::EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
return;
if (Func->getSubprogram())
return;
+ // If the function has a definition, it either already has a
+ // subprogram or it is a nodebug function.
+ if (!Func->isDeclaration())
+ return;
const FunctionDecl *CalleeDecl =
cast<FunctionDecl>(CalleeGlobalDecl.getDecl());
// Do not emit a declaration subprogram for a function with nodebug
- // attribute, or if call site info isn't required.
- if (CalleeDecl->hasAttr<NoDebugAttr>() ||
+ // attribute, or if call site info isn't required. The attribute
+ // could be on a later redeclaration than the one the call resolves to.
+ if (CalleeDecl->getMostRecentDecl()->hasAttr<NoDebugAttr>() ||
getCallSiteRelatedAttrs() == llvm::DINode::FlagZero)
return;
diff --git a/clang/test/DebugInfo/Generic/attr-nodebug2.c b/clang/test/DebugInfo/Generic/attr-nodebug2.c
index a17e1e6cbff7d..4d191f0fc0cf1 100644
--- a/clang/test/DebugInfo/Generic/attr-nodebug2.c
+++ b/clang/test/DebugInfo/Generic/attr-nodebug2.c
@@ -14,6 +14,19 @@ __attribute__((nodebug)) void t1(void) {
a++;
}
+// A deferred caller is emitted after the nodebug definition, so its call site
+// declaration would attach to a function that already has a body.
+void t2(void);
+
+__attribute__((nodebug)) void t2(void) {
+ int a = 10;
+ a++;
+}
+
+static inline void deferred_caller(void) { t2(); }
+
+void use2(void) { deferred_caller(); }
+
#ifdef __cplusplus
}
#endif
@@ -32,3 +45,9 @@ __attribute__((nodebug)) void t1(void) {
// CHECK-SAME: {
// CHECK-NOT: !dbg
// CHECK: }
+
+// CHECK-LABEL: define{{.*}} void @t2()
+// CHECK-NOT: !dbg
+// CHECK-SAME: {
+// CHECK-NOT: !dbg
+// CHECK: }
``````````
</details>
https://github.com/llvm/llvm-project/pull/218070
More information about the cfe-commits
mailing list