Hi,

this takes care of the four locations, two warnings and two errors. I'm also adding the missing complain & tf_warning or tf_error guards, I don't have a SFINAE testcase failing but since the function takes a tsubst_flags_t argument I think it's the right thing to do. Tested x86_64-linux.

By the way, shall we add to cp-tree.h, at least temporarily, a:

inline location_t
cp_expr_loc_or_loc (const_tree t)
{
  return cp_expr_loc_or_loc (t, input_location);
}

overload? We could use it in a ton of places.

Thanks, Paolo.

//////////////////////////

/cp
2019-07-24  Paolo Carlini  <paolo.carl...@oracle.com>

        * decl2.c (delete_sanity): Improve diagnostic locations, use
        cp_expr_loc_or_loc in four places.

/testsuite
2019-07-24  Paolo Carlini  <paolo.carl...@oracle.com>

        * g++.dg/diagnostic/delete1.C: New.
Index: cp/decl2.c
===================================================================
--- cp/decl2.c  (revision 273767)
+++ cp/decl2.c  (working copy)
@@ -487,15 +487,19 @@ delete_sanity (tree exp, tree size, bool doing_vec
     }
 
   /* An array can't have been allocated by new, so complain.  */
-  if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
-    warning (0, "deleting array %q#E", exp);
+  if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
+      && (complain & tf_warning))
+    warning_at (cp_expr_loc_or_loc (exp, input_location), 0,
+               "deleting array %q#E", exp);
 
   t = build_expr_type_conversion (WANT_POINTER, exp, true);
 
   if (t == NULL_TREE || t == error_mark_node)
     {
-      error ("type %q#T argument given to %<delete%>, expected pointer",
-            TREE_TYPE (exp));
+      if (complain & tf_error)
+       error_at (cp_expr_loc_or_loc (exp, input_location),
+                 "type %q#T argument given to %<delete%>, expected pointer",
+                 TREE_TYPE (exp));
       return error_mark_node;
     }
 
@@ -506,8 +510,10 @@ delete_sanity (tree exp, tree size, bool doing_vec
   /* You can't delete functions.  */
   if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
     {
-      error ("cannot delete a function.  Only pointer-to-objects are "
-            "valid arguments to %<delete%>");
+      if (complain & tf_error)
+       error_at (cp_expr_loc_or_loc (exp, input_location),
+                 "cannot delete a function.  Only pointer-to-objects are "
+                 "valid arguments to %<delete%>");
       return error_mark_node;
     }
 
@@ -514,7 +520,10 @@ delete_sanity (tree exp, tree size, bool doing_vec
   /* Deleting ptr to void is undefined behavior [expr.delete/3].  */
   if (VOID_TYPE_P (TREE_TYPE (type)))
     {
-      warning (OPT_Wdelete_incomplete, "deleting %qT is undefined", type);
+      if (complain & tf_warning)
+       warning_at (cp_expr_loc_or_loc (exp, input_location),
+                   OPT_Wdelete_incomplete,
+                   "deleting %qT is undefined", type);
       doing_vec = 0;
     }
 
Index: testsuite/g++.dg/diagnostic/delete1.C
===================================================================
--- testsuite/g++.dg/diagnostic/delete1.C       (nonexistent)
+++ testsuite/g++.dg/diagnostic/delete1.C       (working copy)
@@ -0,0 +1,14 @@
+void f ()
+{
+  int a[1];
+  delete (a);  // { dg-warning "11:deleting array" }
+
+  bool b;
+  delete (b);  // { dg-error "11:type .bool. argument" }
+
+  void g ();
+  delete (g);  // { dg-error "11:cannot delete a function" }
+
+  void* p;
+  delete (p);  // { dg-warning "11:deleting .void*." }
+}

Reply via email to