PR middle-end/98160 - ICE in warn_dealloc_offset on member placement new and delete

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.
This commit is contained in:
Martin Sebor 2020-12-23 16:34:12 -07:00
parent fdd8560cce
commit 0df311657d
2 changed files with 33 additions and 1 deletions

View 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;
}
}

View File

@ -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;
}