annotation

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 24, 2024 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package annotation implements annotation-related structs (site, maps, triggers) and methods. It also implements the annotation analyzer that reads the manually-provided annotations.

Index

Constants

View Source
const ReceiverParamIndex = -1

ReceiverParamIndex is used as the virtual index of the receiver. Since the struct initialization checking for fields of params and fields of receiver uses similar logic, using this virtual index reduces a lot of code repetition.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:       "nilaway_annotation_analyzer",
	Doc:        _doc,
	Run:        analysishelper.WrapRun(run),
	ResultType: reflect.TypeOf((*analysishelper.Result[*ObservedMap])(nil)),
	Requires:   []*analysis.Analyzer{config.Analyzer},
}

Analyzer here is the analyzer than reads annotations and passes them onto the accumulator to be matched against assertions. It returns the map generated from reading the annotations in the source code

View Source
var EmptyVal = Val{
	IsNilable:        false,
	IsDeepNilable:    false,
	IsNilableSet:     false,
	IsDeepNilableSet: false,
}

EmptyVal indicates an annotation value that is fully nonnil but not "set"

Functions

func ConsumeTriggerSlicesEq

func ConsumeTriggerSlicesEq(left, right []*ConsumeTrigger) bool

ConsumeTriggerSlicesEq returns true if the two passed slices of ConsumeTrigger contain the same elements precondition: no duplications

func FullTriggerSlicesEq

func FullTriggerSlicesEq(left, right []FullTrigger) bool

FullTriggerSlicesEq returns true if the two passed slices of FullTriggers contain the same elements. It determines if assertion trees have stabilized during the primary fixpoint loop in `BackpropAcrossFunc` (precondition: no duplications) The equality of two FullTriggers is determined by four parameters: 1) Producer Annotation - this is the first half of the assertion on annotations represented by the trigger 2) Consumer Annotation - this is the second half of the assertion on annotations represented 3) Consumer Expression - this distinguishes triggers that represent the same assertion but should be reported on different lines. If we switch to a purely inference-based approach, this is not necessary - it serves only to report errors on every line that the error repeatedly occurs. 4) Consumer GuardMatched - this is essential because after stabilization, calls to RootAssertionNode.ProcessEntry can use checkGuardOnFullTrigger to rewrite the producer based on its value. So if you accept that the producer is needed for equality, you accept that Consumer.GuardMatched is needed for equality.

func TypeIsDeepDefaultNilable

func TypeIsDeepDefaultNilable(t types.Type) bool

TypeIsDeepDefaultNilable takes an `ast.Expr` that evaluates to a type, and returns true iff we assume default deep nilability for that type - in contrast to the remaining cases, in which we assume default deep non-nil.

func TypeIsDefaultNilable

func TypeIsDefaultNilable(t types.Type) bool

TypeIsDefaultNilable takes a type and returns true iff we assume default nilability for that type - in contrast to the remaining cases, in which we assume default non-nil.

func VarIsGlobal

func VarIsGlobal(v *types.Var) bool

VarIsGlobal returns true iff `v` is a global variable this check is performed by looking up the package of the variable, then the declaring scope of that package, then checking that declaring scope to see if it maps the name of `v` to the passed `*types.Var` instance of `v`

func VarIsParam

func VarIsParam(fdecl *types.Func, v *types.Var) bool

VarIsParam returns true iff `v` is a parameter of `fdecl`

func VarIsRecv

func VarIsRecv(fdecl *types.Func, v *types.Var) bool

VarIsRecv returns true iff `v` is the receiver of `fdecl`

func VarIsVariadicParam

func VarIsVariadicParam(fdecl *types.Func, v *types.Var) bool

VarIsVariadicParam returns true iff `v` is a variadic parameter of `fdecl`

Types

type AffiliationPair

type AffiliationPair struct {
	ImplementingMethod *types.Func
	InterfaceMethod    *types.Func
}

An AffiliationPair is the atomic object of the affiliations mechanism: a pair consisting of an interface method and an implementing method

type ArgFldPass

type ArgFldPass struct {
	*TriggerIfNonNil
	IsPassed bool
}

ArgFldPass is when a struct field value (A.f) flows to a point where it is passed to a function with a param of the same struct type (A)

func (*ArgFldPass) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*ArgFldPass) Prestring

func (f *ArgFldPass) Prestring() Prestring

Prestring returns this ArgFldPass as a Prestring

func (ArgFldPass) String

func (a ArgFldPass) String() string

type ArgFldPassPrestring

type ArgFldPassPrestring struct {
	FieldName     string
	FuncName      string
	ParamNum      int
	RecvName      string
	IsPassed      bool
	AssignmentStr string
}

ArgFldPassPrestring is a Prestring storing the needed information to compactly encode a ArgFldPass

func (ArgFldPassPrestring) String

func (f ArgFldPassPrestring) String() string

type ArgLocAndVal

type ArgLocAndVal struct {
	Location token.Position
	Val      Val
}

ArgLocAndVal pairs the code location of the argument expression and the annotation value.

type ArgPass

type ArgPass struct {
	*TriggerIfNonNil
}

ArgPass is when a value flows to a point where it is passed as an argument to a function. This consumer trigger can be used on top of two different sites: ParamAnnotationKey & CallSiteParamAnnotationKey. ParamAnnotationKey is the parameter site in the function declaration; CallSiteParamAnnotationKey is the argument site in the call expression. CallSiteParamAnnotationKey is specifically used for functions with contracts since we need to duplicate the sites for context sensitivity.

func (*ArgPass) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*ArgPass) Prestring

func (a *ArgPass) Prestring() Prestring

Prestring returns this ArgPass as a Prestring

func (ArgPass) String

func (a ArgPass) String() string

type ArgPassDeep

type ArgPassDeep struct {
	*TriggerIfDeepNonNil
}

ArgPassDeep is when a value deeply flows to a point where it is passed as an argument to a function

func (*ArgPassDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*ArgPassDeep) Prestring

func (a *ArgPassDeep) Prestring() Prestring

Prestring returns this ArgPassDeep as a Prestring

func (ArgPassDeep) String

func (a ArgPassDeep) String() string

type ArgPassDeepPrestring

type ArgPassDeepPrestring struct {
	ParamName string
	FuncName  string
	// Location points to the code location of the argument pass at the call site for a ArgPass
	// enclosing CallSiteParamAnnotationKey; Location is empty for a ArgPass enclosing ParamAnnotationKey.
	Location      string
	AssignmentStr string
}

ArgPassDeepPrestring is a Prestring storing the needed information to compactly encode a ArgPassDeep

func (ArgPassDeepPrestring) String

func (a ArgPassDeepPrestring) String() string

type ArgPassPrestring

type ArgPassPrestring struct {
	ParamName string
	FuncName  string
	// Location points to the code location of the argument pass at the call site for a ArgPass
	// enclosing CallSiteParamAnnotationKey; Location is empty for a ArgPass enclosing ParamAnnotationKey.
	Location      string
	AssignmentStr string
}

ArgPassPrestring is a Prestring storing the needed information to compactly encode a ArgPass

func (ArgPassPrestring) String

func (a ArgPassPrestring) String() string

type ArrayAssign

type ArrayAssign struct {
	*TriggerIfDeepNonNil
}

ArrayAssign is when a value flows to a point where it is assigned into an array

func (*ArrayAssign) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*ArrayAssign) Prestring

func (a *ArrayAssign) Prestring() Prestring

Prestring returns this ArrayAssign as a Prestring

func (ArrayAssign) String

func (a ArrayAssign) String() string

type ArrayAssignPrestring

type ArrayAssignPrestring struct {
	TypeName      string
	AssignmentStr string
}

ArrayAssignPrestring is a Prestring storing the needed information to compactly encode a SliceAssign

func (ArrayAssignPrestring) String

func (a ArrayAssignPrestring) String() string

type ArrayRead

type ArrayRead struct {
	*TriggerIfDeepNilable
}

ArrayRead is when a value is determined to flow from an array index expression

func (*ArrayRead) Prestring

func (a *ArrayRead) Prestring() Prestring

Prestring returns this ArrayRead as a Prestring

type ArrayReadPrestring

type ArrayReadPrestring struct {
	TypeName string
}

ArrayReadPrestring is a Prestring storing the needed information to compactly encode a ArrayRead

func (ArrayReadPrestring) String

func (a ArrayReadPrestring) String() string

type Assignment

type Assignment struct {
	LHSExprStr string
	RHSExprStr string
	Position   token.Position
}

Assignment is a struct that represents an assignment to an expression

func (*Assignment) String

func (a *Assignment) String() string

type BlankVarReturn

type BlankVarReturn struct {
	*ProduceTriggerTautology
}

BlankVarReturn is when a value is determined to flow from a blank variable ('_') to a return of the function

func (*BlankVarReturn) Prestring

func (*BlankVarReturn) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type BlankVarReturnPrestring

type BlankVarReturnPrestring struct{}

BlankVarReturnPrestring is a Prestring storing the needed information to compactly encode a BlankVarReturn

func (BlankVarReturnPrestring) String

type CallSite

type CallSite struct {
	Fun      *types.Func
	Location token.Position
}

CallSite uniquely identifies a function call. It contains the called function object and the code location of the call expression.

type CallSiteParamAnnotationKey

type CallSiteParamAnnotationKey struct {
	FuncDecl *types.Func
	ParamNum int
	Location token.Position
}

CallSiteParamAnnotationKey is similar to ParamAnnotationKey but it represents the site in the caller where the actual argument is passed to the called function. For the same parameter of the same function, there is only one distinct ParamAnnotationKey but there is a new CallSiteParamAnnotationKey for the parameter for every call of the same function.

func NewCallSiteParamKey

func NewCallSiteParamKey(
	fdecl *types.Func, num int, location token.Position) *CallSiteParamAnnotationKey

NewCallSiteParamKey returns a new instance of CallSiteParamAnnotationKey constructed along with validation that its passed argument number is valid for the passed function declaration.

func (*CallSiteParamAnnotationKey) Lookup

