-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[PAC] Fix codegen for polymorphic class variables with consteval constructors #154858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
constructors Fix a bug in CodeGen where such variables could cause a compilation error or be emitted with an undef initializer. rdar://155696134
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-codegen Author: Akira Hatanaka (ahatanak) ChangesFix a bug in CodeGen where such variables could cause a compilation error or be emitted with an undef initializer. rdar://155696134 Full diff: https://github.com/llvm/llvm-project/pull/154858.diff 2 Files Affected:
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index a96c1518d2a1d..3c1bdf9120d21 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -876,8 +876,9 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
for (const BaseInfo &Base : Bases) {
bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl;
- Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase,
- VTableClass, Offset + Base.Offset);
+ if (!Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase,
+ VTableClass, Offset + Base.Offset))
+ return false;
}
}
@@ -1627,7 +1628,7 @@ llvm::Constant *ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *CE) {
if (CE->isGLValue())
RetType = CGM.getContext().getLValueReferenceType(RetType);
- return emitAbstract(CE->getBeginLoc(), CE->getAPValueResult(), RetType);
+ return tryEmitAbstract(CE->getAPValueResult(), RetType);
}
llvm::Constant *
diff --git a/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp b/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp
index 1b103719fbe46..e33525c1ec0f9 100644
--- a/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp
+++ b/clang/test/CodeGenCXX/ptrauth-explicit-vtable-pointer-control.cpp
@@ -1,31 +1,31 @@
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
// RUN: -fptrauth-vtable-pointer-type-discrimination \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
// RUN: -fptrauth-vtable-pointer-address-discrimination \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics \
// RUN: -fptrauth-vtable-pointer-type-discrimination \
// RUN: -fptrauth-vtable-pointer-address-discrimination \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,NODISC %s
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
// RUN: -fptrauth-vtable-pointer-type-discrimination \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,TYPE %s
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
// RUN: -fptrauth-vtable-pointer-address-discrimination \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,ADDR %s
-// RUN: %clang_cc1 %s -x c++ -std=c++11 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
+// RUN: %clang_cc1 %s -x c++ -std=c++20 -triple aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
// RUN: -fptrauth-vtable-pointer-type-discrimination \
// RUN: -fptrauth-vtable-pointer-address-discrimination \
// RUN: -emit-llvm -o - | FileCheck --check-prefixes=CHECK,BOTH %s
@@ -78,6 +78,27 @@ struct authenticated(default_key, default_address_discrimination, custom_discrim
virtual void g();
};
+// CHECK: @_ZTVN5test19ConstEvalE = external unnamed_addr constant { [3 x ptr] }, align 8
+// CHECK: @_ZN5test12ceE = global %{{.*}} { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test19ConstEvalE, i32 0, i32 0, i32 2), i32 2, i64 0, ptr @_ZN5test12ceE) }, align 8
+// CHECK: @_ZTVN5test116ConstEvalDerivedE = linkonce_odr unnamed_addr constant { [3 x ptr] } { [3 x ptr] [ptr null, ptr @_ZTIN5test116ConstEvalDerivedE, ptr ptrauth (ptr @_ZN5test19ConstEval1fEv, i32 0, i64 26259, ptr getelementptr inbounds ({ [3 x ptr] }, ptr @_ZTVN5test116ConstEvalDerivedE, i32 0, i32 0, i32 2))] },{{.*}}align 8
+// CHECK: @_ZN5test13cedE = global { ptr } { ptr ptrauth (ptr getelementptr inbounds inrange(-16, 8) ({ [3 x ptr] }, ptr @_ZTVN5test116ConstEvalDerivedE, i32 0, i32 0, i32 2), i32 2, i64 0, ptr @_ZN5test13cedE) }, align 8
+
+struct authenticated(default_key, address_discrimination, no_extra_discrimination) ConstEval {
+ consteval ConstEval() {}
+ virtual void f();
+};
+
+// clang used to bail out with error message "could not emit constant value abstractly".
+ConstEval ce;
+
+struct ConstEvalDerived : public ConstEval {
+public:
+ consteval ConstEvalDerived() {}
+};
+
+// clang used to emit an undef initializer.
+ConstEvalDerived ced;
+
template <typename T>
struct SubClass : T {
virtual void g();
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, will probably need to be cherry-picked to llvm21 or have a release note.
@@ -876,8 +876,9 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD, | |||
|
|||
for (const BaseInfo &Base : Bases) { | |||
bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl; | |||
Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase, | |||
VTableClass, Offset + Base.Offset); | |||
if (!Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do wonder if it's possible to make this fail without ptrauth as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cor3ntin or @AaronBallman any ideas of whether that might be possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Failing, in this context, means you have an APValue that made it through constant evaluation, so we know it's a constant, but for some reason we can't actually emit it as a constant.
That generally shouldn't happen: the things that we allow through constant evaluation very closely match the things we can actually emit to LLVM IR, normally. The only way it can happen, as far as I know, is if we're trying to emit an authenticated pointer as an abstract constant. (We were looking at doing something for pointers to dllimport variables on Windows at one point, I think, but that never got merged.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@efriedma-quic so nothing other than ptrauth seems plausibly able to cause this given current functionality? Always annoying :D
…tructors (llvm#154858) Fix a bug in CodeGen where such variables could cause a compilation error or be emitted with an undef initializer when the vtable was signed with address discrimination. rdar://155696134
…tructors (llvm#154858) Fix a bug in CodeGen where such variables could cause a compilation error or be emitted with an undef initializer when the vtable was signed with address discrimination. rdar://155696134
/cherry-pick e612f37 |
/pull-request #155319 |
…tructors (llvm#154858) Fix a bug in CodeGen where such variables could cause a compilation error or be emitted with an undef initializer when the vtable was signed with address discrimination. rdar://155696134 (cherry picked from commit e612f37)
Fix a bug in CodeGen where such variables could cause a compilation error or be emitted with an undef initializer when the vtable was signed with address discrimination.
rdar://155696134