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