func (pk *CallSiteParamAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val.

func (*CallSiteParamAnnotationKey) MinimalString

func (pk *CallSiteParamAnnotationKey) MinimalString() string

MinimalString returns a string representation for this CallSiteParamAnnotationKey consisting only of the word "arg" followed by the name of the parameter, if named, or its position otherwise.

func (*CallSiteParamAnnotationKey) Object

Object returns the types.Object that this annotation can best be interpreted as annotating.

func (*CallSiteParamAnnotationKey) ParamName

func (pk *CallSiteParamAnnotationKey) ParamName() *types.Var

ParamName returns the *types.Var naming the parameter associate with this key. nilable(result 0)

func (*CallSiteParamAnnotationKey) ParamNameString

func (pk *CallSiteParamAnnotationKey) ParamNameString() string

ParamNameString returns the name of this parameter, if named, or a placeholder string otherwise.

func (*CallSiteParamAnnotationKey) String

func (pk *CallSiteParamAnnotationKey) String() string

type CallSiteRetAnnotationKey

type CallSiteRetAnnotationKey struct {
	FuncDecl *types.Func
	RetNum   int // which result
	Location token.Position
}

CallSiteRetAnnotationKey is similar to RetAnnotationKey, but it represents the site in the caller where the actual result is returned from the function. For the same return result of the same function, there is only one distinct RetAnnotationKey but there is a new CallSiteRetAnnotationKey for the return result for every call of the same function.

func NewCallSiteRetKey

func NewCallSiteRetKey(fdecl *types.Func, retNum int, location token.Position) *CallSiteRetAnnotationKey

NewCallSiteRetKey returns a new instance of CallSiteRetAnnotationKey constructed from the name of the parameter.

func (*CallSiteRetAnnotationKey) Lookup

func (rk *CallSiteRetAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val.

func (*CallSiteRetAnnotationKey) Object

func (rk *CallSiteRetAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating.

func (*CallSiteRetAnnotationKey) String

func (rk *CallSiteRetAnnotationKey) String() string

type ChanRecv

type ChanRecv struct {
	*TriggerIfDeepNilable
}

ChanRecv is when a value is determined to flow from a channel receive

func (*ChanRecv) Prestring

func (c *ChanRecv) Prestring() Prestring

Prestring returns this ChanRecv as a Prestring

type ChanRecvPrestring

type ChanRecvPrestring struct {
	TypeName string
}

ChanRecvPrestring is a Prestring storing the needed information to compactly encode a ChanRecv

func (ChanRecvPrestring) String

func (c ChanRecvPrestring) String() string

type ChanSend

type ChanSend struct {
	*TriggerIfDeepNonNil
}

ChanSend is when a value flows to a point where it is sent to a channel

func (*ChanSend) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*ChanSend) Prestring

func (c *ChanSend) Prestring() Prestring

Prestring returns this ChanSend as a Prestring

func (ChanSend) String

func (a ChanSend) String() string

type ChanSendPrestring

type ChanSendPrestring struct {
	TypeName      string
	AssignmentStr string
}

ChanSendPrestring is a Prestring storing the needed information to compactly encode a ChanSend

func (ChanSendPrestring) String

func (c ChanSendPrestring) String() string

type ConstNil

type ConstNil struct {
	*ProduceTriggerTautology
}

ConstNil is when a value is determined to flow from a constant nil expression

func (*ConstNil) Prestring

func (*ConstNil) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type ConstNilPrestring

type ConstNilPrestring struct{}

ConstNilPrestring is a Prestring storing the needed information to compactly encode a ConstNil

func (ConstNilPrestring) String

func (ConstNilPrestring) String() string

type ConsumeTrigger

type ConsumeTrigger struct {
	Annotation   ConsumingAnnotationTrigger
	Expr         ast.Expr
	Guards       util.GuardNonceSet
	GuardMatched bool
}

A ConsumeTrigger represents a point at which a value is consumed that may be required to be non-nil by some Annotation (ConsumingAnnotationTrigger). If Parent is not a RootAssertionNode, then that AssertionNode represents the expression that will flow into this consumption point. If Parent is a RootAssertionNode, then it will be paired with a ProduceTrigger

Expr should be the expression being consumed, not the expression doing the consumption. For example, if the field access x.f requires x to be non-nil, then x should be the expression embedded in the ConsumeTrigger not x.f.

The set Guards indicates whether this consumption takes places in a context in which it is known to be _guarded_ by one or more conditional checks that refine its behavior. This is not _all_ conditional checks this is a very small subset of them. Consume triggers become guarded via backpropagation across a check that `propagateRichChecks` identified with a `RichCheckEffect`. This pass will embed a call to `ConsumeTriggerSliceAsGuarded` that will modify all consume triggers for the value targeted by the check as guarded by the guard nonces of the flowed `RichCheckEffect`.

Like a nil check, guarding is used to indicate information refinement local to one branch. The presence of a guard is overwritten by the absence of a guard on a given ConsumeTrigger - see MergeConsumeTriggerSlices. Beyond RichCheckEffects, Guards consume triggers can be introduced by other sites that are known to obey compatible semantics - such as passing the results of one error-returning function directly to a return of another.

ConsumeTriggers arise at consumption sites that may guarded by a meaningful conditional check, adding that guard as a unique nonce to the set Guards of the trigger. The guard is added when the trigger is propagated across the check, so that when it reaches the statement that relies on the guard, the statement can see that the check was performed around the site of the consumption. This allows the statement to switch to more permissive semantics.

GuardMatched is a boolean used to indicate that this ConsumeTrigger, by the current point in backpropagation, passed through a conditional that granted it a guard, and that that guard was determined to match the guard expected by a statement such as `v, ok := m[k]`. Since there could have been multiple paths in the CFG between the current point in backpropagation and the site at which the trigger arose, GuardMatched is true only if a guard arose and was matched along every path. This allows the trigger to maintain its more permissive semantics in later stages of backpropagation.

For some productions, such as reading an index of a map, there is no way for them to generate nonnil without such a guarding along every path to their point of consumption, so if GuardMatched is not true then they will be replaced (by `checkGuardOnFullTrigger`) with an always-produce-nil producer. More explanation of this mechanism is provided in the documentation for `RootAssertionNode.AddGuardMatch`

nonnil(Guards)

func ConsumeTriggerSliceAsGuarded

func ConsumeTriggerSliceAsGuarded(slice []*ConsumeTrigger, guards ...util.GuardNonce) []*ConsumeTrigger

ConsumeTriggerSliceAsGuarded takes a slice of consume triggers, and returns a new slice identical except that each trigger is guarded

func DuplicateReturnConsumer

func DuplicateReturnConsumer(t *ConsumeTrigger, location token.Position) *ConsumeTrigger

DuplicateReturnConsumer duplicates a given consume trigger, assuming the given consumer trigger is for a UseAsReturn annotation.

func GetEscapeFldConsumer

func GetEscapeFldConsumer(escKey Key, selExpr ast.Expr) *ConsumeTrigger

GetEscapeFldConsumer returns the FldEscape consume trigger with given escKey and selExpr

func GetParamFldConsumer

func GetParamFldConsumer(paramKey Key, expr ast.Expr) *ConsumeTrigger

GetParamFldConsumer returns the ArgFldPass consume trigger with given paramKey and expr

func GetRetFldConsumer

func GetRetFldConsumer(retKey Key, expr ast.Expr) *ConsumeTrigger

GetRetFldConsumer returns the UseAsFldOfReturn consume trigger with given retKey and expr

func MergeConsumeTriggerSlices

func MergeConsumeTriggerSlices(left, right []*ConsumeTrigger) []*ConsumeTrigger

MergeConsumeTriggerSlices merges two slices of `ConsumeTrigger`s its semantics are slightly unexpected only in its treatment of guarding: it intersects guard sets

func (*ConsumeTrigger) Copy

func (c *ConsumeTrigger) Copy() *ConsumeTrigger

Copy returns a deep copy of the ConsumeTrigger

func (*ConsumeTrigger) Pos

func (c *ConsumeTrigger) Pos() token.Pos

Pos returns the source position (e.g., line) of the consumer's expression. In special cases, such as named return, it returns the position of the stored return AST node

type ConsumeTriggerTautology

type ConsumeTriggerTautology struct {
	IsGuardNotNeeded bool // ConsumeTriggers need guards by default, when applicable. Set this to true when guards are not needed.
	// contains filtered or unexported fields
}

ConsumeTriggerTautology is used at consumption sites were consuming nil is always an error

func (*ConsumeTriggerTautology) AddAssignment

func (c *ConsumeTriggerTautology) AddAssignment(e Assignment)

AddAssignment adds an assignment to the trigger.

func (*ConsumeTriggerTautology) CheckConsume

func (*ConsumeTriggerTautology) CheckConsume(Map) bool

CheckConsume returns true

func (*ConsumeTriggerTautology) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*ConsumeTriggerTautology) Kind

Kind returns Always.

func (*ConsumeTriggerTautology) NeedsGuard

func (c *ConsumeTriggerTautology) NeedsGuard() bool

NeedsGuard default implementation for ConsumeTriggerTautology. To return non-default value, this method should be overridden.

func (*ConsumeTriggerTautology) Prestring

func (c *ConsumeTriggerTautology) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (*ConsumeTriggerTautology) SetNeedsGuard

func (c *ConsumeTriggerTautology) SetNeedsGuard(b bool)

SetNeedsGuard sets the underlying Guard-Neediness of this ConsumerTrigger

func (*ConsumeTriggerTautology) String

func (a *ConsumeTriggerTautology) String() string

func (*ConsumeTriggerTautology) UnderlyingSite

func (*ConsumeTriggerTautology) UnderlyingSite() Key

UnderlyingSite always returns nil.

type ConsumeTriggerTautologyPrestring

type ConsumeTriggerTautologyPrestring struct {
	AssignmentStr string
}

ConsumeTriggerTautologyPrestring is a Prestring storing the needed information to compactly encode a ConsumeTriggerTautology

func (ConsumeTriggerTautologyPrestring) String

type ConsumingAnnotationTrigger

type ConsumingAnnotationTrigger interface {
	// CheckConsume can be called to determined whether this trigger should be triggered
	// given a particular Annotation map
	// for example - an `ArgPass` trigger triggers iff the corresponding function arg has
	// nonNil type
	CheckConsume(Map) bool
	Prestring() Prestring

	// Kind returns the kind of the trigger.
	Kind() TriggerKind

	// UnderlyingSite returns the underlying site this trigger's nilability depends on. If the
	// trigger always or never fires, the site is nil.
	UnderlyingSite() Key

	// Copy returns a deep copy of this ConsumingAnnotationTrigger
	Copy() ConsumingAnnotationTrigger

	// AddAssignment adds an assignment to the trigger for tracking and printing informative error message.
	// NilAway's `backpropAcrossOneToOneAssignment()` lifts consumer triggers from the RHS of an assignment to the LHS.
	// This implies loss of information about the assignment. This method is used to track such assignments and print
	// a more informative error message.
	AddAssignment(Assignment)

	// NeedsGuard returns true if the trigger needs to be guarded, for example, by a nil check or an ok form.
	NeedsGuard() bool

	// SetNeedsGuard sets the underlying Guard-Neediness of this ConsumerTrigger, if present.
	// Default setting for ConsumerTriggers is that they need a guard. Override this method to set the need for a guard to false.
	SetNeedsGuard(bool)
	// contains filtered or unexported methods
}

A ConsumingAnnotationTrigger indicated a possible reason that a nil flow to this site would indicate an error

All ConsumingAnnotationTriggers must embed one of the following 3 structs: -TriggerIfNonnil -TriggerIfDeepNonnil -ConsumeTriggerTautology

type DeepAssignPrimitive

type DeepAssignPrimitive struct {
	*ConsumeTriggerTautology
}

DeepAssignPrimitive is when a value flows to a point where it is assigned deeply into an unnannotated object

func (*DeepAssignPrimitive) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*DeepAssignPrimitive) Prestring

func (d *DeepAssignPrimitive) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (DeepAssignPrimitive) String

func (a DeepAssignPrimitive) String() string

type DeepAssignPrimitivePrestring

type DeepAssignPrimitivePrestring struct {
	AssignmentStr string
}

DeepAssignPrimitivePrestring is a Prestring storing the needed information to compactly encode a DeepAssignPrimitive

func (DeepAssignPrimitivePrestring) String

type EscapeFieldAnnotationKey

type EscapeFieldAnnotationKey struct {
	FieldDecl *types.Var
}

EscapeFieldAnnotationKey allows the Lookup of a field's Annotation in the Annotation map For fields of depth 1, with struct initialization check, we track the nilability using param field and return field. Anything that is not trackable using those, rely on the default nilability of the field. Thus, we use the escape information for choosing the nilability of the fields that we do not track. The annotation site is only used when the struct initialization check is enabled. The trigger that uses this key creates constraints on escaping fields. We create constraints only on the fields that have nilable type. There are 2 cases, that we currently consider as escaping: 1. If a struct is returned from the function where the field has nilable value, e.g, If aptr is pointer in struct A, then `return &A{}` causes the field aptr to escape 2. If a struct is parameter of a function and the field is not initialized e.g., if we have fun(&A{}) then the field aptr is considered escaped TODO: Add struct assignment as another possible cause of field escape

func NewEscapeFldAnnKey

func NewEscapeFldAnnKey(fieldObj *types.Var) *EscapeFieldAnnotationKey

NewEscapeFldAnnKey returns a new EscapeFieldAnnotationKey for field fieldObj

func (*EscapeFieldAnnotationKey) Lookup

func (ek *EscapeFieldAnnotationKey) Lookup(_ Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val Currently, the annotation key is used only with inference TODO: This should be updated on supporting no-infer with struct initialization

func (*EscapeFieldAnnotationKey) Object

func (ek *EscapeFieldAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*EscapeFieldAnnotationKey) String

func (ek *EscapeFieldAnnotationKey) String() string

type ExprOkCheck

type ExprOkCheck struct {
	*ProduceTriggerNever
}

ExprOkCheck is used when a value is determined to flow from the second argument of a map or typecast operation that necessarily makes it boolean and thus non-nil

type FieldAnnotationKey

type FieldAnnotationKey struct {
	FieldDecl *types.Var
}

FieldAnnotationKey allows the Lookup of a field's Annotation in the Annotation map

func (*FieldAnnotationKey) Lookup

func (k *FieldAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val

func (*FieldAnnotationKey) Object

func (k *FieldAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*FieldAnnotationKey) String

func (k *FieldAnnotationKey) String() string

type FieldAssignDeep

type FieldAssignDeep struct {
	*TriggerIfDeepNonNil
}

FieldAssignDeep is when a value flows to a point where it is assigned deeply into a field

func (*FieldAssignDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*FieldAssignDeep) Prestring

func (f *FieldAssignDeep) Prestring() Prestring

Prestring returns this FieldAssignDeep as a Prestring

func (FieldAssignDeep) String

func (a FieldAssignDeep) String() string

type FieldAssignDeepPrestring

type FieldAssignDeepPrestring struct {
	FldName       string
	AssignmentStr string
}

FieldAssignDeepPrestring is a Prestring storing the needed information to compactly encode a FieldAssignDeep

func (FieldAssignDeepPrestring) String

func (f FieldAssignDeepPrestring) String() string

type FldAccess

type FldAccess struct {
	*ConsumeTriggerTautology

	Sel types.Object
}

FldAccess is when a value flows to a point where a field of it is accessed, and so it must be non-nil

func (*FldAccess) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*FldAccess) Prestring

func (f *FldAccess) Prestring() Prestring

Prestring returns this FldAccess as a Prestring

func (FldAccess) String

func (a FldAccess) String() string

type FldAccessPrestring

type FldAccessPrestring struct {
	FieldName     string
	MethodName    string
	AssignmentStr string
}

FldAccessPrestring is a Prestring storing the needed information to compactly encode a FldAccess

func (FldAccessPrestring) String

func (f FldAccessPrestring) String() string

type FldAssign

type FldAssign struct {
	*TriggerIfNonNil
}

FldAssign is when a value flows to a point where it is assigned into a field

func (*FldAssign) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*FldAssign) Prestring

func (f *FldAssign) Prestring() Prestring

Prestring returns this FldAssign as a Prestring

func (FldAssign) String

func (a FldAssign) String() string

type FldAssignPrestring

type FldAssignPrestring struct {
	FieldName     string
	AssignmentStr string
}

FldAssignPrestring is a Prestring storing the needed information to compactly encode a FldAssign

func (FldAssignPrestring) String

func (f FldAssignPrestring) String() string

type FldEscape

type FldEscape struct {
	*TriggerIfNonNil
}

FldEscape is when a nilable value flows through a field of a struct that escapes. The consumer is added for the fields at sites of escape. There are 2 cases, that we currently consider as escaping: 1. If a struct is returned from the function where the field has nilable value, e.g, If aptr is pointer in struct A, then `return &A{}` causes the field aptr to escape 2. If a struct is parameter of a function and the field is not initialized e.g., if we have fun(&A{}) then the field aptr is considered escaped TODO: Add struct assignment as another possible cause of field escape

func (*FldEscape) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*FldEscape) Prestring

func (f *FldEscape) Prestring() Prestring

Prestring returns this FldEscape as a Prestring

func (FldEscape) String

func (a FldEscape) String() string

type FldEscapePrestring

type FldEscapePrestring struct {
	FieldName     string
	AssignmentStr string
}

FldEscapePrestring is a Prestring storing the needed information to compactly encode a FldEscape

func (FldEscapePrestring) String

func (f FldEscapePrestring) String() string

type FldRead

type FldRead struct {
	*TriggerIfNilable
}

FldRead is used when a value is determined to flow from a read to a field

func (*FldRead) Prestring

func (f *FldRead) Prestring() Prestring

Prestring returns this FldRead as a Prestring

type FldReadDeep

type FldReadDeep struct {
	*TriggerIfDeepNilable
}

FldReadDeep is used when a value is determined to flow from the deep Annotation of a field that is read and then indexed into - for example x.f[0]

func (*FldReadDeep) Prestring

func (f *FldReadDeep) Prestring() Prestring

Prestring returns this FldReadDeep as a Prestring

type FldReadDeepPrestring

type FldReadDeepPrestring struct {
	FieldName string
}

FldReadDeepPrestring is a Prestring storing the needed information to compactly encode a FldReadDeep

func (FldReadDeepPrestring) String

func (f FldReadDeepPrestring) String() string

type FldReadPrestring

type FldReadPrestring struct {
	FieldName string
}

FldReadPrestring is a Prestring storing the needed information to compactly encode a FldRead

func (FldReadPrestring) String

func (f FldReadPrestring) String() string

type FldReturn

type FldReturn struct {
	*TriggerIfNilable
}

FldReturn is used when a struct field value is determined to flow from a return value of a function

func (*FldReturn) Prestring

func (f *FldReturn) Prestring() Prestring

Prestring returns this FldReturn as a Prestring

func (FldReturn) String

func (f FldReturn) String() string

type FldReturnPrestring

type FldReturnPrestring struct {
	RetNum    int
	FuncName  string
	FieldName string
}

FldReturnPrestring is a Prestring storing the needed information to compactly encode a FldReturn

func (FldReturnPrestring) String

func (f FldReturnPrestring) String() string

type FullTrigger

type FullTrigger struct {
	Producer *ProduceTrigger
	Consumer *ConsumeTrigger
	// Controller is the site that controls if this trigger will be activated or not.
	// If the controller site is assigned to nilable, then this full trigger is activated;
	// otherwise the full trigger is deactivated in the inference engine.
	// If this field is nil, it means the trigger is not a controlled trigger and the trigger will
	// be activated all the time.
	Controller *CallSiteParamAnnotationKey
	// CreatedFromDuplication is true if the full trigger is created from duplicating another full
	// trigger; otherwise false, which is also the default value for any normal full trigger.
	CreatedFromDuplication bool
}

A FullTrigger is a completed assertion. It contains both a ProduceTrigger Producer and a ConsumeTrigger Consumer, representing a path along which a nil value can be produced and consumed respectively. All produce and consume triggers are functions of the read set of annotations, so a FullTrigger represents only a possibility of a nil flow error depending on the set of annotations. A FullTrigger can be compared to an Annotation set to see if such a nil flow error actually arises by the Check method.

func FullTriggerForInterfaceParamFlow

func FullTriggerForInterfaceParamFlow(affiliation AffiliationPair, paramNum int) FullTrigger

FullTriggerForInterfaceParamFlow takes the knowledge that `affiliation` represents an affiliation discovered in the analyzed code - for example, an assignment of a variable of interface type `I` to a value of pointer type `*S` - and returns a FullTrigger representing the assertion that the interface method can have a nilable parameter at position `paramNum` only if the implementing method has such a nilable parameter. This encodes "contravariance" of annotations for parameters. Precondition: paramNum < numParams(affiliation.InterfaceMethod)

func FullTriggerForInterfaceResultFlow

func FullTriggerForInterfaceResultFlow(affiliation AffiliationPair, retNum int) FullTrigger

FullTriggerForInterfaceResultFlow takes the knowledge that `affiliation` represents an affiliation discovered in the analyzed code - for example, an assignment of a variable of interface type `I` to a value of pointer type `*S` - and returns a FullTrigger representing the assertion that the implementing method can have a nilable result at position `retNum` only if the interface method has such a nilable result. This encodes "covariance" of annotations for results. Precondition: retNum < numResults(affiliation.InterfaceMethod)

func MergeFullTriggers

func MergeFullTriggers(left []FullTrigger, right ...FullTrigger) []FullTrigger

MergeFullTriggers creates a union of the passed left and right triggers eliminating duplicates Merging is based on three parameters (out of the four discussed above): 1) Producer Annotation 2) Consumer Annotation 3) Consumer Expression The three parameters are chosen based on the fact that we merge two full triggers that disagree only on Consumer.GuardMatched into a single trigger with Consume.GuardMatched = false. In all other cases - such as checking fixed point in propagation, the function FullTriggersEq that does observe GuardMatched should be used instead of this function.

func (*FullTrigger) Check

func (t *FullTrigger) Check(annMap Map) bool

Check is a boolean test that determines whether this FullTrigger should be triggered against the Annotation map `annMap`

func (*FullTrigger) Controlled

func (t *FullTrigger) Controlled() bool

Controlled returns true if this full trigger is controlled by a controller site; otherwise returns false.

func (*FullTrigger) Pos

func (t *FullTrigger) Pos() token.Pos

Pos returns the position for logging the error specified by the ConsumeTrigger

func (*FullTrigger) Prestrings

func (t *FullTrigger) Prestrings(pass *analysis.Pass) (Prestring, Prestring)

Prestrings returns Prestrings for clauses describing the production and consumption indicated by this FullTrigger, of the forms: "assigned into a field a bar.go:10" or "returned from the function foo at baz.go:25"

If the Producer's expression is an artificial one created by NilAway instead of pulled as an authentic AST node from the source, we elide its location as it will be counter-informative. Unfortunately - many if not most Produce Triggers expression are artificial. More specifically any producers that are matched with consumers that reached entry to a function get matched with artifical expression generated from the position of that consumer in the assertion tree, and producers that arise from non-trackable expressions correspond to those real non-trackable expressions.

type FuncParam

type FuncParam struct {
	*TriggerIfNilable
}

FuncParam is used when a value is determined to flow from a function parameter. This consumer trigger can be used on top of two different sites: ParamAnnotationKey & CallSiteParamAnnotationKey. ParamAnnotationKey is the parameter site in the function declaration; CallSiteParamAnnotationKey is the argument site in the call expression. CallSiteParamAnnotationKey is specifically used for functions with contracts since we need to duplicate the sites for context sensitivity.

func (*FuncParam) Prestring

func (f *FuncParam) Prestring() Prestring

Prestring returns this FuncParam as a Prestring

type FuncParamDeep

type FuncParamDeep struct {
	*TriggerIfDeepNilable
}

FuncParamDeep is used when a value is determined to flow deeply from a function parameter

func (*FuncParamDeep) Prestring

func (f *FuncParamDeep) Prestring() Prestring

Prestring returns this FuncParamDeep as a Prestring

type FuncParamDeepPrestring

type FuncParamDeepPrestring struct {
	ParamName string
}

FuncParamDeepPrestring is a Prestring storing the needed information to compactly encode a FuncParamDeep

func (FuncParamDeepPrestring) String

func (f FuncParamDeepPrestring) String() string

type FuncParamPrestring

type FuncParamPrestring struct {
	ParamName string
	FuncName  string
	// Location is empty for a FuncParam enclosing ParamAnnotationKey. Location points to the
	// location of the argument pass at the call site for a FuncParam enclosing CallSiteParamAnnotationKey.
	Location string
}

FuncParamPrestring is a Prestring storing the needed information to compactly encode a FuncParam

func (FuncParamPrestring) String

func (f FuncParamPrestring) String() string

type FuncRetAssignDeep

type FuncRetAssignDeep struct {
	*TriggerIfDeepNonNil
}

FuncRetAssignDeep is when a value flows to a point where it is assigned deeply into a function return

