Skip to content

Commit

Permalink
Merge pull request #5194 from MartinNowak/merge_stable
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'upstream/stable' into merge_stable
  • Loading branch information
9rnsr committed Oct 14, 2015
2 parents 13f4193 + 1973bfd commit b326f6e
Show file tree
Hide file tree
Showing 18 changed files with 296 additions and 34 deletions.
64 changes: 51 additions & 13 deletions src/dstruct.d
Expand Up @@ -8,6 +8,7 @@

module ddmd.dstruct;

import core.stdc.stdio;
import ddmd.aggregate;
import ddmd.argtypes;
import ddmd.arraytypes;
Expand Down Expand Up @@ -104,15 +105,47 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t)
override void visit(TypeStruct t)
{
StructDeclaration sd = t.sym;

/* Step 1: create TypeInfoDeclaration
*/
if (!sc) // inline may request TypeInfo.
{
Scope scx;
scx._module = sd.getModule();
getTypeInfoType(t, &scx);
sd.requestTypeInfo = true;
}
else if (!sc.minst)
{
// don't yet have to generate TypeInfo instance if
// the typeid(T) expression exists in speculative scope.
}
else
{
getTypeInfoType(t, sc);
sd.requestTypeInfo = true;

// Bugzilla 15149, if the typeid operand type comes from a
// result of auto function, it may be yet speculative.
unSpeculative(sc, sd);
}

/* Step 2: If the TypeInfo generation requires sd.semantic3, run it later.
* This should be done even if typeid(T) exists in speculative scope.
* Because it may appear later in non-speculative scope.
*/
if (!sd.members)
return; // opaque struct
if (sd.semanticRun >= PASSsemantic3)
return; // semantic3 will be done
if (!sd.xeq && !sd.xcmp && !sd.postblit && !sd.dtor && !sd.xhash && !search_toString(sd))
return; // none of TypeInfo-specific members

// If the struct is in a non-root module, run semantic3 to get
// correct symbols for the member function.
if (TemplateInstance ti = sd.isInstantiated())
if (sd.semanticRun >= PASSsemantic3)
{
// semantic3 is already done
}
else if (TemplateInstance ti = sd.isInstantiated())
{
if (ti.minst && !ti.minst.isRoot())
Module.addDeferredSemantic3(sd);
Expand All @@ -125,16 +158,6 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t)
Module.addDeferredSemantic3(sd);
}
}
if (!sc) // inline may request TypeInfo.
{
Scope scx;
scx._module = sd.getModule();
getTypeInfoType(t, &scx);
}
else
getTypeInfoType(t, sc);
if (!sc || sc.minst)
sd.requestTypeInfo = true;
}

override void visit(TypeClass t)
Expand All @@ -155,6 +178,16 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t)
}
}

if (sc)
{
if (!sc.func)
return;
if (sc.intypeof)
return;
if (sc.flags & (SCOPEctfe | SCOPEcompile))
return;
}

scope FullTypeInfoVisitor v = new FullTypeInfoVisitor();
v.sc = sc;
t.accept(v);
Expand Down Expand Up @@ -371,19 +404,24 @@ public:
aggNew = cast(NewDeclaration)search(Loc(), Id.classNew);
aggDelete = cast(DeleteDeclaration)search(Loc(), Id.classDelete);
// this->ctor is already set in finalizeSize()

dtor = buildDtor(this, sc2);
postblit = buildPostBlit(this, sc2);

buildOpAssign(this, sc2);
buildOpEquals(this, sc2);

xeq = buildXopEquals(this, sc2);
xcmp = buildXopCmp(this, sc2);
xhash = buildXtoHash(this, sc2);

/* Even if the struct is merely imported and its semantic3 is not run,
* the TypeInfo object would be speculatively stored in each object
* files. To set correct function pointer, run semantic3 for xeq and xcmp.
*/
//if ((xeq && xeq != xerreq || xcmp && xcmp != xerrcmp) && isImportedSym(this))
// Module::addDeferredSemantic3(this);

/* Defer requesting semantic3 until TypeInfo generation is actually invoked.
* See semanticTypeInfo().
*/
Expand Down
4 changes: 2 additions & 2 deletions src/dtemplate.d
Expand Up @@ -7334,8 +7334,8 @@ public:
}
//printf("%s->appendToModuleMember() enclosing = %s mi = %s\n",
// toPrettyChars(),
// enclosing ? enclosing.toPrettyChars() : NULL,
// mi ? mi.toPrettyChars() : NULL);
// enclosing ? enclosing.toPrettyChars() : null,
// mi ? mi.toPrettyChars() : null);
if (!mi || mi.isRoot())
{
/* If the instantiated module is speculative or root, insert to the
Expand Down
8 changes: 0 additions & 8 deletions src/inline.d
Expand Up @@ -1984,14 +1984,6 @@ void expandInline(FuncDeclaration fd, FuncDeclaration parent, Expression eret,
}
scope ids = new InlineDoState(parent, fd);

// When the function is actually expanded
if (TemplateInstance ti = fd.isInstantiated())
{
// change ti to non-speculative root instance
if (!ti.minst)
ti.minst = ti.tempdecl.getModule().importedFrom;
}

if (asStatements)
as = new Statements();
VarDeclaration vret = null;
Expand Down
10 changes: 6 additions & 4 deletions src/objc.d
Expand Up @@ -153,22 +153,24 @@ extern (C++) void objc_InterfaceDeclaration_semantic_objcExtern(InterfaceDeclara
// MARK: semantic
extern (C++) void objc_FuncDeclaration_semantic_setSelector(FuncDeclaration fd, Scope* sc)
{
import ddmd.tokens;

if (!fd.userAttribDecl)
return;
Expressions* udas = fd.userAttribDecl.getAttributes();
arrayExpressionSemantic(udas, sc, true);
for (size_t i = 0; i < udas.dim; i++)
{
Expression uda = (*udas)[i];
assert(uda.type);
if (uda.type.ty != Ttuple)
assert(uda);
if (uda.op != TOKtuple)
continue;
Expressions* exps = (cast(TupleExp)uda).exps;
for (size_t j = 0; j < exps.dim; j++)
{
Expression e = (*exps)[j];
assert(e.type);
if (e.type.ty != Tstruct)
assert(e);
if (e.op != TOKstructliteral)
continue;
StructLiteralExp literal = cast(StructLiteralExp)e;
assert(literal.sd);
Expand Down
2 changes: 1 addition & 1 deletion src/posix.mak
Expand Up @@ -377,7 +377,7 @@ endif
$(shell test \"$(VERSION)\" != "`cat verstr.h 2> /dev/null`" \
&& printf \"$(VERSION)\" > verstr.h )
$(shell test $(SYSCONFDIR) != "`cat SYSCONFDIR.imp 2> /dev/null`" \
&& echo -n '$(SYSCONFDIR)' > SYSCONFDIR.imp )
&& printf '$(SYSCONFDIR)' > SYSCONFDIR.imp )

#########

Expand Down
19 changes: 13 additions & 6 deletions src/traits.d
Expand Up @@ -1049,14 +1049,23 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
//printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars());
if (sm.ident)
{
if (sm.ident.string[0] == '_' && sm.ident.string[1] == '_' && sm.ident != Id.ctor && sm.ident != Id.dtor && sm.ident != Id.__xdtor && sm.ident != Id.postblit && sm.ident != Id.__xpostblit)
if (sm.ident.string[0] == '_' &&
sm.ident.string[1] == '_' &&
sm.ident != Id.ctor &&
sm.ident != Id.dtor &&
sm.ident != Id.__xdtor &&
sm.ident != Id.postblit &&
sm.ident != Id.__xpostblit)
{
return 0;
}
if (sm.ident == Id.empty)
{
return 0;
}
if (sm.isTypeInfoDeclaration()) // Bugzilla 15177
return 0;

//printf("\t%s\n", sm->ident->toChars());
/* Skip if already present in idents[]
*/
Expand All @@ -1065,11 +1074,9 @@ extern (C++) Expression semanticTraits(TraitsExp e, Scope* sc)
Identifier id = (*idents)[j];
if (id == sm.ident)
return 0;
debug
{
// Avoid using strcmp in the first place due to the performance impact in an O(N^2) loop.
assert(strcmp(id.toChars(), sm.ident.toChars()) != 0);
}

// Avoid using strcmp in the first place due to the performance impact in an O(N^2) loop.
debug assert(strcmp(id.toChars(), sm.ident.toChars()) != 0);
}
idents.push(sm.ident);
}
Expand Down
9 changes: 9 additions & 0 deletions test/compilable/imports/test15117a.d
@@ -0,0 +1,9 @@
module imports.test15117a;

struct AssertResult {}

auto test_usr_1()
{
// 2. generate TyepInfoStructDeclaration
auto x = typeid(AssertResult);
}
23 changes: 23 additions & 0 deletions test/compilable/test15177.d
@@ -0,0 +1,23 @@
// REQUIRED_ARGS: -o-
// PERMUTE_ARGS:
// EXTRA_SOURCES: imports/test15117a.d

import users = imports.test15117a;

void RunApiTest(T...)()
{
foreach (name; __traits(allMembers, users))
{
// 3. list the name of TyepInfoStructDeclaration,
// but it's just internal symbol and invisible.
mixin("alias func = users . " ~ name ~ ";");
}
}

void main()
{
// 1. run semantic3 of users.test_usr_1
users.test_usr_1();

RunApiTest!();
}
7 changes: 7 additions & 0 deletions test/compilable/uda.d
@@ -0,0 +1,7 @@
/************************************************/
// 15180: [REG2.069.0-b1] Segfault with empty struct used as UDA

struct foo { }
@foo bar () { }

/************************************************/
9 changes: 9 additions & 0 deletions test/runnable/ice15176.d
@@ -0,0 +1,9 @@
// EXTRA_SOURCES: imports/ice15176a.d imports/ice15176b.d
// COMPILE_SEPARATELY

import imports.ice15176a;

void main()
{
func();
}
11 changes: 11 additions & 0 deletions test/runnable/ice15200.d
@@ -0,0 +1,11 @@
// EXTRA_SOURCES: imports/ice15200a.d imports/ice15200b.d
// COMPILE_SEPARATELY

module ice15200;

import imports.ice15200a;

void main()
{
f();
}
13 changes: 13 additions & 0 deletions test/runnable/imports/ice15176a.d
@@ -0,0 +1,13 @@
module imports.ice15176a;

import imports.ice15176b;

struct Stack(T)
{
T[] data;
}

void func()
{
alias ValStack = Stack!CodepointSet;
}
8 changes: 8 additions & 0 deletions test/runnable/imports/ice15176b.d
@@ -0,0 +1,8 @@
module imports.ice15176b;

alias CodepointSet = InversionList!();

struct InversionList()
{
uint[] data;
}
12 changes: 12 additions & 0 deletions test/runnable/imports/ice15200a.d
@@ -0,0 +1,12 @@
import imports.ice15200b;

auto f() // not void
{
sub([0], false);
}
void sub(R)(R list, bool b)
{
foreach (i; list.filter!(delegate(e) => b))
{
}
}
41 changes: 41 additions & 0 deletions test/runnable/imports/ice15200b.d
@@ -0,0 +1,41 @@
module imports.ice15200b;

template filter(alias pred)
{
auto filter(R)(R range)
{
return FilterResult!(pred, R)(range);
}
}

struct FilterResult(alias pred, R)
{
R _input;

this(R r)
{
_input = r;
while (_input.length && !pred(_input[0]))
{
_input = _input[1..$];
}
}

@property bool empty()
{
return _input.length == 0;
}

@property auto ref front()
{
return _input[0];
}

void popFront()
{
do
{
_input = _input[1..$];
} while (_input.length && !pred(_input[0]));
}
}
7 changes: 7 additions & 0 deletions test/runnable/imports/link15194b.d
@@ -0,0 +1,7 @@
module imports.link15194b;

auto fun()
{
import imports.link15194std;
return new RedBlackTree!int;
}

0 comments on commit b326f6e

Please sign in to comment.