[clang] 2929683 - [clang][codegen] Fix emission of consteval constructor of derived type

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 9 01:54:31 PST 2023


Author: Mariya Podchishchaeva
Date: 2023-02-09T04:43:48-05:00
New Revision: 2929683eef27e6b3ac95325d955cd39bc2e416c0

URL: https://github.com/llvm/llvm-project/commit/2929683eef27e6b3ac95325d955cd39bc2e416c0
DIFF: https://github.com/llvm/llvm-project/commit/2929683eef27e6b3ac95325d955cd39bc2e416c0.diff

LOG: [clang][codegen] Fix emission of consteval constructor of derived type

For simple derived type ConstantEmitter returns a struct of the same
size but different type which is then stored field-by-field into memory
via pointer to derived type. In case base type has more fields than derived,
the incorrect GEP is emitted. So, just cast pointer to derived type to
appropriate type with enough fields.

Fixes https://github.com/llvm/llvm-project/issues/60166

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D142534

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/CodeGen/CGExprAgg.cpp
    clang/test/CodeGenCXX/cxx20-consteval-crash.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 35c3fa5780368..4d52dbb27a90e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -64,6 +64,9 @@ Bug Fixes
   driver mode and emit an error which suggests using ``/TC`` or ``/TP``
   ``clang-cl`` options instead. This fixes
   `Issue 59307 <https://github.com/llvm/llvm-project/issues/59307>`_.
+- Fix crash when evaluating consteval constructor of derived class whose base
+  has more than one field. This fixes
+  `Issue 60166 <https://github.com/llvm/llvm-project/issues/60166>`_.
 
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 34e535a78dd6e..b7fe7fefec2f9 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -131,7 +131,14 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
     EnsureDest(E->getType());
 
     if (llvm::Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
-      CGF.EmitAggregateStore(Result, Dest.getAddress(),
+      Address StoreDest = Dest.getAddress();
+      // The emitted value is guaranteed to have the same size as the
+      // destination but can have a 
diff erent type. Just do a bitcast in this
+      // case to avoid incorrect GEPs.
+      if (Result->getType() != StoreDest.getType())
+        StoreDest =
+            CGF.Builder.CreateElementBitCast(StoreDest, Result->getType());
+      CGF.EmitAggregateStore(Result, StoreDest,
                              E->getType().isVolatileQualified());
       return;
     }

diff  --git a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp
index 44513599ad916..ebd7eafaf7156 100644
--- a/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp
+++ b/clang/test/CodeGenCXX/cxx20-consteval-crash.cpp
@@ -92,3 +92,27 @@ int foo() {
 }
 } // namespace Issue55065
 
+namespace GH60166 {
+
+struct Base {
+   void* one = nullptr;
+   void* two = nullptr;
+};
+
+struct Derived : Base {
+   void* three = nullptr;
+   consteval Derived() = default;
+};
+
+void method() {
+  // CHECK: %agg.tmp.ensured = alloca %"struct.GH60166::Derived"
+  // CHECK: %0 = getelementptr inbounds { ptr, ptr, ptr }, ptr %agg.tmp.ensured, i32 0, i32 0
+  // CHECK: store ptr null, ptr %0, align 8
+  // CHECK: %1 = getelementptr inbounds { ptr, ptr, ptr }, ptr %agg.tmp.ensured, i32 0, i32 1
+  // CHECK: store ptr null, ptr %1, align 8
+  // CHECK: %2 = getelementptr inbounds { ptr, ptr, ptr }, ptr %agg.tmp.ensured, i32 0, i32 2
+  // CHECK: store ptr null, ptr %2, align 8
+   (void)Derived();
+}
+
+} // namespace GH60166


        


More information about the cfe-commits mailing list