[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