interp: make errors during branches more reliable

Previously, there was a suble error in that .IsConstant() is not always
allowed to be called, resulting in a i1 that was not 0 or 1. Fix this by
checking for the constants directly and adding some more diagnostics to
catch more cases.
Этот коммит содержится в:
Ayke van Laethem 2019-05-21 17:40:03 +02:00 коммит произвёл Ron Evans
родитель e4d53daa02
коммит f1d9e7b75e

Просмотреть файл

@ -461,18 +461,22 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
} }
thenBB := inst.Operand(1) thenBB := inst.Operand(1)
elseBB := inst.Operand(2) elseBB := inst.Operand(2)
if !cond.IsConstant() { if !cond.IsAInstruction().IsNil() {
return nil, nil, errors.New("interp: branch on a non-constant") return nil, nil, errors.New("interp: branch on a non-constant")
} else { }
switch cond.ZExtValue() { if !cond.IsAConstantExpr().IsNil() {
case 0: // false // This may happen when the instruction builder could not
// const-fold some instructions.
return nil, nil, errors.New("interp: branch on a non-const-propagated constant expression")
}
switch cond {
case llvm.ConstInt(fr.Mod.Context().Int1Type(), 0, false): // false
return nil, []llvm.Value{thenBB}, nil // then return nil, []llvm.Value{thenBB}, nil // then
case 1: // true case llvm.ConstInt(fr.Mod.Context().Int1Type(), 1, false): // true
return nil, []llvm.Value{elseBB}, nil // else return nil, []llvm.Value{elseBB}, nil // else
default: default:
panic("branch was not true or false") panic("branch was not true or false")
} }
}
case !inst.IsABranchInst().IsNil() && inst.OperandsCount() == 1: case !inst.IsABranchInst().IsNil() && inst.OperandsCount() == 1:
// unconditional branch (goto) // unconditional branch (goto)
return nil, []llvm.Value{inst.Operand(0)}, nil return nil, []llvm.Value{inst.Operand(0)}, nil