mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 23:51:56 +00:00
Fix some obvious bugs in the conditional-cleanup code and then make the
dtor cleanup use it. llvm-svn: 124309
This commit is contained in:
parent
1c7bd7f481
commit
f256eb54a2
@ -179,8 +179,7 @@ llvm::Value *CodeGenFunction::initFullExprCleanup() {
|
||||
// Initialize it to false at a site that's guaranteed to be run
|
||||
// before each evaluation.
|
||||
llvm::BasicBlock *block = OutermostConditional->getStartingBlock();
|
||||
new llvm::StoreInst(Builder.getFalse(), run,
|
||||
block->getFirstNonPHIOrDbg());
|
||||
new llvm::StoreInst(Builder.getFalse(), run, &block->back());
|
||||
|
||||
// Initialize it to true at the current location.
|
||||
Builder.CreateStore(Builder.getTrue(), run);
|
||||
|
@ -16,39 +16,11 @@ using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
namespace {
|
||||
struct DestroyTemporary : EHScopeStack::Cleanup {
|
||||
const CXXTemporary *Temporary;
|
||||
llvm::Value *Addr;
|
||||
llvm::Value *CondPtr;
|
||||
|
||||
DestroyTemporary(const CXXTemporary *Temporary, llvm::Value *Addr,
|
||||
llvm::Value *CondPtr)
|
||||
: Temporary(Temporary), Addr(Addr), CondPtr(CondPtr) {}
|
||||
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEH) {
|
||||
llvm::BasicBlock *CondEnd = 0;
|
||||
|
||||
// If this is a conditional temporary, we need to check the condition
|
||||
// boolean and only call the destructor if it's true.
|
||||
if (CondPtr) {
|
||||
llvm::BasicBlock *CondBlock =
|
||||
CGF.createBasicBlock("temp.cond-dtor.call");
|
||||
CondEnd = CGF.createBasicBlock("temp.cond-dtor.cont");
|
||||
|
||||
llvm::Value *Cond = CGF.Builder.CreateLoad(CondPtr);
|
||||
CGF.Builder.CreateCondBr(Cond, CondBlock, CondEnd);
|
||||
CGF.EmitBlock(CondBlock);
|
||||
}
|
||||
|
||||
CGF.EmitCXXDestructorCall(Temporary->getDestructor(),
|
||||
Dtor_Complete, /*ForVirtualBase=*/false,
|
||||
Addr);
|
||||
|
||||
if (CondPtr) {
|
||||
// Reset the condition to false.
|
||||
CGF.Builder.CreateStore(CGF.Builder.getFalse(), CondPtr);
|
||||
CGF.EmitBlock(CondEnd);
|
||||
}
|
||||
struct DestroyTemporary {
|
||||
static void Emit(CodeGenFunction &CGF, bool forEH,
|
||||
const CXXDestructorDecl *dtor, llvm::Value *addr) {
|
||||
CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*ForVirtualBase=*/false,
|
||||
addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -56,23 +28,9 @@ namespace {
|
||||
/// Emits all the code to cause the given temporary to be cleaned up.
|
||||
void CodeGenFunction::EmitCXXTemporary(const CXXTemporary *Temporary,
|
||||
llvm::Value *Ptr) {
|
||||
llvm::AllocaInst *CondPtr = 0;
|
||||
|
||||
// Check if temporaries need to be conditional. If so, we'll create a
|
||||
// condition boolean, initialize it to 0 and
|
||||
if (isInConditionalBranch()) {
|
||||
CondPtr = CreateTempAlloca(llvm::Type::getInt1Ty(VMContext), "cond");
|
||||
|
||||
// Initialize it to false. This initialization takes place right after
|
||||
// the alloca insert point.
|
||||
InitTempAlloca(CondPtr, llvm::ConstantInt::getFalse(VMContext));
|
||||
|
||||
// Now set it to true.
|
||||
Builder.CreateStore(Builder.getTrue(), CondPtr);
|
||||
}
|
||||
|
||||
EHStack.pushCleanup<DestroyTemporary>(NormalAndEHCleanup,
|
||||
Temporary, Ptr, CondPtr);
|
||||
pushFullExprCleanup<DestroyTemporary>(NormalAndEHCleanup,
|
||||
Temporary->getDestructor(),
|
||||
Ptr);
|
||||
}
|
||||
|
||||
RValue
|
||||
|
@ -214,6 +214,7 @@ public:
|
||||
template <class T, class A0, class A1>
|
||||
class UnconditionalCleanup2 : public Cleanup {
|
||||
A0 a0; A1 a1;
|
||||
public:
|
||||
UnconditionalCleanup2(A0 a0, A1 a1) : a0(a0), a1(a1) {}
|
||||
void Emit(CodeGenFunction &CGF, bool IsForEHCleanup) {
|
||||
T::Emit(CGF, IsForEHCleanup, a0, a1);
|
||||
@ -226,17 +227,18 @@ public:
|
||||
class ConditionalCleanup2 : public ConditionalCleanup {
|
||||
typedef typename SavedValueInCond<A0>::saved_type A0_saved;
|
||||
typedef typename SavedValueInCond<A1>::saved_type A1_saved;
|
||||
A0_saved a0; A1_saved a1;
|
||||
A0_saved a0_saved;
|
||||
A1_saved a1_saved;
|
||||
|
||||
void EmitImpl(CodeGenFunction &CGF, bool IsForEHCleanup) {
|
||||
A0 a0 = SavedValueInCond<A0>::restore(CGF, a0);
|
||||
A1 a1 = SavedValueInCond<A1>::restore(CGF, a1);
|
||||
A0 a0 = SavedValueInCond<A0>::restore(CGF, a0_saved);
|
||||
A1 a1 = SavedValueInCond<A1>::restore(CGF, a1_saved);
|
||||
T::Emit(CGF, IsForEHCleanup, a0, a1);
|
||||
}
|
||||
|
||||
public:
|
||||
ConditionalCleanup2(llvm::Value *cond, A0_saved a0, A1_saved a1)
|
||||
: ConditionalCleanup(cond), a0(a0), a1(a1) {}
|
||||
: ConditionalCleanup(cond), a0_saved(a0), a1_saved(a1) {}
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -196,10 +196,10 @@ namespace test3 {
|
||||
// CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1
|
||||
// CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8
|
||||
// CHECK: [[TMPACTIVE:%.*]] = alloca i1
|
||||
// CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]]
|
||||
// CHECK-NEXT: store i1 false, i1* [[CLEANUPACTIVE]]
|
||||
|
||||
// CHECK: [[COND:%.*]] = trunc i8 {{.*}} to i1
|
||||
// CHECK-NEXT: store i1 false, i1* [[TMPACTIVE]]
|
||||
// CHECK-NEXT: br i1 [[COND]]
|
||||
return (cond ?
|
||||
|
||||
|
@ -502,9 +502,9 @@ namespace PR8623 {
|
||||
// CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
|
||||
// CHECK-NEXT: [[LCONS:%.*]] = alloca i1
|
||||
// CHECK-NEXT: [[RCONS:%.*]] = alloca i1
|
||||
// CHECK: store i1 false, i1* [[LCONS]]
|
||||
// CHECK-NEXT: store i1 false, i1* [[RCONS]]
|
||||
// CHECK-NEXT: store i1 false, i1* [[LCONS]]
|
||||
// CHECK: br i1
|
||||
// CHECK-NEXT: br i1
|
||||
// CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2)
|
||||
// CHECK-NEXT: store i1 true, i1* [[LCONS]]
|
||||
// CHECK-NEXT: br label
|
||||
@ -514,12 +514,10 @@ namespace PR8623 {
|
||||
// CHECK: load i1* [[RCONS]]
|
||||
// CHECK-NEXT: br i1
|
||||
// CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
|
||||
// CHECK-NEXT: store i1 false, i1* [[RCONS]]
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: load i1* [[LCONS]]
|
||||
// CHECK-NEXT: br i1
|
||||
// CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
|
||||
// CHECK-NEXT: store i1 false, i1* [[LCONS]]
|
||||
// CHECK-NEXT: br label
|
||||
// CHECK: ret void
|
||||
b ? A(2) : A(3);
|
||||
|
Loading…
Reference in New Issue
Block a user