func (*FuncRetAssignDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*FuncRetAssignDeep) Prestring

func (f *FuncRetAssignDeep) Prestring() Prestring

Prestring returns this FuncRetAssignDeep as a Prestring

func (FuncRetAssignDeep) String

func (a FuncRetAssignDeep) String() string

type FuncRetAssignDeepPrestring

type FuncRetAssignDeepPrestring struct {
	FuncName      string
	RetNum        int
	AssignmentStr string
}

FuncRetAssignDeepPrestring is a Prestring storing the needed information to compactly encode a FuncRetAssignDeep

func (FuncRetAssignDeepPrestring) String

type FuncReturn

type FuncReturn struct {
	*TriggerIfNilable
}

FuncReturn is used when a value is determined to flow from the return of a function. This consumer trigger can be used on top of two different sites: RetAnnotationKey & CallSiteRetAnnotationKey. RetAnnotationKey is the parameter site in the function declaration; CallSiteRetAnnotationKey is the argument site in the call expression. CallSiteRetAnnotationKey is specifically used for functions with contracts since we need to duplicate the sites for context sensitivity.

func (*FuncReturn) Prestring

func (f *FuncReturn) Prestring() Prestring

Prestring returns this FuncReturn as a Prestring

type FuncReturnDeep

type FuncReturnDeep struct {
	*TriggerIfDeepNilable
}

FuncReturnDeep is used when a value is determined to flow from the deep Annotation of the return of a function

func (*FuncReturnDeep) Prestring

func (f *FuncReturnDeep) Prestring() Prestring

Prestring returns this FuncReturnDeep as a Prestring

type FuncReturnDeepPrestring

type FuncReturnDeepPrestring struct {
	RetNum   int
	FuncName string
}

FuncReturnDeepPrestring is a Prestring storing the needed information to compactly encode a FuncReturnDeep

func (FuncReturnDeepPrestring) String

func (f FuncReturnDeepPrestring) String() string

type FuncReturnPrestring

type FuncReturnPrestring struct {
	RetNum   int
	FuncName string
	// Location is empty for a FuncReturn enclosing RetAnnotationKey. Location points to the
	// location of the result return at the call site for a FuncReturn enclosing CallSiteRetAnnotationKey.
	Location string
}

FuncReturnPrestring is a Prestring storing the needed information to compactly encode a FuncReturn

func (FuncReturnPrestring) String

func (f FuncReturnPrestring) String() string

type GlobalVarAnnotationKey

type GlobalVarAnnotationKey struct {
	VarDecl *types.Var
}

GlobalVarAnnotationKey allows the Lookup of a global variable's annotations in the Annotation Map

func (*GlobalVarAnnotationKey) Lookup

func (gk *GlobalVarAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val

func (*GlobalVarAnnotationKey) Object

func (gk *GlobalVarAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*GlobalVarAnnotationKey) String

func (gk *GlobalVarAnnotationKey) String() string

type GlobalVarAssign

type GlobalVarAssign struct {
	*TriggerIfNonNil
}

GlobalVarAssign is when a value flows to a point where it is assigned into a global variable

func (*GlobalVarAssign) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*GlobalVarAssign) Prestring

func (g *GlobalVarAssign) Prestring() Prestring

Prestring returns this GlobalVarAssign as a Prestring

func (GlobalVarAssign) String

func (a GlobalVarAssign) String() string

type GlobalVarAssignDeep

type GlobalVarAssignDeep struct {
	*TriggerIfDeepNonNil
}

GlobalVarAssignDeep is when a value flows to a point where it is assigned deeply into a global variable

func (*GlobalVarAssignDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*GlobalVarAssignDeep) Prestring

func (g *GlobalVarAssignDeep) Prestring() Prestring

Prestring returns this GlobalVarAssignDeep as a Prestring

func (GlobalVarAssignDeep) String

func (a GlobalVarAssignDeep) String() string

type GlobalVarAssignDeepPrestring

type GlobalVarAssignDeepPrestring struct {
	VarName       string
	AssignmentStr string
}

GlobalVarAssignDeepPrestring is a Prestring storing the needed information to compactly encode a GlobalVarAssignDeep

func (GlobalVarAssignDeepPrestring) String

type GlobalVarAssignPrestring

type GlobalVarAssignPrestring struct {
	VarName       string
	AssignmentStr string
}

GlobalVarAssignPrestring is a Prestring storing the needed information to compactly encode a GlobalVarAssign

func (GlobalVarAssignPrestring) String

func (g GlobalVarAssignPrestring) String() string

type GlobalVarRead

type GlobalVarRead struct {
	*TriggerIfNilable
}

GlobalVarRead is when a value is determined to flow from a read to a global variable

func (*GlobalVarRead) Prestring

func (g *GlobalVarRead) Prestring() Prestring

Prestring returns this GlobalVarRead as a Prestring

type GlobalVarReadDeep

type GlobalVarReadDeep struct {
	*TriggerIfDeepNilable
}

GlobalVarReadDeep is when a value is determined to flow from the deep Annotation of a global variable that is read and indexed into

func (*GlobalVarReadDeep) Prestring

func (g *GlobalVarReadDeep) Prestring() Prestring

Prestring returns this GlobalVarReadDeep as a Prestring

type GlobalVarReadDeepPrestring

type GlobalVarReadDeepPrestring struct {
	VarName string
}

GlobalVarReadDeepPrestring is a Prestring storing the needed information to compactly encode a GlobalVarReadDeep

func (GlobalVarReadDeepPrestring) String

type GlobalVarReadPrestring

type GlobalVarReadPrestring struct {
	VarName string
}

GlobalVarReadPrestring is a Prestring storing the needed information to compactly encode a GlobalVarRead

func (GlobalVarReadPrestring) String

func (g GlobalVarReadPrestring) String() string

type GuardMissing

type GuardMissing struct {
	*ProduceTriggerTautology
	OldAnnotation ProducingAnnotationTrigger
}

GuardMissing is when a value is determined to flow from a site that requires a guard, to a site that is not guarded by that guard.

GuardMissing is never created during backpropagation, but on a call to RootAssertionNode.ProcessEntry that checks the guards on ever FullTrigger created, it is substituted for the producer in any FullTrigger whose producer has NeedsGuard = true and whose consumer has GuardMatched = false, guaranteeing that that producer triggers.

For example, from a read to map without the `v, ok := m[k]` form, thus always resulting in nilable regardless of `m`'s deep nilability

func (*GuardMissing) Prestring

func (g *GuardMissing) Prestring() Prestring

Prestring returns this GuardMissing as a Prestring

type GuardMissingPrestring

type GuardMissingPrestring struct {
	OldPrestring Prestring
}

GuardMissingPrestring is a Prestring storing the needed information to compactly encode a GuardMissing

func (GuardMissingPrestring) String

func (g GuardMissingPrestring) String() string

type InterfaceParamReachesImplementation

type InterfaceParamReachesImplementation struct {
	*TriggerIfNilable
	AffiliationPair
}

InterfaceParamReachesImplementation is used when a param of a method is determined to flow into the param of an implementing method

func (*InterfaceParamReachesImplementation) Prestring

Prestring returns this InterfaceParamReachesImplementation as a Prestring

type InterfaceParamReachesImplementationPrestring

type InterfaceParamReachesImplementationPrestring struct {
	ParamName string
	IntName   string
	ImplName  string
}

InterfaceParamReachesImplementationPrestring is a Prestring storing the needed information to compactly encode a InterfaceParamReachesImplementation

func (InterfaceParamReachesImplementationPrestring) String

type InterfaceResultFromImplementation

type InterfaceResultFromImplementation struct {
	*TriggerIfNonNil
	AffiliationPair
}

InterfaceResultFromImplementation is when a result is determined to flow from a concrete method to an interface method via implementation

func (*InterfaceResultFromImplementation) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*InterfaceResultFromImplementation) Prestring

Prestring returns this InterfaceResultFromImplementation as a Prestring

func (InterfaceResultFromImplementation) String

func (a InterfaceResultFromImplementation) String() string

type InterfaceResultFromImplementationPrestring

type InterfaceResultFromImplementationPrestring struct {
	RetNum        int
	IntName       string
	ImplName      string
	AssignmentStr string
}

InterfaceResultFromImplementationPrestring is a Prestring storing the needed information to compactly encode a InterfaceResultFromImplementation

func (InterfaceResultFromImplementationPrestring) String

type Key

type Key interface {
	// Lookup checks whether this key is present in a given Map - returning false as its
	// second result if not present, and true as its second result with the Val found if
	// one is found.
	// To provide optimistic defaults for unannotated files (formally - files on which the annotations
	// checker has not been run), uses of `Lookup` such as `CheckProduce` and `CheckConsume` always
	// return false (i.e. "don't trigger") if the key they wrap is not found in the map.
	// Since not triggering on the level of a produce or consume trigger always results in fewer
	// errors, this gives optimistic defaults to library code.
	Lookup(Map) (Val, bool)

	// Object returns the underlying object that this annotation key can be interpreted as annotating
	Object() types.Object

	// String returns a string representation of this annotation key
	// These get stored into PrimitiveAnnotationKeys - so KEEP THEM COMPACT
	// a good guideline would be the length of their name plus no more than 10 characters
	String() string
	// contains filtered or unexported methods
}

A Key is an object that can be looked up in a Map

type LocalVarAnnotationKey

type LocalVarAnnotationKey struct {
	VarDecl *types.Var
}

LocalVarAnnotationKey allows the Lookup of a local variable's annotations in the Annotation Map

func (*LocalVarAnnotationKey) Lookup

func (lk *LocalVarAnnotationKey) Lookup(_ Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val TODO: Add support for local variables with no inference (Currently, only works with inference)

func (*LocalVarAnnotationKey) Object

func (lk *LocalVarAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*LocalVarAnnotationKey) String

func (lk *LocalVarAnnotationKey) String() string

type LocalVarAssignDeep

type LocalVarAssignDeep struct {
	*TriggerIfDeepNonNil
}

LocalVarAssignDeep is when a value flows to a point where it is assigned deeply into a local variable of deeply nonnil type

func (*LocalVarAssignDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*LocalVarAssignDeep) Prestring

func (l *LocalVarAssignDeep) Prestring() Prestring

Prestring returns this LocalVarAssignDeep as a Prestring

func (LocalVarAssignDeep) String

func (a LocalVarAssignDeep) String() string

type LocalVarAssignDeepPrestring

type LocalVarAssignDeepPrestring struct {
	VarName       string
	AssignmentStr string
}

LocalVarAssignDeepPrestring is a Prestring storing the needed information to compactly encode a LocalVarAssignDeep

func (LocalVarAssignDeepPrestring) String

type LocalVarReadDeep

type LocalVarReadDeep struct {
	*TriggerIfDeepNilable
}

LocalVarReadDeep is when a value is determined to flow deeply from a local variable.

func (LocalVarReadDeep) Prestring

func (v LocalVarReadDeep) Prestring() Prestring

Prestring returns this LocalVarReadDeep as a Prestring

type LocalVarReadDeepPrestring

type LocalVarReadDeepPrestring struct {
	VarName string
}

LocalVarReadDeepPrestring is a Prestring storing the needed information to compactly encode a LocalVarReadDeep

func (LocalVarReadDeepPrestring) String

func (v LocalVarReadDeepPrestring) String() string

type LocatedPrestring

type LocatedPrestring struct {
	Contained Prestring
	Location  token.Position
}

A LocatedPrestring wraps another Prestring with a `token.Position` - for formatting with that position

func (LocatedPrestring) String

func (l LocatedPrestring) String() string

type Map

type Map interface {
	CheckFieldAnn(*types.Var) (Val, bool)
	CheckFuncParamAnn(*types.Func, int) (Val, bool)
	CheckFuncRetAnn(*types.Func, int) (Val, bool)
	CheckFuncRecvAnn(*types.Func) (Val, bool)
	CheckDeepTypeAnn(*types.TypeName) (Val, bool)
	CheckGlobalVarAnn(*types.Var) (Val, bool)
	CheckFuncCallSiteParamAnn(*CallSiteParamAnnotationKey) (Val, bool)
	CheckFuncCallSiteRetAnn(*CallSiteRetAnnotationKey) (Val, bool)
}

Map is an abstraction that concrete annotation maps must implement to be checked against.

type MapAccess

type MapAccess struct {
	*ConsumeTriggerTautology
}

MapAccess is when a map value flows to a point where it is indexed, and thus must be non-nil

note: this trigger is produced only if config.ErrorOnNilableMapRead == true

func (*MapAccess) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*MapAccess) Prestring

func (i *MapAccess) Prestring() Prestring

Prestring returns this MapAccess as a Prestring

func (MapAccess) String

func (a MapAccess) String() string

type MapAccessPrestring

type MapAccessPrestring struct {
	AssignmentStr string
}

MapAccessPrestring is a Prestring storing the needed information to compactly encode a MapAccess

func (MapAccessPrestring) String

func (i MapAccessPrestring) String() string

type MapAssign

type MapAssign struct {
	*TriggerIfDeepNonNil
}

MapAssign is when a value flows to a point where it is assigned into an annotated map

func (*MapAssign) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*MapAssign) Prestring

func (f *MapAssign) Prestring() Prestring

Prestring returns this MapAssign as a Prestring

func (MapAssign) String

func (a MapAssign) String() string

type MapAssignPrestring

type MapAssignPrestring struct {
	TypeName      string
	AssignmentStr string
}

MapAssignPrestring is a Prestring storing the needed information to compactly encode a MapAssign

func (MapAssignPrestring) String

func (f MapAssignPrestring) String() string

type MapRead

type MapRead struct {
	*TriggerIfDeepNilable
}

MapRead is when a value is determined to flow from a map index expression These should always be instantiated with NeedsGuard = true

func (*MapRead) Prestring

func (m *MapRead) Prestring() Prestring

Prestring returns this MapRead as a Prestring

type MapReadPrestring

type MapReadPrestring struct {
	TypeName string
}

MapReadPrestring is a Prestring storing the needed information to compactly encode a MapRead

func (MapReadPrestring) String

func (m MapReadPrestring) String() string

type MapWrittenTo

type MapWrittenTo struct {
	*ConsumeTriggerTautology
}

MapWrittenTo is when a map value flows to a point where one of its indices is written to, and thus must be non-nil

func (*MapWrittenTo) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*MapWrittenTo) Prestring

func (m *MapWrittenTo) Prestring() Prestring

Prestring returns this MapWrittenTo as a Prestring

func (MapWrittenTo) String

func (a MapWrittenTo) String() string

type MapWrittenToPrestring

type MapWrittenToPrestring struct {
	AssignmentStr string
}

MapWrittenToPrestring is a Prestring storing the needed information to compactly encode a MapWrittenTo

func (MapWrittenToPrestring) String

func (m MapWrittenToPrestring) String() string

type MethodParamFromInterface

type MethodParamFromInterface struct {
	*TriggerIfNonNil
	AffiliationPair
}

MethodParamFromInterface is when a param flows from an interface method to a concrete method via implementation

func (*MethodParamFromInterface) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*MethodParamFromInterface) Prestring

func (m *MethodParamFromInterface) Prestring() Prestring

Prestring returns this MethodParamFromInterface as a Prestring

func (MethodParamFromInterface) String

func (a MethodParamFromInterface) String() string

type MethodParamFromInterfacePrestring

type MethodParamFromInterfacePrestring struct {
	ParamName     string
	ImplName      string
	IntName       string
	AssignmentStr string
}

MethodParamFromInterfacePrestring is a Prestring storing the needed information to compactly encode a MethodParamFromInterface

func (MethodParamFromInterfacePrestring) String

type MethodRecv

type MethodRecv struct {
	*TriggerIfNilable
	VarDecl *types.Var
}

MethodRecv is used when a value is determined to flow from a method receiver

func (*MethodRecv) Prestring

func (m *MethodRecv) Prestring() Prestring

Prestring returns this MethodRecv as a Prestring

type MethodRecvDeep

type MethodRecvDeep struct {
	*TriggerIfDeepNilable
	VarDecl *types.Var
}

MethodRecvDeep is used when a value is determined to flow deeply from a method receiver

func (*MethodRecvDeep) Prestring

func (m *MethodRecvDeep) Prestring() Prestring

Prestring returns this MethodRecv as a Prestring

type MethodRecvDeepPrestring

type MethodRecvDeepPrestring struct {
	RecvName string
}

MethodRecvDeepPrestring is a Prestring storing the needed information to compactly encode a MethodRecv

func (MethodRecvDeepPrestring) String

func (m MethodRecvDeepPrestring) String() string

type MethodRecvPrestring

type MethodRecvPrestring struct {
	RecvName string
}

MethodRecvPrestring is a Prestring storing the needed information to compactly encode a MethodRecv

func (MethodRecvPrestring) String

func (m MethodRecvPrestring) String() string

type MethodResultReachesInterface

type MethodResultReachesInterface struct {
	*TriggerIfNilable
	AffiliationPair
}

MethodResultReachesInterface is used when a result of a method is determined to flow into a result of an interface using inheritance

func (*MethodResultReachesInterface) Prestring

func (m *MethodResultReachesInterface) Prestring() Prestring

Prestring returns this MethodResultReachesInterface as a Prestring

type MethodResultReachesInterfacePrestring

type MethodResultReachesInterfacePrestring struct {
	RetNum   int
	ImplName string
	IntName  string
}

MethodResultReachesInterfacePrestring is a Prestring storing the needed information to compactly encode a MethodResultReachesInterface

func (MethodResultReachesInterfacePrestring) String

type MethodReturn

type MethodReturn struct {
	*TriggerIfNilable
}

MethodReturn is used when a value is determined to flow from the return of a method

func (*MethodReturn) Prestring

func (m *MethodReturn) Prestring() Prestring

Prestring returns this MethodReturn as a Prestring

type MethodReturnPrestring

type MethodReturnPrestring struct {
	RetNum   int
	FuncName string
}

MethodReturnPrestring is a Prestring storing the needed information to compactly encode a MethodReturn

func (MethodReturnPrestring) String

func (m MethodReturnPrestring) String() string

type NegativeNilCheck

type NegativeNilCheck struct {
	*ProduceTriggerNever
}

NegativeNilCheck is used when a value is checked in a conditional to NOT BE nil

func (*NegativeNilCheck) Prestring

func (*NegativeNilCheck) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type NegativeNilCheckPrestring

type NegativeNilCheckPrestring struct{}

NegativeNilCheckPrestring is a Prestring storing the needed information to compactly encode a NegativeNilCheck

func (NegativeNilCheckPrestring) String

type NoVarAssign

type NoVarAssign struct {
	*ProduceTriggerTautology
	VarObj *types.Var
}

NoVarAssign is when a value is determined to flow from a variable that wasn't assigned to

func (*NoVarAssign) Prestring

func (n *NoVarAssign) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type NoVarAssignPrestring

type NoVarAssignPrestring struct {
	VarName string
}

NoVarAssignPrestring is a Prestring storing the needed information to compactly encode a NoVarAssign

func (NoVarAssignPrestring) String

func (n NoVarAssignPrestring) String() string

type ObservedMap

type ObservedMap struct {
	// contains filtered or unexported fields
}

A ObservedMap represents a completed set of annotations read from a file or set of files, it can be checked against an assertionTree using RootAssertionNode.ReportErrors

The maps are keyed by *ast.Idents because such an object is unique at each site in the code it is used; canonically, declarations are identified with the identifier used at the site of the declaration

TODO: handle annotations for anonymous functions too

func (*ObservedMap) Range

func (m *ObservedMap) Range(op func(key Key, isDeep bool, val bool), setSitesOnly bool)

Range calls the passed function `op` on each annotation site in this map. If `setSitesOnly` is true, then it only calls `op` only on the sites with is<Deep?>NilableSet true.

type OkReadReflCheck

type OkReadReflCheck struct {
	*ProduceTriggerNever
}

OkReadReflCheck is used to produce nonnil for artifacts of successful `ok` forms (e.g., maps, channels, type casts). For example, a map value `m` that was read from in a `v, ok := m[k]` check followed by a positive check of `ok`, implies `m` is non-nil. This is valid because nil maps contain no keys.

type ParamAnnotationKey

type ParamAnnotationKey struct {
	FuncDecl *types.Func
	ParamNum int
}

ParamAnnotationKey allows the Lookup of a function parameter's Annotation in the Annotation map Only construct these using ParamKeyFromArgNum and ParamKeyFromName

func ParamKeyFromArgNum

func ParamKeyFromArgNum(fdecl *types.Func, num int) *ParamAnnotationKey

ParamKeyFromArgNum returns a new instance of ParamAnnotationKey constructed along with validation that its passed argument number is valid for the passed function declaration

func ParamKeyFromName

func ParamKeyFromName(fdecl *types.Func, paramName *types.Var) *ParamAnnotationKey

ParamKeyFromName returns a new instance of ParamAnnotationKey constructed from the name of the parameter

func (*ParamAnnotationKey) Lookup

