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; } ...
This is the cause of issue 15239. The null type field will be referenced in ctfeInterpret function, then a segfault happens.
https://github.com/D-Programming-Language/dmd/pull/5263
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.
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
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.
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).
(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
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