From 25a7e78f6610c4e949054847607e0337fbf063fc Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 31 Jul 2019 13:54:26 -0400
Subject: [PATCH 054/124] FIXME: cleaning up old tests

---
 examples/demo.c                                    |  30 +++++++
 examples/lto-double-free/api.c                     |  15 ++++
 examples/lto-double-free/api.h                     |   9 ++
 examples/lto-double-free/client.c                  |   8 ++
 .../DEADCODE-analyzer.dg/constraints/path-count.c  |  16 ----
 gcc/testsuite/DEADCODE-analyzer.dg/demo-2.c        | 100 ---------------------
 gcc/testsuite/DEADCODE-analyzer.dg/demo-4.c        |  61 -------------
 gcc/testsuite/DEADCODE-analyzer.dg/demo.c          |  30 -------
 .../DEADCODE-analyzer.dg/ipa-double-free/api.c     |  15 ----
 .../DEADCODE-analyzer.dg/ipa-double-free/api.h     |   9 --
 .../DEADCODE-analyzer.dg/ipa-double-free/client.c  |   8 --
 gcc/testsuite/DEADCODE-analyzer.dg/malloc/leak.c   |   6 --
 .../DEADCODE-analyzer.dg/malloc/unchecked.c        |  14 ---
 .../DEADCODE-analyzer.dg/memory/example.c          |  16 ----
 gcc/testsuite/gcc.dg/analyzer/conditionals-3.c     |  45 ++++++++++
 gcc/testsuite/gcc.dg/analyzer/data-model-1.c       |  17 +++-
 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-4.c  |  40 +++++++++
 17 files changed, 162 insertions(+), 277 deletions(-)
 create mode 100644 examples/demo.c
 create mode 100644 examples/lto-double-free/api.c
 create mode 100644 examples/lto-double-free/api.h
 create mode 100644 examples/lto-double-free/client.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/constraints/path-count.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/demo-2.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/demo-4.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/demo.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.h
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/client.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/malloc/leak.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/malloc/unchecked.c
 delete mode 100644 gcc/testsuite/DEADCODE-analyzer.dg/memory/example.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/conditionals-3.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-4.c

