llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Shashi Shankar (shashforge) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/175497.diff 3 Files Affected: - (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+1) - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+13-5) - (added) clang/test/CodeGenCXX/bug175423.cpp (+21) ``````````diff 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; } `````````` </details> https://github.com/llvm/llvm-project/pull/175497 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
