[clang] [clang][CodeGen] Avoid emitting dependent record-local definitions (PR #175497)
Shashi Shankar via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 18 11:15:40 PST 2026
https://github.com/shashforge updated https://github.com/llvm/llvm-project/pull/175497
>From 662dd0e3237d8be74b5abab25d5e02e635382e94 Mon Sep 17 00:00:00 2001
From: Shashi Shankar <shashishankar1687 at gmail.com>
Date: Mon, 12 Jan 2026 08:39:29 +0100
Subject: [PATCH] [clang][CodeGen] Avoid emitting dependent record-local
definitions
Clang could enqueue record-local member definitions from dependent
contexts for deferred emission. During code generation this could
lead to crashes when codegen encounters placeholder or dependent
types.
Skip adding record-local definitions whose lexical record context
is still dependent.
Fixes #175423.
---
clang/lib/CodeGen/CodeGenFunction.cpp | 1 +
clang/lib/CodeGen/CodeGenModule.cpp | 18 +++++++++++++-----
clang/test/CodeGenCXX/bug175423.cpp | 21 +++++++++++++++++++++
3 files changed, 35 insertions(+), 5 deletions(-)
create mode 100644 clang/test/CodeGenCXX/bug175423.cpp
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 6c0589be32913..b9fe749791db1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1775,6 +1775,7 @@ bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
bool AllowLabels) {
// FIXME: Rename and handle conversion of other evaluatable things
// to bool.
+
Expr::EvalResult Result;
if (!Cond->EvaluateAsInt(Result, getContext()))
return false; // Not foldable, not integer or not fully evaluatable.
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 85ed38f144627..34dccf25a9c92 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5222,11 +5222,19 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(
// Look for a declaration that's lexically in a record.
for (const auto *FD = cast<FunctionDecl>(D)->getMostRecentDecl(); FD;
FD = FD->getPreviousDecl()) {
- if (isa<CXXRecordDecl>(FD->getLexicalDeclContext())) {
- if (FD->doesThisDeclarationHaveABody()) {
- addDeferredDeclToEmit(GD.getWithDecl(FD));
- break;
- }
+ const auto *LexicalRD =
+ dyn_cast<CXXRecordDecl>(FD->getLexicalDeclContext());
+ if (!LexicalRD)
+ continue;
+
+ // Do not attempt to emit template patterns. These are still in a
+ // dependent context and cannot be code generated until instantiated.
+ if (LexicalRD->isDependentContext())
+ continue;
+
+ if (FD->doesThisDeclarationHaveABody()) {
+ addDeferredDeclToEmit(GD.getWithDecl(FD));
+ break;
}
}
}
diff --git a/clang/test/CodeGenCXX/bug175423.cpp b/clang/test/CodeGenCXX/bug175423.cpp
new file mode 100644
index 0000000000000..7f3fbf24371a3
--- /dev/null
+++ b/clang/test/CodeGenCXX/bug175423.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++20 -emit-llvm -o - %s -w | FileCheck %s
+// CHECK: define{{.*}} i32 @main
+
+template <typename, typename>
+inline constexpr bool is_same_v = false;
+
+template <typename T>
+inline constexpr bool is_same_v<T, T> = true;
+
+template <int &T> void FuncTemplate() { T; }
+
+template <typename T> struct Container {
+ static void Execute() {
+ if (is_same_v<T, int>)
+ ;
+ static int InternalVar;
+ FuncTemplate<InternalVar>;
+ }
+};
+
+int main() { Container<char>::Execute; }
More information about the cfe-commits
mailing list