From ee6448e12a8f47da2ab1e207d0b88addf509c16d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 3 Aug 2020 18:15:38 -0400
Subject: [PATCH 06/20] FIXME: add DEFERRED testcases

---
 .../gcc.dg/analyzer/pr93695.DEFERRED-c        | 18 ++++++
 .../gcc.dg/analyzer/pr94362.DEFERRED-c        | 57 +++++++++++++++++++
 .../gcc.dg/analyzer/pr94365.DEFERRED-c        | 45 +++++++++++++++
 3 files changed, 120 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr93695.DEFERRED-c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr94362.DEFERRED-c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr94365.DEFERRED-c

diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93695.DEFERRED-c b/gcc/testsuite/gcc.dg/analyzer/pr93695.DEFERRED-c
new file mode 100644
index 00000000000..06459b9a200
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93695.DEFERRED-c
@@ -0,0 +1,18 @@
+#define NELEMS 2
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0]))
+
+void
+f (void)
+{
+  int *p[NELEMS];
+  int i;
+
+  for (i = 0; i < ARRAY_SIZE (p); ++i)
+    p[i] = __builtin_malloc (sizeof (i));
+
+  __analyzer_dump ();
+
+  for (i = 0; i < ARRAY_SIZE (p); ++i)
+    __builtin_free (p [i]);
+}
+
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94362.DEFERRED-c b/gcc/testsuite/gcc.dg/analyzer/pr94362.DEFERRED-c
new file mode 100644
index 00000000000..c48fb94e9a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94362.DEFERRED-c
@@ -0,0 +1,57 @@
+typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
+typedef struct engine_st ENGINE;
+struct stack_st_EVP_PKEY_ASN1_METHOD;
+struct evp_pkey_asn1_method_st {
+  unsigned long pkey_flags;
+};
+
+const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe,
+                                                      const char *str, int len);
+extern int
+sk_EVP_PKEY_ASN1_METHOD_num(const struct stack_st_EVP_PKEY_ASN1_METHOD *sk);
+extern const EVP_PKEY_ASN1_METHOD *
+sk_EVP_PKEY_ASN1_METHOD_value(const struct stack_st_EVP_PKEY_ASN1_METHOD *sk,
+                              int idx);
+extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {&hmac_asn1_meth};
+static struct stack_st_EVP_PKEY_ASN1_METHOD *app_methods = ((void *)0);
+
+int EVP_PKEY_asn1_get_count(void) {
+  int num = (sizeof(standard_methods) / sizeof((standard_methods)[0]));
+  if (app_methods)
+    num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
+  return num;
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) {
+  int num = (sizeof(standard_methods) / sizeof((standard_methods)[0]));
+  if (idx < 0)
+    return ((void *)0);
+  if (idx < num)
+    return standard_methods[idx];
+  idx -= num;
+  return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
+}
+
+const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str,
+                                                   int len) {
+  int i;
+  const EVP_PKEY_ASN1_METHOD *ameth = ((void *)0);
+
+  if (pe) {
+    ENGINE *e;
+    ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
+    if (ameth) {
+      *pe = e;
+      return ameth;
+    }
+    *pe = ((void *)0);
+  }
+  for (i = EVP_PKEY_asn1_get_count(); i-- > 0;) {
+    ameth = EVP_PKEY_asn1_get0(i);
+    if (ameth->pkey_flags & 0x1)
+      continue;
+    return ameth;
+  }
+  return ((void *)0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94365.DEFERRED-c b/gcc/testsuite/gcc.dg/analyzer/pr94365.DEFERRED-c
new file mode 100644
index 00000000000..caef8868013
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94365.DEFERRED-c
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+struct a_struct {
+        int a;
+};
+
+struct container {
+        void *a;
+        struct a_struct b;
+};
+
+struct a_struct *foo() {
+        struct container *a = malloc(sizeof(*a));
+
+        /* printf removes the warning */
+        //printf("Alloc'd %p\n", a);
+
+        if (!a)
+                return NULL;
+
+        return &a->b;
+}
+
+
+#define container_of(ptr, type, member) \
+    (type *)((char *)(ptr) - (char *) &((type *)0)->member)
+
+int main() {
+        struct a_struct *b = foo();
+        struct container *a;
+
+        if (!b)
+                return -1;
+
+#if 0
+        a = container_of(b, struct container, b);
+        printf("Freeing %p\n", a);
+        free(a);
+#else
+        free(container_of(b, struct container, b));
+#endif
+
+        return 0;
+}
-- 
2.26.2

