Skip to content

local __result variable declared const for non-virtual methods #20967

@ibuclaw

Description

@ibuclaw

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

Change set: http://www.dsource.org/projects/dmd/changeset/259

Current location in code:

dmd/compiler/src/dmd/funcsem.d

Lines 2420 to 2421 in 4661fec

if (!fd.isVirtual())
fd.vresult.storage_class |= STC.const_;

In the linked changeset, the second setting of const looks odd, as it's against the local variable, not the out parameter.

Consider for example:

struct B
{
    ulong n;
    invariant{}
    string str()
    {
        if (n == 0)
            return "0";
        return "1";
    }
}

The above has multiple returns, which ends up as:

string str()
{
	this.__invariant();
	if (this.n == 0LU)
	{
		__result = "0";
		goto __returnLabel;
	}
	__result = "1";
	goto __returnLabel;
	__returnLabel:
	this.__invariant();
	return __result;
}

The __result variable is initialized at more than one location, so it doesn't conform to const (despite the guarantee it is only set once).

As such, you can't do any valid const optimizations on the decl, such as promoting it to rodata, otherwise you end up with wrong result, or segfault at runtime when calling b.str().

This you don't get with const local variables in D user code, as there can only be one initializer.

The suggested fix then, is to remove these two lines in buildResultVar.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions