PR c++/67942 - diagnose placement new buffer overflow
gcc/cp/ * cp/init.c (warn_placement_new_too_small): Avoid assuming the size of the first operand of placement new or its type is known. gcc/testsuite/ * g++.dg/warn/Wplacement-new-size.C: Exercise placement new invocations where the size of the destination buffer object or its type (or both) is unknown. From-SVN: r229831
This commit is contained in:
parent
925b6a76e2
commit
906f9ad995
@ -1,3 +1,10 @@
|
||||
2015-11-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/67942
|
||||
* cp/init.c (warn_placement_new_too_small): Avoid assuming
|
||||
the size of the first operand of placement new or its type
|
||||
is known.
|
||||
|
||||
2015-11-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/67942
|
||||
|
@ -2384,20 +2384,26 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
|
||||
/* Treat members of unions and members of structs uniformly, even
|
||||
though the size of a member of a union may be viewed as extending
|
||||
to the end of the union itself (it is by __builtin_object_size). */
|
||||
if (TREE_CODE (oper) == VAR_DECL || use_obj_size)
|
||||
if ((TREE_CODE (oper) == VAR_DECL || use_obj_size)
|
||||
&& DECL_SIZE_UNIT (oper))
|
||||
{
|
||||
/* Use the size of the entire array object when the expression
|
||||
refers to a variable or its size depends on an expression
|
||||
that's not a compile-time constant. */
|
||||
bytes_avail = tree_to_shwi (DECL_SIZE_UNIT (oper));
|
||||
bytes_avail = tree_to_uhwi (DECL_SIZE_UNIT (oper));
|
||||
exact_size = !use_obj_size;
|
||||
}
|
||||
else
|
||||
else if (TYPE_SIZE_UNIT (TREE_TYPE (oper)))
|
||||
{
|
||||
/* Use the size of the type of the destination buffer object
|
||||
as the optimistic estimate of the available space in it. */
|
||||
bytes_avail = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (oper)));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Bail if neither the size of the object nor its type is known. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Avoid diagnosing flexible array members (accepted as an extension
|
||||
and diagnosed with -Wpedantic).
|
||||
|
@ -1,3 +1,10 @@
|
||||
2015-11-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/67942
|
||||
* g++.dg/warn/Wplacement-new-size.C: Exercise placement new
|
||||
invocations where the size of the destination buffer object
|
||||
or its type (or both) is unknown.
|
||||
|
||||
2015-11-05 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c++/67942
|
||||
|
@ -408,3 +408,48 @@ void test_user_defined_placement_new ()
|
||||
new (&x) ClassWithGlobalNew[2];
|
||||
}
|
||||
}
|
||||
|
||||
extern char extbuf[];
|
||||
|
||||
template <class> struct TemplateClass { char c; };
|
||||
|
||||
// Declare a specialization but don't provide a definition.
|
||||
template <> struct TemplateClass<void>;
|
||||
|
||||
// Declare an object of an explicit specialization of an unknown size.
|
||||
extern TemplateClass<void> exttempl_void;
|
||||
|
||||
// Verify that no warning is issued when placement new is called with
|
||||
// an extern buffer of unknown size (and the case is handled gracefully
|
||||
// and doesn't cause an ICE).
|
||||
static __attribute__ ((used))
|
||||
void test_extern_buffer_of_unknown_size ()
|
||||
{
|
||||
new (extbuf) int ();
|
||||
new (extbuf) int [1024];
|
||||
|
||||
new (&exttempl_void) int ();
|
||||
new (&exttempl_void) int [1024];
|
||||
}
|
||||
|
||||
extern char extbuf_size_int [sizeof (int)];
|
||||
|
||||
extern TemplateClass<int> exttempl;
|
||||
|
||||
// Verify that a warning is issued as expected when placement new is
|
||||
// called with an extern buffer of known size (and the case is handled
|
||||
// gracefully and doesn't cause an ICE).
|
||||
static __attribute__ ((used))
|
||||
void test_extern_buffer ()
|
||||
{
|
||||
new (extbuf_size_int) int ();
|
||||
new (extbuf_size_int) int [1];
|
||||
|
||||
struct S { int a [2]; };
|
||||
|
||||
new (extbuf_size_int) S; // { dg-warning "placement" }
|
||||
new (extbuf_size_int) int [2]; // { dg-warning "placement" }
|
||||
|
||||
new (&exttempl) int (); // { dg-warning "placement" }
|
||||
new (&exttempl) int [1024]; // { dg-warning "placement" }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user