Bug 3325 – ICE(func.c) function literal with post-contract
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
Windows
Creation time
2009-09-17T07:14:00Z
Last change time
2014-02-15T13:12:34Z
Keywords
ice-on-valid-code, patch
Assigned to
nobody
Creator
k.hanazuki
Comments
Comment #0 by k.hanazuki — 2009-09-17T07:14:19Z
Windows DMD 2.032
Function/delegate literal with post-contract causes the error:
Assertion failure: 'type->nextOf()' on line 927 in file 'func.c'
It compiles and seems working correctly when there is only pre-condition.
----
void main() {
function() body { }; // fine
function() in { } body { }; // fine
function() out { } body { }; // error
function() in { } out { } body { }; // error
delegate() body { }; // fine
delegate() in { } body { }; // fine
delegate() out { } body { }; // error
delegate() in { } out { } body { }; // error
}
Comment #1 by clugdbug — 2009-09-20T12:37:58Z
This ICE is because it needs to know the return type, before it can create the result variable for the post-condition. Creation of the result variable should probably happen in ReturnStatement::semantic, and the semantic for the post-condition run _after_ the function semantic, instead of before.
Comment #2 by clugdbug — 2009-09-23T00:04:31Z
This has also been present on D1, since dinosaurs walked the earth. ICEs on DMD0.175, for example.
Comment #3 by dfj1esp02 — 2009-09-25T05:50:49Z
Hmm... is dmd able to preserve contract info in function pointer type?
Comment #4 by clugdbug — 2009-09-25T05:52:00Z
(In reply to comment #3)
> Hmm... is dmd able to preserve contract info in function pointer type?
No, but this is a function literal, not a function pointer.
Comment #5 by dfj1esp02 — 2009-09-25T05:59:04Z
But literals do not simply exist, they must be used somehow. And contracts should work somehow. It was questioned in bug 302, whether contracts should be called by caller or callee. So this bug can be blocked by 302.
Comment #6 by clugdbug — 2009-09-25T06:39:29Z
(In reply to comment #5)
> But literals do not simply exist, they must be used somehow. And contracts
> should work somehow. It was questioned in bug 302, whether contracts should be
> called by caller or callee. So this bug can be blocked by 302.
No. That would be a general change to how contracts are done, and is nothing to do with this bug. Contracts work perfectly fine on function literals. It's just this case where return type inference is involved where we get a failure in out contacts.
Comment #7 by clugdbug — 2009-09-29T23:52:50Z
(In reply to comment #1)
> This ICE is because it needs to know the return type, before it can create
the result variable for the post-condition. Creation of the result variable
should probably happen in ReturnStatement::semantic, and the semantic for the
> post-condition run _after_ the function semantic, instead of before.
That wouldn't actually work, because there may be more than one return
statement -- the result variable needs to be added at the start of the
function. Maybe it's better for now to simply disallow postconditions on
functions with type inference return statements, turning it from an ICE into an
obscure rejects-valid.
Comment #8 by clugdbug — 2009-09-29T23:52:57Z
Here is a trivial patch to prevent the ICE, and turn it into a rejects-valid.
That's probably enough for now -- the fact that it's taken years for this bug
to be reported shows that it's pretty obscure.
func.c, FuncDeclaration::semantic3(), around line 995.
if (fensure || addPostInvariant())
{ /* fensure is composed of the [out] contracts
*/
ScopeDsymbol *sym = new ScopeDsymbol();
sym->parent = sc2->scopesym;
sc2 = sc2->push(sym);
+ if (!type->nextOf()) {
+ error("Postconditions are not supported if the return type is inferred");
+ return;
+ }
if (type->nextOf() && type->nextOf()->ty == Tvoid)
{
if (outId)
error("void functions have no result");
}