Skip to content

compiler: do not overwrite initialized global variable by default value #2661

@AnnaShaleva

Description

@AnnaShaleva

Given the following code:

package foo
var A = f()
var B int
func Main() int {
	return B
}
func f() int {
	B = 3
	return B
}

the resulting opcodes generated for it will be:

INDEX    OPCODE       PARAMETER
0        INITSSLOT    2    <<
2        CALL         10 (8/08)
4        STSFLD0      
5        PUSH0        
6        STSFLD1      
7        RET          
8        LDSFLD1      
9        RET          
10       PUSH3        
11       STSFLD1      
12       LDSFLD1      
13       RET         

Global variables initialisation is being performed by this code:

for i := range t.Names {
if len(t.Values) != 0 {
if i == 0 || !multiRet {
ast.Walk(c, t.Values[i])
}
} else {
c.emitDefault(c.typeOf(t.Type))
}
c.emitStoreVar("", t.Names[i].Name)
}
So firstly A is initialized by the call to f() and 3 is stored in the 1-st cell of the static slot as B's value. After that B is initialized by default value and 0 overwrites the previously stored 3. As a result, the program leaves 0 on stack, which is wrong.

We need to initialize global variable by default value only if there's no value stored for it yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    I4No visible changesS4RoutineU3RegularbugSomething isn't workingcompilerGo smart contract compiler

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions