interp: fix inserting non-const values in a const aggregate

This bug was triggered by the following code:

    package main

    func foo() byte

    var array = [1]byte{foo()}

    func main() {
    }
This commit is contained in:
Ayke van Laethem
2019-11-17 15:03:16 +01:00
committed by Ron Evans
parent 98eee7c22a
commit 4605cbbc6e
4 changed files with 55 additions and 3 deletions
+9 -3
View File
@@ -36,7 +36,7 @@ func (v *LocalValue) Type() llvm.Type {
}
func (v *LocalValue) IsConstant() bool {
if _, ok := v.Eval.dirtyGlobals[v.Underlying]; ok {
if _, ok := v.Eval.dirtyGlobals[unwrap(v.Underlying)]; ok {
return false
}
return v.Underlying.IsConstant()
@@ -75,6 +75,11 @@ func (v *LocalValue) Store(value llvm.Value) {
}
return
}
if !value.IsConstant() {
v.MarkDirty()
v.Eval.builder.CreateStore(value, v.Underlying)
return
}
switch v.Underlying.Opcode() {
case llvm.GetElementPtr:
indices := v.getConstGEPIndices()
@@ -150,13 +155,14 @@ func (v *LocalValue) getConstGEPIndices() []uint32 {
// MarkDirty marks this global as dirty, meaning that every load from and store
// to this global (from now on) must be performed at runtime.
func (v *LocalValue) MarkDirty() {
if v.Underlying.IsAGlobalVariable().IsNil() {
underlying := unwrap(v.Underlying)
if underlying.IsAGlobalVariable().IsNil() {
panic("trying to mark a non-global as dirty")
}
if !v.IsConstant() {
return // already dirty
}
v.Eval.dirtyGlobals[v.Underlying] = struct{}{}
v.Eval.dirtyGlobals[underlying] = struct{}{}
}
// MapValue implements a Go map which is created at compile time and stored as a