Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Wilson committed Jan 4, 2012
2 parents 59ec5c6 + 7c83996 commit cba7380
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 21 deletions.
8 changes: 4 additions & 4 deletions src/constfold.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
e = ale->elements->tdata()[i];
e->type = type;
if (e->checkSideEffect(2))
if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
}
}
Expand All @@ -1386,7 +1386,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
else
{ e = ale->elements->tdata()[i];
e->type = type;
if (e->checkSideEffect(2))
if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
}
}
Expand All @@ -1406,7 +1406,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
if (ex->isBool(TRUE))
{ e = ae->values->tdata()[i];
e->type = type;
if (e->checkSideEffect(2))
if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
break;
}
Expand Down Expand Up @@ -1459,7 +1459,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
}
else if (e1->op == TOKarrayliteral &&
lwr->op == TOKint64 && upr->op == TOKint64 &&
!e1->checkSideEffect(2))
!e1->hasSideEffect())
{ ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
uinteger_t ilwr = lwr->toInteger();
uinteger_t iupr = upr->toInteger();
Expand Down
24 changes: 12 additions & 12 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -3519,7 +3519,7 @@ int ArrayLiteralExp::checkSideEffect(int flag)
for (size_t i = 0; i < elements->dim; i++)
{ Expression *e = elements->tdata()[i];

f |= e->checkSideEffect(2);
f |= e->hasSideEffect();
}
if (flag == 0 && f == 0)
Expression::checkSideEffect(0);
Expand Down Expand Up @@ -3635,8 +3635,8 @@ int AssocArrayLiteralExp::checkSideEffect(int flag)
{ Expression *key = keys->tdata()[i];
Expression *value = values->tdata()[i];

f |= key->checkSideEffect(2);
f |= value->checkSideEffect(2);
f |= key->hasSideEffect();
f |= value->hasSideEffect();
}
if (flag == 0 && f == 0)
Expression::checkSideEffect(0);
Expand Down Expand Up @@ -3916,7 +3916,7 @@ int StructLiteralExp::checkSideEffect(int flag)
if (!e)
continue;

f |= e->checkSideEffect(2);
f |= e->hasSideEffect();
}
if (flag == 0 && f == 0)
Expression::checkSideEffect(0);
Expand Down Expand Up @@ -4934,7 +4934,7 @@ int TupleExp::checkSideEffect(int flag)
for (size_t i = 0; i < exps->dim; i++)
{ Expression *e = (*exps)[i];

f |= e->checkSideEffect(2);
f |= e->hasSideEffect();
}
if (flag == 0 && f == 0)
Expression::checkSideEffect(0);
Expand Down Expand Up @@ -6684,7 +6684,7 @@ Expression *DotVarExp::semantic(Scope *sc)

Dsymbol *s = ((DsymbolExp *)e)->s;
if (i == 0 && sc->func && tup->objects->dim > 1 &&
e1->checkSideEffect(2))
e1->hasSideEffect())
{
Identifier *id = Lexer::uniqueId("__tup");
ExpInitializer *ei = new ExpInitializer(e1->loc, e1);
Expand Down Expand Up @@ -9268,7 +9268,7 @@ int CommaExp::checkSideEffect(int flag)
}

