Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ddmd/backend/rtlsym.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ void rtlsym_init()

//printf("rtlsym_init(%s)\n", regm_str(FREGSAVED));

#if MARS
type *t = type_fake(TYnfunc);
t->Tmangle = mTYman_c;
t->Tcount++;

#if MARS
// Variadic function
type *tv = type_fake(TYnfunc);
tv->Tmangle = mTYman_c;
Expand Down
1 change: 1 addition & 0 deletions src/ddmd/backend/rtlsym.d
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ enum
RTLSYM_DSWITCHERR,
RTLSYM_DHIDDENFUNC,
RTLSYM_NEWCLASS,
RTLSYM_NEWTHROW,
RTLSYM_NEWARRAYT,
RTLSYM_NEWARRAYIT,
RTLSYM_NEWITEMT,
Expand Down
1 change: 1 addition & 0 deletions src/ddmd/backend/rtlsym.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ SYMBOL_MARS(SWITCH_DSTRING,FLfunc,FREGSAVED,"_d_switch_dstring", 0, t) \
SYMBOL_MARS(DSWITCHERR, FLfunc,FREGSAVED,"_d_switch_error", SFLexit, t) \
SYMBOL_MARS(DHIDDENFUNC, FLfunc,FREGSAVED,"_d_hidden_func", 0, t) \
SYMBOL_MARS(NEWCLASS, FLfunc,FREGSAVED,"_d_newclass", 0, t) \
SYMBOL_MARS(NEWTHROW, FLfunc,FREGSAVED,"_d_newThrowable", 0, t) \
SYMBOL_MARS(NEWARRAYT, FLfunc,FREGSAVED,"_d_newarrayT", 0, t) \
SYMBOL_MARS(NEWARRAYIT, FLfunc,FREGSAVED,"_d_newarrayiT", 0, t) \
SYMBOL_MARS(NEWITEMT, FLfunc,FREGSAVED,"_d_newitemT", 0, t) \
Expand Down
6 changes: 5 additions & 1 deletion src/ddmd/declaration.d
Original file line number Diff line number Diff line change
Expand Up @@ -986,9 +986,10 @@ extern (C++) class VarDeclaration : Declaration
uint sequenceNumber; // order the variables are declared
__gshared uint nextSequenceNumber; // the counter for sequenceNumber
FuncDeclarations nestedrefs; // referenced by these lexically nested functions
bool isargptr; // if parameter that _argptr points to
structalign_t alignment;
bool isargptr; // if parameter that _argptr points to
bool ctorinit; // it has been initialized in a ctor
bool iscatchvar; // this is the exception object variable in catch() clause

// Both these mean the var is not rebindable once assigned,
// and the destructor gets run when it goes out of scope
Expand Down Expand Up @@ -1275,6 +1276,9 @@ extern (C++) class VarDeclaration : Declaration
return null;
}

if (iscatchvar)
return null; // destructor is built by `void semantic(Catch c, Scope* sc)`, not here

Expression e = null;
// Destructors for structs and arrays of structs
Type tv = type.baseElemOf();
Expand Down
3 changes: 2 additions & 1 deletion src/ddmd/declaration.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,10 @@ class VarDeclaration : public Declaration
unsigned offset;
unsigned sequenceNumber; // order the variables are declared
FuncDeclarations nestedrefs; // referenced by these lexically nested functions
bool isargptr; // if parameter that _argptr points to
structalign_t alignment;
bool isargptr; // if parameter that _argptr points to
bool ctorinit; // it has been initialized in a ctor
bool iscatchvar; // this is the exception object variable in catch() clause
bool onstack; // it is a class that was allocated on the stack
bool mynew; // it is a class new'd with custom operator new
int canassign; // it can be assigned to
Expand Down
3 changes: 2 additions & 1 deletion src/ddmd/escape.d
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,8 @@ bool checkThrowEscape(Scope* sc, Expression e, bool gag)

Dsymbol p = v.toParent2();

