CQM-RiskyCode¶
Typical fail-safe mechanisms are misused
Required inputs: IR
Motivation
Fail-safe mechanisms such as exception handling
and default paths for switch statements ensure that in the event of unforeseen
events (e.g. different input values), the application notifies the developer
directly of the locations where the anomaly occurred. If these mechanisms are
forgotten (e.g. missing default) or deliberately undermined (e.g.
empty exception handler), possibly necessary changes of the program are concealed
and the system could, under certain circumstances, supply wrong values much later
at completely different locations.
For example, an empty catch block will
cause all exceptions of a particular type to be ignored, regardless of what
actually threw the exceptions. The problem is that assumptions can only be made
about something that can be anticipated. An empty catch block, however, does not
distinguish between foreseen and unforeseen exceptions, but ignores all of them.
Missing default paths can cause the program to enter an undefined state due to
changed input data, which only becomes apparent much later in the program flow.
For safe queries of all possible values e.g. a default: ASSERT(FALSE)
is helpful.
Missing breaks on the other hand cause a special control flow that is indistinguishable from the one where the break was forgotten.
This rule is based on the CQM Quality Indicator: Risikocode (p. 277-280).
Reference
Simon, Frank/ Seng, Olaf/ Mohaupt, Thomas (2006): Code-Quality-Management: Technische Qualität industrieller Softwaresysteme transparent und vergleichbar gemacht, 1st ed., Heidelberg, Germany: dpunkt.verlag GmbH.
Possible Messages
Key |
Text |
Severity |
Disabled |
|---|---|---|---|
catch_all_not_last |
Catch-all shall occur as last handler. |
None |
False |
empty_catch |
Empty catch block. |
None |
False |
empty_default |
Default clause should contain a statement (in addition to break/return) or a comment. |
None |
False |
missing_default |
Switch has no “default” clause. |
None |
False |
unterminated_case |
This switch-case is not {}, last statement is {}. |
None |
False |
unterminated_empty_case |
This switch-case is empty, not {}. |
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
acceptable_end_items¶
acceptable_end_items : set[bauhaus.ir.PIR_Class_Name] = {'Exit_Switch'}
acceptable_middle_items¶
acceptable_middle_items : set[bauhaus.ir.PIR_Class_Name] = {'Exit_Switch', 'Nondefault_Case_Label'}
allow_complete_enum¶
allow_complete_enum : bool = True
allow_empty_blocks_including_comment¶
allow_empty_blocks_including_comment : bool = False
allow_empty_default_case¶
allow_empty_default_case : bool = False
MISRA C:2012 Rule 16.4 requires a comment or statement in addition.
MISRA C++2008 does not.
allow_empty_statements¶
allow_empty_statements : bool = False
allow_fallthrough_comment¶
allow_fallthrough_comment : bool = True
allow_fallthrough_macro¶
allow_fallthrough_macro : bool = True
__fallthrough macro as marker for allowed fallthrough.
allow_if¶
allow_if : bool = False
allow_noreturn_function_calls¶
allow_noreturn_function_calls : bool = False
[[noreturn]] function is considered a
valid termination.
allow_switch¶
allow_switch : bool = False
comment¶
comment : set[str] = set()