if (flag == 2)
return e1->checkSideEffect(2) || e2->checkSideEffect(2);
return e1->hasSideEffect() || e2->hasSideEffect();
else
{
// Don't check e1 until we cast(void) the a,b code generation
Expand Down Expand Up @@ -11578,7 +11578,7 @@ int OrOrExp::checkSideEffect(int flag)
{
if (flag == 2)
{
return e1->checkSideEffect(2) || e2->checkSideEffect(2);
return e1->hasSideEffect() || e2->hasSideEffect();
}
else
{ e1->checkSideEffect(1);
Expand Down Expand Up @@ -11653,7 +11653,7 @@ int AndAndExp::checkSideEffect(int flag)
{
if (flag == 2)
{
return e1->checkSideEffect(2) || e2->checkSideEffect(2);
return e1->hasSideEffect() || e2->hasSideEffect();
}
else
{
Expand Down Expand Up @@ -12193,9 +12193,9 @@ int CondExp::checkSideEffect(int flag)
{
if (flag == 2)
{
return econd->checkSideEffect(2) ||
e1->checkSideEffect(2) ||
e2->checkSideEffect(2);
return econd->hasSideEffect() ||
e1->hasSideEffect() ||
e2->hasSideEffect();
}
else
{
Expand Down
1 change: 1 addition & 0 deletions src/expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ struct Expression : Object
virtual int isBool(int result);
virtual int isBit();
virtual int checkSideEffect(int flag);
bool hasSideEffect();
int canThrow(bool mustNotThrow);

virtual int inlineCost3(InlineCostState *ics);
Expand Down
2 changes: 1 addition & 1 deletion src/optimize.c
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,7 @@ Expression *CommaExp::optimize(int result)

e1 = e1->optimize(result & WANTinterpret);
e2 = e2->optimize(result);
if (!e1 || e1->op == TOKint64 || e1->op == TOKfloat64 || !e1->checkSideEffect(2))
if (!e1 || e1->op == TOKint64 || e1->op == TOKfloat64 || !e1->hasSideEffect())
{
e = e2;
if (e)
Expand Down
8 changes: 6 additions & 2 deletions src/posix.mak
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ DMD_OBJS = \
hdrgen.o delegatize.o aa.o ti_achar.o toir.o interpret.o traits.o \
builtin.o clone.o aliasthis.o intrange.o \
man.o arrayop.o port.o response.o async.o json.o speller.o aav.o unittests.o \
imphint.o argtypes.o ti_pvoid.o apply.o canthrow.o
imphint.o argtypes.o ti_pvoid.o apply.o canthrow.o sideeffect.o

ifeq (OSX,$(TARGET))
DMD_OBJS += libmach.o machobj.o
Expand All @@ -108,7 +108,7 @@ SRC = win32.mak posix.mak \
delegatize.c toir.h toir.c interpret.c traits.c cppmangle.c \
builtin.c clone.c lib.h libomf.c libelf.c libmach.c arrayop.c \
aliasthis.h aliasthis.c json.h json.c unittests.c imphint.c \
argtypes.c intrange.c apply.c canthrow.c \
argtypes.c intrange.c apply.c canthrow.c sideffect.c \
$C/cdef.h $C/cc.h $C/oper.h $C/ty.h $C/optabgen.c \
$C/global.h $C/code.h $C/type.h $C/dt.h $C/cgcv.h \
$C/el.h $C/iasm.h $C/rtlsym.h $C/html.h \
Expand Down Expand Up @@ -510,6 +510,9 @@ s2ir.o: s2ir.c $C/rtlsym.h statement.h
scope.o: scope.c
$(CC) -c $(CFLAGS) $<

sideeffect.o: sideeffect.c
$(CC) -c $(CFLAGS) $<

speller.o: $(ROOT)/speller.c
$(CC) -c $(GFLAGS) -I$(ROOT) $<

Expand Down Expand Up @@ -640,6 +643,7 @@ endif
gcov parse.c
gcov ph.c
gcov scope.c
gcov sideeffect.c
gcov statement.c
gcov staticassert.c
gcov s2ir.c
Expand Down
112 changes: 112 additions & 0 deletions src/sideeffect.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@

// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.

#include <stdio.h>
#include <assert.h>

#include "mars.h"
#include "init.h"
#include "expression.h"
#include "template.h"
#include "statement.h"
#include "mtype.h"
#include "utf.h"
#include "declaration.h"
#include "aggregate.h"
#include "scope.h"
#include "attrib.h"

int lambdaHasSideEffect(Expression *e, void *param);

/********************************************
* Determine if Expression has any side effects.
*/

bool Expression::hasSideEffect()
{
bool has = FALSE;
apply(&lambdaHasSideEffect, &has);
return has;
}

int lambdaHasSideEffect(Expression *e, void *param)
{
bool *phas = (bool *)param;
switch (e->op)
{
// Sort the cases by most frequently used first
case TOKassign:
case TOKplusplus:
case TOKminusminus:
case TOKdeclaration:
case TOKconstruct:
case TOKblit:
case TOKaddass:
case TOKminass:
case TOKcatass:
case TOKmulass:
case TOKdivass:
case TOKmodass:
case TOKshlass:
case TOKshrass:
case TOKushrass:
case TOKandass:
case TOKorass:
case TOKxorass:
case TOKpowass:
case TOKin:
case TOKremove:
case TOKassert:
case TOKhalt:
case TOKdelete:
case TOKnew:
case TOKnewanonclass:
*phas = TRUE;
break;

case TOKcall:
{ CallExp *ce = (CallExp *)e;

/* Calling a function or delegate that is pure nothrow
* has no side effects.
*/
if (ce->e1->type)
{
Type *t = ce->e1->type->toBasetype();
if ((t->ty == Tfunction && ((TypeFunction *)t)->purity > PUREweak &&
((TypeFunction *)t)->isnothrow)
||
(t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->purity > PUREweak &&
((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow)
)
{
}
else
*phas = TRUE;
}
break;
}

case TOKcast:
{ CastExp *ce = (CastExp *)e;

/* if:
* cast(classtype)func() // because it may throw
*/
if (ce->to->ty == Tclass && ce->e1->op == TOKcall && ce->e1->type->ty == Tclass)
*phas = TRUE;
break;
}

default:
break;
}
return *phas; // stop walking if we determine this expression has side effects
}
6 changes: 4 additions & 2 deletions src/win32.mak
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ OBJ1= mars.obj enum.obj struct.obj dsymbol.obj import.obj id.obj \
builtin.obj clone.obj libomf.obj arrayop.obj irstate.obj \
glue.obj msc.obj ph.obj tk.obj s2ir.obj todt.obj e2ir.obj tocsym.obj \
util.obj eh.obj toobj.obj toctype.obj tocvdebug.obj toir.obj \
json.obj unittests.obj imphint.obj argtypes.obj apply.obj canthrow.obj
json.obj unittests.obj imphint.obj argtypes.obj apply.obj canthrow.obj \
sideeffect.obj

# from C/C++ compiler optimizer and back end

Expand Down Expand Up @@ -125,7 +126,7 @@ SRCS= mars.c enum.c struct.c dsymbol.c import.c idgen.c impcnvgen.c utf.h \
delegatize.c toir.h toir.c interpret.c traits.c builtin.c \
clone.c lib.h libomf.c libelf.c libmach.c arrayop.c intrange.c \
aliasthis.h aliasthis.c json.h json.c unittests.c imphint.c argtypes.c \
apply.c canthrow.c
apply.c canthrow.c sideeffect.c

# From C++ compiler

Expand Down Expand Up @@ -510,6 +511,7 @@ opover.obj : $(TOTALH) expression.h opover.c
optimize.obj : $(TOTALH) expression.h optimize.c
parse.obj : $(TOTALH) attrib.h lexer.h parse.h parse.c
scope.obj : $(TOTALH) scope.h scope.c
sideeffect.obj : $(TOTALH) sideeffect.c
statement.obj : $(TOTALH) statement.h statement.c expression.h
staticassert.obj : $(TOTALH) staticassert.h staticassert.c
struct.obj : $(TOTALH) identifier.h enum.h struct.c
Expand Down

0 comments on commit cba7380

Please sign in to comment.