Skip to content
Open
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
21 changes: 16 additions & 5 deletions assertion/function/assertiontree/parse_expr_producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,22 @@ func (r *RootAssertionNode) ParseExprAsProducer(expr ast.Expr, doNotTrack bool)
return nil, fldReadProduce()

case *ast.CallExpr:
// we delay this check until we're sure we have to make it, as it could be expensive
if r.Pass().TypesInfo.Types[expr.Fun].IsType() {
if len(expr.Args) == 0 {
return nil, nil
}

if r.Pass().ExprBarsNilness(expr.Fun) {
return nil, nil
}

return r.ParseExprAsProducer(expr.Args[0], false)
}

if prod := hook.AssumeReturn(r.Pass(), expr); prod != nil {
return nil, []producer.ParsedProducer{producer.ShallowParsedProducer{Producer: prod}}
}

litArgs := func() bool {
for _, expr := range expr.Args {
if !r.isStable(expr) {
Expand All @@ -241,10 +256,6 @@ func (r *RootAssertionNode) ParseExprAsProducer(expr ast.Expr, doNotTrack bool)
return true
}

if prod := hook.AssumeReturn(r.Pass(), expr); prod != nil {
return nil, []producer.ParsedProducer{producer.ShallowParsedProducer{Producer: prod}}
}

// the cases of a function and method call are different enough here that it would be useless
// to try to subsume this switch with funcIdentFromCallExpr
switch fun := expr.Fun.(type) {
Expand Down
56 changes: 56 additions & 0 deletions testdata/src/go.uber.org/trustedfunc/type_conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) 2024 Uber Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package trustedfunc

type Struct struct {
Field int
}

type StructPtr *Struct

func typeConversionBasic() {
var explicit *Struct
explicit = (*Struct)(nil)
_ = explicit.Field // want "deref"

explicitShort := (*Struct)(nil)
_ = explicitShort.Field // want "deref"

explicitWithoutParens := StructPtr(nil)
_ = explicitWithoutParens.Field // want "deref"

var implicit *Struct
implicit = nil
_ = implicit.Field // want "deref"
}

func typeConversionWithNonNil() {
var s *Struct = &Struct{Field: 42}
explicit := (*Struct)(s)
_ = explicit.Field

var implicit *Struct
implicit = s
_ = implicit.Field
}

func typeConversionToNonNilable() {
var i int = 42
converted := int(i)
_ = converted // Should not report nil dereference

f := float64(i)
_ = f // Should not report nil dereference
}