Skip to content

Add type checking to {bitcast,ptrtoint,inttoptr} #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ir/inst_aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,13 @@ type InstInsertValue struct {
// NewInsertValue returns a new insertvalue instruction based on the given
// aggregate value, element and indicies.
func NewInsertValue(x, elem value.Value, indices ...uint64) *InstInsertValue {
elemType := aggregateElemType(x.Type(), indices)
if !elemType.Equal(elem.Type()) {
panic(fmt.Errorf("insertvalue elem type mismatch, expected %v, got %v", elemType, elem.Type()))
}
inst := &InstInsertValue{X: x, Elem: elem, Indices: indices}
// Compute type.
inst.Type()
return inst
}

Expand Down Expand Up @@ -142,6 +147,8 @@ func aggregateElemType(t types.Type, indices []uint64) types.Type {
return aggregateElemType(t.ElemType, indices[1:])
case *types.StructType:
return aggregateElemType(t.Fields[indices[0]], indices[1:])
case *types.PointerType:
return aggregateElemType(t.ElemType, indices[1:])
default:
panic(fmt.Errorf("support for aggregate type %T not yet implemented", t))
}
Expand Down
23 changes: 23 additions & 0 deletions ir/inst_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ type InstTrunc struct {
// NewTrunc returns a new trunc instruction based on the given source value and
// target type.
func NewTrunc(from value.Value, to types.Type) *InstTrunc {
fromSize := from.Type().(*types.IntType).BitSize
toSize := to.(*types.IntType).BitSize
if fromSize < toSize {
panic(fmt.Errorf("invalid trunc: from.BitSize < to.BitSize (%v < %v)", fromSize, toSize))
}
return &InstTrunc{From: from, To: to}
}

Expand Down Expand Up @@ -444,6 +449,12 @@ type InstPtrToInt struct {
// NewPtrToInt returns a new ptrtoint instruction based on the given source
// value and target type.
func NewPtrToInt(from value.Value, to types.Type) *InstPtrToInt {
if _, isFromPointer := from.Type().(*types.PointerType); !isFromPointer {
panic(fmt.Errorf("invalid ptrtoint operand type; expected *types.PointerType, got \"from\": %T", from.Type()))
}
if _, isToInt := to.(*types.IntType); !isToInt {
panic(fmt.Errorf("invalid ptrtoint operand type; expected *types.IntType, got \"to\": %T", to))
}
return &InstPtrToInt{From: from, To: to}
}

Expand Down Expand Up @@ -490,6 +501,12 @@ type InstIntToPtr struct {
// NewIntToPtr returns a new inttoptr instruction based on the given source
// value and target type.
func NewIntToPtr(from value.Value, to types.Type) *InstIntToPtr {
if _, isFromInt := from.Type().(*types.IntType); !isFromInt {
panic(fmt.Errorf("invalid inttoptr operand type; expected *types.IntType, got \"from\": %T", from.Type()))
}
if _, isToPtr := to.(*types.PointerType); !isToPtr {
panic(fmt.Errorf("invalid inttoptr operand type; expected *types.PointerType, got \"to\": %T", to))
}
return &InstIntToPtr{From: from, To: to}
}

Expand Down Expand Up @@ -536,6 +553,12 @@ type InstBitCast struct {
// NewBitCast returns a new bitcast instruction based on the given source value
// and target type.
func NewBitCast(from value.Value, to types.Type) *InstBitCast {
if _, isFromPtr := from.Type().(*types.PointerType); !isFromPtr {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fairly sure you can bitcase, e.g. a 64-bit integer into a 64-bit floating point value.

llvm/test/CodeGen/Hexagon/float-bitcast.ll: %v0 = bitcast double %a0 to i64

panic(fmt.Errorf("invalid bitcast operand type; expected *types.PointerType, got \"from\": %T", from.Type()))
}
if _, isToPtr := to.(*types.PointerType); !isToPtr {
panic(fmt.Errorf("invalid bitcast operand type; expected *types.PointerType, got \"to\": %T", to))
}
return &InstBitCast{From: from, To: to}
}

Expand Down