D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 15309 - [dmd-internal] ScopeExp.semantic() should set its type always
Summary: [dmd-internal] ScopeExp.semantic() should set its type always
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 normal
Assignee: No Owner
URL:
Keywords: pull
Depends on:
Blocks: 15239
  Show dependency treegraph
 
Reported: 2015-11-10 01:25 UTC by Kenji Hara
Modified: 2016-02-01 13:23 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Kenji Hara 2015-11-10 01:25:25 UTC
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 Kenji Hara 2015-11-10 01:28:21 UTC
This is the cause of issue 15239. The null type field will be referenced in ctfeInterpret function, then a segfault happens.
Comment 3 github-bugzilla 2015-11-10 12:29:22 UTC
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/0d7462ac9ddc37acf11b4a94a8863d3c01bb434e
fix Issue 15309 - [dmd-internal] ScopeExp.semantic() should set its type always

Also check `(type !is null)` at the top of `ScopeExp.semantic()` to avoid repeated semantic analysis.
Comment 4 github-bugzilla 2016-01-03 14:02:22 UTC
Commit pushed to stable at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/0d7462ac9ddc37acf11b4a94a8863d3c01bb434e
fix Issue 15309 - [dmd-internal] ScopeExp.semantic() should set its type always
Comment 5 Martin Nowak 2016-01-25 11:09:21 UTC
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 Martin Nowak 2016-01-26 10:32:37 UTC
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 Kenji Hara 2016-02-01 11:56:20 UTC
(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 github-bugzilla 2016-02-01 13:23:41 UTC
Commits pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/779142e844bd0a2d40e8fee3687ae72d733fb536
fix issue 15309 again, add proper fix for issue 15550

Recognize partial instantiation form inside typeof()

https://github.com/D-Programming-Language/dmd/commit/ef5cb0d2c5cd7562d66b51d44e84e2655704dac6
Merge pull request #5390 from 9rnsr/fix15309

Fix issue 15309 again, without breaking the fix for regression 15550