+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
/* 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).
+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
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" }
+}