2687 – ICE(statement.c): tuple foreach in an erroneous template.

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 2687 - ICE(statement.c): tuple foreach in an erroneous template.
Summary: ICE(statement.c): tuple foreach in an erroneous template.
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: ice-on-invalid-code, patch
Depends on:
Blocks:
Reported: 2009年02月24日 08:39 UTC by Daniel Keep
Modified: 2014年04月18日 09:12 UTC (History)
2 users (show)

See Also:


Attachments
fnalias.d - main program (796 bytes, text/plain)
2009年02月24日 08:40 UTC, Daniel Keep
Details
fnalias_reflect.d - template madness (1.73 KB, text/plain)
2009年02月24日 08:40 UTC, Daniel Keep
Details
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Daniel Keep 2009年02月24日 08:39:38 UTC
There appears to be a few problems here, so I'll try to summarise as best I can.
I have two modules fnalias and fnalias_reflect. There is a class in fnalias_reflect with a template member "void expose(alias Fn)(in string name)". This member directly instantiates a private template in fnalias_reflect "extern(C) int WrapLuaFunction(alias Fn)()".
Inside the WLF template function, I derive the type of the arguments of the function using std.traits.ParameterTypeTuple, then foreach over an instance of the resulting type tuple and static assert(isValidArgType!(typeof(x))) each member.
Now, this works fine in the case of zero arguments. For a non-zero number of arguments, however, the compiler aborts on the static assert with the following:
 Statement::blockExit(02D82CCC)
 static assert(isValidArgType!(argT));
 Assertion failure: '0' on line 123 in file 'statement.c'
 abnormal program termination
Here's where it gets really weird. If I add this line at the top of the template:
 pragma(msg, "Fn: " ~ Fn.stringof);
Then ParameterTypeTuple derives the argument types as "int" when it should be "(double, double)".
But wait, there's more. If I change the template's signature to this:
 extern(C) int WrapNativeFunction(alias Fn)(lua_State* L)
then the compiler fails on the case of a function with zero arguments, mistakenly deriving the argument types of "void hello()" as being "int". Note that lua_State is undefined.
I will attach these source files, which represent as minimal a test case as I could make. When the two files are compiled together with a stock 2.025 compiler (no command-line arguments other than fnalias.d and fnalias_reflect.d) it aborts at fnalias_reflect.d:51. You should also try compiling after uncommenting fnalias_reflect.d:34 (the pragma variant) and by uncommenting the argument to the template function on line 30.
Comment 1 Daniel Keep 2009年02月24日 08:40:25 UTC
Created attachment 291 [details] 
fnalias.d - main program
Comment 2 Daniel Keep 2009年02月24日 08:40:43 UTC
Created attachment 292 [details] 
fnalias_reflect.d - template madness
Comment 3 Don 2009年05月08日 03:15:07 UTC
Here's a much simpler test case which fails only on DMD1:
--
template Tuple(T...){
 alias T Tuple;
}
void foo()(){
 undefined x;
 foreach( i ; Tuple!(2) ){
 static assert( true);
 }
}
void main(){
 foo!()();
}
--
Statement::blockExit(009F1CD0)
static assert(true);
Assertion failure: '0' on line 136 in file 'statement.c'
abnormal program termination
--
This clearly shows that the problem is with (static) foreach.
I'm not sure that the original bug is actually an ice-on-valid-code. It generates an error on D2.029
Comment 4 Don 2009年05月08日 03:25:30 UTC
None of the other bugs mentioned in the original report still occur in D2.029.
-- it was fixed somewhere before 2.029.
I've uncovered a new bug related to use of tuple.length inside a foreach, but I'll create a new report for it. Changing this to a D1 bug.
Comment 5 Don 2009年08月13日 00:03:01 UTC
Failing because StaticAssertStatement doesn't define blockExit(). It's the only type of statement which doesn't.
/* PATCH: statement.h line 435. Add this member to struct StaticAssertStatement.
 int blockExit() 
 { return BEfallthru;
 // Static assert never generates code, it's always fall through.
 }
Comment 6 Walter Bright 2009年10月13日 13:44:28 UTC
Fixed dmd 1.049 and 2.034


AltStyle によって変換されたページ (->オリジナル) /