https://github.com/shashforge created https://github.com/llvm/llvm-project/pull/175497
This patch fixes a crash when compiling templates with record-local definitions in dependent contexts. Clang could enqueue record-local member definitions whose lexical record context is still dependent for deferred emission. During code generation this could lead to crashes when codegen encounters placeholder or dependent types. The fix skips adding record-local definitions whose lexical record context is dependent. A regression test is added. Fixes #175423. >From e29c7aff4817ab122f8e7ec9e8ca01895e57e56a Mon Sep 17 00:00:00 2001 From: Shashi Shankar <[email protected]> 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..377eb3013661f 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5222,12 +5222,20 @@ 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())) { + 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; - } - } + 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; } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
