compiler: implement comparing a pointer against nil

Этот коммит содержится в:
Ayke van Laethem 2018-09-05 20:24:12 +02:00
родитель f44d2f718f
коммит ef2c406127
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED

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

@ -2435,6 +2435,24 @@ func (c *Compiler) parseBinOp(frame *Frame, binop *ssa.BinOp) (llvm.Value, error
} else {
return llvm.Value{}, errors.New("todo: unknown basic type in binop: " + typ.String())
}
case *types.Signature:
if c.ir.SignatureNeedsContext(typ) {
// This is a closure, not a function pointer. Get the underlying
// function pointer.
// This is safe: function pointers are generally not comparable
// against each other, only against nil. So one or both has to be
// nil, so we can ignore the contents of the closure.
x = c.builder.CreateExtractValue(x, 1, "")
y = c.builder.CreateExtractValue(y, 1, "")
}
switch binop.Op {
case token.EQL: // ==
return c.builder.CreateICmp(llvm.IntEQ, x, y, ""), nil
case token.NEQ: // !=
return c.builder.CreateICmp(llvm.IntNE, x, y, ""), nil
default:
return llvm.Value{}, errors.New("binop on signature: " + binop.Op.String())
}
case *types.Interface:
switch binop.Op {
case token.EQL, token.NEQ: // ==, !=
@ -2503,6 +2521,15 @@ func (c *Compiler) parseConst(expr *ssa.Const) (llvm.Value, error) {
} else {
return llvm.Value{}, errors.New("todo: unknown constant: " + expr.String())
}
case *types.Signature:
if expr.Value != nil {
return llvm.Value{}, errors.New("non-nil signature constant")
}
sig, err := c.getLLVMType(expr.Type())
if err != nil {
return llvm.Value{}, err
}
return getZeroValue(sig)
case *types.Interface:
if expr.Value != nil {
return llvm.Value{}, errors.New("non-nil interface constant")