This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 27210
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 21 May 2006 10:27:23 -0700
- Subject: C++ PATCH: PR 27210
- Reply-to: mark at codesourcery dot com
This patch fixes PR c++/27210, a regression introduced by some of my
recent changes to handling of operator new. We were trying to create
a SAVE_EXPR in a template, and the middle-end quite rightly wants
nothing to do with SIZEOF_EXPRs. Fixed by only calling save_expr if
!processing_template_decl.
I noticed that we were trying to issue a warning about:
new int[0]
which, while valid, is odd in that one rarely wants a zero-element
array. However, the code used to issue the warning didn't work
because the warning checked to see if the number of elements was
integer_zero_node, and right before the check, we convert the number
of elements to size_t. So, I fixed the check to use integer_zerop and
added a test case.
Tested on x86_64-unknown-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
2006-05-21 Mark Mitchell <mark@codesourcery.com>
PR c++/27210
* cp-tree.h (cp_save_expr): New function.
* init.c (build_new): Correct logic for zero-element array
warning. Use cp_save_expr.
* tree.c (cp_save_expr): New function.
2006-05-21 Mark Mitchell <mark@codesourcery.com>
PR c++/27210
* g++.dg/warn/new1.C: New test.
* g++.dg/template/new5.C: Likewise.
Index: gcc/cp/init.c
===================================================================
--- gcc/cp/init.c (revision 113902)
+++ gcc/cp/init.c (working copy)
@@ -2088,9 +2088,22 @@ build_new (tree placement, tree type, tr
{
if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
pedwarn ("size in array new must have integral type");
- nelts = save_expr (cp_convert (sizetype, nelts));
- if (nelts == integer_zero_node)
- warning (0, "zero size array reserves no space");
+ nelts = cp_save_expr (cp_convert (sizetype, nelts));
+ /* It is valid to allocate a zero-element array:
+
+ [expr.new]
+
+ When the value of the expression in a direct-new-declarator
+ is zero, the allocation function is called to allocate an
+ array with no elements. The pointer returned by the
+ new-expression is non-null. [Note: If the library allocation
+ function is called, the pointer returned is distinct from the
+ pointer to any other object.]
+
+ However, that is not generally useful, so we issue a
+ warning. */
+ if (integer_zerop (nelts))
+ warning (0, "allocating zero-element array");
}
/* ``A reference cannot be created by the new operator. A reference
Index: gcc/cp/tree.c
===================================================================
--- gcc/cp/tree.c (revision 113902)
+++ gcc/cp/tree.c (working copy)
@@ -2083,6 +2083,14 @@ cp_auto_var_in_fn_p (tree var, tree fn)
&& nonstatic_local_decl_p (var));
}
+tree
+cp_save_expr (tree expr)
+{
+ if (processing_template_decl)
+ return expr;
+ return save_expr (expr);
+}
+
/* Initialize tree.c. */
void
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h (revision 113911)
+++ gcc/cp/cp-tree.h (working copy)
@@ -4336,6 +4336,7 @@ extern int cp_auto_var_in_fn_p (tree,t
extern tree fold_if_not_in_template (tree);
extern tree rvalue (tree);
extern tree convert_bitfield_to_declared_type (tree);
+extern tree cp_save_expr (tree);
/* in typeck.c */
extern int string_conv_p (tree, tree, int);
Index: gcc/testsuite/g++.dg/warn/new1.C
===================================================================
--- gcc/testsuite/g++.dg/warn/new1.C (revision 0)
+++ gcc/testsuite/g++.dg/warn/new1.C (revision 0)
@@ -0,0 +1,3 @@
+void f() {
+ new int[0]; // { dg-warning "zero" }
+}
Index: gcc/testsuite/g++.dg/template/new5.C
===================================================================
--- gcc/testsuite/g++.dg/template/new5.C (revision 0)
+++ gcc/testsuite/g++.dg/template/new5.C (revision 0)
@@ -0,0 +1,9 @@
+// PR c++/27210
+
+template <class foo> class junk {
+ void bar(int a)
+ {
+ unsigned char *c = new unsigned char[a*sizeof(foo)];
+ }
+};
+