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

Reply via email to