Bug 13478 – [REG2.066] Templates not emitted when also referenced in speculative contexts
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-09-15T15:27:00Z
Last change time
2015-02-18T03:37:03Z
Keywords
pull
Assigned to
k.hara.pg
Creator
code
Comments
Comment #0 by code — 2014-09-15T15:27:10Z
---
module a;
import b;
import c;
int main() {
return foo!int();
}
---
module b;
bool foo(T)() {
// Make sure this is not inlined so a.o actually needs
// to reference it.
asm { nop; }
return false;
}
---
module c;
import b;
// Note that foo is only used in the template constraint here,
// so this never causes foo!int to be emitted.
T barImpl(T)(T t) if (is(typeof({ foo!T(); }))) { return t; }
int bar(int a) { return barImpl(a); }
---
Compile with "dmd -inline a.d".
(If it bothers you, you can also do "dmd -c c.d" first and add c.o to the command line. It shouldn't make a difference and indeed doesn't.)
DMD 2.066 does not emit foo!int to a.o.
Comment #1 by code — 2014-09-15T15:27:34Z
(Pull request incoming.)
Comment #2 by code — 2014-09-15T15:46:39Z
This seems to have been fixed on master, and in a different way than I would have tried. Need Kenji to chime in here.
Comment #3 by code — 2014-09-15T15:59:37Z
Explanation of what happens: During the inline scan semantic, the foo!int TemplateInstance in 'c' overwrites the instantiatingModule of the one in 'a', even though it is speculative. Patch, but seems to not occur any longer on master for a different reason:
diff --git a/src/template.c b/src/template.c
index c230f62..45010ec 100644
--- a/src/template.c
+++ b/src/template.c
@@ -6259,7 +6259,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
#if LOG
printf("\tit's a match with instance %p, %d\n", inst, inst->semanticRun);
#endif
- if (!inst->instantiatingModule || inst->instantiatingModule->isRoot())
+ if (!speculative && (!inst->instantiatingModule || inst->instantiatingModule->isRoot()))
inst->instantiatingModule = mi;
errors = inst->errors;
return;
Comment #4 by dlang-bugzilla — 2014-09-15T16:41:34Z
(In reply to David Nadlinger from comment #3)
> Explanation of what happens: During the inline scan semantic, the foo!int
> TemplateInstance in 'c' overwrites the instantiatingModule of the one in
> 'a', even though it is speculative.
-inline will invoke additional semantic3() phase, and it will modify "instantiation graph" expressed by TemplateInstance::tinst and instantiatingModule.
It's the issue that I tried to fix in https://github.com/D-Programming-Language/dmd/pull/3948.
> Patch, but seems to not occur any longer
> on master for a different reason:
>
> diff --git a/src/template.c b/src/template.c
> index c230f62..45010ec 100644
> --- a/src/template.c
> +++ b/src/template.c
> @@ -6259,7 +6259,7 @@ void TemplateInstance::semantic(Scope *sc, Expressions
> *fargs)
> #if LOG
> printf("\tit's a match with instance %p, %d\n", inst,
> inst->semanticRun);
> #endif
> - if (!inst->instantiatingModule ||
> inst->instantiatingModule->isRoot())
> + if (!speculative && (!inst->instantiatingModule ||
> inst->instantiatingModule->isRoot()))
> inst->instantiatingModule = mi;
> errors = inst->errors;
> return;
Patch looks good. Even if a new instantiation (== 'this') is in non-root module, when it's a speculatively instantiation (this->speculative == true), it should not modify the instantiation graph (== inst->instantiatingModule).
Could you please open a Pull Request for 2.066 branch?