func (pk *ParamAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val

func (*ParamAnnotationKey) MinimalString

func (pk *ParamAnnotationKey) MinimalString() string

MinimalString returns a string representation for this ParamAnnotationKey consisting only of the word "arg" followed by the name of the parameter, if named, or its position otherwise

func (*ParamAnnotationKey) Object

func (pk *ParamAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*ParamAnnotationKey) ParamName

func (pk *ParamAnnotationKey) ParamName() *types.Var

ParamName returns the *types.Var naming the parameter associate with this key nilable(result 0)

func (*ParamAnnotationKey) ParamNameString

func (pk *ParamAnnotationKey) ParamNameString() string

ParamNameString returns the name of this parameter, if named, or a placeholder string otherwise

func (*ParamAnnotationKey) String

func (pk *ParamAnnotationKey) String() string

type ParamAssignDeep

type ParamAssignDeep struct {
	*TriggerIfDeepNonNil
}

ParamAssignDeep is when a value flows to a point where it is assigned deeply into a function parameter

func (*ParamAssignDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*ParamAssignDeep) Prestring

func (p *ParamAssignDeep) Prestring() Prestring

Prestring returns this ParamAssignDeep as a Prestring

func (ParamAssignDeep) String

func (a ParamAssignDeep) String() string

type ParamAssignDeepPrestring

type ParamAssignDeepPrestring struct {
	ParamName     string
	AssignmentStr string
}

ParamAssignDeepPrestring is a Prestring storing the needed information to compactly encode a ParamAssignDeep

func (ParamAssignDeepPrestring) String

func (p ParamAssignDeepPrestring) String() string

type ParamFieldAnnotationKey

type ParamFieldAnnotationKey struct {
	// FuncDecl is the function corresponding to the key
	FuncDecl *types.Func
	// ParamNum is the index of the param. It is set to const ReceiverParamIndex -1 if IsReceiver is set to true
	ParamNum int
	// FieldDecl is the declaration of the field
	FieldDecl *types.Var
	// IsTrackingSideEffect is true if the key is used for tracking the param field nilability from callee to caller
	IsTrackingSideEffect bool
}

ParamFieldAnnotationKey allows the Lookup of Annotation of a function parameter's fields in the Annotation map. The key is used for tracking flows through both function params and the receiver. In case, the key is tracking nilability flow through receivers ParamNum is set to ReceiverParamIndex If the key is tracking flow from caller to callee then IsTrackingSideEffect is false. If the key is tracking flow from callee to caller at return of the callee function then IsTrackingSideEffect is true

func NewParamFldAnnKey

func NewParamFldAnnKey(funcObj *types.Func, index int, fieldDecl *types.Var) *ParamFieldAnnotationKey

NewParamFldAnnKey returns ParamFieldAnnotationKey for a field fieldDecl of param at index of the function funcObj

func (*ParamFieldAnnotationKey) IsReceiver

func (pf *ParamFieldAnnotationKey) IsReceiver() bool

IsReceiver returns true if the key is corresponding to a receiver of a method

func (*ParamFieldAnnotationKey) Lookup

func (pf *ParamFieldAnnotationKey) Lookup(_ Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val Currently, the annotation key is used only with inference TODO: This should be updated on supporting no-infer with struct initialization

func (*ParamFieldAnnotationKey) Object

func (pf *ParamFieldAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*ParamFieldAnnotationKey) ParamName

func (pf *ParamFieldAnnotationKey) ParamName() *types.Var

ParamName returns the *types.Var naming the parameter associate with this key nilable(result 0)

func (*ParamFieldAnnotationKey) String

func (pf *ParamFieldAnnotationKey) String() string

String returns a string representation of this annotation key for ParamFieldAnnotationKey

type ParamFldRead

type ParamFldRead struct {
	*TriggerIfNilable
}

ParamFldRead is used when a struct field value is determined to flow from the param of a function to a consumption site within the body of the function

func (*ParamFldRead) Prestring

func (f *ParamFldRead) Prestring() Prestring

Prestring returns this ParamFldRead as a Prestring

type ParamFldReadPrestring

type ParamFldReadPrestring struct {
	FieldName string
}

ParamFldReadPrestring is a Prestring storing the needed information to compactly encode a ParamFldRead

func (ParamFldReadPrestring) String

func (f ParamFldReadPrestring) String() string

type PositiveNilCheck

type PositiveNilCheck struct {
	*ProduceTriggerTautology
}

PositiveNilCheck is used when a value is checked in a conditional to BE nil

func (*PositiveNilCheck) Prestring

func (*PositiveNilCheck) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type PositiveNilCheckPrestring

type PositiveNilCheckPrestring struct{}

PositiveNilCheckPrestring is a Prestring storing the needed information to compactly encode a PositiveNilCheck

func (PositiveNilCheckPrestring) String

type Prestring

type Prestring interface {
	String() string
}

Prestring is an interface used to encode objects that have compact on-the-wire encodings (via gob) but can still be expanded into verbose string representations on demand using type information. These are key for compact encoding of InferredAnnotationMaps

type ProduceTrigger

type ProduceTrigger struct {
	Annotation ProducingAnnotationTrigger
	Expr       ast.Expr
}

A ProduceTrigger represents a point at which a value is produced that may be nilable because of an Annotation (ProducingAnnotationTrigger). Will always be paired with a ConsumeTrigger. For semantics' sake, the Annotation field of a ProduceTrigger is all that matters - the Expr is included only to produce more informative error messages

func DuplicateParamProducer

func DuplicateParamProducer(t *ProduceTrigger, location token.Position) *ProduceTrigger

DuplicateParamProducer duplicates a given produce trigger, assuming the given produce trigger is of FuncParam.

type ProduceTriggerNever

type ProduceTriggerNever struct {
	NeedsGuard bool
}

ProduceTriggerNever is used for trigger producers that will never be nil

func (*ProduceTriggerNever) CheckProduce

func (*ProduceTriggerNever) CheckProduce(Map) bool

CheckProduce returns true false

func (*ProduceTriggerNever) Kind

Kind returns Never.

func (*ProduceTriggerNever) NeedsGuardMatch

func (p *ProduceTriggerNever) NeedsGuardMatch() bool

NeedsGuardMatch returns true if this trigger needs to be matched with a guarded consumer

func (*ProduceTriggerNever) Prestring

func (*ProduceTriggerNever) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (*ProduceTriggerNever) SetNeedsGuard

func (p *ProduceTriggerNever) SetNeedsGuard(b bool)

SetNeedsGuard sets the underlying Guard-Neediness of this ProduceTrigger, if present

func (*ProduceTriggerNever) UnderlyingSite

func (*ProduceTriggerNever) UnderlyingSite() Key

UnderlyingSite always returns nil.

type ProduceTriggerNeverPrestring

type ProduceTriggerNeverPrestring struct{}

ProduceTriggerNeverPrestring is a Prestring storing the needed information to compactly encode a ProduceTriggerNever

func (ProduceTriggerNeverPrestring) String

type ProduceTriggerTautology

type ProduceTriggerTautology struct {
	NeedsGuard bool
}

ProduceTriggerTautology is used for trigger producers that will always result in nil

func (*ProduceTriggerTautology) CheckProduce

func (*ProduceTriggerTautology) CheckProduce(Map) bool

CheckProduce returns true

func (*ProduceTriggerTautology) Kind

Kind returns Always.

func (*ProduceTriggerTautology) NeedsGuardMatch

func (p *ProduceTriggerTautology) NeedsGuardMatch() bool

NeedsGuardMatch returns true if this trigger needs to be matched with a guarded consumer

func (*ProduceTriggerTautology) Prestring

func (*ProduceTriggerTautology) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (*ProduceTriggerTautology) SetNeedsGuard

func (p *ProduceTriggerTautology) SetNeedsGuard(b bool)

SetNeedsGuard sets the underlying Guard-Neediness of this ProduceTrigger, if present

func (*ProduceTriggerTautology) UnderlyingSite

func (*ProduceTriggerTautology) UnderlyingSite() Key

UnderlyingSite always returns nil.

type ProduceTriggerTautologyPrestring

type ProduceTriggerTautologyPrestring struct{}

ProduceTriggerTautologyPrestring is a Prestring storing the needed information to compactly encode a ProduceTriggerTautology

func (ProduceTriggerTautologyPrestring) String

type ProducingAnnotationTrigger

type ProducingAnnotationTrigger interface {
	// CheckProduce can be called to determined whether this trigger should be triggered
	// given a particular Annotation map
	// for example - a `FuncReturn` trigger triggers iff the corresponding function has
	// nilable return type
	CheckProduce(Map) bool

	// NeedsGuardMatch returns whether this production is contingent on being
	// paired with a guarded consumer.
	// In other words, this production is only given the freedom to produce
	// a non-nil value in the case that it is matched with a guarded consumer.
	// otherwise, it is replaced with annotation.GuardMissing
	NeedsGuardMatch() bool

	// SetNeedsGuard sets the underlying Guard-Neediness of this ProduceTrigger, if present
	// This should be very sparingly used, and only with utter conviction of correctness.
	// Default setting for ProduceTriggers is to not need a guard.
	SetNeedsGuard(bool)

	Prestring() Prestring

	// Kind returns the kind of the trigger.
	Kind() TriggerKind

	// UnderlyingSite returns the underlying site this trigger's nilability depends on. If the
	// trigger always or never fires, the site is nil.
	UnderlyingSite() Key
	// contains filtered or unexported methods
}

A ProducingAnnotationTrigger is a possible reason that a nil value might be produced

All ProducingAnnotationTriggers must embed one of the following 4 structs: -TriggerIfNilable -TriggerIfDeepNilable -ProduceTriggerTautology -ProduceTriggerNever

This is because there are interfaces, such as AdmitsPrimitive, that are implemented only for those structs, and to which a ProducingAnnotationTrigger must be able to be case

func DeepNilabilityAsNamedType

func DeepNilabilityAsNamedType(typ types.Type) ProducingAnnotationTrigger

DeepNilabilityAsNamedType tries to interpret the named type as a typedef of a map or slice, returning the deep nilability annotation of that typedef if found. Otherwise, it returns ProduceTriggerNever to indicate that we assume in the default case the type is NOT deeply nilable

func DeepNilabilityOfFld

func DeepNilabilityOfFld(fld *types.Var) ProducingAnnotationTrigger

DeepNilabilityOfFld inspects a struct field for deep nilability annotation

func DeepNilabilityOfFuncRet

func DeepNilabilityOfFuncRet(fn *types.Func, retNum int) ProducingAnnotationTrigger

DeepNilabilityOfFuncRet inspects a function return for deep nilability annotation

func DeepNilabilityOfVar

func DeepNilabilityOfVar(fdecl *types.Func, v *types.Var) ProducingAnnotationTrigger

DeepNilabilityOfVar inspects a variable for deep nilability annotation

func ParamAsProducer

func ParamAsProducer(fdecl *types.Func, param *types.Var) ProducingAnnotationTrigger

ParamAsProducer inspects a variable, which must be a parameter to the passed function, and returns a produce trigger for its value as annotated at its function's declaration. The interesting case is when the parameter is variadic - and then the annotation is interpreted as referring to the elements of the variadic slice not the slice itself

type PtrAssign

type PtrAssign struct {
	*TriggerIfDeepNonNil
}

PtrAssign is when a value flows to a point where it is assigned into a pointer

func (*PtrAssign) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*PtrAssign) Prestring

func (f *PtrAssign) Prestring() Prestring

Prestring returns this PtrAssign as a Prestring

func (PtrAssign) String

func (a PtrAssign) String() string

type PtrAssignPrestring

type PtrAssignPrestring struct {
	TypeName      string
	AssignmentStr string
}

PtrAssignPrestring is a Prestring storing the needed information to compactly encode a PtrAssign

func (PtrAssignPrestring) String

func (f PtrAssignPrestring) String() string

type PtrLoad

type PtrLoad struct {
	*ConsumeTriggerTautology
}

PtrLoad is when a value flows to a point where it is loaded as a pointer

func (*PtrLoad) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*PtrLoad) Prestring

func (p *PtrLoad) Prestring() Prestring

Prestring returns this PtrLoad as a Prestring

func (PtrLoad) String

func (a PtrLoad) String() string

type PtrLoadPrestring

type PtrLoadPrestring struct {
	AssignmentStr string
}

PtrLoadPrestring is a Prestring storing the needed information to compactly encode a PtrLoad

func (PtrLoadPrestring) String

func (p PtrLoadPrestring) String() string

type PtrRead

type PtrRead struct {
	*TriggerIfDeepNilable
}

PtrRead is when a value is determined to flow from a read to a pointer

func (*PtrRead) Prestring

func (p *PtrRead) Prestring() Prestring

Prestring returns this PtrRead as a Prestring

type PtrReadPrestring

type PtrReadPrestring struct {
	TypeName string
}

PtrReadPrestring is a Prestring storing the needed information to compactly encode a PtrRead

func (PtrReadPrestring) String

func (p PtrReadPrestring) String() string

type RangeIndexAssignment

type RangeIndexAssignment struct {
	*ProduceTriggerNever
}

RangeIndexAssignment is used when a value is determined to flow from the first argument of a range loop, and thus be an integer and non-nil

type RangeOver

type RangeOver struct {
	*ProduceTriggerNever
}

RangeOver is used when a value is ranged over - and thus nonnil in its range body

type RecvAnnotationKey

type RecvAnnotationKey struct {
	FuncDecl *types.Func
}

RecvAnnotationKey allows the Lookup of a method's receiver Annotation in the Annotation map

func (*RecvAnnotationKey) Exported

func (rk *RecvAnnotationKey) Exported() bool

Exported returns true iff this annotation is observable by downstream packages

func (*RecvAnnotationKey) Lookup

func (rk *RecvAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val

func (*RecvAnnotationKey) Object

func (rk *RecvAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*RecvAnnotationKey) Package

func (rk *RecvAnnotationKey) Package() *types.Package

Package returns the package containing the site of this annotation key

func (*RecvAnnotationKey) String

func (rk *RecvAnnotationKey) String() string

type RecvPass

type RecvPass struct {
	*TriggerIfNonNil
}

RecvPass is when a receiver value flows to a point where it is used to invoke a method. E.g., `s.foo()`, here `s` is a receiver and forms the RecvPass Consumer

func (*RecvPass) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*RecvPass) Prestring

