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
- Variables
- func ConsumeTriggerSlicesEq(left, right []*ConsumeTrigger) bool
- func FullTriggerSlicesEq(left, right []FullTrigger) bool
- func TypeIsDeepDefaultNilable(t types.Type) bool
- func TypeIsDefaultNilable(t types.Type) bool
- func VarIsGlobal(v *types.Var) bool
- func VarIsParam(fdecl *types.Func, v *types.Var) bool
- func VarIsRecv(fdecl *types.Func, v *types.Var) bool
- func VarIsVariadicParam(fdecl *types.Func, v *types.Var) bool
- type AffiliationPair
- type ArgFldPass
- type ArgFldPassRepr
- type ArgLocAndVal
- type ArgPass
- type ArgPassDeep
- type ArgPassDeepRepr
- type ArgPassRepr
- type ArrayAssign
- type ArrayAssignRepr
- type ArrayRead
- type ArrayReadRepr
- type Assignment
- type BlankVarReturn
- type BlankVarReturnRepr
- type CallSite
- type CallSiteParamAnnotationKey
- func (pk *CallSiteParamAnnotationKey) Lookup(annMap Map) (Val, bool)
- func (pk *CallSiteParamAnnotationKey) MinimalString() string
- func (pk *CallSiteParamAnnotationKey) Object() types.Object
- func (pk *CallSiteParamAnnotationKey) ParamName() *types.Var
- func (pk *CallSiteParamAnnotationKey) ParamNameString() string
- func (pk *CallSiteParamAnnotationKey) String() string
- type CallSiteRetAnnotationKey
- type ChanRecv
- type ChanRecvRepr
- type ChanSend
- type ChanSendRepr
- type ConstNil
- type ConstNilRepr
- type ConsumeTrigger
- func ConsumeTriggerSliceAsGuarded(slice []*ConsumeTrigger, guards ...guard.Nonce) []*ConsumeTrigger
- func DuplicateReturnConsumer(t *ConsumeTrigger, location token.Position) *ConsumeTrigger
- func GetEscapeFldConsumer(escKey Key, selExpr ast.Expr) *ConsumeTrigger
- func GetParamFldConsumer(paramKey Key, expr ast.Expr) *ConsumeTrigger
- func GetRetFldConsumer(retKey Key, expr ast.Expr) *ConsumeTrigger
- func MergeConsumeTriggerSlices(left, right []*ConsumeTrigger) []*ConsumeTrigger
- type ConsumeTriggerTautology
- func (c *ConsumeTriggerTautology) AddAssignment(e Assignment)
- func (*ConsumeTriggerTautology) CheckConsume(Map) bool
- func (c *ConsumeTriggerTautology) Copy() ConsumingAnnotationTrigger
- func (*ConsumeTriggerTautology) Kind() TriggerKind
- func (c *ConsumeTriggerTautology) NeedsGuard() bool
- func (c *ConsumeTriggerTautology) Repr() fmt.Stringer
- func (c *ConsumeTriggerTautology) SetNeedsGuard(b bool)
- func (a *ConsumeTriggerTautology) String() string
- func (*ConsumeTriggerTautology) UnderlyingSite() Key
- type ConsumeTriggerTautologyRepr
- type ConsumingAnnotationTrigger
- type DeepAssignPrimitive
- type DeepAssignPrimitiveRepr
- type EscapeFieldAnnotationKey
- type ExprOkCheck
- type FieldAnnotationKey
- type FieldAssignDeep
- type FieldAssignDeepRepr
- type FldAccess
- type FldAccessRepr
- type FldAssign
- type FldAssignRepr
- type FldEscape
- type FldEscapeRepr
- type FldRead
- type FldReadDeep
- type FldReadDeepRepr
- type FldReadRepr
- type FldReturn
- type FldReturnRepr
- type FullTrigger
- type FuncParam
- type FuncParamDeep
- type FuncParamDeepRepr
- type FuncParamRepr
- type FuncRetAssignDeep
- type FuncRetAssignDeepRepr
- type FuncReturn
- type FuncReturnDeep
- type FuncReturnDeepRepr
- type FuncReturnRepr
- type GlobalVarAnnotationKey
- type GlobalVarAssign
- type GlobalVarAssignDeep
- type GlobalVarAssignDeepRepr
- type GlobalVarAssignRepr
- type GlobalVarRead
- type GlobalVarReadDeep
- type GlobalVarReadDeepRepr
- type GlobalVarReadRepr
- type GuardMissing
- type GuardMissingRepr
- type InterfaceParamReachesImplementation
- type InterfaceParamReachesImplementationRepr
- type InterfaceResultFromImplementation
- type InterfaceResultFromImplementationRepr
- type Key
- type LocalVarAnnotationKey
- type LocalVarAssignDeep
- type LocalVarAssignDeepRepr
- type LocalVarReadDeep
- type LocalVarReadDeepRepr
- type LocatedRepr
- type Map
- type MapAccess
- type MapAccessRepr
- type MapAssign
- type MapAssignRepr
- type MapRead
- type MapReadRepr
- type MapWrittenTo
- type MapWrittenToRepr
- type MethodParamFromInterface
- type MethodParamFromInterfaceRepr
- type MethodRecv
- type MethodRecvDeep
- type MethodRecvDeepRepr
- type MethodRecvRepr
- type MethodResultReachesInterface
- type MethodResultReachesInterfaceRepr
- type MethodReturn
- type MethodReturnRepr
- type NegativeNilCheck
- type NegativeNilCheckRepr
- type NoVarAssign
- type NoVarAssignRepr
- type ObservedMap
- type OkReadReflCheck
- type ParamAnnotationKey
- func (pk *ParamAnnotationKey) Lookup(annMap Map) (Val, bool)
- func (pk *ParamAnnotationKey) MinimalString() string
- func (pk *ParamAnnotationKey) Object() types.Object
- func (pk *ParamAnnotationKey) ParamName() *types.Var
- func (pk *ParamAnnotationKey) ParamNameString() string
- func (pk *ParamAnnotationKey) String() string
- type ParamAssignDeep
- type ParamAssignDeepRepr
- type ParamFieldAnnotationKey
- type ParamFldRead
- type ParamFldReadRepr
- type PositiveNilCheck
- type PositiveNilCheckRepr
- type ProduceTrigger
- type ProduceTriggerNever
- type ProduceTriggerNeverRepr
- type ProduceTriggerTautology
- func (*ProduceTriggerTautology) CheckProduce(Map) bool
- func (*ProduceTriggerTautology) Kind() TriggerKind
- func (p *ProduceTriggerTautology) NeedsGuardMatch() bool
- func (*ProduceTriggerTautology) Repr() fmt.Stringer
- func (p *ProduceTriggerTautology) SetNeedsGuard(b bool)
- func (*ProduceTriggerTautology) UnderlyingSite() Key
- type ProduceTriggerTautologyRepr
- type ProducingAnnotationTrigger
- func DeepNilabilityAsNamedType(typ types.Type) ProducingAnnotationTrigger
- func DeepNilabilityOfFld(fld *types.Var) ProducingAnnotationTrigger
- func DeepNilabilityOfFuncRet(fn *types.Func, retNum int) ProducingAnnotationTrigger
- func DeepNilabilityOfVar(fdecl *types.Func, v *types.Var) ProducingAnnotationTrigger
- func ParamAsProducer(fdecl *types.Func, param *types.Var) ProducingAnnotationTrigger
- type PtrAssign
- type PtrAssignRepr
- type PtrLoad
- type PtrLoadRepr
- type PtrRead
- type PtrReadRepr
- type RangeIndexAssignment
- type RangeOver
- type RecvAnnotationKey
- type RecvPass
- type RecvPassRepr
- type RetAnnotationKey
- type RetFieldAnnotationKey
- type SliceAccess
- type SliceAccessRepr
- type SliceAssign
- type SliceAssignRepr
- type SliceRead
- type SliceReadRepr
- type StructFieldContextKind
- type StructFieldContextSite
- type StructFieldFromContext
- type StructFieldFromContextRepr
- type StructFieldNil
- type StructFieldNilRepr
- type StructFieldToContext
- type StructFieldToContextRepr
- type TriggerIfDeepNilable
- func (t *TriggerIfDeepNilable) CheckProduce(annMap Map) bool
- func (t *TriggerIfDeepNilable) Kind() TriggerKind
- func (t *TriggerIfDeepNilable) NeedsGuardMatch() bool
- func (*TriggerIfDeepNilable) Repr() fmt.Stringer
- func (t *TriggerIfDeepNilable) SetNeedsGuard(b bool)
- func (t *TriggerIfDeepNilable) UnderlyingSite() Key
- type TriggerIfDeepNilableRepr
- type TriggerIfDeepNonNil
- func (t *TriggerIfDeepNonNil) AddAssignment(e Assignment)
- func (t *TriggerIfDeepNonNil) CheckConsume(annMap Map) bool
- func (t *TriggerIfDeepNonNil) Copy() ConsumingAnnotationTrigger
- func (*TriggerIfDeepNonNil) Kind() TriggerKind
- func (t *TriggerIfDeepNonNil) NeedsGuard() bool
- func (t *TriggerIfDeepNonNil) Repr() fmt.Stringer
- func (t *TriggerIfDeepNonNil) SetNeedsGuard(b bool)
- func (a *TriggerIfDeepNonNil) String() string
- func (t *TriggerIfDeepNonNil) UnderlyingSite() Key
- type TriggerIfDeepNonNilRepr
- type TriggerIfNilable
- type TriggerIfNilableRepr
- type TriggerIfNonNil
- func (t *TriggerIfNonNil) AddAssignment(e Assignment)
- func (t *TriggerIfNonNil) CheckConsume(annMap Map) bool
- func (t *TriggerIfNonNil) Copy() ConsumingAnnotationTrigger
- func (*TriggerIfNonNil) Kind() TriggerKind
- func (t *TriggerIfNonNil) NeedsGuard() bool
- func (t *TriggerIfNonNil) Repr() fmt.Stringer
- func (t *TriggerIfNonNil) SetNeedsGuard(b bool)
- func (a *TriggerIfNonNil) String() string
- func (t *TriggerIfNonNil) UnderlyingSite() Key
- type TriggerIfNonNilRepr
- type TriggerKind
- type TrustedFuncNilable
- type TrustedFuncNilableRepr
- type TrustedFuncNonnil
- type TrustedFuncNonnilRepr
- type TypeNameAnnotationKey
- type UnassignedFld
- type UnassignedFldRepr
- type UseAsErrorResult
- type UseAsErrorResultRepr
- type UseAsErrorRetWithNilabilityUnknown
- type UseAsErrorRetWithNilabilityUnknownRepr
- type UseAsFldOfReturn
- type UseAsFldOfReturnRepr
- type UseAsNonErrorRetDependentOnErrorRetNilability
- type UseAsNonErrorRetDependentOnErrorRetNilabilityRepr
- type UseAsReturn
- type UseAsReturnDeep
- type UseAsReturnDeepRepr
- type UseAsReturnRepr
- type Val
- type VariadicFuncParam
- type VariadicFuncParamDeep
- type VariadicFuncParamDeepRepr
- type VariadicFuncParamRepr
- type VariadicParamAssignDeep
- type VariadicParamAssignDeepRepr
Constants ¶
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 ¶
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
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 ¶
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 ¶
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 ¶
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 ¶
VarIsParam returns true iff `v` is a parameter of `fdecl`
Types ¶
type AffiliationPair ¶
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 ¶
func (f *ArgFldPass) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*ArgFldPass) Repr ¶
func (f *ArgFldPass) Repr() fmt.Stringer
Repr returns this ArgFldPass as a fmt.Stringer
type ArgFldPassRepr ¶
type ArgFldPassRepr struct {
FieldName string
FuncName string
ParamNum int
RecvName string
IsPassed bool
AssignmentStr string
}
ArgFldPassRepr is a fmt.Stringer storing the needed information to compactly encode a ArgFldPass
func (ArgFldPassRepr) String ¶
func (f ArgFldPassRepr) String() string
type ArgLocAndVal ¶
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 ¶
func (a *ArgPass) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
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 ¶
func (a *ArgPassDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*ArgPassDeep) Repr ¶
func (a *ArgPassDeep) Repr() fmt.Stringer
Repr returns this ArgPassDeep as a fmt.Stringer
type ArgPassDeepRepr ¶
type ArgPassDeepRepr 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
}
ArgPassDeepRepr is a fmt.Stringer storing the needed information to compactly encode a ArgPassDeep
func (ArgPassDeepRepr) String ¶
func (a ArgPassDeepRepr) String() string
type ArgPassRepr ¶
type ArgPassRepr 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
}
ArgPassRepr is a fmt.Stringer storing the needed information to compactly encode a ArgPass
func (ArgPassRepr) String ¶
func (a ArgPassRepr) 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 ¶
func (a *ArrayAssign) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*ArrayAssign) Repr ¶
func (a *ArrayAssign) Repr() fmt.Stringer
Repr returns this ArrayAssign as a fmt.Stringer
type ArrayAssignRepr ¶
ArrayAssignRepr is a fmt.Stringer storing the needed information to compactly encode a SliceAssign
func (ArrayAssignRepr) String ¶
func (a ArrayAssignRepr) String() string
type ArrayRead ¶
type ArrayRead struct {
*TriggerIfDeepNilable
}
ArrayRead is when a value is determined to flow from an array index expression
type ArrayReadRepr ¶
type ArrayReadRepr struct {
TypeName string
}
ArrayReadRepr is a fmt.Stringer storing the needed information to compactly encode a ArrayRead
func (ArrayReadRepr) String ¶
func (a ArrayReadRepr) String() string
type Assignment ¶
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) Repr ¶
func (*BlankVarReturn) Repr() fmt.Stringer
Repr returns a compact string representation.
type BlankVarReturnRepr ¶
type BlankVarReturnRepr struct{}
BlankVarReturnRepr is a fmt.Stringer storing the needed information to compactly encode a BlankVarReturn
func (BlankVarReturnRepr) String ¶
func (BlankVarReturnRepr) String() string
type CallSite ¶
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 ¶
func (pk *CallSiteParamAnnotationKey) Object() types.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
type ChanRecvRepr ¶
type ChanRecvRepr struct {
TypeName string
}
ChanRecvRepr is a fmt.Stringer storing the needed information to compactly encode a ChanRecv
func (ChanRecvRepr) String ¶
func (c ChanRecvRepr) 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 ¶
func (c *ChanSend) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type ChanSendRepr ¶
ChanSendRepr is a fmt.Stringer storing the needed information to compactly encode a ChanSend
func (ChanSendRepr) String ¶
func (c ChanSendRepr) String() string
type ConstNil ¶
type ConstNil struct {
*ProduceTriggerTautology
}
ConstNil is when a value is determined to flow from a constant nil expression
type ConstNilRepr ¶
type ConstNilRepr struct{}
ConstNilRepr is a fmt.Stringer storing the needed information to compactly encode a ConstNil
func (ConstNilRepr) String ¶
func (ConstNilRepr) String() string
type ConsumeTrigger ¶
type ConsumeTrigger struct {
Annotation ConsumingAnnotationTrigger
Expr ast.Expr
Guards guard.NonceSet
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 ...guard.Nonce) []*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 ¶
func (c *ConsumeTriggerTautology) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*ConsumeTriggerTautology) Kind ¶
func (*ConsumeTriggerTautology) Kind() TriggerKind
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) Repr ¶
func (c *ConsumeTriggerTautology) Repr() fmt.Stringer
Repr returns a compact string representation.
func (*ConsumeTriggerTautology) SetNeedsGuard ¶
func (c *ConsumeTriggerTautology) SetNeedsGuard(b bool)
SetNeedsGuard sets the underlying Guard-Neediness of this ConsumerTrigger
func (*ConsumeTriggerTautology) UnderlyingSite ¶
func (*ConsumeTriggerTautology) UnderlyingSite() Key
UnderlyingSite always returns nil.
type ConsumeTriggerTautologyRepr ¶
type ConsumeTriggerTautologyRepr struct {
AssignmentStr string
}
ConsumeTriggerTautologyRepr is a fmt.Stringer storing the needed information to compactly encode a ConsumeTriggerTautology
func (ConsumeTriggerTautologyRepr) String ¶
func (c ConsumeTriggerTautologyRepr) String() 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
Repr() fmt.Stringer
// 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 ¶
func (d *DeepAssignPrimitive) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*DeepAssignPrimitive) Repr ¶
func (d *DeepAssignPrimitive) Repr() fmt.Stringer
Repr returns a compact string representation.
type DeepAssignPrimitiveRepr ¶
type DeepAssignPrimitiveRepr struct {
AssignmentStr string
}
DeepAssignPrimitiveRepr is a fmt.Stringer storing the needed information to compactly encode a DeepAssignPrimitive
func (DeepAssignPrimitiveRepr) String ¶
func (d DeepAssignPrimitiveRepr) String() string
type EscapeFieldAnnotationKey ¶
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 ¶
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 ¶
func (f *FieldAssignDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*FieldAssignDeep) Repr ¶
func (f *FieldAssignDeep) Repr() fmt.Stringer
Repr returns this FieldAssignDeep as a fmt.Stringer
type FieldAssignDeepRepr ¶
FieldAssignDeepRepr is a fmt.Stringer storing the needed information to compactly encode a FieldAssignDeep
func (FieldAssignDeepRepr) String ¶
func (f FieldAssignDeepRepr) 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 ¶
func (f *FldAccess) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type FldAccessRepr ¶
FldAccessRepr is a fmt.Stringer storing the needed information to compactly encode a FldAccess
func (FldAccessRepr) String ¶
func (f FldAccessRepr) 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 ¶
func (f *FldAssign) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type FldAssignRepr ¶
FldAssignRepr is a fmt.Stringer storing the needed information to compactly encode a FldAssign
func (FldAssignRepr) String ¶
func (f FldAssignRepr) 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 ¶
func (f *FldEscape) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type FldEscapeRepr ¶
FldEscapeRepr is a fmt.Stringer storing the needed information to compactly encode a FldEscape
func (FldEscapeRepr) String ¶
func (f FldEscapeRepr) String() string
type FldRead ¶
type FldRead struct {
*TriggerIfNilable
}
FldRead is used when a value is determined to flow from a read to a field
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) Repr ¶
func (f *FldReadDeep) Repr() fmt.Stringer
Repr returns this FldReadDeep as a fmt.Stringer
type FldReadDeepRepr ¶
type FldReadDeepRepr struct {
FieldName string
}
FldReadDeepRepr is a fmt.Stringer storing the needed information to compactly encode a FldReadDeep
func (FldReadDeepRepr) String ¶
func (f FldReadDeepRepr) String() string
type FldReadRepr ¶
type FldReadRepr struct {
FieldName string
}
FldReadRepr is a fmt.Stringer storing the needed information to compactly encode a FldRead
func (FldReadRepr) String ¶
func (f FldReadRepr) 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
type FldReturnRepr ¶
FldReturnRepr is a fmt.Stringer storing the needed information to compactly encode a FldReturn
func (FldReturnRepr) String ¶
func (f FldReturnRepr) 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. This function modifies the `left` slice, by appending the non-duplicate right triggers into it.
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) Reprs ¶
func (t *FullTrigger) Reprs(pass *analysishelper.EnhancedPass) (fmt.Stringer, fmt.Stringer)
Reprs returns compact representations 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.
type FuncParamDeep ¶
type FuncParamDeep struct {
*TriggerIfDeepNilable
}
FuncParamDeep is used when a value is determined to flow deeply from a function parameter
func (*FuncParamDeep) Repr ¶
func (f *FuncParamDeep) Repr() fmt.Stringer
Repr returns this FuncParamDeep as a fmt.Stringer
type FuncParamDeepRepr ¶
type FuncParamDeepRepr struct {
ParamName string
}
FuncParamDeepRepr is a fmt.Stringer storing the needed information to compactly encode a FuncParamDeep
func (FuncParamDeepRepr) String ¶
func (f FuncParamDeepRepr) String() string
type FuncParamRepr ¶
type FuncParamRepr 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
}
FuncParamRepr is a fmt.Stringer storing the needed information to compactly encode a FuncParam
func (FuncParamRepr) String ¶
func (f FuncParamRepr) 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 ¶
func (f *FuncRetAssignDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*FuncRetAssignDeep) Repr ¶
func (f *FuncRetAssignDeep) Repr() fmt.Stringer
Repr returns this FuncRetAssignDeep as a fmt.Stringer
type FuncRetAssignDeepRepr ¶
FuncRetAssignDeepRepr is a fmt.Stringer storing the needed information to compactly encode a FuncRetAssignDeep
func (FuncRetAssignDeepRepr) String ¶
func (f FuncRetAssignDeepRepr) String() string
type FuncReturn ¶
type FuncReturn struct {
*TriggerIfNilable
IsFromRichCheckEffectFunc bool
}
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) Repr ¶
func (f *FuncReturn) Repr() fmt.Stringer
Repr returns this FuncReturn as a fmt.Stringer
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) Repr ¶
func (f *FuncReturnDeep) Repr() fmt.Stringer
Repr returns this FuncReturnDeep as a fmt.Stringer
type FuncReturnDeepRepr ¶
FuncReturnDeepRepr is a fmt.Stringer storing the needed information to compactly encode a FuncReturnDeep
func (FuncReturnDeepRepr) String ¶
func (f FuncReturnDeepRepr) String() string
type FuncReturnRepr ¶
type FuncReturnRepr 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
}
FuncReturnRepr is a fmt.Stringer storing the needed information to compactly encode a FuncReturn
func (FuncReturnRepr) String ¶
func (f FuncReturnRepr) String() string
type GlobalVarAnnotationKey ¶
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 ¶
func (g *GlobalVarAssign) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*GlobalVarAssign) Repr ¶
func (g *GlobalVarAssign) Repr() fmt.Stringer
Repr returns this GlobalVarAssign as a fmt.Stringer
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 ¶
func (g *GlobalVarAssignDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*GlobalVarAssignDeep) Repr ¶
func (g *GlobalVarAssignDeep) Repr() fmt.Stringer
Repr returns this GlobalVarAssignDeep as a fmt.Stringer
type GlobalVarAssignDeepRepr ¶
GlobalVarAssignDeepRepr is a fmt.Stringer storing the needed information to compactly encode a GlobalVarAssignDeep
func (GlobalVarAssignDeepRepr) String ¶
func (g GlobalVarAssignDeepRepr) String() string
type GlobalVarAssignRepr ¶
GlobalVarAssignRepr is a fmt.Stringer storing the needed information to compactly encode a GlobalVarAssign
func (GlobalVarAssignRepr) String ¶
func (g GlobalVarAssignRepr) 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) Repr ¶
func (g *GlobalVarRead) Repr() fmt.Stringer
Repr returns this GlobalVarRead as a fmt.Stringer
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) Repr ¶
func (g *GlobalVarReadDeep) Repr() fmt.Stringer
Repr returns this GlobalVarReadDeep as a fmt.Stringer
type GlobalVarReadDeepRepr ¶
type GlobalVarReadDeepRepr struct {
VarName string
}
GlobalVarReadDeepRepr is a fmt.Stringer storing the needed information to compactly encode a GlobalVarReadDeep
func (GlobalVarReadDeepRepr) String ¶
func (g GlobalVarReadDeepRepr) String() string
type GlobalVarReadRepr ¶
type GlobalVarReadRepr struct {
VarName string
}
GlobalVarReadRepr is a fmt.Stringer storing the needed information to compactly encode a GlobalVarRead
func (GlobalVarReadRepr) String ¶
func (g GlobalVarReadRepr) 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) Repr ¶
func (g *GuardMissing) Repr() fmt.Stringer
Repr returns this GuardMissing as a fmt.Stringer
type GuardMissingRepr ¶
type GuardMissingRepr struct {
// OldPrestring retains the existing gob field name for fact encoding compatibility.
OldPrestring fmt.Stringer
}
GuardMissingRepr is a fmt.Stringer storing the needed information to compactly encode a GuardMissing
func (GuardMissingRepr) String ¶
func (g GuardMissingRepr) 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) Repr ¶
func (i *InterfaceParamReachesImplementation) Repr() fmt.Stringer
Repr returns this InterfaceParamReachesImplementation as a fmt.Stringer
type InterfaceParamReachesImplementationRepr ¶
type InterfaceParamReachesImplementationRepr struct {
ParamName string
IntName string
ImplName string
}
InterfaceParamReachesImplementationRepr is a fmt.Stringer storing the needed information to compactly encode a InterfaceParamReachesImplementation
func (InterfaceParamReachesImplementationRepr) String ¶
func (i InterfaceParamReachesImplementationRepr) String() 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 ¶
func (i *InterfaceResultFromImplementation) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*InterfaceResultFromImplementation) Repr ¶
func (i *InterfaceResultFromImplementation) Repr() fmt.Stringer
Repr returns this InterfaceResultFromImplementation as a fmt.Stringer
type InterfaceResultFromImplementationRepr ¶
type InterfaceResultFromImplementationRepr struct {
RetNum int
IntName string
ImplName string
AssignmentStr string
}
InterfaceResultFromImplementationRepr is a fmt.Stringer storing the needed information to compactly encode a InterfaceResultFromImplementation
func (InterfaceResultFromImplementationRepr) String ¶
func (i InterfaceResultFromImplementationRepr) String() 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 ¶
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 ¶
func (l *LocalVarAssignDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*LocalVarAssignDeep) Repr ¶
func (l *LocalVarAssignDeep) Repr() fmt.Stringer
Repr returns this LocalVarAssignDeep as a fmt.Stringer
type LocalVarAssignDeepRepr ¶
LocalVarAssignDeepRepr is a fmt.Stringer storing the needed information to compactly encode a LocalVarAssignDeep
func (LocalVarAssignDeepRepr) String ¶
func (l LocalVarAssignDeepRepr) String() string
type LocalVarReadDeep ¶
type LocalVarReadDeep struct {
*TriggerIfDeepNilable
}
LocalVarReadDeep is when a value is determined to flow deeply from a local variable.
func (LocalVarReadDeep) Repr ¶
func (v LocalVarReadDeep) Repr() fmt.Stringer
Repr returns this LocalVarReadDeep as a fmt.Stringer
type LocalVarReadDeepRepr ¶
type LocalVarReadDeepRepr struct {
VarName string
}
LocalVarReadDeepRepr is a fmt.Stringer storing the needed information to compactly encode a LocalVarReadDeep
func (LocalVarReadDeepRepr) String ¶
func (v LocalVarReadDeepRepr) String() string
type LocatedRepr ¶
A LocatedRepr wraps another fmt.Stringer with a `token.Position` - for formatting with that position
func (LocatedRepr) String ¶
func (l LocatedRepr) 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 ¶
func (i *MapAccess) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type MapAccessRepr ¶
type MapAccessRepr struct {
AssignmentStr string
}
MapAccessRepr is a fmt.Stringer storing the needed information to compactly encode a MapAccess
func (MapAccessRepr) String ¶
func (i MapAccessRepr) 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 ¶
func (f *MapAssign) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type MapAssignRepr ¶
MapAssignRepr is a fmt.Stringer storing the needed information to compactly encode a MapAssign
func (MapAssignRepr) String ¶
func (f MapAssignRepr) 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
type MapReadRepr ¶
type MapReadRepr struct {
TypeName string
}
MapReadRepr is a fmt.Stringer storing the needed information to compactly encode a MapRead
func (MapReadRepr) String ¶
func (m MapReadRepr) 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 ¶
func (m *MapWrittenTo) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*MapWrittenTo) Repr ¶
func (m *MapWrittenTo) Repr() fmt.Stringer
Repr returns this MapWrittenTo as a fmt.Stringer
type MapWrittenToRepr ¶
type MapWrittenToRepr struct {
AssignmentStr string
}
MapWrittenToRepr is a fmt.Stringer storing the needed information to compactly encode a MapWrittenTo
func (MapWrittenToRepr) String ¶
func (m MapWrittenToRepr) 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 ¶
func (m *MethodParamFromInterface) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*MethodParamFromInterface) Repr ¶
func (m *MethodParamFromInterface) Repr() fmt.Stringer
Repr returns this MethodParamFromInterface as a fmt.Stringer
type MethodParamFromInterfaceRepr ¶
type MethodParamFromInterfaceRepr struct {
ParamName string
ImplName string
IntName string
AssignmentStr string
}
MethodParamFromInterfaceRepr is a fmt.Stringer storing the needed information to compactly encode a MethodParamFromInterface
func (MethodParamFromInterfaceRepr) String ¶
func (m MethodParamFromInterfaceRepr) String() 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) Repr ¶
func (m *MethodRecv) Repr() fmt.Stringer
Repr returns this MethodRecv as a fmt.Stringer
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) Repr ¶
func (m *MethodRecvDeep) Repr() fmt.Stringer
Repr returns this MethodRecv as a fmt.Stringer
type MethodRecvDeepRepr ¶
type MethodRecvDeepRepr struct {
RecvName string
}
MethodRecvDeepRepr is a fmt.Stringer storing the needed information to compactly encode a MethodRecv
func (MethodRecvDeepRepr) String ¶
func (m MethodRecvDeepRepr) String() string
type MethodRecvRepr ¶
type MethodRecvRepr struct {
RecvName string
}
MethodRecvRepr is a fmt.Stringer storing the needed information to compactly encode a MethodRecv
func (MethodRecvRepr) String ¶
func (m MethodRecvRepr) 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) Repr ¶
func (m *MethodResultReachesInterface) Repr() fmt.Stringer
Repr returns this MethodResultReachesInterface as a fmt.Stringer
type MethodResultReachesInterfaceRepr ¶
MethodResultReachesInterfaceRepr is a fmt.Stringer storing the needed information to compactly encode a MethodResultReachesInterface
func (MethodResultReachesInterfaceRepr) String ¶
func (m MethodResultReachesInterfaceRepr) String() 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) Repr ¶
func (m *MethodReturn) Repr() fmt.Stringer
Repr returns this MethodReturn as a fmt.Stringer
type MethodReturnRepr ¶
MethodReturnRepr is a fmt.Stringer storing the needed information to compactly encode a MethodReturn
func (MethodReturnRepr) String ¶
func (m MethodReturnRepr) 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) Repr ¶
func (*NegativeNilCheck) Repr() fmt.Stringer
Repr returns a compact string representation.
type NegativeNilCheckRepr ¶
type NegativeNilCheckRepr struct{}
NegativeNilCheckRepr is a fmt.Stringer storing the needed information to compactly encode a NegativeNilCheck
func (NegativeNilCheckRepr) String ¶
func (NegativeNilCheckRepr) String() 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) Repr ¶
func (n *NoVarAssign) Repr() fmt.Stringer
Repr returns a compact string representation.
type NoVarAssignRepr ¶
type NoVarAssignRepr struct {
VarName string
}
NoVarAssignRepr is a fmt.Stringer storing the needed information to compactly encode a NoVarAssign
func (NoVarAssignRepr) String ¶
func (n NoVarAssignRepr) 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
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 ¶
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 ¶
func (p *ParamAssignDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*ParamAssignDeep) Repr ¶
func (p *ParamAssignDeep) Repr() fmt.Stringer
Repr returns this ParamAssignDeep as a fmt.Stringer
type ParamAssignDeepRepr ¶
ParamAssignDeepRepr is a fmt.Stringer storing the needed information to compactly encode a ParamAssignDeep
func (ParamAssignDeepRepr) String ¶
func (p ParamAssignDeepRepr) 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) Repr ¶
func (f *ParamFldRead) Repr() fmt.Stringer
Repr returns this ParamFldRead as a fmt.Stringer
type ParamFldReadRepr ¶
type ParamFldReadRepr struct {
FieldName string
}
ParamFldReadRepr is a fmt.Stringer storing the needed information to compactly encode a ParamFldRead
func (ParamFldReadRepr) String ¶
func (f ParamFldReadRepr) String() string
type PositiveNilCheck ¶
type PositiveNilCheck struct {
*ProduceTriggerTautology
}
PositiveNilCheck is used when a value is checked in a conditional to BE nil
func (*PositiveNilCheck) Repr ¶
func (*PositiveNilCheck) Repr() fmt.Stringer
Repr returns a compact string representation.
type PositiveNilCheckRepr ¶
type PositiveNilCheckRepr struct{}
PositiveNilCheckRepr is a fmt.Stringer storing the needed information to compactly encode a PositiveNilCheck
func (PositiveNilCheckRepr) String ¶
func (PositiveNilCheckRepr) String() string
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 ¶
func (*ProduceTriggerNever) Kind() TriggerKind
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) Repr ¶
func (*ProduceTriggerNever) Repr() fmt.Stringer
Repr returns a compact string representation.
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 ProduceTriggerNeverRepr ¶
type ProduceTriggerNeverRepr struct{}
ProduceTriggerNeverRepr is a fmt.Stringer storing the needed information to compactly encode a ProduceTriggerNever
func (ProduceTriggerNeverRepr) String ¶
func (ProduceTriggerNeverRepr) String() 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 ¶
func (*ProduceTriggerTautology) Kind() TriggerKind
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) Repr ¶
func (*ProduceTriggerTautology) Repr() fmt.Stringer
Repr returns a compact string representation.
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 ProduceTriggerTautologyRepr ¶
type ProduceTriggerTautologyRepr struct{}
ProduceTriggerTautologyRepr is a fmt.Stringer storing the needed information to compactly encode a ProduceTriggerTautology
func (ProduceTriggerTautologyRepr) String ¶
func (ProduceTriggerTautologyRepr) String() 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)
Repr() fmt.Stringer
// 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 ¶
func (f *PtrAssign) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type PtrAssignRepr ¶
PtrAssignRepr is a fmt.Stringer storing the needed information to compactly encode a PtrAssign
func (PtrAssignRepr) String ¶
func (f PtrAssignRepr) 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 ¶
func (p *PtrLoad) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type PtrLoadRepr ¶
type PtrLoadRepr struct {
AssignmentStr string
}
PtrLoadRepr is a fmt.Stringer storing the needed information to compactly encode a PtrLoad
func (PtrLoadRepr) String ¶
func (p PtrLoadRepr) String() string
type PtrRead ¶
type PtrRead struct {
*TriggerIfDeepNilable
}
PtrRead is when a value is determined to flow from a read to a pointer
type PtrReadRepr ¶
type PtrReadRepr struct {
TypeName string
}
PtrReadRepr is a fmt.Stringer storing the needed information to compactly encode a PtrRead
func (PtrReadRepr) String ¶
func (p PtrReadRepr) 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 ¶
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 ¶
func (a *RecvPass) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
type RecvPassRepr ¶
RecvPassRepr is a fmt.Stringer storing the needed information to compactly encode a RecvPass
func (RecvPassRepr) String ¶
func (a RecvPassRepr) String() string
type RetAnnotationKey ¶
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 ¶
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 ¶
func (s *SliceAccess) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*SliceAccess) Repr ¶
func (s *SliceAccess) Repr() fmt.Stringer
Repr returns this SliceAccess as a fmt.Stringer
type SliceAccessRepr ¶
type SliceAccessRepr struct {
AssignmentStr string
}
SliceAccessRepr is a fmt.Stringer storing the needed information to compactly encode a SliceAccess
func (SliceAccessRepr) String ¶
func (s SliceAccessRepr) 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 ¶
func (f *SliceAssign) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*SliceAssign) Repr ¶
func (f *SliceAssign) Repr() fmt.Stringer
Repr returns this SliceAssign as a fmt.Stringer
type SliceAssignRepr ¶
SliceAssignRepr is a fmt.Stringer storing the needed information to compactly encode a SliceAssign
func (SliceAssignRepr) String ¶
func (f SliceAssignRepr) String() string
type SliceRead ¶
type SliceRead struct {
*TriggerIfDeepNilable
}
SliceRead is when a value is determined to flow from a slice index expression
type SliceReadRepr ¶
type SliceReadRepr struct {
TypeName string
}
SliceReadRepr is a fmt.Stringer storing the needed information to compactly encode a SliceRead
func (SliceReadRepr) String ¶
func (s SliceReadRepr) String() string
type StructFieldContextKind ¶
type StructFieldContextKind uint8
StructFieldContextKind distinguishes whether a context site summarizes a field of a function return value or of a function parameter/receiver.
const ( // StructFieldReturnContext is the nilability of a field of a function's return value. StructFieldReturnContext StructFieldContextKind = iota // StructFieldParamContext is the nilability of a field of a function's parameter/receiver, // as observed on entry to the function (the value passed in by the caller). StructFieldParamContext // StructFieldParamOutContext is the nilability of a parameter or receiver field after the // function has assigned it. StructFieldParamOutContext )
type StructFieldContextSite ¶
type StructFieldContextSite struct {
FuncObj *types.Func
Kind StructFieldContextKind
Index int
// Path is the dotted field path from the boundary value to the tracked field (e.g. "aptr").
Path string
}
StructFieldContextSite is an annotation site (annotation.Key) representing the nilability of a nested field, identified by Path, of the Index-th return value or parameter of FuncObj. It is inference-only.
func (*StructFieldContextSite) Lookup ¶
func (s *StructFieldContextSite) Lookup(Map) (Val, bool)
Lookup always returns the non-annotated default: these sites carry no syntactic annotation, so their nilability comes purely from inference.
func (*StructFieldContextSite) Object ¶
func (s *StructFieldContextSite) Object() types.Object
Object returns the function this site belongs to. Cross-package inference identity uses Object() together with String(); the function is unique across packages, while the field may come from a shared struct type.
func (*StructFieldContextSite) String ¶
func (s *StructFieldContextSite) String() string
type StructFieldFromContext ¶
type StructFieldFromContext struct {
*TriggerIfNilable
}
StructFieldFromContext is a producer: the value of a field (read from a boundary, e.g. `b.f` where `b := give()`) is nil iff the corresponding context site is inferred nilable.
func (*StructFieldFromContext) Repr ¶
func (s *StructFieldFromContext) Repr() fmt.Stringer
Repr returns this StructFieldFromContext as a fmt.Stringer.
type StructFieldFromContextRepr ¶
type StructFieldFromContextRepr struct {
Path string
Kind StructFieldContextKind
Index int
FuncName string
}
StructFieldFromContextRepr is the compact encoding of a StructFieldFromContext.
func (StructFieldFromContextRepr) String ¶
func (s StructFieldFromContextRepr) String() string
type StructFieldNil ¶
type StructFieldNil struct {
*ProduceTriggerTautology
// FieldName is the name of the field that is nil, used only for diagnostics.
FieldName string
}
StructFieldNil is a producer for a nil field in a specific struct allocation. It always produces nil. Because it is attached to the field node for that allocation, different allocations of the same struct type keep separate producers.
func (*StructFieldNil) Repr ¶
func (s *StructFieldNil) Repr() fmt.Stringer
Repr returns this StructFieldNil as a fmt.Stringer.
type StructFieldNilRepr ¶
type StructFieldNilRepr struct {
FieldName string
}
StructFieldNilRepr is a fmt.Stringer storing the information needed to compactly encode a StructFieldNil.
func (StructFieldNilRepr) String ¶
func (s StructFieldNilRepr) String() string
type StructFieldToContext ¶
type StructFieldToContext struct {
*TriggerIfNonNil
}
StructFieldToContext is a consumer: a value flows into a field of a boundary (e.g. a returned struct's field). It requires the context site to be nonnil; when a definitely-nil producer reaches it, inference marks the site nilable.
func (*StructFieldToContext) Copy ¶
func (s *StructFieldToContext) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this consumer.
func (*StructFieldToContext) Repr ¶
func (s *StructFieldToContext) Repr() fmt.Stringer
Repr returns this StructFieldToContext as a fmt.Stringer.
type StructFieldToContextRepr ¶
type StructFieldToContextRepr struct {
Path string
Kind StructFieldContextKind
Index int
FuncName string
}
StructFieldToContextRepr is the compact encoding of a StructFieldToContext.
func (StructFieldToContextRepr) String ¶
func (s StructFieldToContextRepr) String() string
type TriggerIfDeepNilable ¶
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 ¶
func (t *TriggerIfDeepNilable) Kind() TriggerKind
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) Repr ¶
func (*TriggerIfDeepNilable) Repr() fmt.Stringer
Repr returns a compact string representation.
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 TriggerIfDeepNilableRepr ¶
type TriggerIfDeepNilableRepr struct{}
TriggerIfDeepNilableRepr is a fmt.Stringer storing the needed information to compactly encode a TriggerIfDeepNilable
func (TriggerIfDeepNilableRepr) String ¶
func (TriggerIfDeepNilableRepr) String() 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 ¶
func (t *TriggerIfDeepNonNil) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*TriggerIfDeepNonNil) Kind ¶
func (*TriggerIfDeepNonNil) Kind() TriggerKind
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) Repr ¶
func (t *TriggerIfDeepNonNil) Repr() fmt.Stringer
Repr returns a compact string representation.
func (*TriggerIfDeepNonNil) SetNeedsGuard ¶
func (t *TriggerIfDeepNonNil) SetNeedsGuard(b bool)
SetNeedsGuard sets the underlying Guard-Neediness of this ConsumerTrigger
func (*TriggerIfDeepNonNil) UnderlyingSite ¶
func (t *TriggerIfDeepNonNil) UnderlyingSite() Key
UnderlyingSite the underlying site this trigger's nilability depends on.
type TriggerIfDeepNonNilRepr ¶
type TriggerIfDeepNonNilRepr struct {
AssignmentStr string
}
TriggerIfDeepNonNilRepr is a fmt.Stringer storing the needed information to compactly encode a TriggerIfDeepNonNil
func (TriggerIfDeepNonNilRepr) String ¶
func (t TriggerIfDeepNonNilRepr) String() string
type TriggerIfNilable ¶
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) Repr ¶
func (*TriggerIfNilable) Repr() fmt.Stringer
Repr returns a compact string representation.
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 TriggerIfNilableRepr ¶
type TriggerIfNilableRepr struct{}
TriggerIfNilableRepr is a fmt.Stringer storing the needed information to compactly encode a TriggerIfNilable
func (TriggerIfNilableRepr) String ¶
func (TriggerIfNilableRepr) String() 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 ¶
func (t *TriggerIfNonNil) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
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) Repr ¶
func (t *TriggerIfNonNil) Repr() fmt.Stringer
Repr returns a compact string representation.
func (*TriggerIfNonNil) SetNeedsGuard ¶
func (t *TriggerIfNonNil) SetNeedsGuard(b bool)
SetNeedsGuard sets the underlying Guard-Neediness of this ConsumerTrigger
func (*TriggerIfNonNil) UnderlyingSite ¶
func (t *TriggerIfNonNil) UnderlyingSite() Key
UnderlyingSite the underlying site this trigger's nilability depends on.
type TriggerIfNonNilRepr ¶
type TriggerIfNonNilRepr struct {
AssignmentStr string
}
TriggerIfNonNilRepr is a fmt.Stringer storing the needed information to compactly encode a TriggerIfNonNil
func (TriggerIfNonNilRepr) String ¶
func (t TriggerIfNonNilRepr) 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) Repr ¶
func (*TrustedFuncNilable) Repr() fmt.Stringer
Repr returns a compact string representation.
type TrustedFuncNilableRepr ¶
type TrustedFuncNilableRepr struct{}
TrustedFuncNilableRepr is a fmt.Stringer storing the needed information to compactly encode a TrustedFuncNilable
func (TrustedFuncNilableRepr) String ¶
func (TrustedFuncNilableRepr) String() 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) Repr ¶
func (*TrustedFuncNonnil) Repr() fmt.Stringer
Repr returns a compact string representation.
type TrustedFuncNonnilRepr ¶
type TrustedFuncNonnilRepr struct{}
TrustedFuncNonnilRepr is a fmt.Stringer storing the needed information to compactly encode a TrustedFuncNonnil
func (TrustedFuncNonnilRepr) String ¶
func (TrustedFuncNonnilRepr) String() string
type TypeNameAnnotationKey ¶
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) Repr ¶
func (*UnassignedFld) Repr() fmt.Stringer
Repr returns a compact string representation.
type UnassignedFldRepr ¶
type UnassignedFldRepr struct{}
UnassignedFldRepr is a fmt.Stringer storing the needed information to compactly encode a UnassignedFld
func (UnassignedFldRepr) String ¶
func (UnassignedFldRepr) 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 ¶
func (u *UseAsErrorResult) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*UseAsErrorResult) Repr ¶
func (u *UseAsErrorResult) Repr() fmt.Stringer
Repr returns this UseAsErrorResult as a fmt.Stringer
type UseAsErrorResultRepr ¶
type UseAsErrorResultRepr struct {
Pos int
ReturningFuncStr string
IsNamedReturn bool
RetName string
AssignmentStr string
}
UseAsErrorResultRepr is a fmt.Stringer storing the needed information to compactly encode a UseAsErrorResult
func (UseAsErrorResultRepr) String ¶
func (u UseAsErrorResultRepr) 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 ¶
func (u *UseAsErrorRetWithNilabilityUnknown) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*UseAsErrorRetWithNilabilityUnknown) Repr ¶
func (u *UseAsErrorRetWithNilabilityUnknown) Repr() fmt.Stringer
Repr returns this UseAsErrorRetWithNilabilityUnknown as a fmt.Stringer
type UseAsErrorRetWithNilabilityUnknownRepr ¶
type UseAsErrorRetWithNilabilityUnknownRepr struct {
FuncName string
RetNum int
IsNamedReturn bool
RetName string
AssignmentStr string
}
UseAsErrorRetWithNilabilityUnknownRepr is a fmt.Stringer storing the needed information to compactly encode a UseAsErrorRetWithNilabilityUnknown
func (UseAsErrorRetWithNilabilityUnknownRepr) String ¶
func (u UseAsErrorRetWithNilabilityUnknownRepr) String() 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 ¶
func (u *UseAsFldOfReturn) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*UseAsFldOfReturn) Repr ¶
func (u *UseAsFldOfReturn) Repr() fmt.Stringer
Repr returns this UseAsFldOfReturn as a fmt.Stringer
type UseAsFldOfReturnRepr ¶
type UseAsFldOfReturnRepr struct {
FuncName string
FieldName string
RetNum int
AssignmentStr string
}
UseAsFldOfReturnRepr is a fmt.Stringer storing the needed information to compactly encode a UseAsFldOfReturn
func (UseAsFldOfReturnRepr) String ¶
func (u UseAsFldOfReturnRepr) 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 ¶
func (u *UseAsNonErrorRetDependentOnErrorRetNilability) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*UseAsNonErrorRetDependentOnErrorRetNilability) Repr ¶
func (u *UseAsNonErrorRetDependentOnErrorRetNilability) Repr() fmt.Stringer
Repr returns this UseAsNonErrorRetDependentOnErrorRetNilability as a fmt.Stringer
type UseAsNonErrorRetDependentOnErrorRetNilabilityRepr ¶
type UseAsNonErrorRetDependentOnErrorRetNilabilityRepr struct {
FuncName string
RetNum int
RetName string
ErrRetNum int
IsNamedReturn bool
AssignmentStr string
}
UseAsNonErrorRetDependentOnErrorRetNilabilityRepr is a fmt.Stringer storing the needed information to compactly encode a UseAsNonErrorRetDependentOnErrorRetNilability
func (UseAsNonErrorRetDependentOnErrorRetNilabilityRepr) String ¶
func (u UseAsNonErrorRetDependentOnErrorRetNilabilityRepr) String() string
type UseAsReturn ¶
type UseAsReturn struct {
*TriggerIfNonNil
IsNamedReturn bool
IsTrackingAlwaysSafe 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 ¶
func (u *UseAsReturn) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*UseAsReturn) Repr ¶
func (u *UseAsReturn) Repr() fmt.Stringer
Repr returns this UseAsReturn as a fmt.Stringer
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 ¶
func (u *UseAsReturnDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*UseAsReturnDeep) Repr ¶
func (u *UseAsReturnDeep) Repr() fmt.Stringer
Repr returns this UseAsReturn as a fmt.Stringer
type UseAsReturnDeepRepr ¶
UseAsReturnDeepRepr is a fmt.Stringer storing the needed information to compactly encode a UseAsReturnDeep
func (UseAsReturnDeepRepr) String ¶
func (u UseAsReturnDeepRepr) String() string
type UseAsReturnRepr ¶
type UseAsReturnRepr 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
}
UseAsReturnRepr is a fmt.Stringer storing the needed information to compactly encode a UseAsReturn
func (UseAsReturnRepr) String ¶
func (u UseAsReturnRepr) String() string
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) Repr ¶
func (v *VariadicFuncParam) Repr() fmt.Stringer
Repr returns a compact string representation.
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) Repr ¶
func (v *VariadicFuncParamDeep) Repr() fmt.Stringer
Repr returns this VariadicFuncParamDeep as a fmt.Stringer
type VariadicFuncParamDeepRepr ¶
type VariadicFuncParamDeepRepr struct {
ParamName string
}
VariadicFuncParamDeepRepr is a fmt.Stringer storing the needed information to compactly encode a VariadicFuncParamDeep
func (VariadicFuncParamDeepRepr) String ¶
func (v VariadicFuncParamDeepRepr) String() string
type VariadicFuncParamRepr ¶
type VariadicFuncParamRepr struct {
ParamName string
}
VariadicFuncParamRepr is a fmt.Stringer storing the needed information to compactly encode a VariadicFuncParam
func (VariadicFuncParamRepr) String ¶
func (v VariadicFuncParamRepr) String() 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 ¶
func (v *VariadicParamAssignDeep) Copy() ConsumingAnnotationTrigger
Copy returns a deep copy of this ConsumingAnnotationTrigger
func (*VariadicParamAssignDeep) Repr ¶
func (v *VariadicParamAssignDeep) Repr() fmt.Stringer
Repr returns this VariadicParamAssignDeep as a fmt.Stringer
type VariadicParamAssignDeepRepr ¶
VariadicParamAssignDeepRepr is a fmt.Stringer storing the needed information to compactly encode a VariadicParamAssignDeep
func (VariadicParamAssignDeepRepr) String ¶
func (v VariadicParamAssignDeepRepr) String() string