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.
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))
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;
}
}
--- /dev/null
+/* 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;
+}