Emit all D inline asm labels as local labels.

On OS X, there is an actual significance to the distinction, which before lead e.g. to exception throwing in the below example being broken:

---
import core.exception;

void main() {
  asm {
    jmp Lfoo;
Lfoo:
    ;
  }
  throw cast(OutOfMemoryError)cast(void*)OutOfMemoryError.classinfo.init;
  assert(0);
}
---
This commit is contained in:
David Nadlinger
2011-12-04 18:13:33 +01:00
parent 1afc01df72
commit d0ea856024
7 changed files with 25 additions and 9 deletions

View File

@@ -561,7 +561,8 @@ void AsmBlockStatement::toIR(IRState* p)
// we use a simple static counter to make sure the new end labels are unique
static size_t uniqueLabelsId = 0;
std::ostringstream asmGotoEndLabel;
asmGotoEndLabel << "." << fdmangle << "__llvm_asm_end" << uniqueLabelsId++;
printLabelName(asmGotoEndLabel, fdmangle, "_llvm_asm_end");
asmGotoEndLabel << uniqueLabelsId++;
// initialize the setter statement we're going to build
IRAsmStmt* outSetterStmt = new IRAsmStmt;
@@ -599,7 +600,8 @@ void AsmBlockStatement::toIR(IRState* p)
// provide an in-asm target for the branch and set value
Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string);
code << fdmangle << '_' << a->isBranchToLabel->string << ":\n\t";
printLabelName(code, fdmangle, a->isBranchToLabel->string);
code << ":\n\t";
code << "movl $<<in" << n_goto << ">>, $<<out0>>\n";
//FIXME: Store the value -> label mapping somewhere, so it can be referenced later
outSetterStmt->in.push_back(DtoConstUint(n_goto));