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 Feb 22, 2012
2 parents cfa40b3 + 112b885 commit dca4387
Show file tree
Hide file tree
Showing 18 changed files with 110 additions and 28 deletions.
5 changes: 5 additions & 0 deletions src/class.c
Expand Up @@ -905,7 +905,12 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
if (scope && !symtab)
{ Scope *sc = scope;
sc->mustsemantic++;
// If speculatively gagged, ungag now.
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging())
global.gag = 0;
semantic(sc);
global.gag = oldgag;
sc->mustsemantic--;
}

Expand Down
4 changes: 2 additions & 2 deletions src/declaration.c
Expand Up @@ -503,7 +503,7 @@ void AliasDeclaration::semantic(Scope *sc)
ScopeDsymbol::multiplyDefined(0, this, overnext);
this->inSemantic = 0;

if (errors != global.errors)
if (global.gag && errors != global.errors)
type = savedtype;
return;

Expand Down Expand Up @@ -539,7 +539,7 @@ void AliasDeclaration::semantic(Scope *sc)
assert(global.errors);
s = NULL;
}
if (errors != global.errors)
if (global.gag && errors != global.errors)
{
type = savedtype;
overnext = savedovernext;
Expand Down
17 changes: 17 additions & 0 deletions src/dsymbol.c
Expand Up @@ -277,6 +277,23 @@ TemplateInstance *Dsymbol::inTemplateInstance()
return NULL;
}

// Check if this function is a member of a template which has only been
// instantiated speculatively, eg from inside is(typeof()).
// Return the speculative template instance it is part of,
// or NULL if not speculative.
TemplateInstance *Dsymbol::isSpeculative()
{
Dsymbol * par = parent;
while (par)
{
TemplateInstance *ti = par->isTemplateInstance();
if (ti && ti->speculative)
return ti;
par = par->toParent();
}
return NULL;
}

int Dsymbol::isAnonymous()
{
return ident ? 0 : 1;
Expand Down
1 change: 1 addition & 0 deletions src/dsymbol.h
Expand Up @@ -137,6 +137,7 @@ struct Dsymbol : Object
Dsymbol *toParent();
Dsymbol *toParent2();
TemplateInstance *inTemplateInstance();
TemplateInstance *isSpeculative();

int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()

Expand Down
36 changes: 13 additions & 23 deletions src/expression.c
@@ -1,6 +1,6 @@

// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
Expand Down Expand Up @@ -670,23 +670,6 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e, int noscope)
}
#endif

// Check if this function is a member of a template which has only been
// instantiated speculatively, eg from inside is(typeof()).
// Return the speculative template instance it is part of,
// or NULL if not speculative.
TemplateInstance *isSpeculativeFunction(FuncDeclaration *fd)
{
Dsymbol * par = fd->parent;
while (par)
{
TemplateInstance *ti = par->isTemplateInstance();
if (ti && ti->speculative)
return ti;
par = par->toParent();
}
return NULL;
}

/****************************************
* Now that we know the exact type of the function we're calling,
* the arguments[] need to be adjusted:
Expand Down Expand Up @@ -716,7 +699,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
// If inferring return type, and semantic3() needs to be run if not already run
if (!tf->next && fd->inferRetType)
{
TemplateInstance *spec = isSpeculativeFunction(fd);
TemplateInstance *spec = fd->isSpeculative();
int olderrs = global.errors;
fd->semantic3(fd->scope);
// Update the template instantiation with the number
Expand Down Expand Up @@ -2737,12 +2720,18 @@ Expression *DsymbolExp::semantic(Scope *sc)
{ //printf("'%s' is a function\n", f->toChars());

if (!f->originalType && f->scope) // semantic not yet run
{
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging() && !f->isSpeculative())
global.gag = 0;
f->semantic(f->scope);
global.gag = oldgag;
}

// if inferring return type, sematic3 needs to be run
if (f->inferRetType && f->scope && f->type && !f->type->nextOf())
{
TemplateInstance *spec = isSpeculativeFunction(f);
TemplateInstance *spec = f->isSpeculative();
int olderrs = global.errors;
f->semantic3(f->scope);
// Update the template instantiation with the number
Expand Down Expand Up @@ -9572,18 +9561,19 @@ Expression *PostExp::semantic(Scope *sc)
return new ErrorExp();
}

e1 = e1->modifiableLvalue(sc, e1);
if (e1->op != TOKarraylength)
e1 = e1->modifiableLvalue(sc, e1);

Type *t1 = e1->type->toBasetype();
if (t1->ty == Tclass || t1->ty == Tstruct)
if (t1->ty == Tclass || t1->ty == Tstruct || e1->op == TOKarraylength)
{ /* Check for operator overloading,
* but rewrite in terms of ++e instead of e++
*/

