summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-02-07 23:02:10 +0000
committerMike Stump <mrs@apple.com>2009-02-07 23:02:10 +0000
commit0509d9635b160b8b44a454d32257827aaeaacf8d (patch)
tree00c6dfe24ab45aa1f14fbeb056b81b8816abc0fc /clang/lib/CodeGen
parent394dfeb37b41c04540d39c5d281124520770b7d6 (diff)
downloadbcm5719-llvm-0509d9635b160b8b44a454d32257827aaeaacf8d.tar.gz
bcm5719-llvm-0509d9635b160b8b44a454d32257827aaeaacf8d.zip
Ensure we track all the stack depths for all break and continue points
correctly. This should lay the ground work to throw the big switch and start code gening break and continue in the presense of vlas. llvm-svn: 64046
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp14
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp20
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h15
3 files changed, 34 insertions, 15 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index a116316641f..efd9299d1a0 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -361,6 +361,11 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
return;
}
+ // We want to ensure that any vlas between here and when we
+ // push the break and continue context below can be destroyed
+ // when we break
+ llvm::Value *saveBreakStackDepth = StackDepth;
+
if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement())) {
EmitStmt(SD);
assert(HaveInsertPoint() && "DeclStmt destroyed insert point!");
@@ -446,10 +451,6 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
llvm::BasicBlock *LoopStart = createBasicBlock("loopstart");
EmitBlock(LoopStart);
- // We want to ensure there are no vlas between here and when we
- // push the break and continue context below.
- llvm::Value *saveStackDepth = StackDepth;
-
llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr");
Builder.CreateStore(Zero, CounterPtr);
@@ -519,9 +520,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
- assert (StackDepth == saveStackDepth && "vla unhandled in for");
-
- BreakContinuePush(LoopEnd, AfterBody);
+ // Ensure any vlas created between there and here, are undone
+ BreakContinuePush(LoopEnd, AfterBody, saveBreakStackDepth, StackDepth);
EmitStmt(S.getBody());
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index c65b8114f37..ac97c6329da 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -466,6 +466,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
EmitBlock(CondBlock);
+ llvm::Value *saveStackDepth = StackDepth;
+
// Evaluate the condition if present. If not, treat it as a
// non-zero-constant according to 6.8.5.3p2, aka, true.
if (S.getCond()) {
@@ -491,8 +493,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
ContinueBlock = CondBlock;
// Store the blocks to use for break and continue.
- BreakContinuePush(AfterFor, ContinueBlock);
-
+ // Ensure any vlas created between there and here, are undone
+ BreakContinuePush(AfterFor, ContinueBlock,
+ saveStackDepth, saveStackDepth);
+
// If the condition is true, execute the body of the for stmt.
EmitStmt(S.getBody());
@@ -708,6 +712,9 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
llvm::SwitchInst *SavedSwitchInsn = SwitchInsn;
llvm::BasicBlock *SavedCRBlock = CaseRangeBlock;
+ // Ensure any vlas created inside are destroyed on break.
+ llvm::Value *saveBreakStackDepth = StackDepth;
+
// Create basic block to hold stuff that comes after switch
// statement. We also need to create a default block now so that
// explicit case ranges tests can have a place to jump to on
@@ -723,9 +730,14 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
// All break statements jump to NextBlock. If BreakContinueStack is non empty
// then reuse last ContinueBlock.
llvm::BasicBlock *ContinueBlock = NULL;
- if (!BreakContinueStack.empty())
+ llvm::Value *saveContinueStackDepth = NULL;
+ if (!BreakContinueStack.empty()) {
ContinueBlock = BreakContinueStack.back().ContinueBlock;
- BreakContinuePush(NextBlock, ContinueBlock);
+ saveContinueStackDepth = BreakContinueStack.back().SaveContinueStackDepth;
+ }
+ // Ensure any vlas created between there and here, are undone
+ BreakContinuePush(NextBlock, ContinueBlock,
+ saveBreakStackDepth, saveContinueStackDepth);
// Emit switch body.
EmitStmt(S.getBody());
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 4ff3badd99d..068627139d7 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -156,6 +156,12 @@ private:
/// condition has possibly started a vla.
void BreakContinuePush(llvm::BasicBlock *bb, llvm::BasicBlock *cb) {
BreakContinueStack.push_back(BreakContinue(bb, cb, StackDepth,
+ StackDepth,
+ ObjCEHStack.size()));
+ }
+ void BreakContinuePush(llvm::BasicBlock *bb, llvm::BasicBlock *cb,
+ llvm::Value *bsd, llvm::Value *csd) {
+ BreakContinueStack.push_back(BreakContinue(bb, cb, bsd, csd,
ObjCEHStack.size()));
}
@@ -169,13 +175,14 @@ private:
// of the eh stack.
struct BreakContinue {
BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb,
- llvm::Value *sd, size_t ehss)
- : BreakBlock(bb), ContinueBlock(cb), SaveStackDepth(sd),
- EHStackSize(ehss) {}
+ llvm::Value *bsd, llvm::Value *csd, size_t ehss)
+ : BreakBlock(bb), ContinueBlock(cb), SaveBreakStackDepth(bsd),
+ SaveContinueStackDepth(csd), EHStackSize(ehss) {}
llvm::BasicBlock *BreakBlock;
llvm::BasicBlock *ContinueBlock;
- llvm::Value *SaveStackDepth;
+ llvm::Value *SaveBreakStackDepth;
+ llvm::Value *SaveContinueStackDepth;
size_t EHStackSize;
};
llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
OpenPOWER on IntegriCloud