Mercurial > projects > ldc
comparison gen/llvmhelpers.cpp @ 355:d8357f7004ca trunk
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
It is now possible to add label scopes in IrFunction and all labels names will be prefixed accordingly.
Also disallow goto into finally blocks.
Fixes nocompile/finally_02 and others.
author | ChristianK |
---|---|
date | Mon, 14 Jul 2008 11:48:55 +0200 |
parents | a7a26f538d6e |
children | 44daf304421c |
comparison
equal
deleted
inserted
replaced
354:ac654d4cb935 | 355:d8357f7004ca |
---|---|
182 LabelStatement* lblstmt = DtoLabelStatement(target); | 182 LabelStatement* lblstmt = DtoLabelStatement(target); |
183 assert(lblstmt != NULL); | 183 assert(lblstmt != NULL); |
184 | 184 |
185 // if the target label is inside inline asm, error | 185 // if the target label is inside inline asm, error |
186 if(lblstmt->asmLabel) | 186 if(lblstmt->asmLabel) |
187 error("cannot goto into inline asm block", loc->toChars()); | 187 error(*loc, "cannot goto into inline asm block"); |
188 | 188 |
189 // find target basic block | 189 // find target basic block |
190 std::string labelname = target->toChars(); | 190 std::string labelname = gIR->func()->getScopedLabelName(target->toChars()); |
191 llvm::BasicBlock*& targetBB = gIR->func()->labelToBB[labelname]; | 191 llvm::BasicBlock*& targetBB = gIR->func()->labelToBB[labelname]; |
192 if (targetBB == NULL) | 192 if (targetBB == NULL) |
193 targetBB = llvm::BasicBlock::Create("label", gIR->topfunc()); | 193 targetBB = llvm::BasicBlock::Create("label", gIR->topfunc()); |
194 | 194 |
195 // find finallys between goto and label | 195 // find finallys between goto and label |
198 endfinally = endfinally->getEnclosing(); | 198 endfinally = endfinally->getEnclosing(); |
199 } | 199 } |
200 | 200 |
201 // error if didn't find tf statement of label | 201 // error if didn't find tf statement of label |
202 if(endfinally != lblstmt->enclosinghandler) | 202 if(endfinally != lblstmt->enclosinghandler) |
203 error("cannot goto into try block", loc->toChars()); | 203 error(*loc, "cannot goto into try block"); |
204 | |
205 // goto into finally blocks is forbidden by the spec | |
206 // though it should not be problematic to implement | |
207 if(lblstmt->tf) | |
208 error(*loc, "spec disallows goto into finally block"); | |
204 | 209 |
205 // emit code for finallys between goto and label | 210 // emit code for finallys between goto and label |
206 DtoEnclosingHandlers(enclosinghandler, endfinally); | 211 DtoEnclosingHandlers(enclosinghandler, endfinally); |
207 | 212 |
208 llvm::BranchInst::Create(targetBB, gIR->scopebb()); | 213 llvm::BranchInst::Create(targetBB, gIR->scopebb()); |
261 while(endfinally != NULL && endfinally != end) { | 266 while(endfinally != NULL && endfinally != end) { |
262 endfinally = endfinally->getEnclosing(); | 267 endfinally = endfinally->getEnclosing(); |
263 } | 268 } |
264 assert(endfinally == end); | 269 assert(endfinally == end); |
265 | 270 |
271 | |
272 // | |
266 // emit code for finallys between start and end | 273 // emit code for finallys between start and end |
274 // | |
275 | |
276 // since the labelstatements possibly inside are private | |
277 // and might already exist push a label scope | |
278 gIR->func()->pushUniqueLabelScope("enclosing"); | |
267 EnclosingHandler* tf = start; | 279 EnclosingHandler* tf = start; |
268 while(tf != end) { | 280 while(tf != end) { |
269 tf->emitCode(gIR); | 281 tf->emitCode(gIR); |
270 tf = tf->getEnclosing(); | 282 tf = tf->getEnclosing(); |
271 } | 283 } |
284 gIR->func()->popLabelScope(); | |
272 } | 285 } |
273 | 286 |
274 /****************************************************************************************/ | 287 /****************************************************************************************/ |
275 /*//////////////////////////////////////////////////////////////////////////////////////// | 288 /*//////////////////////////////////////////////////////////////////////////////////////// |
276 // SYNCHRONIZED SECTION HELPERS | 289 // SYNCHRONIZED SECTION HELPERS |