From 2a656ff47a2df9f42f3c31e3cbaf6f01aacf317d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 14 Mar 2019 16:13:50 -0400
Subject: [PATCH 109/217] FIXME: handle wrappers around 'abort', add test
 coverage for noreturn attrs

---
 gcc/analyzer/engine.cc                             | 11 ++++++
 .../TODO-analyzer/facts/noreturn/assert/input.c    | 37 ------------------
 .../TODO-analyzer/facts/noreturn/assert/script.py  | 33 ----------------
 .../TODO-analyzer/facts/noreturn/assert/stdout.txt |  0
 .../facts/noreturn/custom_abort/input.c            | 42 ---------------------
 .../facts/noreturn/custom_abort/script.py          | 33 ----------------
 .../facts/noreturn/custom_abort/stdout.txt         |  0
 .../custom_abort_with_noreturn_attribute/input.c   | 44 ----------------------
 .../custom_abort_with_noreturn_attribute/script.py | 33 ----------------
 .../stdout.txt                                     |  0
 gcc/testsuite/gcc.dg/analyzer/abort.c              | 42 +++++++++++++++++++++
 11 files changed, 53 insertions(+), 222 deletions(-)
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/input.c
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/script.py
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/stdout.txt
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/input.c
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/script.py
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/stdout.txt
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/input.c
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/script.py
 delete mode 100644 gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/stdout.txt

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index c7317df..06f7132 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -321,6 +321,11 @@ public:
     m_hashset.add (e);
   }
 
+  bool is_empty () const
+  {
+    return m_hashset.elements () == 0;
+  }
+
   iterator begin () const { return m_hashset.begin (); }
   iterator end () const { return m_hashset.end (); }
 
