The C++ 2004, section 15.3 "Handling an Exception", saysStandard, [except.handle], paragraph 4 [ISO/IEC 14882-2014], states the following:
The handlers for a try block are tried in order of appearance. That makes it possible to write handlers that can that can never be executed, for example by placing a handler for a derived class after a handler for a corresponding base corresponding base class.
A ... in a handlers exception-declaration functions similarly to ... in a function parameter declaration; it specifies a match for any exception. If present, a ... handler shall be the last handler for its try block.
Consequently Consequently, if two handlers catch exceptions that are derived from the same base class (such as std::exception), the most derived exception should must come first.
...
Noncompliant Code Example
In this non-compliant noncompliant code example, the first handler will catch catches all exceptions of class B, as well as exceptions of class D, since they are also of class B. Consequently, the second handler will does not catch any exceptions.
| Code Block | ||||
|---|---|---|---|---|
| ||||
// classesClasses used for exception handling class B {}; class D : public B {}; // ... Using the classes from above void f() { try { // ... } catch (B &b) { // ... } catch (D &d) { // ... } } |
Compliant Solution
In this compliant solution, the first handler will catch catches all exceptions of class D, and the second handler will catch catches all the other exceptions of class B.
| Code Block | ||||
|---|---|---|---|---|
| ||||
// classesClasses used for exception handling class B {}; class D : public B {}; // ... Using the classes from above void f() { try { // ... } catch (D &d) { // ... } catch (B &b) { // ... } } |
Risk Assessment
Badly ordering exception handlers can Exception handlers with inverted priorities cause unexpected control flow when an exception of the derived type occurs.
Rule | Severity | Likelihood | Detectable |
|---|
Repairable | Priority | Level |
|---|
ERR54-CPP | Medium |
Likely |
Yes |
Yes |
P18 | L1 |
Automated Detection
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Astrée |
| exception-caught-by-earlier-handler | Fully checked | ||||||
| Axivion Bauhaus Suite |
| CertC++-ERR54 | |||||||
| Clang |
| -Wexceptions | |||||||
| CodeSonar |
| LANG.STRUCT.UCTCH | Masked by handler | ||||||
| CP1.ERR36 | Fully implemented |
Bibliography
...
| Helix QAC |
| C++4030, C++4639 | |||||||
| Klocwork |
| MISRA.CATCH.NOALL MISRA.CATCH.WRONGORD | |||||||
| LDRA tool suite |
| 541 S, 556 S | Fully implemented | ||||||
| Parasoft C/C++test |
| CERT_CPP-ERR54-a | Where multiple handlers are provided in a single try-catch statement or function-try-block for a derived class and some or all of its bases, the handlers shall be ordered most-derived to base class | ||||||
| Polyspace Bug Finder |
| CERT C++: ERR54-CPP | Checks for:
Rule fully covered. | ||||||
| PVS-Studio |
| V759 | |||||||
| RuleChecker |
| exception-caught-by-earlier-handler | Fully checked | ||||||
| SonarQube C/C++ Plugin |
| S1045 |
Related Vulnerabilities
Search for other vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
| [MISRA 08] | Rule 15-3-6 (Required) |
Bibliography
| [ISO/IEC 14882-2014] | Subclause 15.3, "Handling an Exception" |
...