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,17 +461,21 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
}
thenBB := inst.Operand(1)
elseBB := inst.Operand(2)
if !cond.IsConstant() {
if !cond.IsAInstruction().IsNil() {
return nil, nil, errors.New("interp: branch on a non-constant")
} else {
switch cond.ZExtValue() {
case 0: // false
return nil, []llvm.Value{thenBB}, nil // then
case 1: // true
return nil, []llvm.Value{elseBB}, nil // else
default:
panic("branch was not true or false")
}
}
if !cond.IsAConstantExpr().IsNil() {
// 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
case llvm.ConstInt(fr.Mod.Context().Int1Type(), 1, false): // true
return nil, []llvm.Value{elseBB}, nil // else
default:
panic("branch was not true or false")
}
case !inst.IsABranchInst().IsNil() && inst.OperandsCount() == 1:
// unconditional branch (goto)