Two fixes to type cast evaluation (#3186)
* proc: allow casts form unsafe.Pointer to any pointer and vice versa We've allowed doing this with uintptr but we should allow unsafe.Pointer to be used like Go uses it. * proc: fix type casts to ptr-to-ptr types Fix type casts to **type.
This commit is contained in:
parent
c7fa713c34
commit
824e0a81e8
@ -739,9 +739,14 @@ func (scope *EvalScope) evalTypeCastOrFuncCall(node *ast.CallExpr) (*Variable, e
|
||||
return v, err
|
||||
}
|
||||
|
||||
fnnode := removeParen(node.Fun)
|
||||
if n, _ := fnnode.(*ast.StarExpr); n != nil {
|
||||
fnnode = removeParen(n.X)
|
||||
fnnode := node.Fun
|
||||
for {
|
||||
fnnode = removeParen(fnnode)
|
||||
n, _ := fnnode.(*ast.StarExpr)
|
||||
if n == nil {
|
||||
break
|
||||
}
|
||||
fnnode = n.X
|
||||
}
|
||||
|
||||
switch n := fnnode.(type) {
|
||||
@ -811,6 +816,11 @@ func (scope *EvalScope) evalTypeCast(node *ast.CallExpr) (*Variable, error) {
|
||||
|
||||
// compatible underlying types
|
||||
if typeCastCompatibleTypes(argv.RealType, typ) {
|
||||
if ptyp, isptr := typ.(*godwarf.PtrType); argv.Kind == reflect.Ptr && argv.loaded && len(argv.Children) > 0 && isptr {
|
||||
cv := argv.Children[0]
|
||||
argv.Children[0] = *newVariable(cv.Name, cv.Addr, ptyp.Type, cv.bi, cv.mem)
|
||||
argv.Children[0].OnlyAddr = true
|
||||
}
|
||||
argv.RealType = typ
|
||||
argv.DwarfType = styp
|
||||
return argv, nil
|
||||
@ -1028,6 +1038,11 @@ func typeCastCompatibleTypes(typ1, typ2 godwarf.Type) bool {
|
||||
switch ttyp1 := typ1.(type) {
|
||||
case *godwarf.PtrType:
|
||||
if ttyp2, ok := typ2.(*godwarf.PtrType); ok {
|
||||
_, isvoid1 := ttyp1.Type.(*godwarf.VoidType)
|
||||
_, isvoid2 := ttyp2.Type.(*godwarf.VoidType)
|
||||
if isvoid1 || isvoid2 {
|
||||
return true
|
||||
}
|
||||
// pointer types are compatible if their element types are compatible
|
||||
return typeCastCompatibleTypes(resolveTypedef(ttyp1.Type), resolveTypedef(ttyp2.Type))
|
||||
}
|
||||
|
||||
@ -820,6 +820,15 @@ func TestEvalExpression(t *testing.T) {
|
||||
{`(*string)(&typedstringvar)`, false, `(*string)(…`, `(*string)(…`, "*string", nil},
|
||||
{`(*main.astruct)(&namedA1)`, false, `(*main.astruct)(…`, `(*main.astruct)(…`, "*main.astruct", nil},
|
||||
{`(*main.astructName2)(&namedA1)`, false, `(*main.astructName2)(…`, `(*main.astructName2)(…`, "*main.astructName2", nil},
|
||||
|
||||
// Conversions to and from uintptr/unsafe.Pointer
|
||||
{`*(*uint)(uintptr(p1))`, false, `1`, `1`, "uint", nil},
|
||||
{`*(*uint)(uintptr(&i1))`, false, `1`, `1`, "uint", nil},
|
||||
{`*(*uint)(unsafe.Pointer(p1))`, false, `1`, `1`, "uint", nil},
|
||||
{`*(*uint)(unsafe.Pointer(&i1))`, false, `1`, `1`, "uint", nil},
|
||||
|
||||
// Conversions to ptr-to-ptr types
|
||||
{`**(**runtime.hmap)(uintptr(&m1))`, false, `…`, `…`, "runtime.hmap", nil},
|
||||
}
|
||||
|
||||
ver, _ := goversion.Parse(runtime.Version())
|
||||
|
||||
Loading…
Reference in New Issue
Block a user