CodingStyle-StrongTypeViolations¶
At assignment sites, the strong types of left and right side should match
Required inputs: IR
The rule allows to select the typedefs that should be seen as strong, and it allows to limit the operations (like assignment sites, comparison sites etc.) that should be checked. Both is done with the parameter checks which is an ordered dictionary of entries that provide typedef names (as globbing patterns) and the checks to perform for these typedefs.
The checks to be done are chosen from the below list as provided in module
strong_types. They can be freely combined with Python operations to create
iterables (e.g. lists or sets). The default setup only configures ('*', strong_types.all_checks),which means that all typedefs (globbing pattern
*) should be seen as
strong, and being checked with all checks.
An example custom configuration could be
checks = collections.OrderedDict([
('MY_INT', set(strong_types.all_checks) - set(strong_types.all_extracts)),
('Other*', strong_types.all_assignments),
])
In this case the typedef MY_INT would be assumed to be strong,
and all checks except those at extracting operations would be applied.
Also, all typedefs having a name that matches Other* would be strong and
checked at assignments.The following list summarizes the available predefined elementary checks (from module strong_types) as well as predefined groups of such checks which simplify typical selections of similar operations:
- Assignments to strong types (lint: A flag with modifiers)
- all_assignments = [assignment_lhs, field_init_lhs, init_lhs, return_lhs, param_lhs]
The elementary checks like assignment_lhs each cover a certain kind of assignment (assignment operator, field initialization, variable initialization, return statement, parameter passing). This includes the below special categories with non-zero/const right-hand side - all_nonzero_assignments = [nonzero_assignment_lhs, nonzero_field_init_lhs, nonzero_init_lhs, nonzero_return_lhs, nonzero_param_lhs]
This checks assignments to a strong type except where the assigned value is literally given as 0 - all_nonconst_assignments = [nonconst_assignment_lhs, nonconst_field_init_lhs, nonconst_init_lhs, nonconst_return_lhs, nonconst_param_lhs]
This checks assignments to a strong type except where the assigned value is an integer constant expression, string literal, or address of a stack or global object
- all_assignments = [assignment_lhs, field_init_lhs, init_lhs, return_lhs, param_lhs]
- Assignments from strong types (extracts, lint: X flag with modifiers)
all_extracts = [assignment_rhs, field_init_rhs, init_rhs, return_rhs, param_rhs] - Use of strong types as operand in binary/ternary operators (joins, lint: J flag with modifiers)
- all_joins = [conditional, equality, relational, multiplicative, additive, bitwise] The elementary checks cover the conditional operator (?:), (in)equality comparisons, relational comparisons, multiplicative operators, additive operators, and bitwise operators. This includes the below special categories with non-zero/const right-hand side
- all_nonzero_joins = [nonzero_conditional, nonzero_equality, nonzero_relational, nonzero_multiplicative, nonzero_additive, nonzero_bitwise] This checks uses of strong types as operand in binary/ternary operators except where the assigned value is literally given as 0
- all_nonconst_joins = [nonconst_conditional, nonconst_equality, nonconst_relational, nonconst_multiplicative, nonconst_additive, nonconst_bitwise] This checks uses of strong types as operand in binary/ternary operators except where the assigned value is an integer constant expression, string literal, or address of a stack or global object
- Operands that should be boolean (similar to lint: B flag)
all_bools = [binary_logical, unary_logical] The elementary checks inspect logical operators and check that the operands are of boolean type (native bool, if present in the language, and those configured via /Analysis/types.user_bool_types)
Notice that Misra checks exist as well to check for proper use of bool. - Combination of all checks
all_checks = all_assignments + all_extracts + all_joins + all_bools
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
arithmetic_strong_type_violation |
Mismatched operand type in arithmetic operator causes implicit strong type conversion from {} to {} |
None |
False |
assignment_strong_type_violation |
Assignment causes implicit strong type conversion from {} to {} |
None |
False |
bitwise_strong_type_violation |
Mismatched operand type in bitwise operator causes implicit strong type conversion from {} to {} |
None |
False |
comparison_strong_type_violation |
Comparison causes implicit strong type conversion from {} to {} |
None |
False |
conditional_strong_type_violation |
Mismatched operand type in conditional operator causes implicit strong type conversion from {} to {} |
None |
False |
field_init_strong_type_violation |
Field initialization causes implicit strong type conversion from {} to {} |
None |
False |
init_strong_type_violation |
Initialization of {} causes implicit strong type conversion from {} to {} |
None |
False |
logical_strong_type_violation |
Mismatched operand type in logical operator causes implicit strong type conversion from {} to {} |
None |
False |
parameter_strong_type_violation |
Passing {} as argument for parameter {} causes implicit strong type conversion from {} to {} |
None |
False |
return_strong_type_violation |
Return statement causes implicit strong type conversion from {} to {} |
None |
False |
switch_strong_type_violation |
Switch case causes implicit strong type conversion from {} to {} |
None |
False |
Options¶
This rule shares the following common options: exclude_in_macros, exclude_messages_in_system_headers, excludes, extend_exclude_to_macro_invocations, includes, justification_checker, languages, post_processing, provider, report_at, severity
The following places define options that affect this rule: Stylechecks, Analysis-GlobalOptions
checks¶
checks
Configuration of checks to apply. This maps globbing patterns for the (qualified) typedef names to a list of checks, using an ordered dict to retain the order (last matching entry for a typedef wins). The checks are functions from moduleType: dict[str, list[typing.Callable[[typing.Union[bauhaus.ir.common.expressions.assignments.AssignmentSite, Expression], bool, typing.Union[Physical_IR_Root, bauhaus.ir.NoNode[Physical_IR_Root]], bauhaus.ir.common.types.strong_types.StrongType], bool]]]
Default:
{ '*': [<function bauhaus.ir.common.types.strong_types.assignment_lhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.field_init_lhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.init_lhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.return_lhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.param_lhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.assignment_rhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.field_init_rhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.init_rhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.return_rhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.param_rhs(site: 'Check_Site', is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.conditional(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.equality(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.relational(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.multiplicative(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.additive(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.bitwise(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.binary_logical(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>, <function bauhaus.ir.common.types.strong_types.unary_logical(site: 'Check_Site', _is_lhs: 'bool', _other: 'Check_RHS', _other_type: 'StrongType') -> 'bool'>] }
strong_types, or your own predicates that should take
(site, is_lhs, rhs) as arguments.
dimensions¶
dimensions : dict[str, str] = {}
'Meter' : '', 'Area' : 'Meter*Meter'would declare the strong types
Meter and Area to be
dimensions, and the formula allows assigning the product of two variables of type
Meter to a variable of type Area.