diff --git a/examples/demo.c b/examples/demo.c
new file mode 100644
index 0000000..7e17781
--- /dev/null
+++ b/examples/demo.c
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+
+typedef struct boxed_int
+{
+  int val;
+} boxed_int;
+
+extern boxed_int *make_boxed_int (int i);
+extern void free_boxed_int (boxed_int *victim);
+
+boxed_int *
+make_boxed_int (int val)
+{
+  boxed_int *new_ptr = (boxed_int *)malloc (sizeof (boxed_int));
+  new_ptr->val = val;
+  return new_ptr;
+}
+
+void
+free_boxed_int (boxed_int *victim)
+{
+  free (victim);
+}
+
+void test (int x)
+{
+  boxed_int *bi = make_boxed_int (x);
+  free_boxed_int (bi);
+  free_boxed_int (bi); /* BUG: double-free.  */
+}
diff --git a/examples/lto-double-free/api.c b/examples/lto-double-free/api.c
new file mode 100644
index 0000000..a418ee4
--- /dev/null
+++ b/examples/lto-double-free/api.c
@@ -0,0 +1,15 @@
+#include "api.h"
+
+boxed_int *
+make_boxed_int (int i)
+{
+  boxed_int *bi = (boxed_int *)malloc (sizeof (boxed_int));
+  bi->i = i;
+  return bi;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+  free (bi);
+}
diff --git a/examples/lto-double-free/api.h b/examples/lto-double-free/api.h
new file mode 100644
index 0000000..ebdfa89
--- /dev/null
+++ b/examples/lto-double-free/api.h
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+typedef struct boxed_int
+{
+  int i;
+} boxed_int;
+
+extern boxed_int *make_boxed_int (int i);
+extern void free_boxed_int (boxed_int *bi);
diff --git a/examples/lto-double-free/client.c b/examples/lto-double-free/client.c
new file mode 100644
index 0000000..4c7e642
--- /dev/null
+++ b/examples/lto-double-free/client.c
@@ -0,0 +1,8 @@
+#include "api.h"
+
+void test (int i)
+{
+  boxed_int *bi = make_boxed_int (i);
+  free_boxed_int (bi);
+  free_boxed_int (bi); /* BUG: double-free.  */
+}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/constraints/path-count.c b/gcc/testsuite/DEADCODE-analyzer.dg/constraints/path-count.c
deleted file mode 100644
index f6f9bd8..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/constraints/path-count.c
+++ /dev/null
@@ -1,16 +0,0 @@
-extern void foo (void);
-extern void bar (void);
-extern void baz (void);
-
-void test (int flag)
-{
-  if (flag)
-    foo ();
-  
-  bar ();
-
-  if (flag)
-    baz ();
-}
-
-/* { dg-final { scan-dump "analysis" "num paths: 2" "analyzer.txt" } } */
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/demo-2.c b/gcc/testsuite/DEADCODE-analyzer.dg/demo-2.c
deleted file mode 100644
index 254a9b3..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/demo-2.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Control flow tests.  */
-
-#include <stdlib.h>
-
-/* Ensure that we don't need to laboriously walk every path to get
-   to the end of the function.  */
-
-int test_1 (int n)
-{
-  int i, j, k;
-  k = 0;
-  for (int i = 0; i < n; i++)
-    for (int j = 0; j < 1000; j++)
-      k++;
-  return k;
-}
-
-/* Ensure that we don't get an exponential growth in paths due to
-   repeated diamonds in the CFG.  */
-
-typedef struct obj {
-  int ob_refcnt;
-} PyObject;
-
-extern void Py_Dealloc (PyObject *op);
-
-#define Py_DECREF(op)                                   \
-    do {                                                \
-      if (--((PyObject*)(op))->ob_refcnt == 0)		\
-	Py_Dealloc((PyObject *)(op));			\
-    } while (0)
-
-int test_2 (PyObject *obj_01, PyObject *obj_02, PyObject *obj_03,
-	    PyObject *obj_04, PyObject *obj_05, PyObject *obj_06,
-	    PyObject *obj_07, PyObject *obj_08, PyObject *obj_09,
-	    PyObject *obj_10, PyObject *obj_11, PyObject *obj_12,
-	    PyObject *obj_13, PyObject *obj_14, PyObject *obj_15)
-{
-    Py_DECREF (obj_01); Py_DECREF (obj_02); Py_DECREF (obj_03);
-    Py_DECREF (obj_04); Py_DECREF (obj_05); Py_DECREF (obj_06);
-    Py_DECREF (obj_07); Py_DECREF (obj_08); Py_DECREF (obj_09);
-    Py_DECREF (obj_10); Py_DECREF (obj_11); Py_DECREF (obj_12);
-    Py_DECREF (obj_13); Py_DECREF (obj_14); Py_DECREF (obj_15);
-}
-
-int test_3 (int i)
-{
-  switch (i)
-    {
-    case 0:
-      return 43;
-    case 1:
-    case 2:
-      return 72;
-    default:
-      return i * 5;
-    }
-}
-
-void __attribute__((noinline)) do_something (int *ptr)
-{
-  *ptr = 42; /* BUG: can be NULL if malloc fails */
-}
-
-int test_4 (int i, int flag)
-{
-  /* Double diamond CFG; either use &i, or a malloc-ed buffer.  */
-  int *ptr = &i;
-  if (flag)
-    ptr = (int *)malloc (sizeof (int));
-  do_something (ptr);
-  if (flag)
-    free (ptr);
-  return i;
-}
-
-/* What about:  */
-
-int test_5 (int flag)
-{
-  int i;
-
-  if (flag)
-    do_something (&i);
-
-  do_something (&i);
-
-  if (!flag)
-    {
-      /* need to ensure we reach here in the traversal, even though
-	 no states have changed, and we already reached the join-point
-	 earlier with flag == true before trying this.
-	 Does the depth-firstness help?
-	 Also, we've called do_something twice; do we need function
-	 summaries here?  */
-      void *ptr = malloc (16);
-      free (ptr);
-      free (ptr);
-    }
-}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/demo-4.c b/gcc/testsuite/DEADCODE-analyzer.dg/demo-4.c
deleted file mode 100644
index 2ab0f5c..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/demo-4.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Control flow constraint tests.  */
-
-extern void __dump_truthiness (int);
-
-static void only_called_when_flag_a_true (int val)
-{
-  __dump_truthiness (i == 42); /* { dg-message "true" } */
-}
-
-static void only_called_when_flag_b_true (int val)
-{
-  __dump_truthiness (i == 17); /* { dg-message "true" } */
-}
-
-int test_1 (int flag_a, int flag_b)
-{
-  int i = 17;
-
-  __dump_truthiness (flag_a); /* { dg-message "unknown" } */
-  __dump_truthiness (flag_b); /* { dg-message "unknown" } */
-
-  if (flag_a)
-    {
-      __dump_truthiness (flag_a); /* { dg-message "true" } */
-      __dump_truthiness (flag_b); /* { dg-message "unknown" } */
-      i = 42;
-    }
-
-  __dump_truthiness (flag_b); /* { dg-message "unknown" } */
-
-  if (flag_a)
-    {
-      __dump_truthiness (flag_a); /* { dg-message "true" } */
-      __dump_truthiness (flag_b); /* { dg-message "unknown" } */
-      __dump_truthiness (i == 42); /* { dg-message "true" } */
-      __dump_truthiness (i == 17); /* { dg-message "false" } */
-      only_called_when_flag_a_true (i);
-    }  
-  else
-    {
-      __dump_truthiness (flag_a); /* { dg-message "false" } */
-      __dump_truthiness (flag_b); /* { dg-message "unknown" } */
-      __dump_truthiness (i == 42); /* { dg-message "false" } */
-      __dump_truthiness (i == 17); /* { dg-message "true" } */
-      only_called_when_flag_b_true (i);
-    }
-}
-
-int test_3 (int i)
-{
-  switch (i)
-    {
-    case 0:
-      return 43;
-    case 1:
-    case 2:
-      return 72;
-    default:
-      return i * 5;
-    }
-}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/demo.c b/gcc/testsuite/DEADCODE-analyzer.dg/demo.c
deleted file mode 100644
index 7e17781..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/demo.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <stdlib.h>
-
-typedef struct boxed_int
-{
-  int val;
-} boxed_int;
-
-extern boxed_int *make_boxed_int (int i);
-extern void free_boxed_int (boxed_int *victim);
-
-boxed_int *
-make_boxed_int (int val)
-{
-  boxed_int *new_ptr = (boxed_int *)malloc (sizeof (boxed_int));
-  new_ptr->val = val;
-  return new_ptr;
-}
-
-void
-free_boxed_int (boxed_int *victim)
-{
-  free (victim);
-}
-
-void test (int x)
-{
-  boxed_int *bi = make_boxed_int (x);
-  free_boxed_int (bi);
-  free_boxed_int (bi); /* BUG: double-free.  */
-}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.c b/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.c
deleted file mode 100644
index a418ee4..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "api.h"
-
-boxed_int *
-make_boxed_int (int i)
-{
-  boxed_int *bi = (boxed_int *)malloc (sizeof (boxed_int));
-  bi->i = i;
-  return bi;
-}
-
-void
-free_boxed_int (boxed_int *bi)
-{
-  free (bi);
-}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.h b/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.h
deleted file mode 100644
index ebdfa89..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/api.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <stdlib.h>
-
-typedef struct boxed_int
-{
-  int i;
-} boxed_int;
-
-extern boxed_int *make_boxed_int (int i);
-extern void free_boxed_int (boxed_int *bi);
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/client.c b/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/client.c
deleted file mode 100644
index 4c7e642..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/ipa-double-free/client.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "api.h"
-
-void test (int i)
-{
-  boxed_int *bi = make_boxed_int (i);
-  free_boxed_int (bi);
-  free_boxed_int (bi); /* BUG: double-free.  */
-}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/malloc/leak.c b/gcc/testsuite/DEADCODE-analyzer.dg/malloc/leak.c
deleted file mode 100644
index 957f554..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/malloc/leak.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include <stdlib.h>
-
-void test (void)
-{
-  void *p = malloc (256); /* { dg-error "leak" } */
-}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/malloc/unchecked.c b/gcc/testsuite/DEADCODE-analyzer.dg/malloc/unchecked.c
deleted file mode 100644
index a30ff08..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/malloc/unchecked.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <stdlib.h>
-
-struct foo
-{
-  int i;
-};
-
-struct foo *test (void)
-{
-  struct foo *p;
-  p = (struct foo *)malloc (sizeof (struct foo));
-  p->i = 42; /* unchecked deref */
-  return p;
-}
diff --git a/gcc/testsuite/DEADCODE-analyzer.dg/memory/example.c b/gcc/testsuite/DEADCODE-analyzer.dg/memory/example.c
deleted file mode 100644
index d9af197..0000000
--- a/gcc/testsuite/DEADCODE-analyzer.dg/memory/example.c
+++ /dev/null
@@ -1,16 +0,0 @@
-struct s {
-  struct s *next;
-  int f;
-};
-
-void foo (struct s *in)
-{
-  struct s a;
-  struct s b;
-  struct s c;
-  a.next = &b;
-  b.next = &c;
-  in->next = &a;
-  c.f = 42;
-  __analyzer_eval (in->next->next->next->f == 42);  /* { dg-warning "TRUE" } */
-}
diff --git a/gcc/testsuite/gcc.dg/analyzer/conditionals-3.c b/gcc/testsuite/gcc.dg/analyzer/conditionals-3.c
new file mode 100644
index 0000000..d19a8b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/conditionals-3.c
@@ -0,0 +1,45 @@
+/* { dg-additional-options "-fno-analyzer-state-merge" } */
+
+static void only_called_when_flag_a_true (int i)
+{
+  __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+}
+
+static void only_called_when_flag_b_true (int i)
+{
+  __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+}
+
+int test_1 (int flag_a, int flag_b)
+{
+  int i = 17;
+
+  __analyzer_eval (flag_a); /* { dg-warning "UNKNOWN" } */
+  __analyzer_eval (flag_b); /* { dg-warning "UNKNOWN" } */
+
+  if (flag_a)
+    {
+      __analyzer_eval (flag_a); /* { dg-warning "TRUE" } */
+      __analyzer_eval (flag_b); /* { dg-warning "UNKNOWN" } */
+      i = 42;
+    }
+
+  __analyzer_eval (flag_b); /* { dg-warning "UNKNOWN" } */
+
+  if (flag_a)
+    {
+      __analyzer_eval (flag_a); /* { dg-warning "TRUE" } */
+      __analyzer_eval (flag_b); /* { dg-warning "UNKNOWN" } */
+      __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+      __analyzer_eval (i == 17); /* { dg-warning "FALSE" } */
+      only_called_when_flag_a_true (i);
+    }  
+  else
+    {
+      __analyzer_eval (flag_a); /* { dg-warning "FALSE" } */
+      __analyzer_eval (flag_b); /* { dg-warning "UNKNOWN" } */
+      __analyzer_eval (i == 42); /* { dg-warning "FALSE" } */
+      __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+      only_called_when_flag_b_true (i);
+    }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
index cd1e5cd..defe409 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
@@ -735,13 +735,26 @@ int test_40 (int flag)
     __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
 }
 
