Ambiguous mangling of symbols declared in nested scopes

H. S. Teoh via Digitalmars-d digitalmars-d at puremagic.com
Wed Jul 16 10:22:48 PDT 2014


Today I was investigating this bug:

	https://issues.dlang.org/show_bug.cgi?id=10619

and found that the problem appears to be an ambiguous mangling of local
variables declared in nested scopes. For example, given this code:

	import std.stdio;
	void myFunc(alias Sym)()
	{
		writeln(Sym);
	}
	void main()
	{
		{
			{
				int x = 789;
				myFunc!x();
			}
	
			int x = 456;
			myFunc!x();
		}
	
		int x = 123;
		myFunc!x();
	}

The expected output is:

	789
	456
	123

However, the actual output is:

	789
	789
	789

Checking the compiler output, myFunc is only instantiated once, with the
mangled name:

	_D4test31__T6myFuncS17_D4test4mainFZ1xiZ6myFuncMFZv

This name is ambiguous, since there is no way to distinguish between the
three different instances of 'x' in main(). So it seems that the
compiler conflates them into a single function, even though they should
be 3 distinct ones.

Interestingly enough, moving the nested blocks to after the outer
block's 'x' is declared will trigger a variable shadowing error, but in
the above code, there is actually no shadowing since the inner 'x' is
already out of scope by the time the outer 'x' is declared, so it's
ostensibly legal code.

The question then is, how should we fix this bug? Outlaw the above code?
Or change the mangling scheme to uniquely identify local variables
declared in nested blocks?


P.S. Hmph, looks like we're going to have to go with the second route,
because the following clearly-legal code is broken:

	import std.stdio;
	
	void myFunc(alias Sym)()
	{
		pragma(msg, myFunc.mangleof);
		writeln(Sym);
	}
	
	void main()
	{
		foreach (i; 0..3) {
			myFunc!i();
		}
	
		foreach (i; 5..8) {
			myFunc!i();
		}
	}

Output:

	0
	1
	2
	2
	2
	2

Notice how the second invocation of myFunc appears to reference the
first, out-of-scope, 'i'.  Moreover, 'i' is local to both scopes, so we
*can't* outlaw this usage!

So looks like we'll have to change the mangling scheme of templates with
alias arguments to local variables.


T

-- 
"No, John.  I want formats that are actually useful, rather than
over-featured megaliths that address all questions by piling on
ridiculous internal links in forms which are hideously over-complex." --
Simon St. Laurent on xml-dev


More information about the Digitalmars-d mailing list