mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
c++: Don't crash upon invalid placement new operator [PR117101]
We currently crash upon the following invalid code (notice the "void void**" parameter) === cut here === using size_t = decltype(sizeof(int)); void *operator new(size_t, void void **p) noexcept { return p; } int x; void f() { int y; new (&y) int(x); } === cut here === The problem is that in this case, we end up with a NULL_TREE parameter list for the new operator because of the error, and (1) coerce_new_type wrongly complains about the first parameter type not being size_t, (2) std_placement_new_fn_p blindly accesses the parameter list, hence a crash. This patch does NOT address #1 since we can't easily distinguish between a new operator declaration without parameters from one with erroneous parameters (and it's not worth the risk to refactor and break things for an error recovery issue) hence a dg-bogus in new52.C, but it does address #2 and the ICE by simply checking the first parameter against NULL_TREE. It also adds a new testcase checking that we complain about new operators with no or invalid first parameters, since we did not have any. PR c++/117101 gcc/cp/ChangeLog: * init.cc (std_placement_new_fn_p): Check first_arg against NULL_TREE. gcc/testsuite/ChangeLog: * g++.dg/init/new52.C: New test. * g++.dg/init/new53.C: New test.
This commit is contained in:
parent
b1d92aeb85
commit
5821f5c8c8
@ -2980,8 +2980,9 @@ std_placement_new_fn_p (tree alloc_fn)
|
||||
if (DECL_NAMESPACE_SCOPE_P (alloc_fn))
|
||||
{
|
||||
tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
|
||||
if ((TREE_VALUE (first_arg) == ptr_type_node)
|
||||
&& TREE_CHAIN (first_arg) == void_list_node)
|
||||
if (first_arg
|
||||
&& (TREE_VALUE (first_arg) == ptr_type_node)
|
||||
&& (TREE_CHAIN (first_arg) == void_list_node))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
14
gcc/testsuite/g++.dg/init/new52.C
Normal file
14
gcc/testsuite/g++.dg/init/new52.C
Normal file
@ -0,0 +1,14 @@
|
||||
// PR c++/117101
|
||||
// { dg-do "compile" { target c++11 } }
|
||||
|
||||
using size_t = decltype(sizeof(int));
|
||||
void* operator new(size_t, // { dg-bogus "first parameter" "" { xfail *-*-* } }
|
||||
void void **p) noexcept // { dg-error "two or more" }
|
||||
{
|
||||
return p; // { dg-error "not declared" }
|
||||
}
|
||||
int x;
|
||||
void f() {
|
||||
int y;
|
||||
new (&y) int(x);
|
||||
}
|
8
gcc/testsuite/g++.dg/init/new53.C
Normal file
8
gcc/testsuite/g++.dg/init/new53.C
Normal file
@ -0,0 +1,8 @@
|
||||
// Check that we reject operator new with no argument or non-size_t first
|
||||
// argument.
|
||||
// { dg-do "compile" }
|
||||
|
||||
void* operator new(); // { dg-error "takes type .size_t." }
|
||||
void* operator new(char); // { dg-error "takes type .size_t." }
|
||||
void* operator new(char*); // { dg-error "takes type .size_t." }
|
||||
void* operator new(char&); // { dg-error "takes type .size_t." }
|
Loading…
Reference in New Issue
Block a user