-// TODO:
-
 struct link
 {
   struct link *next;
+  int f;
 };
 
+/* Traversing a singly-linked list.  */
+
+void foo (struct link *in)
+{
+  struct link a;
+  struct link b;
+  struct link c;
+  a.next = &b;
+  b.next = &c;
+  in->next = &a;
+  c.f = 42;
+  __analyzer_eval (in->next->next->next->f == 42);  /* { dg-warning "TRUE" } */
+}
+
 // TODO:
 
 union u
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-4.c b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-4.c
new file mode 100644
index 0000000..c5520f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-4.c
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+
+void __attribute__((noinline)) callee_1 (int *ptr)
+{
+  *ptr = 42; /* { dg-warning "use of possibly-NULL 'ptr'" } */
+}
+
+int test_1 (int i, int flag)
+{
+  /* Double diamond CFG; either use &i, or a malloc-ed buffer.  */
+  int *ptr = &i;
+  if (flag)
+    ptr = (int *)malloc (sizeof (int));
+  callee_1 (ptr);
+  if (flag)
+    free (ptr);
+  return i;
+}
+
+void __attribute__((noinline)) callee_2 (int *ptr)
+{
+  *ptr = 42;
+}
+
+int test_2 (int flag)
+{
+  int i;
+
+  if (flag)
+    callee_2 (&i);
+
+  callee_2 (&i);
+
+  if (!flag)
+    {
+      void *ptr = malloc (16);
+      free (ptr);
+      free (ptr); /* { dg-warning "double-free of 'ptr'" } */
+    }
+}
-- 
1.8.5.3

