Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r16-7206-gb5d5cab8e4b807.
gcc/analyzer/ChangeLog:
PR analyzer/123880
* engine.cc (throw_custom_edge::update_model): Gracefully handle
not knowing the current exception in a rethrow.
(exploded_node::on_throw): Likewise.
gcc/testsuite/ChangeLog:
PR analyzer/123880
* g++.dg/analyzer/exception-rethrow-3.C: New test.
Signed-off-by: David Malcolm <[email protected]>
---
gcc/analyzer/engine.cc | 22 +++++++--
.../g++.dg/analyzer/exception-rethrow-3.C | 46 +++++++++++++++++++
2 files changed, 63 insertions(+), 5 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/analyzer/exception-rethrow-3.C
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 2d22abf05303..8dc9a8b78ce3 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1575,9 +1575,14 @@ public:
{
if (m_is_rethrow)
{
- auto eh_node = model->get_current_caught_exception ();
- gcc_assert (eh_node);
- model->push_thrown_exception (*eh_node);
+ if (auto eh_node = model->get_current_caught_exception ())
+ model->push_thrown_exception (*eh_node);
+ else
+ {
+ /* We have a rethrow of some unknown exception.
+ We don't have a good way of representing this;
+ leave the exception stack empty. */
+ }
}
else
{
@@ -1811,8 +1816,15 @@ exploded_node::on_throw (exploded_graph &eg,
if (is_rethrow)
{
const exception_node *eh_node = model->get_current_caught_exception ();
- gcc_assert (eh_node);
- type = eh_node->maybe_get_type ();
+ if (eh_node)
+ type = eh_node->maybe_get_type ();
+ else
+ {
+ /* We have a "throw;" but no exception to rethrow.
+ Presumably the top-level of the analysis is an
+ entrypoint for handling exceptions, so we will
+ simulate fully unwinding. */
+ }
}
else
{
diff --git a/gcc/testsuite/g++.dg/analyzer/exception-rethrow-3.C
b/gcc/testsuite/g++.dg/analyzer/exception-rethrow-3.C
new file mode 100644
index 000000000000..652020c705b3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/analyzer/exception-rethrow-3.C
@@ -0,0 +1,46 @@
+#include "../../gcc.dg/analyzer/analyzer-decls.h"
+
+/* Top-level rethrow (PR analyzer/123880). */
+
+void test_1 ()
+{
+ throw;
+}
+
+/* Intraprocedural leak involving a rethrow. */
+
+void test_2 ()
+{
+ void *p = __builtin_malloc (1024);
+ throw; // { dg-warning "leak of 'p'" }
+ // { dg-message "rethrowing exception here\.\.\." "rethrow event" { target
*-*-* } .-1 }
+}
+
+/* Interprocedural leak involving a rethrow. */
+
+static void called_by_test_3 ()
+{
+ throw; // { dg-warning "leak of 'p'" }
+ // { dg-message "rethrowing exception here\.\.\." "rethrow event" { target
*-*-* } .-1 }
+}
+
+void test_3 ()
+{
+ void *p = __builtin_malloc (1024); // { dg-message "allocated here" }
+ called_by_test_3 ();
+}
+
+/* Rethrow of a rethrow. */
+
+void test_4 ()
+{
+ try
+ {
+ throw;
+ }
+ catch (...)
+ {
+ __analyzer_dump_path (); // { dg-message "path" "" { xfail *-*-* } }
+ throw;
+ }
+}
--
2.26.3