3174 – ICE(mtype.c): Compiler crash or compiler error with auto returns and const / immutable / invarient / pure

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 3174 - ICE(mtype.c): Compiler crash or compiler error with auto returns and const / immutable / invarient / pure
Summary: ICE(mtype.c): Compiler crash or compiler error with auto returns and const / ...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86 Windows
: P2 normal
Assignee: No Owner
URL:
Keywords: ice-on-valid-code, patch, rejects-valid
Depends on:
Blocks:
Reported: 2009年07月14日 10:16 UTC by Rob Jacques
Modified: 2015年06月09日 01:28 UTC (History)
2 users (show)

See Also:


Attachments
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 Rob Jacques 2009年07月14日 10:16:54 UTC
DMD either crashes or fails to compile a auto return function marked const/immutable or invarient
class A {
 const foo(int i) { return i; } // DMD crash
 const auto foo(int i) { return i; } // DMD crash
 pure auto foo(int i) { return i; } // Okay
 auto foo(int i) pure { return i; } // Fails to compile
 foo(int i) const { return i; } // Fails to compile
 auto foo(int i) const { return i; } // Fails to compile
}
void main(char[][] args) {
 const A a = new A();
 a.foo(5);
 return;
}
Errors for auto foo(int i) const { return i; } (line 146)
main.d(147): found 'int' when expecting ')'
main.d(147): no identifier for declarator foo
main.d(147): semicolon expected, not 'i'
main.d(147): no identifier for declarator i
main.d(147): semicolon expected, not ')'
main.d(147): Declaration expected, not ')'
main.d(148): unrecognized declaration
 
The issues using const also apply to immutable / invarient.
DMD Crash:
Unhandled exception at 0x00410ba3 in dmd.exe: 0xC0000005: Access violation reading location 0x00000000.
inside mytype.c, at line 3800:
void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag)
{ unsigned char mc;
 //printf("TypeFunction::toDecoBuffer() this = %p %s\n", this, toChars());
 //static int nest; if (++nest == 50) *(char*)0=0;
 if (inuse)
 {	inuse = 2;		// flag error to caller
	return;
 }
 inuse++;
#if 1
 if (mod & MODshared)
	buf->writeByte('O');
 if (mod & MODconst)
	buf->writeByte('x');
 else if (mod & MODinvariant)
	buf->writeByte('y');
#endif
 switch (linkage)
 {
	case LINKd:		mc = 'F';	break;
	case LINKc:		mc = 'U';	break;
	case LINKwindows:	mc = 'W';	break;
	case LINKpascal:	mc = 'V';	break;
	case LINKcpp:		mc = 'R';	break;
	default:
	 assert(0);
 }
 buf->writeByte(mc);
 if (ispure || isnothrow || isref)
 {
	if (ispure)
	 buf->writestring("Na");
	if (isnothrow)
	 buf->writestring("Nb");
	if (isref)
	 buf->writestring("Nc");
 }
 // Write argument types
 Argument::argsToDecoBuffer(buf, parameters);
 //if (buf->data[buf->offset - 1] == '@') halt();
 buf->writeByte('Z' - varargs);	// mark end of arg list
 next->toDecoBuffer(buf);
 
Watch reports 
next is null
this	0x076471c4
TypeFunction::toDecoBuffer::buf	0x0012faa4 
TypeFunction::toDecoBuffer::mc	70 'F'	
TypeFunction::toDecoBuffer::flag	0
Call Stack:
>	dmd.exe!TypeFunction::toDecoBuffer(OutBuffer*,int )() Line 3800 + 0x8 bytes	C++
 	dmd.exe!Type::merge()() Line 1122	C++
 	dmd.exe!FuncDeclaration::semantic(Scope*)() Line 165 + 0x7 bytes	C++
 	dmd.exe!ClassDeclaration::semantic(Scope*)() Line 596	C++
 	dmd.exe!Module::semantic()() Line 675	C++
 	dmd.exe!main() Line 1057	C++
 	dmd.exe!_mainCRTStartup() + 0xa9 bytes	
 	kernel32.dll!7c816fe7()
Comment 1 Don 2009年10月02日 00:08:13 UTC
There are actually 2 independent bugs here. My patch only deals with the ICE. 
I've created bug 3359 for the parsing failure.
CAUSE: It's trying to do type->deco->merge() on a function, when it doesn't yet 
know the return type. merge() is never done on plain auto functions, which is 
why the thrid case doesn't segfault.
COMMENT: mtype.c, TypeFunction::toDecoBuffer() desperately needs an 
assert(next); to generate an ICE instead of a segfault. I have seen at least 
five different
bugs that crash there.
PATCH: I've done this by copy-and-paste, you probably want to reorganize this 
function a bit to avoid duplication. This makes 'const' functions behave the 
same as 'auto'
-- but actually plain 'auto' functions suffer from the other bugs, I think 
because the merge() never happens.
Index: func.c
===================================================================
--- func.c	(revision 75)
+++ func.c	(working copy)
@@ -144,6 +144,13 @@
 	 * to the function type
 	 */
 	type = type->semantic(loc, sc);
+ if (type->ty != Tfunction)
+	{
+		error("%s must be a function", toChars());
+		return;
+	}
+ f = (TypeFunction *)(type);
+
 	unsigned stc = storage_class;
 	if (type->isInvariant())
 	 stc |= STCimmutable;
@@ -159,22 +166,22 @@
 	 case STCimmutable | STCshared:
 		// Don't use toInvariant(), as that will do a merge()
 		type = type->makeInvariant();
-		type->deco = type->merge()->deco;
+		if (f->next) type->deco = type->merge()->deco;
 		break;
 
 	 case STCconst:
 		type = type->makeConst();
-		type->deco = type->merge()->deco;
+		if (f->next) type->deco = type->merge()->deco;
 		break;
 
 	 case STCshared | STCconst:
 		type = type->makeSharedConst();
-		type->deco = type->merge()->deco;
+		if (f->next) type->deco = type->merge()->deco;
 		break;
 
 	 case STCshared:
 		type = type->makeShared();
-		type->deco = type->merge()->deco;
+		if (f->next) type->deco = type->merge()->deco;
 		break;
 
 	 case 0:
Comment 2 Walter Bright 2009年10月13日 13:46:05 UTC
Fixed dmd 1.049 and 2.034


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