The C++ Standard, [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 never be executed, for example by placing a handler for a derived class after a handler for a corresponding base class.

Consequently, if two handlers catch exceptions that are derived from the same base class (such as std::exception), the most derived exception must come first.

Noncompliant Code Example

In this noncompliant code example, the first handler catches all exceptions of class B, as well as exceptions of class D, since they are also of class B. Consequently, the second handler does not catch any exceptions.

// Classes used for exception handling
class B {};
class D : public B {};

void f() {
  try {
    // ...
  } catch (B &b) {
    // ...
  } catch (D &d) {
    // ...
  }
}

Compliant Solution

In this compliant solution, the first handler catches all exceptions of class D, and the second handler catches all the other exceptions of class B.

// Classes used for exception handling
class B {};
class D : public B {};

void f() {
  try {
    // ...
  } catch (D &d) {
    // ...
  } catch (B &b) {
    // ...
  }
}

Risk Assessment

Exception handlers with inverted priorities cause unexpected control flow when an exception of the derived type occurs.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR54-CPP

Medium

Likely

Low

P18

L1

Automated Detection

Tool

Version

Checker

Description

Astrée

22.10

exception-caught-by-earlier-handler
Fully checked
Axivion Bauhaus Suite

7.2.0

CertC++-ERR54
Clang
3.9
-Wexceptions
CodeSonar
8.1p0

LANG.STRUCT.UCTCH

Unreachable Catch

ECLAIR

1.2

CP1.ERR36

Fully implemented

Helix QAC

2024.1

C++4030, C++4639
Klocwork
2024.1
MISRA.CATCH.NOALL
MISRA.CATCH.WRONGORD 

LDRA tool suite
9.7.1

 

541 S, 556 S

Fully implemented

Parasoft C/C++test
2023.1
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

R2023b

CERT C++: ERR54-CPP

Checks for:

  • Exception handlers not ordered from most-derived to base class
  • Incorrect order of ellipsis handler

Rule fully covered.

PVS-Studio

7.30

V759
RuleChecker
22.10
exception-caught-by-earlier-handler
Fully checked
SonarQube C/C++ Plugin
4.10
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)
Rule 15-3-7 (Required)

Bibliography

[ISO/IEC 14882-2014]Subclause 15.3, "Handling an Exception"