/* If e1 is not trivial, take a reference to it
*/
Expression *de = NULL;
if (e1->op != TOKvar)
if (e1->op != TOKvar && e1->op != TOKarraylength)
{
// ref v = e1;
Identifier *id = Lexer::uniqueId("__postref");
Expand Down
3 changes: 1 addition & 2 deletions src/interpret.c
Expand Up @@ -27,7 +27,6 @@
#include "attrib.h" // for AttribDeclaration

#include "template.h"
TemplateInstance *isSpeculativeFunction(FuncDeclaration *fd);


#define LOG 0
Expand Down Expand Up @@ -480,7 +479,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
*/
int olderrors = global.errors;
int oldgag = global.gag;
TemplateInstance *spec = isSpeculativeFunction(this);
TemplateInstance *spec = isSpeculative();
if (global.gag && !spec)
global.gag = 0;
semantic3(scope);
Expand Down
5 changes: 5 additions & 0 deletions src/mars.c
Expand Up @@ -117,6 +117,11 @@ bool Global::endGagging(unsigned oldGagged)
return anyErrs;
}

bool Global::isSpeculativeGagging()
{
return gag && gag == speculativeGag;
}


char *Loc::toChars()
{
Expand Down
6 changes: 6 additions & 0 deletions src/mars.h
Expand Up @@ -262,6 +262,12 @@ struct Global
unsigned gag; // !=0 means gag reporting of errors & warnings
unsigned gaggedErrors; // number of errors reported while gagged

/* Gagging can either be speculative (is(typeof()), etc)
* or because of forward references
*/
unsigned speculativeGag; // == gag means gagging is for is(typeof);
bool isSpeculativeGagging();

// Start gagging. Return the current number of gagged errors
unsigned startGagging();

Expand Down
5 changes: 5 additions & 0 deletions src/mtype.c
Expand Up @@ -6730,7 +6730,12 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc)
Scope *sc2 = sc->push();
sc2->intypeof++;
sc2->flags |= sc->flags & SCOPEstaticif;
unsigned oldspecgag = global.speculativeGag;
if (global.gag)
global.speculativeGag = global.gag;
exp = exp->semantic(sc2);
global.speculativeGag = oldspecgag;

#if DMDV2
if (exp->type && exp->type->ty == Tfunction &&
((TypeFunction *)exp->type)->isproperty)
Expand Down
5 changes: 5 additions & 0 deletions src/struct.c
Expand Up @@ -473,7 +473,12 @@ void StructDeclaration::semantic(Scope *sc)
if (sizeok == 0 && s->isAliasDeclaration())
finalizeSize();
}
// Ungag errors when not speculative
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging() && !isSpeculative())
global.gag = 0;
s->semantic(sc2);
global.gag = oldgag;
}

if (sizeok == 2)
Expand Down
3 changes: 3 additions & 0 deletions src/traits.c
Expand Up @@ -451,6 +451,8 @@ Expression *TraitsExp::semantic(Scope *sc)
Expression *e;

unsigned errors = global.startGagging();
unsigned oldspec = global.speculativeGag;
global.speculativeGag = global.gag;

Type *t = isType(o);
if (t)
Expand All @@ -471,6 +473,7 @@ Expression *TraitsExp::semantic(Scope *sc)
}
}

global.speculativeGag = oldspec;
if (global.endGagging(errors))
{
goto Lfalse;
Expand Down
11 changes: 11 additions & 0 deletions test/fail_compilation/gag4269a.d
@@ -0,0 +1,11 @@
// REQUIRED_ARGS: -c -o-

static if(is(typeof(A4269.sizeof))) {}

class A4269
{
void foo(B b);
}



6 changes: 6 additions & 0 deletions test/fail_compilation/gag4269b.d
@@ -0,0 +1,6 @@
// REQUIRED_ARGS: -c -o-

static if(is(typeof(X2.init))) {}
struct X2 { Y y; }


5 changes: 5 additions & 0 deletions test/fail_compilation/gag4269c.d
@@ -0,0 +1,5 @@
// REQUIRED_ARGS: -c -o-

static if(is(typeof(X3.init))) {}
void X3(T3) { }

5 changes: 5 additions & 0 deletions test/fail_compilation/gag4269d.d
@@ -0,0 +1,5 @@
// REQUIRED_ARGS: -c -o-

static if(is(typeof(X4.init))) {}
Y4 X4() { return typeof(return).init; }

4 changes: 4 additions & 0 deletions test/fail_compilation/gag4269e.d
@@ -0,0 +1,4 @@
// REQUIRED_ARGS: -c -o-

static if(is(typeof(X8.init))) {}
class X8 : Y8 {}
4 changes: 4 additions & 0 deletions test/fail_compilation/gag4269f.d
@@ -0,0 +1,4 @@
// REQUIRED_ARGS: -c -o-

static if(is(typeof(X9.init))) {}
interface X9 { Y9 y; }
13 changes: 12 additions & 1 deletion test/runnable/xtest46.d
Expand Up @@ -1120,6 +1120,17 @@ void test62()

/***************************************************/

void test3927()
{
int[] array;
assert(array.length++ == 0);
assert(array.length == 1);
assert(array.length-- == 1);
assert(array.length == 0);
}

/***************************************************/

void test63()
{
int[3] b;
Expand Down Expand Up @@ -4771,7 +4782,7 @@ int main()
test103();
test104();
test105();

test3927();
test107();

test109();
Expand Down

0 comments on commit dca4387

Please sign in to comment.