diff options
| author | Alex Voicu <alexandru.voicu@amd.com> | 2023-08-28 20:44:06 +0100 |
|---|---|---|
| committer | Alex Voicu <alexandru.voicu@amd.com> | 2023-08-28 20:44:06 +0100 |
| commit | 9c760ca8ecfd570212b47a5e980d38575b879029 (patch) | |
| tree | 1dbfcae018448791bdfeda8c3a6a17beb7b7541a /clang/lib/CodeGen/CGExprCXX.cpp | |
| parent | dd3aa26fc8e9de37a39611f7a6a602bcb4153784 (diff) | |
[Clang][CodeGen] `typeid` needs special care when `type_info` is not in the default AS
After https://reviews.llvm.org/D153092, for targets that use a non-default AS for globals, an "interesting" situation arises around typeid and its paired type, type_info:
- on the AST level, the type_info interface is defined with default / generic addresses, be it for function arguments, or for this;
- in IR, type_info values are globals, and thus pointers to type_info values are pointers to global
This leads to a mismatch between the function signature / formal type of the argument, and its actual type. Currently we try to handle such mismatches via `bitcast`, but that is wrong in this case, since an `ascast` is required. This patch ensures that iff the pointer to `type_info` points to a non-default AS, an ascast is inserted so as to match the `typeid` interface / return value type.
Reviewed by: yaxunl
Differential Revision: https://reviews.llvm.org/D157452
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 4d3f3e9603d9..34d4f37a5d29 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -2195,11 +2195,19 @@ static llvm::Value *EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { llvm::Type *PtrTy = llvm::PointerType::getUnqual(getLLVMContext()); + LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr); + + auto MaybeASCast = [=](auto &&TypeInfo) { + if (GlobAS == LangAS::Default) + return TypeInfo; + return getTargetHooks().performAddrSpaceCast(CGM,TypeInfo, GlobAS, + LangAS::Default, PtrTy); + }; if (E->isTypeOperand()) { llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(E->getTypeOperand(getContext())); - return TypeInfo; + return MaybeASCast(TypeInfo); } // C++ [expr.typeid]p2: @@ -2212,7 +2220,7 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { return EmitTypeidFromVTable(*this, E->getExprOperand(), PtrTy); QualType OperandTy = E->getExprOperand()->getType(); - return CGM.GetAddrOfRTTIDescriptor(OperandTy); + return MaybeASCast(CGM.GetAddrOfRTTIDescriptor(OperandTy)); } static llvm::Value *EmitDynamicCastToNull(CodeGenFunction &CGF, |
