================ @@ -0,0 +1,83 @@ +.. title:: clang-tidy - bugprone-exception-rethrow + +bugprone-exception-rethrow +========================== + +Identifies problematic exception rethrowing, especially with caught exception +variables or empty throw statements outside catch blocks. + +In C++ exception handling, a common pitfall occurs when developers rethrow +caught exceptions within catch blocks by directly passing the caught exception +variable to the ``throw`` statement. While this approach can propagate +exceptions to higher levels of the program, it often leads to code that is less +clear and more error-prone. Rethrowing caught exceptions with the same exception +object within catch blocks can obscure the original context of the exception and +make it challenging to trace program flow. Additionally, this method can +introduce issues such as exception object slicing and performance overhead due +to the invocation of the copy constructor. + +.. code-block:: c++ + + try { + // Code that may throw an exception + } catch (const std::exception& e) { + throw e; // Bad, 'e' is copied + } + +.. code-block:: c++ + + class derived_exception : public std::exception { ... }; + + void throwDerived() { throw derived_exception{}; } + + try { + throwDerived(); + } catch (const std::exception& e) { + throw e; // Bad, exception slicing occurs when 'derived_exception' is + // being rethrown as 'std::exception' + } + +To prevent these issues, it is advisable to utilize ``throw;`` statements to +rethrow the original exception object for currently handled exceptions. + +.. code-block:: c++ + + try { + // Code that may throw an exception + } catch (const std::exception&) { + throw; // Good + } + +However, when an empty throw statement is used outside a catch block, it +results in a call to ``std::terminate()``, which abruptly terminates the +application. This behavior can lead to the abnormal termination of the +program and is often unintended. Such occurrences may indicate errors or +oversights in the exception handling logic, and it is essential to avoid empty +throw statements outside catch blocks to prevent unintended program termination. + +.. code-block:: c++ + + void foo() { + // std::terminate will be called because there is no exception to rethrow + throw; + } + + int main() { + try { + foo(); + } catch(...) { + return 1; + } + return 0; + } ---------------- 5chmidti wrote:
I don't think the check should figure out if a dangling `throw` inside a function is actually only called from within a `catch` block, as it is IMO an antipattern that obscures error-handling. Immediately-invoked lambdas might be something to think about though. > it often leads to code that is less clear and more error-prone. Rethrowing caught exceptions with the same exception object within catch blocks can obscure the original context of the exception and make it challenging to trace program flow. https://github.com/llvm/llvm-project/pull/86448 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits