diff --git a/dmd/constfold.c b/dmd/constfold.c index f913337e..25c05d0a 100644 --- a/dmd/constfold.c +++ b/dmd/constfold.c @@ -1160,7 +1160,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) uinteger_t i = e2->toInteger(); if (i >= es1->len) - e1->error("string index %ju is out of bounds [0 .. %zu]", i, es1->len); + e1->error("string index %llu is out of bounds [0 .. %"PRIuSIZE"]", i, es1->len); else { unsigned value = es1->charAt(i); e = new IntegerExp(loc, value, type); @@ -1172,7 +1172,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) uinteger_t i = e2->toInteger(); if (i >= length) - { e2->error("array index %ju is out of bounds %s[0 .. %ju]", i, e1->toChars(), length); + { + e2->error("array index %llu is out of bounds %s[0 .. %llu]", i, e1->toChars(), length); } else if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; @@ -1187,7 +1188,8 @@ Expression *Index(Type *type, Expression *e1, Expression *e2) if (e1->op == TOKarrayliteral && !e1->checkSideEffect(2)) { ArrayLiteralExp *ale = (ArrayLiteralExp *)e1; if (i >= ale->elements->dim) - { e2->error("array index %ju is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); + { + e2->error("array index %llu is out of bounds %s[0 .. %u]", i, e1->toChars(), ale->elements->dim); } else { e = (Expression *)ale->elements->data[i]; @@ -1237,7 +1239,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) uinteger_t iupr = upr->toInteger(); if (iupr > es1->len || ilwr > iupr) - e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr); + e1->error("string slice [%llu .. %llu] is out of bounds", ilwr, iupr); else { integer_t value; void *s; @@ -1264,7 +1266,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr) uinteger_t iupr = upr->toInteger(); if (iupr > es1->elements->dim || ilwr > iupr) - e1->error("array slice [%ju .. %ju] is out of bounds", ilwr, iupr); + e1->error("array slice [%llu .. %llu] is out of bounds", ilwr, iupr); else { Expressions *elements = new Expressions(); diff --git a/dmd/declaration.c b/dmd/declaration.c index ed49b291..482f45b7 100644 --- a/dmd/declaration.c +++ b/dmd/declaration.c @@ -675,7 +675,7 @@ void VarDeclaration::semantic(Scope *sc) { Argument *arg = Argument::getNth(tt->arguments, i); OutBuffer buf; - buf.printf("_%s_field_%zu", ident->toChars(), i); + buf.printf("_%s_field_%"PRIuSIZE, ident->toChars(), i); buf.writeByte(0); char *name = (char *)buf.extractData(); Identifier *id = new Identifier(name, TOKidentifier); diff --git a/dmd/declaration.h b/dmd/declaration.h index 8b36061a..914e38d9 100644 --- a/dmd/declaration.h +++ b/dmd/declaration.h @@ -16,6 +16,7 @@ #endif /* __DMC__ */ #include +#include #include "dsymbol.h" #include "lexer.h" @@ -24,6 +25,7 @@ struct Expression; struct Statement; struct LabelDsymbol; +struct LabelStatement; struct Initializer; struct Module; struct InlineScanState; @@ -611,6 +613,11 @@ struct FuncDeclaration : Declaration // llvmdc stuff bool runTimeHack; std::set nestedVars; + + // we keep our own table of label statements as LabelDsymbolS + // don't always carry their corresponding statement along ... + typedef std::map LabelMap; + LabelMap labmap; }; struct FuncAliasDeclaration : FuncDeclaration diff --git a/dmd/dump.c b/dmd/dump.c index 1f6fecd1..8d521884 100644 --- a/dmd/dump.c +++ b/dmd/dump.c @@ -52,7 +52,7 @@ void Expression::dump(int i) void IntegerExp::dump(int i) { indent(i); - printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type)); + printf("%p %lld type=%s\n", this, (intmax_t)value, type_print(type)); } void IdentifierExp::dump(int i) diff --git a/dmd/expression.c b/dmd/expression.c index 7a73dca6..2a6f2b95 100644 --- a/dmd/expression.c +++ b/dmd/expression.c @@ -405,7 +405,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume size_t nparams = Argument::dim(tf->parameters); if (nargs > nparams && tf->varargs == 0) - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) @@ -429,7 +429,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume { if (tf->varargs == 2 && i + 1 == nparams) goto L2; - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); break; } arg = p->defaultArg->copy(); @@ -443,7 +443,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume if (arg->implicitConvTo(p->type)) { if (nargs != nparams) - error(loc, "expected %zu arguments, not %zu", nparams, nargs); + error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs); goto L1; } L2: @@ -1050,8 +1050,7 @@ char *IntegerExp::toChars() return Expression::toChars(); #else static char buffer[sizeof(value) * 3 + 1]; - - sprintf(buffer, "%jd", value); + sprintf(buffer, "%lld", value); return buffer; #endif } @@ -1228,11 +1227,11 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) break; case Tint64: - buf->printf("%jdL", v); + buf->printf("%lldL", v); break; case Tuns64: - buf->printf("%juLU", v); + buf->printf("%lluLU", v); break; case Tbit: @@ -1254,17 +1253,17 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) } } else if (v & 0x8000000000000000LL) - buf->printf("0x%jx", v); + buf->printf("0x%llx", v); else - buf->printf("%jd", v); + buf->printf("%lld", v); } void IntegerExp::toMangleBuffer(OutBuffer *buf) { if ((sinteger_t)value < 0) - buf->printf("N%jd", -value); + buf->printf("N%lld", -value); else - buf->printf("%jd", value); + buf->printf("%lld", value); } /******************************** RealExp **************************/ @@ -6469,7 +6468,7 @@ Expression *SliceExp::semantic(Scope *sc) } else { - error("string slice [%ju .. %ju] is out of bounds", i1, i2); + error("string slice [%llu .. %llu] is out of bounds", i1, i2); e = e1; } return e; @@ -6828,9 +6827,9 @@ Expression *IndexExp::semantic(Scope *sc) } else { - error("array index [%ju] is outside array bounds [0 .. %zu]", - index, length); - e = e1; + error("array index [%llu] is outside array bounds [0 .. %"PRIuSIZE"]", + index, length); + e = e1; } break; } diff --git a/dmd/func.c b/dmd/func.c index 2d67ea6f..c098c439 100644 --- a/dmd/func.c +++ b/dmd/func.c @@ -767,7 +767,7 @@ void FuncDeclaration::semantic3(Scope *sc) * because we need it later on. */ OutBuffer buf; - buf.printf("_param_%zu", i); + buf.printf("_param_%"PRIuSIZE, i); char *name = (char *)buf.extractData(); id = new Identifier(name, TOKidentifier); arg->ident = id; diff --git a/dmd/init.c b/dmd/init.c index 47e99b7d..ccc85776 100644 --- a/dmd/init.c +++ b/dmd/init.c @@ -382,7 +382,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t) } unsigned long amax = 0x80000000; if ((unsigned long) dim * t->next->size() >= amax) - error(loc, "array dimension %u exceeds max of %ju", dim, amax / t->next->size()); + error(loc, "array dimension %u exceeds max of %llu", dim, amax / t->next->size()); return this; } diff --git a/dmd/lexer.c b/dmd/lexer.c index b78d53a4..87e2ffde 100644 --- a/dmd/lexer.c +++ b/dmd/lexer.c @@ -137,11 +137,11 @@ char *Token::toChars() break; case TOKint64v: - sprintf(buffer,"%jdL",int64value); + sprintf(buffer,"%lldL",int64value); break; case TOKuns64v: - sprintf(buffer,"%juUL",uns64value); + sprintf(buffer,"%lluUL",uns64value); break; #if IN_GCC diff --git a/dmd/mangle.c b/dmd/mangle.c index 1e88fcee..5eead78e 100644 --- a/dmd/mangle.c +++ b/dmd/mangle.c @@ -213,7 +213,7 @@ char *TemplateInstance::mangle() p += 2; buf.writestring(p); } - buf.printf("%zu%s", strlen(id), id); + buf.printf("%"PRIuSIZE"%s", strlen(id), id); id = buf.toChars(); buf.data = NULL; //printf("TemplateInstance::mangle() %s = %s\n", toChars(), id); @@ -241,7 +241,7 @@ char *Dsymbol::mangle() p += 2; buf.writestring(p); } - buf.printf("%zu%s", strlen(id), id); + buf.printf("%"PRIuSIZE"%s", strlen(id), id); id = buf.toChars(); buf.data = NULL; //printf("Dsymbol::mangle() %s = %s\n", toChars(), id); diff --git a/dmd/mars.h b/dmd/mars.h index 4167a539..49875659 100644 --- a/dmd/mars.h +++ b/dmd/mars.h @@ -16,8 +16,10 @@ #endif /* __DMC__ */ #include -#include -#include +#include +#define __STDC_FORMAT_MACROS 1 +#include +#include #ifdef __DMC__ #ifdef DEBUG @@ -225,6 +227,19 @@ typedef long double real_t; #include "d-gcc-complex_t.h" #endif +// taken from GDC +// for handling printf incompatibilities +#if __MSVCRT__ +#define PRIuSIZE "Iu" +#define PRIxSIZE "Ix" +#elif __MINGW32__ +#define PRIuSIZE "u" +#define PRIxSIZE "x" +#else +#define PRIuSIZE "zu" +#define PRIxSIZE "zx" +#endif + struct Module; //typedef unsigned Loc; // file location diff --git a/dmd/mtype.c b/dmd/mtype.c index 743acca5..ffdb7598 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -1653,7 +1653,7 @@ d_uns64 TypeSArray::size(Loc loc) return sz; Loverflow: - error(loc, "index %jd overflow for static array", sz); + error(loc, "index %lld overflow for static array", sz); return 1; } @@ -1721,7 +1721,7 @@ void TypeSArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol sc = sc->pop(); if (d >= td->objects->dim) - { error(loc, "tuple index %ju exceeds %u", d, td->objects->dim); + { error(loc, "tuple index %llu exceeds %u", d, td->objects->dim); goto Ldefault; } Object *o = (Object *)td->objects->data[(size_t)d]; @@ -1775,7 +1775,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) uinteger_t d = dim->toUInteger(); if (d >= sd->objects->dim) - { error(loc, "tuple index %ju exceeds %u", d, sd->objects->dim); + { error(loc, "tuple index %llu exceeds %u", d, sd->objects->dim); return Type::terror; } Object *o = (Object *)sd->objects->data[(size_t)d]; @@ -1832,7 +1832,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) if (n && n2 / n != d2) { Loverflow: - error(loc, "index %jd overflow for static array", d1); + error(loc, "index %lld overflow for static array", d1); dim = new IntegerExp(0, 1, tsize_t); } } @@ -1846,7 +1846,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) uinteger_t d = dim->toUInteger(); if (d >= tt->arguments->dim) - { error(loc, "tuple index %ju exceeds %u", d, tt->arguments->dim); + { error(loc, "tuple index %llu exceeds %u", d, tt->arguments->dim); return Type::terror; } Argument *arg = (Argument *)tt->arguments->data[(size_t)d]; @@ -1867,7 +1867,7 @@ void TypeSArray::toDecoBuffer(OutBuffer *buf) { buf->writeByte(mangleChar[ty]); if (dim) - buf->printf("%ju", dim->toInteger()); + buf->printf("%llu", dim->toInteger()); if (next) next->toDecoBuffer(buf); } @@ -4965,7 +4965,7 @@ Type *TypeSlice::semantic(Loc loc, Scope *sc) uinteger_t i2 = upr->toUInteger(); if (!(i1 <= i2 && i2 <= tt->arguments->dim)) - { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, tt->arguments->dim); + { error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, tt->arguments->dim); return Type::terror; } @@ -5010,7 +5010,7 @@ void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol sc = sc->pop(); if (!(i1 <= i2 && i2 <= td->objects->dim)) - { error(loc, "slice [%ju..%ju] is out of range of [0..%u]", i1, i2, td->objects->dim); + { error(loc, "slice [%llu..%llu] is out of range of [0..%u]", i1, i2, td->objects->dim); goto Ldefault; } diff --git a/dmd/optimize.c b/dmd/optimize.c index 8356e13c..57c6fff2 100644 --- a/dmd/optimize.c +++ b/dmd/optimize.c @@ -234,7 +234,7 @@ Expression *AddrExp::optimize(int result) TypeSArray *ts = (TypeSArray *)ve->type; integer_t dim = ts->dim->toInteger(); if (index < 0 || index >= dim) - error("array index %jd is out of bounds [0..%jd]", index, dim); + error("array index %lld is out of bounds [0..%lld]", index, dim); e = new SymOffExp(loc, ve->var, index * ts->next->size()); e->type = type; return e; @@ -380,7 +380,8 @@ Expression *BinExp::optimize(int result) integer_t i2 = e2->toInteger(); d_uns64 sz = e1->type->size() * 8; if (i2 < 0 || i2 > sz) - { error("shift assign by %jd is outside the range 0..%zu", i2, sz); + { + error("shift assign by %lld is outside the range 0..%"PRIuSIZE, i2, sz); e2 = new IntegerExp(0); } } @@ -475,7 +476,8 @@ Expression *shift_optimize(int result, BinExp *e, Expression *(*shift)(Type *, E integer_t i2 = e->e2->toInteger(); d_uns64 sz = e->e1->type->size() * 8; if (i2 < 0 || i2 > sz) - { error("shift by %jd is outside the range 0..%zu", i2, sz); + { + error("shift by %lld is outside the range 0..%"PRIuSIZE, i2, sz); e->e2 = new IntegerExp(0); } if (e->e1->isConst() == 1) diff --git a/dmd/root.c b/dmd/root.c index f7336e6e..d0b1b8c7 100644 --- a/dmd/root.c +++ b/dmd/root.c @@ -36,6 +36,7 @@ #include "root.h" #include "dchar.h" #include "mem.h" +#include "mars.h" #if 0 //__SC__ //def DEBUG extern "C" void __cdecl _assert(void *e, void *f, unsigned line) @@ -1325,7 +1326,7 @@ void File::stat() void File::checkoffset(size_t offset, size_t nbytes) { if (offset > len || offset + nbytes > len) - error("Corrupt file '%s': offset x%zx off end of file",toChars(),offset); + error("Corrupt file '%s': offset x%"PRIxSIZE" off end of file",toChars(),offset); } char *File::toChars() diff --git a/dmd/statement.c b/dmd/statement.c index b7c08e1f..d28f96eb 100644 --- a/dmd/statement.c +++ b/dmd/statement.c @@ -3519,6 +3519,7 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement) this->lblock = NULL; this->isReturnLabel = 0; this->llvmBB = NULL; + this->asmLabel = false; } Statement *LabelStatement::syntaxCopy() @@ -3546,6 +3547,10 @@ Statement *LabelStatement::semantic(Scope *sc) if (statement) statement = statement->semantic(sc); sc->pop(); + + // LLVMDC put in labmap + fd->labmap[ident->toChars()] = this; + return this; } @@ -3605,7 +3610,6 @@ LabelDsymbol::LabelDsymbol(Identifier *ident) : Dsymbol(ident) { statement = NULL; - asmLabel = false; } LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()? diff --git a/dmd/statement.h b/dmd/statement.h index 4e231f4b..a330adf2 100644 --- a/dmd/statement.h +++ b/dmd/statement.h @@ -761,13 +761,12 @@ struct LabelStatement : Statement // LLVMDC llvm::BasicBlock* llvmBB; + bool asmLabel; // for labels inside inline assembler }; struct LabelDsymbol : Dsymbol { LabelStatement *statement; -// LLVMDC - bool asmLabel; // for labels inside inline assembler LabelDsymbol(Identifier *ident); LabelDsymbol *isLabel(); @@ -793,8 +792,8 @@ struct AsmStatement : Statement void toIR(IRState *irs); // LLVMDC - // non-zero if this is a branch, contains the target - LabelDsymbol* isBranchToLabel; + // non-zero if this is a branch, contains the target labels identifier + Identifier* isBranchToLabel; }; struct AsmBlockStatement : CompoundStatement diff --git a/dmd/template.c b/dmd/template.c index 4138f94b..18800ec2 100644 --- a/dmd/template.c +++ b/dmd/template.c @@ -3444,7 +3444,7 @@ Identifier *TemplateInstance::genIdent() //printf("TemplateInstance::genIdent('%s')\n", tempdecl->ident->toChars()); id = tempdecl->ident->toChars(); - buf.printf("__T%zu%s", strlen(id), id); + buf.printf("__T%"PRIuSIZE"%s", strlen(id), id); args = tiargs; for (int i = 0; i < args->dim; i++) { Object *o = (Object *)args->data[i]; @@ -3511,7 +3511,7 @@ Identifier *TemplateInstance::genIdent() else { char *p = sa->mangle(); - buf.printf("%zu%s", strlen(p), p); + buf.printf("%"PRIuSIZE"%s", strlen(p), p); } } else if (va) diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index e6afd525..1f0c122f 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -461,16 +461,24 @@ void AsmBlockStatement::toIR(IRState* p) // a post-asm switch // maps each special value to a goto destination - std::map valToGoto; + std::map valToGoto; // location of the value containing the index into the valToGoto map // will be set if post-asm dispatcher block is needed llvm::AllocaInst* jump_target; { + FuncDeclaration* fd = gIR->func()->decl; + char* fdmangle = fd->mangle(); + + // 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++; + // initialize the setter statement we're going to build IRAsmStmt* outSetterStmt = new IRAsmStmt; - std::string asmGotoEnd = "jmp __llvm_asm_end ; "; + std::string asmGotoEnd = "jmp "+asmGotoEndLabel.str()+" ; "; std::ostringstream code; code << asmGotoEnd; @@ -490,7 +498,7 @@ void AsmBlockStatement::toIR(IRState* p) end = asmblock->internalLabels.end(); bool skip = false; for(it = asmblock->internalLabels.begin(); it != end; ++it) - if((*it)->equals(a->isBranchToLabel->ident)) + if((*it)->equals(a->isBranchToLabel)) skip = true; if(skip) continue; @@ -499,11 +507,11 @@ void AsmBlockStatement::toIR(IRState* p) valToGoto[n_goto] = a->isBranchToLabel; // 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->ident->string); - code << a->isBranchToLabel->ident->string << ": ; "; + Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string); + code << fdmangle << '_' << a->isBranchToLabel->string << ": ; "; code << "movl $<>, $<> ; "; //FIXME: Store the value -> label mapping somewhere, so it can be referenced later - outSetterStmt->in.push_back(llvm::ConstantInt::get(llvm::IntegerType::get(32), n_goto)); + outSetterStmt->in.push_back(DtoConstUint(n_goto)); outSetterStmt->in_c += "i,"; code << asmGotoEnd; @@ -513,11 +521,11 @@ void AsmBlockStatement::toIR(IRState* p) { // finalize code outSetterStmt->code = code.str(); - outSetterStmt->code += "__llvm_asm_end: ; "; + outSetterStmt->code += asmGotoEndLabel.str()+": ; "; // create storage for and initialize the temporary jump_target = new llvm::AllocaInst(llvm::IntegerType::get(32), "__llvm_jump_target", p->topallocapoint()); - gIR->ir->CreateStore(llvm::ConstantInt::get(llvm::IntegerType::get(32), 0), jump_target); + gIR->ir->CreateStore(DtoConstUint(0), jump_target); // setup variable for output from asm outSetterStmt->out_c = "=*m,"; outSetterStmt->out.push_back(jump_target); @@ -623,7 +631,7 @@ void AsmBlockStatement::toIR(IRState* p) llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, valToGoto.size()); // add all cases - std::map::iterator it, end = valToGoto.end(); + std::map::iterator it, end = valToGoto.end(); for(it = valToGoto.begin(); it != end; ++it) { llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb); diff --git a/gen/d-asm-i386.h b/gen/d-asm-i386.h index f17f9f3a..4214021f 100644 --- a/gen/d-asm-i386.h +++ b/gen/d-asm-i386.h @@ -1420,6 +1420,8 @@ struct AsmProcessor } void addLabel(char* id) { + insnTemplate->writestring(sc->func->mangle()); + insnTemplate->writestring("_"); insnTemplate->writestring(id); } @@ -1902,7 +1904,7 @@ struct AsmProcessor asmcode->dollarLabel = 1; } else if (e->op == TOKdsymbol) { LabelDsymbol * lbl = (LabelDsymbol *) ((DsymbolExp *) e)->s; - stmt->isBranchToLabel = lbl; + stmt->isBranchToLabel = lbl->ident; use_star = false; addLabel(lbl->ident->toChars()); diff --git a/gen/irstate.h b/gen/irstate.h index 4a4dd29c..f4aa9024 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -74,7 +74,7 @@ struct IRAsmStmt std::vector in; // if this is nonzero, it contains the target label - LabelDsymbol* isBranchToLabel; + Identifier* isBranchToLabel; }; struct IRAsmBlock diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 9cd167f8..6c97e953 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -150,35 +150,58 @@ void DtoAssert(Loc* loc, DValue* msg) gIR->ir->CreateUnreachable(); } +/****************************************************************************************/ +/*//////////////////////////////////////////////////////////////////////////////////////// +// LABEL HELPER +////////////////////////////////////////////////////////////////////////////////////////*/ +LabelStatement* DtoLabelStatement(Identifier* ident) +{ + FuncDeclaration* fd = gIR->func()->decl; + FuncDeclaration::LabelMap::iterator iter = fd->labmap.find(ident->toChars()); + if (iter == fd->labmap.end()) + { + if (fd->returnLabel->ident->equals(ident)) + { + assert(fd->returnLabel->statement); + return fd->returnLabel->statement; + } + return NULL; + } + return iter->second; +} + /****************************************************************************************/ /*//////////////////////////////////////////////////////////////////////////////////////// // GOTO HELPER ////////////////////////////////////////////////////////////////////////////////////////*/ -void DtoGoto(Loc* loc, LabelDsymbol* target, TryFinallyStatement* enclosingtryfinally) +void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfinally) { assert(!gIR->scopereturned()); + LabelStatement* lblstmt = DtoLabelStatement(target); + assert(lblstmt != NULL); + // if the target label is inside inline asm, error - if(target->asmLabel) + if(lblstmt->asmLabel) error("cannot goto into inline asm block", loc->toChars()); - if (target->statement->llvmBB == NULL) - target->statement->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc()); + if (lblstmt->llvmBB == NULL) + lblstmt->llvmBB = llvm::BasicBlock::Create("label", gIR->topfunc()); // find finallys between goto and label TryFinallyStatement* endfinally = enclosingtryfinally; - while(endfinally != NULL && endfinally != target->statement->enclosingtryfinally) { + while(endfinally != NULL && endfinally != lblstmt->enclosingtryfinally) { endfinally = endfinally->enclosingtryfinally; } // error if didn't find tf statement of label - if(endfinally != target->statement->enclosingtryfinally) + if(endfinally != lblstmt->enclosingtryfinally) error("cannot goto into try block", loc->toChars()); // emit code for finallys between goto and label DtoFinallyBlocks(enclosingtryfinally, endfinally); - llvm::BranchInst::Create(target->statement->llvmBB, gIR->scopebb()); + llvm::BranchInst::Create(lblstmt->llvmBB, gIR->scopebb()); } /****************************************************************************************/ diff --git a/gen/llvmhelpers.h b/gen/llvmhelpers.h index 66fe3173..c86065d0 100644 --- a/gen/llvmhelpers.h +++ b/gen/llvmhelpers.h @@ -13,8 +13,10 @@ void DtoDeleteArray(DValue* arr); // assertion generator void DtoAssert(Loc* loc, DValue* msg); +// return the LabelStatement from the current function with the given identifier or NULL if not found +LabelStatement* DtoLabelStatement(Identifier* ident); // emit goto -void DtoGoto(Loc* loc, LabelDsymbol* target, TryFinallyStatement* enclosingtryfinally); +void DtoGoto(Loc* loc, Identifier* target, TryFinallyStatement* enclosingtryfinally); // generates IR for finally blocks between the 'start' and 'end' statements // will begin with the finally block belonging to 'start' and does not include diff --git a/gen/statements.cpp b/gen/statements.cpp index e0385d3e..e74e61f5 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -1045,6 +1045,8 @@ void LabelStatement::toIR(IRState* p) if (p->asmBlock) { IRAsmStmt* a = new IRAsmStmt; + a->code += p->func()->decl->mangle(); + a->code += "_"; a->code += ident->toChars(); a->code += ":"; p->asmBlock->s.push_back(a); @@ -1052,18 +1054,17 @@ void LabelStatement::toIR(IRState* p) } else { - assert(tf == NULL); - + llvm::BasicBlock* oldend = gIR->scopeend(); if (llvmBB) llvmBB->moveBefore(oldend); else llvmBB = llvm::BasicBlock::Create("label", p->topfunc(), oldend); - + if (!p->scopereturned()) llvm::BranchInst::Create(llvmBB, p->scopebb()); - + p->scope() = IRScope(llvmBB,oldend); } @@ -1086,7 +1087,7 @@ void GotoStatement::toIR(IRState* p) llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* bb = llvm::BasicBlock::Create("aftergoto", p->topfunc(), oldend); - DtoGoto(&loc, label, enclosingtryfinally); + DtoGoto(&loc, label->ident, enclosingtryfinally); p->scope() = IRScope(bb,oldend); } diff --git a/tango/lib/compiler/llvmdc/lifetime.d b/tango/lib/compiler/llvmdc/lifetime.d index 21f6e596..46a786ab 100644 --- a/tango/lib/compiler/llvmdc/lifetime.d +++ b/tango/lib/compiler/llvmdc/lifetime.d @@ -29,9 +29,6 @@ module lifetime; //debug=PRINTF; //debug=PRINTF2; -// we're not allowed to jump out of asm blocks -//version(D_InlineAsm_X86) version = Asm86; - private { import tango.stdc.stdlib; @@ -213,7 +210,7 @@ extern (C) void* _d_newarrayT(TypeInfo ti, size_t length) if (length == 0 || size == 0) return null; - version (Asm86) + version (D_InlineAsm_X86) { asm { @@ -252,7 +249,7 @@ extern (C) void* _d_newarrayiT(TypeInfo ti, size_t length) auto initializer = ti.next.init(); auto isize = initializer.length; auto q = initializer.ptr; - version (Asm86) + version (D_InlineAsm_X86) { asm { @@ -515,7 +512,7 @@ body if (newlength) { - version (Asm86) + version (D_InlineAsm_X86) { size_t newsize = void; @@ -614,7 +611,7 @@ body if (newlength) { - version (Asm86) + version (D_InlineAsm_X86) { size_t newsize = void; diff --git a/tango/lib/compiler/llvmdc/llvmdc.mak b/tango/lib/compiler/llvmdc/llvmdc.mak index db6a8f21..9aea4749 100644 --- a/tango/lib/compiler/llvmdc/llvmdc.mak +++ b/tango/lib/compiler/llvmdc/llvmdc.mak @@ -24,10 +24,10 @@ MD=mkdir -p CFLAGS=-g $(ADD_CFLAGS) #DFLAGS=-release -O3 -inline -w $(ADD_DFLAGS) -DFLAGS=-g -w -noasm $(ADD_DFLAGS) +DFLAGS=-g -w $(ADD_DFLAGS) #TFLAGS=-O3 -inline -w $(ADD_DFLAGS) -TFLAGS=-g -w -noasm $(ADD_DFLAGS) +TFLAGS=-g -w $(ADD_DFLAGS) DOCFLAGS=-version=DDoc diff --git a/tango/lib/gc/basic/gc.d b/tango/lib/gc/basic/gc.d index a303908f..64040bb1 100644 --- a/tango/lib/gc/basic/gc.d +++ b/tango/lib/gc/basic/gc.d @@ -70,8 +70,7 @@ extern (C) void gc_term() // NOTE: Due to popular demand, this has been re-enabled. It still has // the problems mentioned above though, so I guess we'll see. - // FIXME: LLVMDC crashes ... - //_gc.fullCollectNoStack(); // not really a 'collect all' -- still scans + _gc.fullCollectNoStack(); // not really a 'collect all' -- still scans // static data area, roots, and ranges. _gc.Dtor(); } diff --git a/tangotests/asm7.d b/tangotests/asm7.d new file mode 100644 index 00000000..9ea56339 --- /dev/null +++ b/tangotests/asm7.d @@ -0,0 +1,41 @@ +module tangotests.asm7; + +// test massive label collisions (runtime uses Loverflow too) + +void main() +{ + int a = add(1,2); + int s = sub(1,2); + assert(a == 3); + assert(s == -1); +} + +int add(int a, int b) +{ + int res; + asm + { + mov EAX, a; + add EAX, b; + jo Loverflow; + mov res, EAX; + } + return res; +Loverflow: + assert(0, "add overflow"); +} + +int sub(int a, int b) +{ + int res; + asm + { + mov EAX, a; + sub EAX, b; + jo Loverflow; + mov res, EAX; + } + return res; +Loverflow: + assert(0, "sub overflow"); +} diff --git a/test/arrays.d b/test/arrays15.d similarity index 100% rename from test/arrays.d rename to test/arrays15.d