Bug 3366 – Segfault(declaration.c) variadic template with unmatched constraint
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2009-10-05T08:55:00Z
Last change time
2015-06-09T01:26:48Z
Keywords
ice-on-valid-code, patch
Assigned to
nobody
Creator
rayerd.wiz
Comments
Comment #0 by rayerd.wiz — 2009-10-05T08:55:57Z
> type ice.d
class A
{
void f(T...)() if (T.length != 1){}
}
void main()
{
A a = new A;
a.f!int();
}
> dmd main 2> error.txt
// dmd crash
>type error.txt
//ice.d(3): Error: template ice.A.f(T...) if (T.length != 1) declaration T is already defined
Comment #1 by clugdbug — 2009-10-07T00:22:00Z
Reduced test case:
void f(T...)() if (T.length > 20){}
void main(){
f!(int, int)();
}
If the tuple length isn't used in the constraint, there's no ICE, but you get the same silly error message about "T is already defined". It only happens if the function has no parameters, and when there is no match.
It thinks T is already defined, because in the code which is patched below, it's trying to pass an empty tuple for T. But it's already worked out what T must be (in this case (int, int)). So it gets horribly confused.
Root cause: deduceFunctionTemplateMatch() missed this case.
PATCH:
template.c, deduceFunctionTemplateMatch(), line 885.
----------------
/* Check for match of function arguments with variadic template
* parameter, such as:
*
* template Foo(T, A...) { void Foo(T t, A a); }
* void main() { Foo(1,2,3); }
*/
if (tp) // if variadic
{
- if (nfparams == 0) // if no function parameters
+ if (nfparams == 0 && nfargs!=0) // if no function parameters
{
Tuple *t = new Tuple();
//printf("t = %p\n", t);
dedargs->data[parameters->dim - 1] = (void *)t;
declareParameter(paramscope, tp, t);
goto L2;
}