func (a *RecvPass) Prestring() Prestring

Prestring returns this RecvPass as a Prestring

func (RecvPass) String

func (a RecvPass) String() string

type RecvPassPrestring

type RecvPassPrestring struct {
	FuncName      string
	AssignmentStr string
}

RecvPassPrestring is a Prestring storing the needed information to compactly encode a RecvPass

func (RecvPassPrestring) String

func (a RecvPassPrestring) String() string

type RetAnnotationKey

type RetAnnotationKey struct {
	FuncDecl *types.Func
	RetNum   int // which result
}

RetAnnotationKey allows the Lookup of a function's return Annotation in the Annotation Map

func RetKeyFromRetNum

func RetKeyFromRetNum(fdecl *types.Func, retNum int) *RetAnnotationKey

RetKeyFromRetNum returns a new instance of RetAnnotationKey constructed from the name of the parameter

func (*RetAnnotationKey) Lookup

func (rk *RetAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val

func (*RetAnnotationKey) Object

func (rk *RetAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*RetAnnotationKey) String

func (rk *RetAnnotationKey) String() string

type RetFieldAnnotationKey

type RetFieldAnnotationKey struct {
	// FuncDecl is the function type of function containing return
	FuncDecl *types.Func
	// RetNum is the index of the return for the key
	RetNum int
	// FieldDecl is the declaration for the field of the key
	FieldDecl *types.Var
}

RetFieldAnnotationKey allows the Lookup of the Annotation on a specific field within a function's return of struct (or pointer to struct) type, in the Annotation Map. This key is only effective when the struct initialization checking is enabled.

TODO: Add support for field of function return with no inference (Currently, only works with inference)

func NewRetFldAnnKey

func NewRetFldAnnKey(funcDecl *types.Func, retNum int, fieldDecl *types.Var) *RetFieldAnnotationKey

NewRetFldAnnKey returns the RetFieldAnnotationKey for return at retNum and the field fieldDecl. This function is called from multiple places where funcDecl could be the declaration of the function being analyzed (when looking at a return statement) or a function called from the function being analyzed (when looking at a function call statement, in which case funcDecl is the callee).

func (*RetFieldAnnotationKey) Lookup

func (rf *RetFieldAnnotationKey) Lookup(_ Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val.

func (*RetFieldAnnotationKey) Object

func (rf *RetFieldAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*RetFieldAnnotationKey) String

func (rf *RetFieldAnnotationKey) String() string

String returns a string representation of this annotation key

type SliceAccess

type SliceAccess struct {
	*ConsumeTriggerTautology
}

SliceAccess is when a slice value flows to a point where it is sliced, and thus must be non-nil

func (*SliceAccess) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*SliceAccess) Prestring

func (s *SliceAccess) Prestring() Prestring

Prestring returns this SliceAccess as a Prestring

func (SliceAccess) String

func (a SliceAccess) String() string

type SliceAccessPrestring

type SliceAccessPrestring struct {
	AssignmentStr string
}

SliceAccessPrestring is a Prestring storing the needed information to compactly encode a SliceAccess

func (SliceAccessPrestring) String

func (s SliceAccessPrestring) String() string

type SliceAssign

type SliceAssign struct {
	*TriggerIfDeepNonNil
}

SliceAssign is when a value flows to a point where it is assigned into a slice

func (*SliceAssign) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*SliceAssign) Prestring

func (f *SliceAssign) Prestring() Prestring

Prestring returns this SliceAssign as a Prestring

func (SliceAssign) String

func (a SliceAssign) String() string

type SliceAssignPrestring

type SliceAssignPrestring struct {
	TypeName      string
	AssignmentStr string
}

SliceAssignPrestring is a Prestring storing the needed information to compactly encode a SliceAssign

func (SliceAssignPrestring) String

func (f SliceAssignPrestring) String() string

type SliceRead

type SliceRead struct {
	*TriggerIfDeepNilable
}

SliceRead is when a value is determined to flow from a slice index expression

func (*SliceRead) Prestring

func (s *SliceRead) Prestring() Prestring

Prestring returns this SliceRead as a Prestring

type SliceReadPrestring

type SliceReadPrestring struct {
	TypeName string
}

SliceReadPrestring is a Prestring storing the needed information to compactly encode a SliceRead

func (SliceReadPrestring) String

func (s SliceReadPrestring) String() string

type TriggerIfDeepNilable

type TriggerIfDeepNilable struct {
	Ann        Key
	NeedsGuard bool
}

TriggerIfDeepNilable is a general trigger indicating the the bad case occurs when a certain Annotation key is deeply nilable

func (*TriggerIfDeepNilable) CheckProduce

func (t *TriggerIfDeepNilable) CheckProduce(annMap Map) bool

CheckProduce returns true if the underlying annotation is present in the passed map and deeply nilable

func (*TriggerIfDeepNilable) Kind

Kind returns DeepConditional.

func (*TriggerIfDeepNilable) NeedsGuardMatch

func (t *TriggerIfDeepNilable) NeedsGuardMatch() bool

NeedsGuardMatch returns true if this trigger needs to be matched with a guarded consumer

func (*TriggerIfDeepNilable) Prestring

func (*TriggerIfDeepNilable) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (*TriggerIfDeepNilable) SetNeedsGuard

func (t *TriggerIfDeepNilable) SetNeedsGuard(b bool)

SetNeedsGuard sets the underlying Guard-Neediness of this ProduceTrigger, if present

func (*TriggerIfDeepNilable) UnderlyingSite

func (t *TriggerIfDeepNilable) UnderlyingSite() Key

UnderlyingSite returns the underlying site this trigger's nilability depends on.

type TriggerIfDeepNilablePrestring

type TriggerIfDeepNilablePrestring struct{}

TriggerIfDeepNilablePrestring is a Prestring storing the needed information to compactly encode a TriggerIfDeepNilable

func (TriggerIfDeepNilablePrestring) String

type TriggerIfDeepNonNil

type TriggerIfDeepNonNil struct {
	Ann              Key
	IsGuardNotNeeded bool // ConsumeTriggers need guards by default, when applicable. Set this to true when guards are not needed.
	// contains filtered or unexported fields
}

TriggerIfDeepNonNil is triggered if the contained Annotation is deeply non-nil

func (*TriggerIfDeepNonNil) AddAssignment

func (t *TriggerIfDeepNonNil) AddAssignment(e Assignment)

AddAssignment adds an assignment to the trigger.

func (*TriggerIfDeepNonNil) CheckConsume

func (t *TriggerIfDeepNonNil) CheckConsume(annMap Map) bool

CheckConsume returns true if the underlying annotation is present in the passed map and deeply nonnil

func (*TriggerIfDeepNonNil) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*TriggerIfDeepNonNil) Kind

Kind returns DeepConditional.

func (*TriggerIfDeepNonNil) NeedsGuard

func (t *TriggerIfDeepNonNil) NeedsGuard() bool

NeedsGuard default implementation for TriggerIfDeepNonNil. To return non-default value, this method should be overridden.

func (*TriggerIfDeepNonNil) Prestring

func (t *TriggerIfDeepNonNil) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (*TriggerIfDeepNonNil) SetNeedsGuard

func (t *TriggerIfDeepNonNil) SetNeedsGuard(b bool)

SetNeedsGuard sets the underlying Guard-Neediness of this ConsumerTrigger

func (*TriggerIfDeepNonNil) String

func (a *TriggerIfDeepNonNil) String() string

func (*TriggerIfDeepNonNil) UnderlyingSite

func (t *TriggerIfDeepNonNil) UnderlyingSite() Key

UnderlyingSite the underlying site this trigger's nilability depends on.

type TriggerIfDeepNonNilPrestring

type TriggerIfDeepNonNilPrestring struct {
	AssignmentStr string
}

TriggerIfDeepNonNilPrestring is a Prestring storing the needed information to compactly encode a TriggerIfDeepNonNil

func (TriggerIfDeepNonNilPrestring) String

type TriggerIfNilable

type TriggerIfNilable struct {
	Ann        Key
	NeedsGuard bool
}

TriggerIfNilable is a general trigger indicating that the bad case occurs when a certain Annotation key is nilable

func (*TriggerIfNilable) CheckProduce

func (t *TriggerIfNilable) CheckProduce(annMap Map) bool

CheckProduce returns true if the underlying annotation is present in the passed map and nilable

func (*TriggerIfNilable) Kind

func (t *TriggerIfNilable) Kind() TriggerKind

Kind returns Conditional.

func (*TriggerIfNilable) NeedsGuardMatch

func (t *TriggerIfNilable) NeedsGuardMatch() bool

NeedsGuardMatch returns true if this trigger needs to be matched with a guarded consumer

func (*TriggerIfNilable) Prestring

func (*TriggerIfNilable) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (*TriggerIfNilable) SetNeedsGuard

func (t *TriggerIfNilable) SetNeedsGuard(b bool)

SetNeedsGuard sets the underlying Guard-Neediness of this ProduceTrigger, if present

func (*TriggerIfNilable) UnderlyingSite

func (t *TriggerIfNilable) UnderlyingSite() Key

UnderlyingSite returns the underlying site this trigger's nilability depends on.

type TriggerIfNilablePrestring

type TriggerIfNilablePrestring struct{}

TriggerIfNilablePrestring is a Prestring storing the needed information to compactly encode a TriggerIfNilable

func (TriggerIfNilablePrestring) String

type TriggerIfNonNil

type TriggerIfNonNil struct {
	Ann              Key
	IsGuardNotNeeded bool // ConsumeTriggers need guards by default, when applicable. Set this to true when guards are not needed.
	// contains filtered or unexported fields
}

TriggerIfNonNil is triggered if the contained Annotation is non-nil

func (*TriggerIfNonNil) AddAssignment

func (t *TriggerIfNonNil) AddAssignment(e Assignment)

AddAssignment adds an assignment to the trigger.

func (*TriggerIfNonNil) CheckConsume

func (t *TriggerIfNonNil) CheckConsume(annMap Map) bool

CheckConsume returns true if the underlying annotation is present in the passed map and nonnil

func (*TriggerIfNonNil) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*TriggerIfNonNil) Kind

func (*TriggerIfNonNil) Kind() TriggerKind

Kind returns Conditional.

func (*TriggerIfNonNil) NeedsGuard

func (t *TriggerIfNonNil) NeedsGuard() bool

NeedsGuard is the default implementation for TriggerIfNonNil. To return non-default value, this method should be overridden.

func (*TriggerIfNonNil) Prestring

func (t *TriggerIfNonNil) Prestring() Prestring

Prestring returns this Prestring as a Prestring

func (*TriggerIfNonNil) SetNeedsGuard

func (t *TriggerIfNonNil) SetNeedsGuard(b bool)

SetNeedsGuard sets the underlying Guard-Neediness of this ConsumerTrigger

func (*TriggerIfNonNil) String

func (a *TriggerIfNonNil) String() string

func (*TriggerIfNonNil) UnderlyingSite

func (t *TriggerIfNonNil) UnderlyingSite() Key

UnderlyingSite the underlying site this trigger's nilability depends on.

type TriggerIfNonNilPrestring

type TriggerIfNonNilPrestring struct {
	AssignmentStr string
}

TriggerIfNonNilPrestring is a Prestring storing the needed information to compactly encode a TriggerIfNonNil

func (TriggerIfNonNilPrestring) String

func (t TriggerIfNonNilPrestring) String() string

type TriggerKind

type TriggerKind uint8