@@ -2165,6 +2170,12 @@ engine::follow_call (sm_instance sm_inst, backtrace b, path_state ps,
     m_sm_inst->m_active_vars.m_set.add (var_state_t (var, to));
 #endif
 
+  if (callee_summary_edges.is_empty ())
+    {
+      log ("function did not return; stopping traversal");
+      return;
+    }
+
   /* TODO: restore the edges in S to the caller's context.  */
 
   /* TODO: create sm_instances for each disjoint exit state,
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/input.c b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/input.c
deleted file mode 100644
index 15c932a..0000000
--- a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/input.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
-   Copyright 2012 Red Hat, Inc.
-
-   This is free software: you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see
-   <http://www.gnu.org/licenses/>.
-*/
-
-#include <assert.h>
-
-extern void marker_A(void);
-extern void marker_B(void);
-
-void test(int i)
-{
-  marker_A();
-
-  /*
-     We have not defined NDEBUG, so this will call __assert_fail if
-     i <= 10, which is labelled with __attribute__ ((__noreturn__))
-  */
-  assert(i > 10);
-
-  /* Hence the fact-finder ought to know (i > 10) here: */
-  marker_B();
-}
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/script.py b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/script.py
deleted file mode 100644
index 51ea56f..0000000
--- a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/script.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
-#   Copyright 2012, 2013 Red Hat, Inc.
-#
-#   This is free software: you can redistribute it and/or modify it
-#   under the terms of the GNU General Public License as published by
-#   the Free Software Foundation, either version 3 of the License, or
-#   (at your option) any later version.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#   General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with this program.  If not, see
-#   <http://www.gnu.org/licenses/>.
-
-from sm import main
-from sm.parser import parse_file
-
-def selftest(ctxt, solution):
-    if 0:
-        import sys
-        solution.dump(sys.stderr)
-
-    node = ctxt.find_call_of('marker_A')
-
-    node = ctxt.find_call_of('marker_B')
-    ctxt.assert_fact(node, 'i', '>', 10)
-
-checker = parse_file('sm/checkers/malloc_checker.sm')
-main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/stdout.txt b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/assert/stdout.txt
deleted file mode 100644
index e69de29..0000000
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/input.c b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/input.c
deleted file mode 100644
index 79c7c4e..0000000
--- a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/input.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
-   Copyright 2012 Red Hat, Inc.
-
-   This is free software: you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see
-   <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-extern void marker_A(void);
-extern void marker_B(void);
-
-void custom_abort(const char *msg)
-{
-  fprintf(stderr, "%s", msg);
-  abort();
-}
-
-void test(void *ptr)
-{
-  marker_A();
-
-  if (!ptr) {
-    custom_abort("ptr was NULL");
-  }
-
-  /* Hence the fact-finder ought to know (ptr != 0) here: */
-  marker_B();
-}
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/script.py b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/script.py
deleted file mode 100644
index e71cf1d..0000000
--- a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/script.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
-#   Copyright 2012, 2013 Red Hat, Inc.
-#
-#   This is free software: you can redistribute it and/or modify it
-#   under the terms of the GNU General Public License as published by
-#   the Free Software Foundation, either version 3 of the License, or
-#   (at your option) any later version.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#   General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with this program.  If not, see
-#   <http://www.gnu.org/licenses/>.
-
-from sm import main
-from sm.parser import parse_file
-
-def selftest(ctxt, solution):
-    if 0:
-        import sys
-        solution.dump(sys.stderr)
-
-    node = ctxt.find_call_of('marker_A')
-
-    node = ctxt.find_call_of('marker_B')
-    ctxt.assert_fact(node, 'ptr', '!=', 0)
-
-checker = parse_file('sm/checkers/malloc_checker.sm')
-main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/stdout.txt b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort/stdout.txt
deleted file mode 100644
index e69de29..0000000
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/input.c b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/input.c
deleted file mode 100644
index 0d82dd8..0000000
--- a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/input.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
-   Copyright 2012 Red Hat, Inc.
-
-   This is free software: you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see
-   <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-extern void marker_A(void);
-extern void marker_B(void);
-
-void custom_abort(const char *msg)  __attribute__ ((__noreturn__));
-
-void custom_abort(const char *msg)
-{
-  fprintf(stderr, "%s", msg);
-  abort();
-}
-
-void test(void *ptr)
-{
-  marker_A();
-
-  if (!ptr) {
-    custom_abort("ptr was NULL");
-  }
-
-  /* Hence the fact-finder ought to know (ptr != 0) here: */
-  marker_B();
-}
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/script.py b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/script.py
deleted file mode 100644
index e71cf1d..0000000
--- a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/script.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# -*- coding: utf-8 -*-
-#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
-#   Copyright 2012, 2013 Red Hat, Inc.
-#
-#   This is free software: you can redistribute it and/or modify it
-#   under the terms of the GNU General Public License as published by
-#   the Free Software Foundation, either version 3 of the License, or
-#   (at your option) any later version.
-#
-#   This program is distributed in the hope that it will be useful, but
-#   WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#   General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with this program.  If not, see
-#   <http://www.gnu.org/licenses/>.
-
-from sm import main
-from sm.parser import parse_file
-
-def selftest(ctxt, solution):
-    if 0:
-        import sys
-        solution.dump(sys.stderr)
-
-    node = ctxt.find_call_of('marker_A')
-
-    node = ctxt.find_call_of('marker_B')
-    ctxt.assert_fact(node, 'ptr', '!=', 0)
-
-checker = parse_file('sm/checkers/malloc_checker.sm')
-main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/stdout.txt b/gcc/testsuite/gcc.dg/TODO-analyzer/facts/noreturn/custom_abort_with_noreturn_attribute/stdout.txt
deleted file mode 100644
index e69de29..0000000
diff --git a/gcc/testsuite/gcc.dg/analyzer/abort.c b/gcc/testsuite/gcc.dg/analyzer/abort.c
index ef8e501..cfbf74c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/abort.c
+++ b/gcc/testsuite/gcc.dg/analyzer/abort.c
@@ -1,3 +1,5 @@
+#include <assert.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 extern void foo ();
@@ -27,3 +29,43 @@ void test_2 (int i)
 
   __analyzer_eval (i != 0); /* { dg-warning "TRUE" } */
 }
+
+/**************************************************************************/
+
+void calls_abort (const char *msg)
+{
+  fprintf (stderr, "%s", msg);
+  abort ();
+}
+
+void test_3 (void *ptr)
+{
+  if (!ptr)
+    calls_abort ("ptr was NULL");
+
+  __analyzer_eval (ptr != 0); /* { dg-warning "TRUE" } */
+}
+
+/**************************************************************************/
+
+extern void marked_noreturn (const char *msg)
+  __attribute__ ((__noreturn__));
+
+void test_4 (void *ptr)
+{
+  if (!ptr)
+    marked_noreturn ("ptr was NULL");
+
+  __analyzer_eval (ptr != 0); /* { dg-warning "TRUE" } */
+}
+
+/**************************************************************************/
+
+void test_5 (int i)
+{
+  assert (i < 10);
+
+  /* We have not defined NDEBUG, so this will call __assert_fail if
+     i >= 10, which is labelled with __attribute__ ((__noreturn__)).  */
+  __analyzer_eval (i < 10); /* { dg-warning "TRUE" } */
+}
-- 
1.8.5.3

