class point¶
A single program point.
The point class corresponds to the PDG_VERTEX abstraction.
Internal representation for points is available for C/C++ and binary analyses only. For C# and Java analyses, plug-ins that rely on point properties and relationships will generally not produce useful information.
point Members¶
point Details¶
-
class
cs.point¶ A single program point.
-
__cmp__(other)¶ Comparison function for
point.Parameters: other ( point) – Thepointobject to compare against.Return type: int Returns: An integer N such that: - N==0 if the two objects compare equal
- N<0 if
self< other - N>0 if
self> other
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooexit = foofn.exit_point() >>> fooout0 = foofn.formal_outs_vector()[0] >>> fooexit <cs.point [exit] foo> >>> fooout0 <cs.point [formal-out] > >>> fooexit.__cmp__(fooout0) -1
-
__eq__(b)¶ Equality operator for
point.Parameters: b ( point) – Thepointto compare against.Return type: bool Returns: Trueifselfandbcompare equal,Falseotherwise.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> fooexit = foofn.exit_point() >>> fooentry == fooexit False
-
__ge__(b)¶ Greater-than-or-equal operator for
point.Parameters: b ( point) – Thepointto compare against.Return type: bool Returns: Trueifself>=b,Falseotherwise.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> fooexit = foofn.exit_point() >>> fooentry >= fooexit False
-
__gt__(b)¶ Greater-than operator for
point.Parameters: b ( point) – Thepointto compare against.Return type: bool Returns: Trueifself>b,Falseotherwise.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> fooexit = foofn.exit_point() >>> fooentry > fooexit False
-
__hash__()¶ Get a hash value for a
point.Return type: int >>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> hash(fooentry) 531434718
-
__le__(b)¶ Less-than-or-equal operator for
point.Parameters: b ( point) – Thepointto compare against.Return type: bool Returns: Trueifself<=b,Falseotherwise.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> fooexit = foofn.exit_point() >>> fooentry <= fooexit True
-
__lt__(b)¶ Less-than operator for
point.Parameters: b ( point) – Thepointto compare against.Return type: bool Returns: Trueifself<b,Falseotherwise.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> fooexit = foofn.exit_point() >>> fooentry < fooexit True
-
__ne__(b)¶ Inequality operator for
point.Parameters: b ( point) – Thepointto compare against.Return type: bool Returns: Falseifselfandbcompare equal,Trueotherwise.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> fooexit = foofn.exit_point() >>> fooentry != fooexit True
-
__repr__()¶ Get a representation of a
pointobject that includes information useful for debugging.Return type: str Returns: The string representation. >>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> repr(fooentry) '<cs.point [entry] foo>'
-
__str__()¶ Get a string representation of a point containing information useful for debugging.
Return type: str Returns: A string containing the representation. Do not modify or free the return value. The return value is only valid until another API function is invoked. >>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooentry = foofn.entry_point() >>> str(fooentry) '[entry] foo'
-
actual_in(_rank)¶ Get the actual-in, having the specified rank, associated with a call site
point.Parameters: _rank (int) – The (1-based) index of the actual-in to retrieve.
Return type: Returns: The actual-in of the specified rank.
Raises: result.ELEMENT_NOT_PRESENTif there is no actual-in whose rank is_rank.result.ERROR_INVALID_ARGUMENTif_rankis 0.result.ERROR_NOT_A_CALL_SITEif the point does not represent a call site.
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actual_in(1) <cs.point [actual-in] $param_1 = 5>
-
actual_out(_rank)¶ Get the actual-out, having the specified rank, associated with a call site
point.Parameters: _rank (int) – The (1-based) index of the actual-out to retrieve.
Return type: Returns: The actual-out of the specified rank.
Raises: result.ELEMENT_NOT_PRESENTif there is no actual-out whose rank is_rank.result.ERROR_INVALID_ARGUMENTif_rankis 0.result.ERROR_NOT_A_CALL_SITEif the point does not represent a call site.
In most languages (including C and C++), only an actual-out of rank 1 can exist. It corresponds to the return value of a function.
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actual_out(1) <cs.point [actual-out] _Z3bariPvi$result3>
-
actual_to_formals()¶ Get the formal-in points associated with an actual-in
point.Return type: Returns: A
point_setcontaining the formal-ins associated with thepoint, if thepointis an actual-in in a call to a defined function.Raises: result.ERROR_NOT_AN_ACTUAL_INif the point is not an actual-in.result.PDG_IS_UNDEFINEDif the call site associated with the point is an undefined function.result.ELEMENT_NOT_PRESENTif there is no call site associated with the point.result.ERROR_NOT_A_CALL_SITEif the call site associated with the point is an indirect call.result.ERROR_SDG_NOT_PRESENT
The modeling of GNU extension
__builtin_applyleads to the possibility that more than one formal can be associated with a given actual. In this case, the returnedpoint_setwill contain several formals.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actual_in(1).actual_to_formals() <cs.point_set {<cs.point [formal-in] >}>
-
actuals_in()¶ Get the actual-in and global-actual-in points associated with a call site
point.Return type: point_setReturns: A point_setcontaining the actual-in and global-actual-in vertices associated with thepoint, provided it represents a call site.Raises: result.ERROR_NOT_A_CALL_SITEif the point does not represent a call site.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actuals_in() <cs.point_set {<cs.point [actual-in] $param_3 = 100 + 5>, <cs.point [actual-in] $param_2 = (void*)&foo>, <cs.point [actual-in] $param_1 = 5>}>
-
actuals_in_as_list()¶ Get the actual-in and global-actual-in points associated with a call site
point.Return type: [ point]Returns: A list of the actual-ins and global-actual-ins associated with the point.Raises: result.ERROR_NOT_A_CALL_SITEif the point does not represent a call site.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actuals_in_as_list() (<cs.point [actual-in] $param_1 = 5>, <cs.point [actual-in] $param_2 = (void*)&foo>, <cs.point [actual-in] $param_3 = 100 + 5>)
-
actuals_out()¶ Get the actual-out and global-actual-out points associated with a call site
point.Return type: point_setReturns: A point_setcontaining the actual-out and global-actual-out point associated with thepoint, provided it represents a call site.Raises: result.ERROR_NOT_A_CALL_SITEif the point does not represent a call site.>>> v0 = project.current() >>> v1 = v0.procedures_vector() >>> v2 = v1[4].call_sites_vector() >>> v2[1].actuals_out_as_list() (<cs.point [actual-out] _Z8mymalloci$result2>,)
-
actuals_out_as_list()¶ Get the actual-out points associated with a call site
point.Return type: [ point]Returns: A list of the actual-outs associated with the point, if it represents a call site.Raises: result.ERROR_NOT_A_CALL_SITEif the point does not represent a call site.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actuals_out_as_list() (<cs.point [actual-out] _Z3bariPvi$result3>,)
-
adjusted_callee()¶ Get the callee
procedureof a call sitepoint, taking into account any translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.Return type: Returns: The point’s callee
procedure.Raises: result.ERROR_INVALID_PHASE_FOR_OPERATIONif called before the beginning of the bottom-up phase.result.ERROR_NOT_A_CALL_SITEif the point is not a call site.result.NO_SUCH_PDGif v is a call site but its calleeprocedurecannot be determined.result.ELEMENT_NOT_PRESENTif the point is a call site with more than one callee procedure. No procedure will be returned in this case: to traverse all callees, use thepoint_adjusted_callees_iteratorreturned bypoint.adjusted_callees().
Redirection resolution is completed in the pointer analysis phase, so this function must be called in the bottom-up phase or later.
A direct call site (that is, a point of kind
point_kind.CALL_SITEwill always have exactly one callee.An indirect call site (a kind
point_kind.INDIRECT_CALL) can have zero or more callees. This function will only successfully retrieve a callee if the analysis identifies exactly one callee.Use the
point_adjusted_callees_iteratorreturned bypoint.adjusted_callees()to iterate over all callees of a point, taking into account translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.adjusted_callee() <cs.procedure bar>
-
adjusted_callee_no_reroute()¶ Get the callee
procedureof a call sitepoint, ignoring any translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.Return type: Returns: The point’s callee
procedure.Raises: result.ERROR_NOT_A_CALL_SITEresult.NO_SUCH_PDGresult.ELEMENT_NOT_PRESENTif the point is a call site with more than one callee procedure. No procedure will be returned in this case: to traverse all callees, use thepoint_adjusted_callees_no_reroute_iteratorreturned bypoint.adjusted_callees_no_reroute().
A direct call site (that is, a point of kind
point_kind.CALL_SITEwill always have exactly one callee.An indirect call site (a kind
point_kind.INDIRECT_CALL) can have zero or more callees. This function will only successfully retrieve a callee if the analysis identifies exactly one callee. Indirect call resolution takes place in the pointer analysis phase, so results for indirect call sites will be best if this function is called in the bottom-up phase or later.Use the
point_adjusted_callees_no_reroute_iteratorreturned bypoint.adjusted_callees_no_reroute()to iterate over all callees of a point, ignoring translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.adjusted_callee_no_reroute() <cs.procedure bar>
-
adjusted_callees()¶ Get an iterator over the callee procedures (
procedure) from a point, taking into account any translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.Return type: point_adjusted_callees_iteratorReturns: The initialized point_adjusted_callees_iterator.A direct call site (that is, a
pointof kindpoint_kind.CALL_SITE) will always have exactly one callee. As an alternative to setting up an iterator, you can usepoint.adjusted_callee()to retrieve the callee, taking into account any translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.An indirect call site (
pointof kindpoint_kind.INDIRECT_CALL) can have zero or more callees.>>> cu = next(c for c in project.current().compunits() ... if c.name().endswith('apitest.cpp')) >>> proc = next(p for p in cu.procedures() if p.name()=='bar') >>> cs = next(pt for pt in proc.call_sites() ... if pt.callee().name()=='mymalloc') >>> for callee in cs.adjusted_callees(): # iteration managed by point_adjusted_callees_iterator.__iter__() ... # and point_adjusted_callees_iterator.__next__() ... print(callee.name()) ... mymalloc
-
adjusted_callees_no_reroute()¶ Get an iterator over the callee procedures (
procedure) from a point, ignoring any translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.Return type: point_adjusted_callees_no_reroute_iteratorReturns: The initialized point_adjusted_callees_no_reroute_iterator.A direct call site (that is, a
pointof kindpoint_kind.CALL_SITE) will always have exactly one callee. As an alternative to setting up an iterator, you can usepoint.adjusted_callee_no_reroute()to retrieve the callee, ignoring any translations incurred bycsonar_replace_*()calls and the FUNCTION_MAP configuration file variable.An indirect call site (
pointof kindpoint_kind.INDIRECT_CALL) can have zero or more callees.>>> cu = next(c for c in project.current().compunits() ... if c.name().endswith('apitest.cpp')) >>> proc = next(p for p in cu.procedures() if p.name()=='bar') >>> cs = next(pt for pt in proc.call_sites() ... if pt.callee().name()=='mymalloc') >>> for callee in cs.adjusted_callees_no_reroute(): # iteration managed by point_adjusted_callees_no_reroute_iterator.__iter__() ... # and point_adjusted_callees_no_reroute_iterator.__next__() ... print(callee.name()) ... mymalloc
-
call_site()¶ Get the call site of a subordinate
point.Return type: pointReturns: The corresponding call site point.Raises: result.ELEMENT_NOT_PRESENTif no corresponding call site exists: either the point is not of an a suitable kind, or it is an indirect-call with no corresponding call site.A subordinate
pointis one whose kind is one of the following.point_kind.GLOBAL_ACTUAL_INpoint_kind.GLOBAL_ACTUAL_OUTpoint_kind.ACTUAL_INpoint_kind.ACTUAL_OUTpoint_kind.INDIRECT_CALLpoint_kind.NORMAL_RETURNpoint_kind.EXCPT_RETURN
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> ao0 = foocs0.actuals_out_as_list()[0] >>> ao0 <cs.point [actual-out] _Z3bariPvi$result3> >>> ao0.call_site() <cs.point [call-site] bar(int, void *, int)> >>> ao0.call_site() == foocs0 True
-
callee()¶ Get the callee procedure associated with a call-site
point.Return type: Returns: The callee
procedure.Raises: result.ERROR_NOT_A_CALL_SITEif the point does not represent a call site.result.ELEMENT_NOT_PRESENTif the point represents a call site, but there is no associated callee.result.ERROR_SDG_NOT_PRESENTif no project is loaded.
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.callee() <cs.procedure bar>
-
cfg_inter_targets()¶ Get the inter-procedural successors of a
point.Return type: Returns: A
cfg_edge_setcontaining the inter-procedural successor edges from thepoint.Raises: result.ERROR_NO_DEPENDENCES[CodeSonar only] if the kind ofselfis one ofpoint_kind.EXIT,point_kind.CALL_SITE,point_kind.INDIRECT_CALL,point_kind.ACTUAL_IN. This affects only CodeSonar: CodeSurfer retains more dependence information.result.ERROR_SDG_NOT_PRESENTif no project is loaded.
See CFG Edges for more information.
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actual_out(1) <cs.point [actual-out] _Z3bariPvi$result3> >>> foocs0.actual_out(1).cfg_inter_targets() <cs.cfg_edge_set {}>
-
cfg_targets()¶ Get the intra-procedural successors of a
point.Return type: cfg_edge_setReturns: A cfg_edge_setcontaining the intra-procedural successor edges from thepoint.Raises: result.ERROR_SDG_NOT_PRESENTif no project is loaded.See CFG Edges for more information.
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.actual_out(1) <cs.point [actual-out] _Z3bariPvi$result3> >>> foocs0.actual_out(1).cfg_targets() <cs.cfg_edge_set {(<cs.point [expression] a = _Z3bariPvi$result3>, <cs.edge_label T>)}>
-
characters([limit = SIZE_MAX])¶ Get a string representation of a
point.Parameters: limit (int) – (optional) The maximum length of the retrieved representation. Specify SIZE_MAXfor no limit.Return type: str Returns: The string formed by concatenating all characters in the relevant source file that are associated with the point. Raises: result.ELEMENT_NOT_PRESENTif there is no position information associated with thepoint.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.characters(2) 'ba'
>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.characters() 'bar()'
-
charpos()¶ Get the character positions (in the source code) for a
point.Return type: ( sfileinst,int_pair_set)Returns: The ( sfileinst,int_pair_set) representing thepoint‘s character positions.Raises: result.NO_POSITIONifselfdoes not have a position in any file in the project>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> foocs0 = foofn.call_sites_vector()[0] >>> foocs0.charpos() (<cs.sfileinst C:\alex\test\apitest.cpp>, <cs.int_pair_set {(571, 3), (595, 0)}>)
-
condition_number()¶ [CodeSonar only] Get the condition number of a
point.Return type: int Returns: The condition number, or 0 on failure. Each group of points in the same conditional will share the same condition number. The value has no meaning, beyond grouping vertices by conditional. A conditional is defined as the predicate of one if statement or loop. Multiple vertices can arise from one conditional because normalizations decompose a single if statement into many vertices in the presence of language features such as short-circuiting connectives.
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> p = next(pt for pt in barfn.points() if pt.get_kind() == point_kind.CONTROL_POINT) >>> p.condition_number() 1
-
csonar_enum_killed()¶ Get the list of killed symbols (
symbol) for apoint, computing the list on-demand.Return type: [ symbol]Returns: The killed symbols for the point. The list is generated on-demand and will be recomputed if the method is called again on the same point.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barexps = [p for p in barfn.points() if p.get_kind() == point_kind.EXPRESSION] >>> for p in barexps: ... print(str(p).ljust(40), p.csonar_enum_killed()) ... [expression] $temp3 = i (<cs.symbol $temp3>,) [expression] i = i + 1 (<cs.symbol i>,) [expression] i = $temp3 (<cs.symbol i>,) [expression] x = _Z3bariPvi$result1 (<cs.symbol x>,) [expression] p = _Z8mymalloci$result2 (<cs.symbol p>,) [expression] *p = x () [expression] $temp4 = i + 1 (<cs.symbol $temp4>,) [expression] _Z3bariPvi$return = $temp4 (<cs.symbol bar(int, void *, int)$return>,) [expression] i = 25 (<cs.symbol i>,) [expression] i = 23 (<cs.symbol i>,) [expression] i = 21 (<cs.symbol i>,) [expression] i = 19 (<cs.symbol i>,) [expression] $temp2 = i (<cs.symbol $temp2>,)
-
csonar_enum_referenced()¶ Get the list of referenced symbols (
symbol) for apoint, computing the list on-demand.Return type: [ symbol]Returns: The referenced symbols for the point. The list is generated on-demand and will be recomputed if the method is called again on the same point.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barexps = [p for p in barfn.points() if p.get_kind() == point_kind.EXPRESSION] >>> for p in barexps: ... print(str(p).ljust(40), p.csonar_enum_referenced()) ... [expression] $temp3 = i (<cs.symbol $temp3>, <cs.symbol i>) [expression] i = i + 1 (<cs.symbol i>, <cs.symbol i>) [expression] i = $temp3 (<cs.symbol i>, <cs.symbol $temp3>) [expression] x = _Z3bariPvi$result1 (<cs.symbol x>, <cs.symbol bar(int, void *, int)$result1>) [expression] p = _Z8mymalloci$result2 (<cs.symbol p>, <cs.symbol mymalloc(int)$result2>) [expression] *p = x (<cs.symbol p>, <cs.symbol x>) [expression] $temp4 = i + 1 (<cs.symbol $temp4>, <cs.symbol i>) [expression] _Z3bariPvi$return = $temp4 (<cs.symbol bar(int, void *, int)$return>, <cs.symbol $temp4>) [expression] i = 25 (<cs.symbol i>,) [expression] i = 23 (<cs.symbol i>,) [expression] i = 21 (<cs.symbol i>,) [expression] i = 19 (<cs.symbol i>,) [expression] $temp2 = i (<cs.symbol $temp2>, <cs.symbol i>)
-
csonar_enum_used()¶ Get the list of used symbols (
symbol) for apoint, computing the list on-demand.Return type: [ symbol]Returns: The used symbols for the point. The list is generated on-demand and will be recomputed if the method is called again on the same point.>>> cu = next(c for c in project.current().compunits() ... if c.name().endswith('apitest.cpp')) >>> proc = next(p for p in cu.procedures() if p.name()=='bar') >>> pt = next(p for p in proc.points() ... if p.get_kind()==point_kind.EXPRESSION ... and p.get_ast()[1].get_class()==ast_class.NC_POINTEREXPR) >>> print(pt) [expression] *p = x >>> pt_used = symbol_set(pt.csonar_enum_used()) >>> for sym in pt_used: # iteration managed by symbol_set.__iter__() ... # and symbol_set_iterator.__next__() ... print(sym.file_line(), sym.name()) ... (<cs.sfileinst C:\alex\test\apitest.cpp>, 14) x (<cs.sfileinst C:\alex\test\apitest.cpp>, 15) p
-
file_line()¶ Get the file instance and (smallest offset) line for a
point.Return type: ( sfileinst, int)Returns: The source file instance containing the point, and the (smallest offset) line on which thepointoccurs in that source file instance.Raises: result.NO_POSITIONif the point does not have a position in any file instance in the project.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barexit = barfn.exit_point() >>> barexit.file_line() (<cs.sfileinst C:\alex\test\apitest.cpp>, 29)
-
get_ast([fam = ast_family.DEFAULT])¶ Get the AST associated with a
point.Parameters: fam (
ast_family) – (optional) Points may be associated with multiple ASTs. This specifies which one to get.Return type: Returns: The
astofast_familyfamthat is associated with thepoint.Raises: result.ELEMENT_NOT_PRESENTif the point does not have an associated AST of familyfam. This includes the case where the project was not built to include ASTs of familyfam, and the case wherefamisast_family.C_UNNORMALIZEDresult.ERROR_INVALID_ARGUMENTresult.ERROR_SDG_NOT_PRESENTif no project is loaded
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barcs0 = barfn.call_sites_vector()[0] >>> barcs0.get_ast(ast_family.C_NORMALIZED) <cs.ast [c:call] bar()>
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barfo0 = barfn.formal_outs_vector()[0] >>> barfo0.get_ast() <cs.ast [c:variable] _Z3bariPvi$return>
-
get_id()¶ Get a
point‘s unique identifier.Return type: int Returns: The unique identifier. - Identifiers are unique within a
procedure. - In an incremental analysis where the containing compilation unit is not recompiled, a
pointwill have the same identifier that it did in the incremental parent. - In all other cases do not persist between different analyses of the same project (or the same code in a different project).
To get a point given its ID, use
procedure.retrieve_point().>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barcs0 = barfn.call_sites_vector()[0] >>> barcs0.get_id() 16
- Identifiers are unique within a
-
get_kind()¶ Get a
point‘s kind.Return type: point_kindReturns: The kind, as a point_kind.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barcs0 = barfn.call_sites_vector()[0] >>> barcs0.get_kind() <cs.point_kind call-site>
-
get_procedure()¶ Get the procedure containing a
point.Return type: procedureReturns: The point‘s containingprocedure.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barcs0 = barfn.call_sites_vector()[0] >>> barcs0.get_procedure() <cs.procedure bar>
-
get_syntax_element()¶ Get a
point‘s syntax element.Return type: point_syntax_elementReturns: The point‘s syntax element, as apoint_syntax_element.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> ctrl = next(p for p in barfn.points() if p.get_kind() == point_kind.CONTROL_POINT) >>> ctrl <cs.point [control-point] i == 0> >>> ctrl.get_syntax_element() <cs.point_syntax_element cond>
-
get_syntax_kind()¶ Get a
point‘s syntax kind.Return type: point_syntax_kindReturns: The syntax kind, as a point_syntax_kind.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> ctrl = next(p for p in barfn.points() if p.get_kind() == point_kind.CONTROL_POINT) >>> ctrl <cs.point [control-point] i == 0> >>> ctrl.get_syntax_kind() <cs.point_syntax_kind if>
-
handle()¶ Get a handle for this
point.Return type: str Returns: The point’s handle. Use this function to retrieve a handle to the
pointwhich can be stored externally and used withproject.lookup_point_handle()to retrieve thepointwhen needed. This handle is valid only for the analysis it was generated from. If you rebuild the project, the handle will no longer be valid.A handle is a string consisting of letters (upper and lower case) and numbers, and could also include the following characters: “+”, “=”, and “_”.
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> ctrl = next(p for p in barfn.points() if p.get_kind() == point_kind.CONTROL_POINT) >>> ctrl.handle() 'goCAgAILGA=='
-
has_ast([fam = ast_family.DEFAULT])¶ Check: does a point have an associated AST (
ast) of the specified family (ast_family)?Parameters: fam ( ast_family) – (optional) Points may be associated with multiple ASTs. This specifies which one to check for. Each language dependent AST header file will define its AST families.Return type: bool Returns: Trueif the point has an associated AST whose family isfam,Falseotherwise.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> ctrl = next(p for p in barfn.points() if p.get_kind() == point_kind.CONTROL_POINT) >>> ctrl.has_ast(ast_family.C_NORMALIZED) True >>> ctrl.has_ast(ast_family.C_UNNORMALIZED) False
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> ctrl = next(p for p in barfn.points() if p.get_kind() == point_kind.CONTROL_POINT) >>> ctrl.has_ast() True
-
is_implicit_actual_in()¶ Check: is a
pointan actual-in that is implicitly generated?Return type: bool Returns: Trueif called on apointthat is an actual-in and is implicit.FalseotherwiseAn implicit actual-in can occur in C++ code where the callee returns a non-trivial C++ object. For example:
std::string s = std::to_string(1);
will have two actual-ins, where the first is implicit:
[actual-in] $param_1 = &s [actual-in] $param_2 = 1
Note that default arguments are not considered implicit, despite also not being being written at the call site.
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> for cs in barfn.call_sites(): ... print(cs) ... for ai in cs.actuals_in(): ... print(' ', str(ai).ljust(32), ai.is_implicit_actual_in()) ... [call-site] bar(int, void *, int) [actual-in] $param_3 = 2 False [actual-in] $param_2 = (void*)0 False [actual-in] $param_1 = (int)1.5 False [call-site] mymalloc(int) [actual-in] $param_1 = 10 False
-
is_inside_macro()¶ Check: is a
pointentirely contained inside a macro?Return type: bool Returns: Trueif called on apointthat lies entirely inside a C or C++ macro expansion.Falseotherwise, including the case where only part of thepointis inside a macro expansion.This function will return
Falseif called on apointfor which only only part is inside a macro expansion, such as thepointcorresponding to the assignment “p = NULL”.>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barcs0 = barfn.call_sites_vector()[0] >>> barcs0.is_inside_macro() False
-
rank()¶ Get the rank of a
point.Return type: int Returns: The rank, as a size_t. Raises: result.VERTEX_HAS_NO_RANKif the point is not a {formal,actual}-{in,out} or global-{formal,actual}-{in,out}: these are the only points that have rank.Rank starts at 1, with globals coming first, followed by non-globals. For non-globals, rank shows the order they appear in the source.
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> for fi in barfn.formal_ins(): ... print(fi.csonar_enum_referenced(), fi.rank()) ... (<cs.symbol i>, <cs.symbol $param_1>) 1 (<cs.symbol j>, <cs.symbol $param_2>) 2 (<cs.symbol k>, <cs.symbol $param_3>) 3
-
solitary_cfg_target()¶ Get the CFG successor of a
pointthat has exactly one successor CFG edge.Return type: Returns: The single CFG successor.
Raises: result.PDG_VERTEX_HAS_ZERO_OR_MULTIPLE_SUCCESSORSif the point does not have exactly one successor CFG edge (this includes the case where it has one CFG successor but multiple CFG edges to that successor).result.ERROR_SDG_NOT_PRESENT
See CFG Edges for more information.
>>> barfn = next(f for f in project.current().procedures() if f.name()=='bar') >>> barentry = barfn.entry_point() >>> barentry.solitary_cfg_target() <cs.point [control-point] i == 0>
-
source_pp()¶ [CodeSonar only] Get a string containing a pretty printed version of an actual-in, expression, call-site, or control-point
point.Return type: str
Returns: The string representation.
Raises: result.ERROR_INVALID_ARGUMENTif called on a point that is not an actual-in, expression, call-site, or control-point.result.ELEMENT_NOT_PRESENTif the point does not have the necessary information associated with it.
>>> for csite in project.current().find_procedure('foo').call_sites(): ... print(csite.source_pp()) ... bar(5, (void *)foo, 100 + 5) bar(5, (void *)foo, 100 + 5) mymalloc(20) bar(5, (void *)foo, 100 + 5)
-
stable_cmp(other)¶ Compare with another
point, with stable results across sufficiently-similar analyses.Parameters: other ( point) – The point to compare against.Return type: int Returns: An integer N, such that: - N<0 if
selfconsidered less thanother - N==0 if
selfandotherare the same object - N>0 if
selfconsidered greater thanother
The comparison is stable in the following sense. Suppose there are two analyses A1 and A2 generated with exactly the same inputs (including identical analyzed code, underlying build commands and ordering, command line and configuration settings, increment order and contents). Let a1 and b1 be two
pointobjects in A1, and a2 and b2 be thepointobjects in A2 that correspond to a1 and b1 respectively. Then a1.stable_cmp(b1)==a2.stable_cmp(b2).If you don’t need comparison relationships to be stable across analyses, use
point.__cmp__(): it has better performance.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooexit = foofn.exit_point() >>> fooout0 = foofn.formal_outs_vector()[0] >>> fooexit <cs.point [exit] foo> >>> fooout0 <cs.point [formal-out] > >>> fooexit.stable_cmp(fooout0) -1
- N<0 if
-
stable_hash()¶ Get a hash value for a point, with stable results across sufficiently-similar analyses.
Return type: int Returns: The computed hash value. This hash value is stable in the following sense. Suppose there are two analyses A1 and A2 generated with exactly the same inputs (including identical analyzed code, underlying build commands and ordering, command line and configuration settings, increment order and contents). Let v1 be a
pointobject in A1, and v2 be thepointobject in A2 that corresponds to v1. Then v1.stable_hash()==v2.stable_hash().If you don’t need hash values to be stable across analyses, use
point.__hash__(): it has better performance.>>> foofn = next(f for f in project.current().procedures() if f.name()=='foo') >>> fooexit = foofn.exit_point() >>> fooexit <cs.point [exit] foo> >>> fooexit.stable_hash() 1623397462
-