TriggerKind indicates the kind of the producer / consume trigger, e.g., a trigger will always fire, or a trigger will only fire if the underlying site is nilable etc.

const (
	// Always indicates a trigger will always fire.
	Always TriggerKind = iota + 1
	// Conditional indicates a trigger will only fire depending on the nilability of the
	// underlying site.
	Conditional
	// DeepConditional indicates a trigger will only fire depending on the deep nilability of the
	// underlying site.
	DeepConditional
	// Never indicates a trigger will never fire.
	Never
)

type TrustedFuncNilable

type TrustedFuncNilable struct {
	*ProduceTriggerTautology
}

TrustedFuncNilable is used when a value is determined to be nilable by a trusted function call

func (*TrustedFuncNilable) Prestring

func (*TrustedFuncNilable) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type TrustedFuncNilablePrestring

type TrustedFuncNilablePrestring struct{}

TrustedFuncNilablePrestring is a Prestring storing the needed information to compactly encode a TrustedFuncNilable

func (TrustedFuncNilablePrestring) String

type TrustedFuncNonnil

type TrustedFuncNonnil struct {
	*ProduceTriggerNever
}

TrustedFuncNonnil is used when a value is determined to be nonnil by a trusted function call

func (*TrustedFuncNonnil) Prestring

func (*TrustedFuncNonnil) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type TrustedFuncNonnilPrestring

type TrustedFuncNonnilPrestring struct{}

TrustedFuncNonnilPrestring is a Prestring storing the needed information to compactly encode a TrustedFuncNonnil

func (TrustedFuncNonnilPrestring) String

type TypeNameAnnotationKey

type TypeNameAnnotationKey struct {
	TypeDecl *types.TypeName
}

TypeNameAnnotationKey allows the Lookup of a named type annotations in the Annotation Map

func (*TypeNameAnnotationKey) Lookup

func (tk *TypeNameAnnotationKey) Lookup(annMap Map) (Val, bool)

Lookup looks this key up in the passed map, returning a Val

func (*TypeNameAnnotationKey) Object

func (tk *TypeNameAnnotationKey) Object() types.Object

Object returns the types.Object that this annotation can best be interpreted as annotating

func (*TypeNameAnnotationKey) String

func (tk *TypeNameAnnotationKey) String() string

type UnassignedFld

type UnassignedFld struct {
	*ProduceTriggerTautology
}

UnassignedFld is when a field of struct is not assigned at initialization

func (*UnassignedFld) Prestring

func (*UnassignedFld) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type UnassignedFldPrestring

type UnassignedFldPrestring struct{}

UnassignedFldPrestring is a Prestring storing the needed information to compactly encode a UnassignedFld

func (UnassignedFldPrestring) String

func (UnassignedFldPrestring) String() string

type UseAsErrorResult

type UseAsErrorResult struct {
	*TriggerIfNonNil

	RetStmt       *ast.ReturnStmt
	IsNamedReturn bool
}

UseAsErrorResult is when a value flows to the error result of a function, where it is expected to be non-nil

func (*UseAsErrorResult) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*UseAsErrorResult) Prestring

func (u *UseAsErrorResult) Prestring() Prestring

Prestring returns this UseAsErrorResult as a Prestring

func (UseAsErrorResult) String

func (a UseAsErrorResult) String() string

type UseAsErrorResultPrestring

type UseAsErrorResultPrestring struct {
	Pos              int
	ReturningFuncStr string
	IsNamedReturn    bool
	RetName          string
	AssignmentStr    string
}

UseAsErrorResultPrestring is a Prestring storing the needed information to compactly encode a UseAsErrorResult

func (UseAsErrorResultPrestring) String

func (u UseAsErrorResultPrestring) String() string

type UseAsErrorRetWithNilabilityUnknown

type UseAsErrorRetWithNilabilityUnknown struct {
	*TriggerIfNonNil

	IsNamedReturn bool
	RetStmt       *ast.ReturnStmt
}

UseAsErrorRetWithNilabilityUnknown is when a value flows to a point where it is returned from an error returning function

func (*UseAsErrorRetWithNilabilityUnknown) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*UseAsErrorRetWithNilabilityUnknown) Prestring

Prestring returns this UseAsErrorRetWithNilabilityUnknown as a Prestring

func (UseAsErrorRetWithNilabilityUnknown) String

func (a UseAsErrorRetWithNilabilityUnknown) String() string

type UseAsErrorRetWithNilabilityUnknownPrestring

type UseAsErrorRetWithNilabilityUnknownPrestring struct {
	FuncName      string
	RetNum        int
	IsNamedReturn bool
	RetName       string
	AssignmentStr string
}

UseAsErrorRetWithNilabilityUnknownPrestring is a Prestring storing the needed information to compactly encode a UseAsErrorRetWithNilabilityUnknown

func (UseAsErrorRetWithNilabilityUnknownPrestring) String

type UseAsFldOfReturn

type UseAsFldOfReturn struct {
	*TriggerIfNonNil
}

UseAsFldOfReturn is when a struct field value (A.f) flows to a point where it is returned from a function with the return expression of the same struct type (A)

func (*UseAsFldOfReturn) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*UseAsFldOfReturn) Prestring

func (u *UseAsFldOfReturn) Prestring() Prestring

Prestring returns this UseAsFldOfReturn as a Prestring

func (UseAsFldOfReturn) String

func (a UseAsFldOfReturn) String() string

type UseAsFldOfReturnPrestring

type UseAsFldOfReturnPrestring struct {
	FuncName      string
	FieldName     string
	RetNum        int
	AssignmentStr string
}

UseAsFldOfReturnPrestring is a Prestring storing the needed information to compactly encode a UseAsFldOfReturn

func (UseAsFldOfReturnPrestring) String

func (u UseAsFldOfReturnPrestring) String() string

type UseAsNonErrorRetDependentOnErrorRetNilability

type UseAsNonErrorRetDependentOnErrorRetNilability struct {
	*TriggerIfNonNil

	IsNamedReturn bool
	RetStmt       *ast.ReturnStmt
}

UseAsNonErrorRetDependentOnErrorRetNilability is when a value flows to a point where it is returned from an error returning function

func (*UseAsNonErrorRetDependentOnErrorRetNilability) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*UseAsNonErrorRetDependentOnErrorRetNilability) Prestring

Prestring returns this UseAsNonErrorRetDependentOnErrorRetNilability as a Prestring

func (UseAsNonErrorRetDependentOnErrorRetNilability) String

func (a UseAsNonErrorRetDependentOnErrorRetNilability) String() string

type UseAsNonErrorRetDependentOnErrorRetNilabilityPrestring

type UseAsNonErrorRetDependentOnErrorRetNilabilityPrestring struct {
	FuncName      string
	RetNum        int
	RetName       string
	ErrRetNum     int
	IsNamedReturn bool
	AssignmentStr string
}

UseAsNonErrorRetDependentOnErrorRetNilabilityPrestring is a Prestring storing the needed information to compactly encode a UseAsNonErrorRetDependentOnErrorRetNilability

func (UseAsNonErrorRetDependentOnErrorRetNilabilityPrestring) String

type UseAsReturn

type UseAsReturn struct {
	*TriggerIfNonNil
	IsNamedReturn bool
	RetStmt       *ast.ReturnStmt
}

UseAsReturn is when a value flows to a point where it is returned from a function. This consumer trigger can be used on top of two different sites: RetAnnotationKey & CallSiteRetAnnotationKey. RetAnnotationKey is the parameter site in the function declaration; CallSiteRetAnnotationKey is the argument site in the call expression. CallSiteRetAnnotationKey is specifically used for functions with contracts since we need to duplicate the sites for context sensitivity.

func (*UseAsReturn) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*UseAsReturn) Prestring

func (u *UseAsReturn) Prestring() Prestring

Prestring returns this UseAsReturn as a Prestring

func (UseAsReturn) String

func (a UseAsReturn) String() string

type UseAsReturnDeep

type UseAsReturnDeep struct {
	*TriggerIfDeepNonNil
	IsNamedReturn bool
	RetStmt       *ast.ReturnStmt
}

UseAsReturnDeep is when a deep value flows to a point where it is returned from a function.

func (*UseAsReturnDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*UseAsReturnDeep) Prestring

func (u *UseAsReturnDeep) Prestring() Prestring

Prestring returns this UseAsReturn as a Prestring

func (UseAsReturnDeep) String

func (a UseAsReturnDeep) String() string

type UseAsReturnDeepPrestring

type UseAsReturnDeepPrestring struct {
	FuncName      string
	RetNum        int
	RetName       string
	AssignmentStr string
}

UseAsReturnDeepPrestring is a Prestring storing the needed information to compactly encode a UseAsReturnDeep

func (UseAsReturnDeepPrestring) String

func (u UseAsReturnDeepPrestring) String() string

type UseAsReturnPrestring

type UseAsReturnPrestring struct {
	FuncName      string
	RetNum        int
	IsNamedReturn bool
	RetName       string
	// Location is empty for a UseAsReturn enclosing RetAnnotationKey. Location points to the
	// location of the result at the call site for a UseAsReturn enclosing
	// CallSiteRetAnnotationKey.
	Location      string
	AssignmentStr string
}

UseAsReturnPrestring is a Prestring storing the needed information to compactly encode a UseAsReturn

func (UseAsReturnPrestring) String

func (u UseAsReturnPrestring) String() string

type Val

type Val struct {
	IsNilable        bool
	IsDeepNilable    bool
	IsNilableSet     bool
	IsDeepNilableSet bool
}

Val is a possible value of an Annotation

type VariadicFuncParam

type VariadicFuncParam struct {
	*ProduceTriggerTautology
	VarDecl *types.Var
}

VariadicFuncParam is used when a value is determined to flow from a variadic function parameter, and thus always be nilable

func (*VariadicFuncParam) Prestring

func (v *VariadicFuncParam) Prestring() Prestring

Prestring returns this Prestring as a Prestring

type VariadicFuncParamDeep

type VariadicFuncParamDeep struct {
	*TriggerIfNilable
}

VariadicFuncParamDeep is used when a value is determined to flow deeply from a variadic function parameter, and thus be nilable iff the shallow Annotation on that parameter is nilable

func (*VariadicFuncParamDeep) Prestring

func (v *VariadicFuncParamDeep) Prestring() Prestring

Prestring returns this VariadicFuncParamDeep as a Prestring

type VariadicFuncParamDeepPrestring

type VariadicFuncParamDeepPrestring struct {
	ParamName string
}

VariadicFuncParamDeepPrestring is a Prestring storing the needed information to compactly encode a VariadicFuncParamDeep

func (VariadicFuncParamDeepPrestring) String

type VariadicFuncParamPrestring

type VariadicFuncParamPrestring struct {
	ParamName string
}

VariadicFuncParamPrestring is a Prestring storing the needed information to compactly encode a VariadicFuncParam

func (VariadicFuncParamPrestring) String

type VariadicParamAssignDeep

type VariadicParamAssignDeep struct {
	*TriggerIfNonNil
}

VariadicParamAssignDeep is when a value flows to a point where it is assigned deeply into a variadic function parameter

func (*VariadicParamAssignDeep) Copy

Copy returns a deep copy of this ConsumingAnnotationTrigger

func (*VariadicParamAssignDeep) Prestring

func (v *VariadicParamAssignDeep) Prestring() Prestring

Prestring returns this VariadicParamAssignDeep as a Prestring

func (VariadicParamAssignDeep) String

func (a VariadicParamAssignDeep) String() string

type VariadicParamAssignDeepPrestring

type VariadicParamAssignDeepPrestring struct {
	ParamName     string
	AssignmentStr string
}

VariadicParamAssignDeepPrestring is a Prestring storing the needed information to compactly encode a VariadicParamAssignDeep

func (VariadicParamAssignDeepPrestring) String

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL