Expression.semantic should set the 'type' field when the semantic analysis process succeeds. However ScopeExp.semantic may leave it as 'null'. Look at this snippet.
int foo(T, U...)(U arg) { return 0; }
void main() { auto x = foo!int; } // 'foo!int' is parsed as ScopeExp.
When you compile the code, it will pass a problematic code path.
override Expression semantic(Scope* sc)
{
...
ScopeDsymbol sds2 = sds;
TemplateInstance ti = sds2.isTemplateInstance();
while (ti)
{
...
if (ti.needsTypeInference(sc))
{
if (auto td = ti.tempdecl.isTemplateDeclaration())
{
...
}
else if (auto os = ti.tempdecl.isOverloadSet())
{
...
}
/* here, this.type will leave as 'null' */
return this;
}
...
Comment #1 by k.hara.pg — 2015-11-10T01:28:21Z
This is the cause of issue 15239. The null type field will be referenced in ctfeInterpret function, then a segfault happens.
I don't agree w/ this change, my comment from
https://github.com/D-Programming-Language/dmd/pull/5263/files#r50680394.
+ // ti is an instance which requires IFTI.
+ sds = ti;
+ type = Type.tvoid;
This in particular changed the semantic of typeof(func!arg) from Error: expression (func!arg) has no type to plain void. I think it's incorrect to type a not fully instantiated template function as void (even though there is some precedence w/ templates being of type void).
For non-function templates it's an error when arguments are missing and even with this change typeof(&func!arg) triggers the same error.
On top of this all this change broken is(typeof(T.someAttribute)) detection for types w/ opDispatch.
Also see issue 15550 which was introduced by this change.
Comment #6 by code — 2016-01-26T10:32:37Z
Trying to fix this I arrived at the following conclusion.
https://github.com/D-Programming-Language/dmd/pull/5366#issuecomment-174946328
> It's also a deeper problem, because ScopeExp can't know whether it's used in a
> function call with arguments or in a typeof expression, it's not possible to
> resolve the template instance only within ScopeExp. Subsequently ScopeExp
> should be what it's doc comment says `Mainly just a placeholder`, and do
> nothing (or better `assert(0)`) in it's semantic function.
> Anything involving a ScopeExp must be handled above it (using the template
> instance stored in the ScopeExp).
Comment #7 by k.hara.pg — 2016-02-01T11:56:20Z
(In reply to Martin Nowak from comment #6)
> Trying to fix this I arrived at the following conclusion.
> https://github.com/D-Programming-Language/dmd/pull/5366#issuecomment-
> 174946328
>
> > It's also a deeper problem, because ScopeExp can't know whether it's used in a
> > function call with arguments or in a typeof expression, it's not possible to
> > resolve the template instance only within ScopeExp. Subsequently ScopeExp
> > should be what it's doc comment says `Mainly just a placeholder`, and do
> > nothing (or better `assert(0)`) in it's semantic function.
> > Anything involving a ScopeExp must be handled above it (using the template
> > instance stored in the ScopeExp).
We can easily check that a ScopeExp is a partial instantiation or not.
https://github.com/D-Programming-Language/dmd/pull/5390
Comment #8 by github-bugzilla — 2016-02-01T13:23:41Z