if (v.isScope())
if (v.isScope() && !v.iscatchvar) // special case: allow catch var to be rethrown
// despite being `scope`
{
if (sc._module && sc._module.isRoot())
{
Expand Down
4 changes: 3 additions & 1 deletion src/ddmd/expression.d
Original file line number Diff line number Diff line change
Expand Up @@ -4037,10 +4037,12 @@ extern (C++) final class NewExp : Expression
Expressions* newargs; // Array of Expression's to call new operator
Type newtype;
Expressions* arguments; // Array of Expression's

Expression argprefix; // expression to be evaluated just before arguments[]
CtorDeclaration member; // constructor function
NewDeclaration allocator; // allocator function
int onstack; // allocate on stack
bool onstack; // allocate on stack
bool thrownew; // this NewExp is the expression of a ThrowStatement

extern (D) this(Loc loc, Expression thisexp, Expressions* newargs, Type newtype, Expressions* arguments)
{
Expand Down
3 changes: 2 additions & 1 deletion src/ddmd/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,8 @@ class NewExp : public Expression

CtorDeclaration *member; // constructor function
NewDeclaration *allocator; // allocator function
int onstack; // allocate on stack
bool onstack; // allocate on stack
bool thrownew; // this NewExp is the expression of a ThrowStatement

static NewExp *create(Loc loc, Expression *thisexp, Expressions *newargs, Type *newtype, Expressions *arguments);
Expression *syntaxCopy();
Expand Down
1 change: 1 addition & 0 deletions src/ddmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ struct Param
bool fix16997; // fix integral promotions for unary + - ~ operators
// https://issues.dlang.org/show_bug.cgi?id=16997
bool vsafe; // use enhanced @safe checking
bool ehnogc; // use @nogc exception handling
/** The --transition=safe switch should only be used to show code with
* silent semantics changes related to @safe improvements. It should not be
* used to hide a feature that will have to go through deprecate-then-error
Expand Down
1 change: 1 addition & 0 deletions src/ddmd/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ struct Param
bool fix16997; // fix integral promotions for unary + - ~ operators
// https://issues.dlang.org/show_bug.cgi?id=16997
bool vsafe; // use enhanced @safe checking
bool ehnogc; // use @nogc exception handling
bool showGaggedErrors; // print gagged errors anyway
bool manual; // open browser on compiler manual
bool usage; // print usage and exit
Expand Down
1 change: 1 addition & 0 deletions src/ddmd/id.d
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ immutable Msgtable[] msgtable =
{ "_ArrayEq" },
{ "_ArrayPostblit" },
{ "_ArrayDtor" },
{ "_d_delThrowable" },

// For pragma's
{ "Pinline", "inline" },
Expand Down
5 changes: 5 additions & 0 deletions src/ddmd/mars.d
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ Where:
"%s" /* placeholder for fpic */ ~ "
-dip25 implement http://wiki.dlang.org/DIP25 (experimental)
-dip1000 implement http://wiki.dlang.org/DIP1000 (experimental)
-dip1008 implement DIP1008 (experimental)
-g add symbolic debug info
-gf emit debug info for all referenced types
-gs always emit stack frame
Expand Down Expand Up @@ -1954,6 +1955,10 @@ private bool parseCommandLine(const ref Strings arguments, const size_t argc, re
params.useDIP25 = true;
params.vsafe = true;
}
else if (strcmp(p + 1, "dip1008") == 0)
{
params.ehnogc = true;
}
else if (strcmp(p + 1, "lib") == 0) // https://dlang.org/dmd-windows.html#switch-lib
params.lib = true;
else if (strcmp(p + 1, "nofloat") == 0)
Expand Down
2 changes: 2 additions & 0 deletions src/ddmd/nogc.d
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ public:
return;
if (e.allocator)
return;
if (global.params.ehnogc && e.thrownew)
return; // separate allocator is called for this, not the GC
if (f.setGC())
{
e.error("cannot use 'new' in @nogc %s '%s'",
Expand Down
32 changes: 31 additions & 1 deletion src/ddmd/statementsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -3808,6 +3808,12 @@ else
FuncDeclaration fd = sc.parent.isFuncDeclaration();
fd.hasReturnExp |= 2;

if (ts.exp.op == TOKnew)
{
NewExp ne = cast(NewExp)ts.exp;
ne.thrownew = true;
}

ts.exp = ts.exp.expressionSemantic(sc);
ts.exp = resolveProperties(sc, ts.exp);
ts.exp = checkGC(sc, ts.exp);
Expand Down Expand Up @@ -4010,6 +4016,7 @@ void catchSemantic(Catch c, Scope* sc)
c.errors = true;
else
{
StorageClass stc;
auto cd = c.type.toBasetype().isClassHandle();
if (!cd)
{
Expand Down Expand Up @@ -4041,12 +4048,35 @@ void catchSemantic(Catch c, Scope* sc)
error(c.loc, "can only catch class objects derived from Exception in @safe code, not `%s`", c.type.toChars());
c.errors = true;
}
else if (global.params.ehnogc)
{
stc |= STCscope;
}

if (c.ident)
{
c.var = new VarDeclaration(c.loc, c.type, c.ident, null);
c.var = new VarDeclaration(c.loc, c.type, c.ident, null, stc);
c.var.iscatchvar = true;
c.var.dsymbolSemantic(sc);
sc.insert(c.var);

if (global.params.ehnogc && stc & STCscope)
{
/* Add a destructor for c.var
* try { handler } finally { if (!__ctfe) _d_delThrowable(var); }
*/
assert(!c.var.edtor); // ensure we didn't create one in callScopeDtor()

Loc loc = c.loc;
Expression e = new VarExp(loc, c.var);
e = new CallExp(loc, new IdentifierExp(loc, Id._d_delThrowable), e);

Expression ec = new IdentifierExp(loc, Id.ctfe);
ec = new NotExp(loc, ec);
Statement s = new IfStatement(loc, null, ec, new ExpStatement(loc, e), null, loc);
c.handler = new TryFinallyStatement(loc, c.handler, s);
}

}
c.handler = c.handler.statementSemantic(sc);
if (c.handler && c.handler.isErrorStatement())
Expand Down
21 changes: 21 additions & 0 deletions test/compilable/testdip1008.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// PERMUTE_ARGS:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing argument to actually test the dip.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it'll never work until the druntime changes are pulled, so I disabled it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's actually a good thing, it will prevent this P.R. from being pulled before it's ready.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which came first, the chicken or the egg?

// won't work until druntime is updated, so disable XXXEQUIRED_ARGS: -dip1008

int bar()
{
try
{
throw new Exception("message");
}
catch (Exception e)
{
return 7;
}
}


void foo()
{
enum r = bar();
static assert(r == 7);
}