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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits