erichkeane created this revision. erichkeane added reviewers: rnk, pcc. Herald added a subscriber: hiraditya. Herald added a project: LLVM.
r369697 changed the behavior of stripPointerCasts to no longer include aliases. However, the code in CGDeclCXX.cpp's createAtExitStub counted on the looking through aliases to properly set the calling convention of a call. The result of the change was that the calling convention mismatch of the call would be replaced with a llvm.trap, causing a runtime crash. https://reviews.llvm.org/D68584 Files: clang/lib/CodeGen/CGDeclCXX.cpp clang/test/CodeGenCXX/call-conv-thru-alias.cpp llvm/include/llvm/IR/Value.h llvm/lib/IR/Value.cpp
Index: llvm/lib/IR/Value.cpp =================================================================== --- llvm/lib/IR/Value.cpp +++ llvm/lib/IR/Value.cpp @@ -455,6 +455,7 @@ // Various metrics for how much to strip off of pointers. enum PointerStripKind { PSK_ZeroIndices, + PSK_ZeroIndicesAndAliases, PSK_ZeroIndicesSameRepresentation, PSK_ZeroIndicesAndInvariantGroups, PSK_InBoundsConstantIndices, @@ -475,6 +476,7 @@ if (auto *GEP = dyn_cast<GEPOperator>(V)) { switch (StripKind) { case PSK_ZeroIndices: + case PSK_ZeroIndicesAndAliases: case PSK_ZeroIndicesSameRepresentation: case PSK_ZeroIndicesAndInvariantGroups: if (!GEP->hasAllZeroIndices()) @@ -497,6 +499,8 @@ // TODO: If we know an address space cast will not change the // representation we could look through it here as well. V = cast<Operator>(V)->getOperand(0); + } else if (StripKind == PSK_ZeroIndicesAndAliases && isa<GlobalAlias>(V)) { + V = cast<GlobalAlias>(V)->getAliasee(); } else { if (const auto *Call = dyn_cast<CallBase>(V)) { if (const Value *RV = Call->getReturnedArgOperand()) { @@ -526,6 +530,10 @@ return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this); } +const Value *Value::stripPointerCastsAndAliases() const { + return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this); +} + const Value *Value::stripPointerCastsSameRepresentation() const { return stripPointerCastsAndOffsets<PSK_ZeroIndicesSameRepresentation>(this); } Index: llvm/include/llvm/IR/Value.h =================================================================== --- llvm/include/llvm/IR/Value.h +++ llvm/include/llvm/IR/Value.h @@ -523,6 +523,16 @@ static_cast<const Value *>(this)->stripPointerCasts()); } + /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases. + /// + /// Returns the original uncasted value. If this is called on a non-pointer + /// value, it returns 'this'. + const Value *stripPointerCastsAndAliases() const; + Value *stripPointerCastsAndAliases() { + return const_cast<Value *>( + static_cast<const Value *>(this)->stripPointerCastsAndAliases()); + } + /// Strip off pointer casts, all-zero GEPs and address space casts /// but ensures the representation of the result stays the same. /// Index: clang/test/CodeGenCXX/call-conv-thru-alias.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/call-conv-thru-alias.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple i686-windows-pc -emit-llvm -o - -mconstructor-aliases -O1 -disable-llvm-passes %s | FileCheck %s + +struct Base { virtual ~Base(); }; +struct Derived : Base { + virtual ~Derived(); + static Derived inst; +}; + +Base::~Base(){} +Derived::~Derived(){} +Derived Derived::inst; + +// CHECK: @"??1Derived@@UAE@XZ" = dso_local unnamed_addr alias void (%struct.Derived*), bitcast (void (%struct.Base*)* @"??1Base@@UAE@XZ" to void (%struct.Derived*)*) + +// CHECK: define dso_local x86_thiscallcc void @"??1Base@@UAE@XZ" +// CHECK: define internal void @"??__E?inst@Derived@@2U1@A@@YAXXZ" +// CHECK: call i32 @atexit(void ()* @"??__F?inst@Derived@@2U1@A@@YAXXZ" +// +// CHECK: define internal void @"??__F?inst@Derived@@2U1@A@@YAXXZ" +// CHECK-NEXT: entry: +// CHECK-NEXT: call x86_thiscallcc void @"??1Derived@@UAE@XZ" Index: clang/lib/CodeGen/CGDeclCXX.cpp =================================================================== --- clang/lib/CodeGen/CGDeclCXX.cpp +++ clang/lib/CodeGen/CGDeclCXX.cpp @@ -248,8 +248,8 @@ llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); // Make sure the call and the callee agree on calling convention. - if (llvm::Function *dtorFn = - dyn_cast<llvm::Function>(dtor.getCallee()->stripPointerCasts())) + if (llvm::Function *dtorFn = dyn_cast<llvm::Function>( + dtor.getCallee()->stripPointerCastsAndAliases())) call->setCallingConv(dtorFn->getCallingConv()); CGF.FinishFunction();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits