[svn r326] Fixed a bunch of issues with printf's that MinGW32 did not support.

Fixed problems with label collisions when using labels inside inline asm. LabelStatement is now easily reached given its
Identifier, which should be useful elsewhere too.
Enabled inline asm for building the lib/compiler/llvmdc runtime code, fixing branches out of asm makes this possible.
This commit is contained in:
Tomas Lindquist Olsen
2008-06-27 22:04:35 +02:00
parent b064c794de
commit 03d26e1178
27 changed files with 186 additions and 84 deletions

View File

@@ -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();

View File

@@ -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);

View File

@@ -16,6 +16,7 @@
#endif /* __DMC__ */
#include <set>
#include <map>
#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<VarDeclaration*> nestedVars;
// we keep our own table of label statements as LabelDsymbolS
// don't always carry their corresponding statement along ...
typedef std::map<const char*, LabelStatement*> LabelMap;
LabelMap labmap;
};
struct FuncAliasDeclaration : FuncDeclaration

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);

View File

@@ -16,8 +16,10 @@
#endif /* __DMC__ */
#include <stdint.h>
#include <string>
#include <cstdarg>
#include <stdarg.h>
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
#include <stdarg.h>
#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

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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()

View File

@@ -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()?

View File

@@ -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

View File

@@ -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)

View File

@@ -461,16 +461,24 @@ void AsmBlockStatement::toIR(IRState* p)
// a post-asm switch
// maps each special value to a goto destination
std::map<int, LabelDsymbol*> valToGoto;
std::map<int, Identifier*> 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 $<<in" << n_goto << ">>, $<<out0>> ; ";
//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<int, LabelDsymbol*>::iterator it, end = valToGoto.end();
std::map<int, Identifier*>::iterator it, end = valToGoto.end();
for(it = valToGoto.begin(); it != end; ++it)
{
llvm::BasicBlock* casebb = llvm::BasicBlock::Create("case", p->topfunc(), bb);

View File

@@ -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());

View File

@@ -74,7 +74,7 @@ struct IRAsmStmt
std::vector<LLValue*> in;
// if this is nonzero, it contains the target label
LabelDsymbol* isBranchToLabel;
Identifier* isBranchToLabel;
};
struct IRAsmBlock

View File

@@ -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());
}
/****************************************************************************************/

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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();
}

41
tangotests/asm7.d Normal file
View File

@@ -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");
}