Patchwork [C++] PR 43452

login
register
mail settings
Submitter Paolo Carlini
Date Sept. 5, 2013, 10:44 p.m.
Message ID <5229093C.6050904@oracle.com>
Download mbox | patch
Permalink /patch/272994/
State New
Headers show

Comments

Paolo Carlini - Sept. 5, 2013, 10:44 p.m.
Hi,

this very old minor issue is about the kind of diagnostic we want to 
produce for something like the existing g++.dg/init/delete1.C:

class C;

  void foo(void *p) {
   delete [] ((C*)p) ;
  }

that is when the array delete is called for a pointer to incomplete 
type. Currently we emit an hard error (we used to ICE) but arguably we 
should only warn and explain the possible undefined behavior at runtime, 
consistently with what we do for the non-array variant of delete (clang 
and icc likewise warn). I tested the below on x86_64-linux.

Thanks!
Paolo.

///////////////////////
/cp
2013-09-06

	PR c++/43452
	* init.c (build_vec_delete_1): When the type is incomplete emit
	a warning not an error.

/testsuite
2013-09-06

	PR c++/43452
	* g++.dg/init/delete1.C: Adjust.
Jason Merrill - Sept. 9, 2013, 4:35 a.m.
On 09/05/2013 06:44 PM, Paolo Carlini wrote:
> +	  && warning (0, "possible problem detected in invocation of "
> +		      "delete [] operator:"))

The warning should probably be suppressible by some flag.

Jason

Patch

Index: cp/init.c
===================================================================
--- cp/init.c	(revision 202296)
+++ cp/init.c	(working copy)
@@ -3078,7 +3078,7 @@  build_vec_delete_1 (tree base, tree maxindex, tree
 {
   tree virtual_size;
   tree ptype = build_pointer_type (type = complete_type (type));
-  tree size_exp = size_in_bytes (type);
+  tree size_exp;
 
   /* Temporary variables used by the loop.  */
   tree tbase, tbase_init;
@@ -3106,6 +3106,22 @@  build_vec_delete_1 (tree base, tree maxindex, tree
   if (base == error_mark_node || maxindex == error_mark_node)
     return error_mark_node;
 
+  if (!COMPLETE_TYPE_P (type))
+    {
+      if ((complain & tf_warning)
+	  && warning (0, "possible problem detected in invocation of "
+		      "delete [] operator:"))
+       {
+         cxx_incomplete_type_diagnostic (base, type, DK_WARNING);
+         inform (input_location, "neither the destructor nor the "
+                 "class-specific operator delete [] will be called, "
+                 "even if they are declared when the class is defined");
+       }
+      return build_builtin_delete_call (base);
+    } 
+
+  size_exp = size_in_bytes (type);
+
   if (! MAYBE_CLASS_TYPE_P (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
     goto no_destructor;
 
Index: testsuite/g++.dg/init/delete1.C
===================================================================
--- testsuite/g++.dg/init/delete1.C	(revision 202284)
+++ testsuite/g++.dg/init/delete1.C	(working copy)
@@ -1,7 +1,7 @@ 
 // PR c++/19811
 
-class C; // { dg-error "forward" }
+class C; // { dg-warning "forward" }
 
 void foo(void *p) {
-  delete [] ((C*)p) ; // { dg-error "" }
+  delete [] ((C*)p) ; // { dg-warning "problem|incomplete" }
 }