[llvm-branch-commits] [clang] 58f9e80 - [clang] CodeGen: fix ConstantExpr LValue emission (#181057)
Cullen Rhodes via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Feb 23 00:33:16 PST 2026
Author: Matheus Izvekov
Date: 2026-02-23T08:33:08Z
New Revision: 58f9e8036cc6de6e4642ca68acf344f493ee41cd
URL: https://github.com/llvm/llvm-project/commit/58f9e8036cc6de6e4642ca68acf344f493ee41cd
DIFF: https://github.com/llvm/llvm-project/commit/58f9e8036cc6de6e4642ca68acf344f493ee41cd.diff
LOG: [clang] CodeGen: fix ConstantExpr LValue emission (#181057)
This fixes a regression introduced in #161029, though not the fault of
that patch, only by incidental changes regarding the preservation of
constant expression nodes.
The LValue emission of ConstantExpr was doing strange things with
regards to what type corresponds to the result of the constant
expression, which are not justified by any tests or in the discussions
of the relevant patches.
See
https://github.com/llvm/llvm-project/commit/09669e6c5fa1e8db9c1091cc264640fb0377d6b6
and https://github.com/llvm/llvm-project/pull/78041 and
https://github.com/llvm/llvm-project/commit/51e4aa87e05c45bebf9658a47980b1934c88be31
This simplifies it to just use the expression type.
Since this regression was never released, there are no release notes.
Fixes #177807
(cherry picked from commit a3b51529d1948dee37b5bb44d49fa82b9ea37157)
Added:
Modified:
clang/lib/CodeGen/CGExpr.cpp
clang/test/CodeGenCXX/cxx2a-consteval.cpp
clang/test/CodeGenCXX/template-cxx20.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 999726340aaed..56e2569c8122f 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1701,14 +1701,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E,
return LV;
}
-static QualType getConstantExprReferredType(const FullExpr *E,
- const ASTContext &Ctx) {
- const Expr *SE = E->getSubExpr()->IgnoreImplicit();
- if (isa<OpaqueValueExpr>(SE))
- return SE->getType();
- return cast<CallExpr>(SE)->getCallReturnType(Ctx)->getPointeeType();
-}
-
LValue CodeGenFunction::EmitLValueHelper(const Expr *E,
KnownNonNull_t IsKnownNonNull) {
ApplyDebugLocation DL(*this, E);
@@ -1746,10 +1738,8 @@ LValue CodeGenFunction::EmitLValueHelper(const Expr *E,
return EmitDeclRefLValue(cast<DeclRefExpr>(E));
case Expr::ConstantExprClass: {
const ConstantExpr *CE = cast<ConstantExpr>(E);
- if (llvm::Value *Result = ConstantEmitter(*this).tryEmitConstantExpr(CE)) {
- QualType RetType = getConstantExprReferredType(CE, getContext());
- return MakeNaturalAlignAddrLValue(Result, RetType);
- }
+ if (llvm::Value *Result = ConstantEmitter(*this).tryEmitConstantExpr(CE))
+ return MakeNaturalAlignPointeeAddrLValue(Result, CE->getType());
return EmitLValue(cast<ConstantExpr>(E)->getSubExpr(), IsKnownNonNull);
}
case Expr::ParenExprClass:
diff --git a/clang/test/CodeGenCXX/cxx2a-consteval.cpp b/clang/test/CodeGenCXX/cxx2a-consteval.cpp
index bfeabc946da41..ace603ffe5713 100644
--- a/clang/test/CodeGenCXX/cxx2a-consteval.cpp
+++ b/clang/test/CodeGenCXX/cxx2a-consteval.cpp
@@ -2,16 +2,17 @@
// RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s
// RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s
// RUN: FileCheck -check-prefix=EVAL-FN -input-file=%t.ll %s
+// RUN: FileCheck -check-prefix=EVAL-FN-NONEXPR -input-file=%t.ll %s
//
// RUN: %clang_cc1 -emit-llvm %s -Dconsteval="" -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll
// RUN: FileCheck -check-prefix=EXPR -input-file=%t.ll %s
-// RUN: %clang_cc1 -emit-llvm %s -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -emit-llvm %s -DEXPR -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll -fexperimental-new-constant-interpreter
// RUN: FileCheck -check-prefix=EVAL -input-file=%t.ll %s
// RUN: FileCheck -check-prefix=EVAL-STATIC -input-file=%t.ll %s
// RUN: FileCheck -check-prefix=EVAL-FN -input-file=%t.ll %s
//
-// RUN: %clang_cc1 -emit-llvm %s -Dconsteval="" -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -emit-llvm %s -DEXPR -Dconsteval="" -std=c++2a -triple x86_64-unknown-linux-gnu -o %t.ll -fexperimental-new-constant-interpreter
// RUN: FileCheck -check-prefix=EXPR -input-file=%t.ll %s
// there is two version of symbol checks to ensure
@@ -259,6 +260,28 @@ int test_UserConvOverload_ceval() {
return test_UserConvOverload_helper_ceval(UserConv());
}
+#ifndef EXPR
+namespace virt {
+struct A { alignas(32) char a[32]; };
+struct B : virtual A {
+ long long x, y;
+};
+struct C { virtual void v(); };
+struct D : C, B {};
+
+extern D d;
+consteval B& c() { return d; }
+long long f() { return c().y; }
+
+// Make sure the non-virtual alignment is used.
+
+// EVAL-FN-NONEXPR-LABEL: define {{.*}} i64 @_ZN4virt1fEv()
+// EVAL-FN-NONEXPR-NEXT: entry:
+// EVAL-FN-NONEXPR-NEXT: load i64, ptr getelementptr inbounds nuw (%"struct.virt::B", ptr getelementptr (i8, ptr @_ZN4virt1dE, i64 8), i32 0, i32 2), align 8
+// EVAL-FN-NONEXPR-NEXT: ret i64
+} // namespace virt
+#endif
+
consteval void void_test() {}
void void_call() { // EVAL-FN-LABEL: define {{.*}} @_Z9void_call
// EVAL-FN-NOT: call
diff --git a/clang/test/CodeGenCXX/template-cxx20.cpp b/clang/test/CodeGenCXX/template-cxx20.cpp
index aeb1cc915145f..0e603ac1e0f2f 100644
--- a/clang/test/CodeGenCXX/template-cxx20.cpp
+++ b/clang/test/CodeGenCXX/template-cxx20.cpp
@@ -20,5 +20,16 @@ namespace GH161029_regression1 {
void h() {
g<decltype([](auto) -> void { s.U(); }), 0>();
}
- // CHECK: call void @_ZN20GH161029_regression11SINS_6TagSetINS_1EELS2_0EEEE1UEv
+ // CHECK-DAG: call void @_ZN20GH161029_regression11SINS_6TagSetINS_1EELS2_0EEEE1UEv
+}
+
+namespace GH177807 {
+ template<int &G> void foo() {
+ [](auto ...A) {
+ (((void)A, G), ...) = 1234;
+ }(0);
+ }
+ int i = 0;
+ template void foo<i>();
+ // CHECK-DAG: store i32 1234, ptr @_ZN8GH1778071iE, align 4
}
More information about the llvm-branch-commits
mailing list