PR middle-end/98160 - ICE in warn_dealloc_offset on member placement new and delete
authorMartin Sebor <msebor@redhat.com>
Wed, 23 Dec 2020 23:34:12 +0000 (16:34 -0700)
committerMartin Sebor <msebor@redhat.com>
Wed, 23 Dec 2020 23:38:18 +0000 (16:38 -0700)
gcc/ChangeLog:

PR middle-end/98160
* builtins.c (warn_dealloc_offset): Avoid assuming calls are made
through declared functions and not pointers.

gcc/testsuite/ChangeLog:

PR middle-end/98160
* g++.dg/warn/pr98160.C: New test.

gcc/builtins.c
gcc/testsuite/g++.dg/warn/pr98160.C [new file with mode: 0644]

index 498a112..ffbb9b7 100644 (file)
@@ -13400,6 +13400,8 @@ warn_dealloc_offset (location_t loc, tree exp, const access_ref &aref)
     return false;
 
   tree dealloc_decl = get_callee_fndecl (exp);
+  if (!dealloc_decl)
+    return false;
 
   if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl)
       && !DECL_IS_REPLACEABLE_OPERATOR (dealloc_decl))
@@ -13413,7 +13415,7 @@ warn_dealloc_offset (location_t loc, tree exp, const access_ref &aref)
          if (is_gimple_call (def_stmt))
            {
              tree alloc_decl = gimple_call_fndecl (def_stmt);
-             if (!DECL_IS_OPERATOR_NEW_P (alloc_decl))
+             if (!alloc_decl || !DECL_IS_OPERATOR_NEW_P (alloc_decl))
                return false;
            }
        }
diff --git a/gcc/testsuite/g++.dg/warn/pr98160.C b/gcc/testsuite/g++.dg/warn/pr98160.C
new file mode 100644 (file)
index 0000000..b3c5783
--- /dev/null
@@ -0,0 +1,30 @@
+/* PR middle-end/98160 - ICE in warn_dealloc_offset on member placement
+   new and delete
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* (*pf) (size_t);
+
+struct A;
+struct B
+{
+  B ();
+
+  void* operator new (size_t, A*);
+  void operator delete (void*, A*);
+};
+
+void operator delete (void *, A*);
+
+void B::operator delete (void*, A *p)
+{
+  void *q = pf (1);
+  ::operator delete ((char*)q + 1, p);
+}
+
+void* f (A *p)
+{
+  return new (p) B;
+}