This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 27210


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)];
+  }
+};
+



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]