[C++] Improve build_functional_cast locations

Message ID 54566c67-c294-9ae1-8972-fa909862a480@oracle.com
State New
Headers show
Series
  • [C++] Improve build_functional_cast locations
Related show

Commit Message

Paolo Carlini Dec. 4, 2019, 4:44 p.m.
Hi,

this exemplifies in a compact way the kind of change we can implement 
for the other casts too: near the end of cp_parser_functional_cast 
instead of using the combined_loc only for the returned cp_expr we can 
also pass it to build_functional_cast. Tested x86_64-linux.

Thanks, Paolo.

///////////////////////////
/gcc/cp
2019-12-04  Paolo Carlini  <paolo.carlini@oracle.com>

	* typeck2.c (build_functional_cast): Add location_t parameter
	and use it.
	* cp-tree.h: Update declaration.
	* parser.c (cp_parser_functional_cast): Adjust call.
	* call.c (build_op_delete_call): Likewise.
	(build_new_method_call_1): Likewise.
	* decl.c (check_initializer): Likewise.
	* pt.c (tsubst_copy_and_build): Likewise.
	* semantics.c (finish_compound_literal): Likewise.

/libcc1
2019-12-04  Paolo Carlini  <paolo.carlini@oracle.com>

	* libcp1plugin.cc (plugin_build_expression_list_expr): Adjust
	build_functional_cast call.

/testsuite
2019-12-04  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/diagnostic/functional-cast-to-array-type-1.C: New.
	* g++.dg/cpp0x/auto25.C: Check location(s) too.
	* g++.dg/cpp0x/auto28.C: Likewise.
	* g++.dg/init/reference2.C: Likewise.
	* g++.dg/parse/template2.C: Likewise.
	* g++.dg/template/error8.C: Likewise.
	* g++.old-deja/g++.ns/crash3.C: Likewise.
	* g++.old-deja/g++.ns/template7.C: Likewise.
	* g++.old-deja/g++.pt/crash8.C: Likewise.

Comments

Jason Merrill Dec. 4, 2019, 8:48 p.m. | #1
On 12/4/19 11:44 AM, Paolo Carlini wrote:
> Hi,

> 

> this exemplifies in a compact way the kind of change we can implement 

> for the other casts too: near the end of cp_parser_functional_cast 

> instead of using the combined_loc only for the returned cp_expr we can 

> also pass it to build_functional_cast. Tested x86_64-linux.


OK.

Jason

Patch

Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 278959)
+++ gcc/cp/call.c	(working copy)
@@ -6933,7 +6933,8 @@  build_op_delete_call (enum tree_code code, tree ad
 	      rtype = cv_unqualified (rtype);
 	      rtype = TYPE_POINTER_TO (rtype);
 	      addr = cp_convert (rtype, oaddr, complain);
-	      destroying = build_functional_cast (destroying, NULL_TREE,
+	      destroying = build_functional_cast (input_location,
+						  destroying, NULL_TREE,
 						  complain);
 	    }
 
@@ -9997,7 +9998,8 @@  build_new_method_call_1 (tree instance, tree fns,
 		     basetype, name))
 	inform (input_location, "for a function-style cast, remove the "
 		"redundant %<::%D%>", name);
-      call = build_functional_cast (basetype, build_tree_list_vec (user_args),
+      call = build_functional_cast (input_location, basetype,
+				    build_tree_list_vec (user_args),
 				    complain);
       return call;
     }
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 278959)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -7681,7 +7681,8 @@  extern tree build_scoped_ref			(tree, tree, tree *
 extern tree build_x_arrow			(location_t, tree,
 						 tsubst_flags_t);
 extern tree build_m_component_ref		(tree, tree, tsubst_flags_t);
-extern tree build_functional_cast		(tree, tree, tsubst_flags_t);
+extern tree build_functional_cast		(location_t, tree, tree,
+						 tsubst_flags_t);
 extern tree add_exception_specifier		(tree, tree, tsubst_flags_t);
 extern tree merge_exception_specifiers		(tree, tree);
 
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 278959)
+++ gcc/cp/decl.c	(working copy)
@@ -6764,7 +6764,8 @@  check_initializer (tree decl, tree init, int flags
 	      if (CLASS_TYPE_P (type)
 		  && (!init || TREE_CODE (init) == TREE_LIST))
 		{
-		  init = build_functional_cast (type, init, tf_none);
+		  init = build_functional_cast (input_location, type,
+						init, tf_none);
 		  if (TREE_CODE (init) == TARGET_EXPR)
 		    TARGET_EXPR_DIRECT_INIT_P (init) = true;
 		}
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 278959)
+++ gcc/cp/parser.c	(working copy)
@@ -29268,8 +29268,17 @@  cp_parser_functional_cast (cp_parser* parser, tree
       release_tree_vector (vec);
     }
 
-  cast = build_functional_cast (type, expression_list,
+  /* Create a location of the form:
+       float(i)
+       ^~~~~~~~
+     with caret == start at the start of the type name,
+     finishing at the closing paren.  */
+  location_t combined_loc = make_location (start_loc, start_loc,
+					   parser->lexer);
+  cast = build_functional_cast (combined_loc, type, expression_list,
                                 tf_warning_or_error);
+  cast.set_location (combined_loc);
+  
   /* [expr.const]/1: In an integral constant expression "only type
      conversions to integral or enumeration type can be used".  */
   if (TREE_CODE (type) == TYPE_DECL)
@@ -29280,13 +29289,6 @@  cp_parser_functional_cast (cp_parser* parser, tree
 						     NIC_CONSTRUCTOR))
     return error_mark_node;
 
-  /* Create a location of the form:
-       float(i)
-       ^~~~~~~~
-     with caret == start at the start of the type name,
-     finishing at the closing paren.  */
-  location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
-  cast.set_location (combined_loc);
   return cast;
 }
 
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 278959)
+++ gcc/cp/pt.c	(working copy)
@@ -19017,7 +19017,7 @@  tsubst_copy_and_build (tree t,
 	switch (TREE_CODE (t))
 	  {
 	  case CAST_EXPR:
-	    r = build_functional_cast (type, op, complain);
+	    r = build_functional_cast (input_location, type, op, complain);
 	    break;
 	  case REINTERPRET_CAST_EXPR:
 	    r = build_reinterpret_cast (type, op, complain);
Index: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 278959)
+++ gcc/cp/semantics.c	(working copy)
@@ -2929,7 +2929,8 @@  finish_compound_literal (tree type, tree compound_
 	 that it came from T{} rather than T({}).  */
       CONSTRUCTOR_IS_DIRECT_INIT (compound_literal) = 1;
       compound_literal = build_tree_list (NULL_TREE, compound_literal);
-      return build_functional_cast (type, compound_literal, complain);
+      return build_functional_cast (input_location, type,
+				    compound_literal, complain);
     }
 
   if (TREE_CODE (type) == ARRAY_TYPE
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 278959)
+++ gcc/cp/typeck2.c	(working copy)
@@ -2228,7 +2228,8 @@  build_m_component_ref (tree datum, tree component,
 /* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */
 
 tree
-build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
+build_functional_cast (location_t loc, tree exp, tree parms,
+		       tsubst_flags_t complain)
 {
   /* This is either a call to a constructor,
      or a C cast in C++'s `functional' notation.  */
@@ -2254,7 +2255,7 @@  tree
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
       if (complain & tf_error)
-	error ("functional cast to array type %qT", type);
+	error_at (loc, "functional cast to array type %qT", type);
       return error_mark_node;
     }
 
@@ -2263,7 +2264,7 @@  tree
       if (!CLASS_PLACEHOLDER_TEMPLATE (anode))
 	{
 	  if (complain & tf_error)
-	    error ("invalid use of %qT", anode);
+	    error_at (loc, "invalid use of %qT", anode);
 	  return error_mark_node;
 	}
       else if (!parms)
@@ -2276,8 +2277,8 @@  tree
 	  if (type == error_mark_node)
 	    {
 	      if (complain & tf_error)
-		error ("cannot deduce template arguments for %qT from %<()%>",
-		       anode);
+		error_at (loc, "cannot deduce template arguments "
+			  "for %qT from %<()%>", anode);
 	      return error_mark_node;
 	    }
 	}
@@ -2296,7 +2297,7 @@  tree
       if (TYPE_REF_P (type) && !parms)
 	{
 	  if (complain & tf_error)
-	    error ("invalid value-initialization of reference type");
+	    error_at (loc, "invalid value-initialization of reference type");
 	  return error_mark_node;
 	}
 
Index: gcc/testsuite/g++.dg/cpp0x/auto25.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/auto25.C	(revision 278959)
+++ gcc/testsuite/g++.dg/cpp0x/auto25.C	(working copy)
@@ -3,10 +3,10 @@ 
 
 template<int> struct A
 {
-  int a[auto(1)]; // { dg-error "invalid use of" }
+  int a[auto(1)]; // { dg-error "9:invalid use of" }
 };
 
 template<int> void foo()
 {
-  int a[auto(1)]; // { dg-error "invalid use of" }
+  int a[auto(1)]; // { dg-error "9:invalid use of" }
 }
Index: gcc/testsuite/g++.dg/cpp0x/auto28.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/auto28.C	(revision 278959)
+++ gcc/testsuite/g++.dg/cpp0x/auto28.C	(working copy)
@@ -1,4 +1,4 @@ 
 // PR c++/51404
 // { dg-do compile { target c++11 } }
 
-int i = auto().x;  // { dg-error "invalid use of" }
+int i = auto().x;  // { dg-error "9:invalid use of" }
Index: gcc/testsuite/g++.dg/diagnostic/functional-cast-to-array-type-1.C
===================================================================
--- gcc/testsuite/g++.dg/diagnostic/functional-cast-to-array-type-1.C	(nonexistent)
+++ gcc/testsuite/g++.dg/diagnostic/functional-cast-to-array-type-1.C	(working copy)
@@ -0,0 +1,2 @@ 
+typedef int A [1];
+A a = A(1);  // { dg-error "7:functional cast to array type" }
Index: gcc/testsuite/g++.dg/init/reference2.C
===================================================================
--- gcc/testsuite/g++.dg/init/reference2.C	(revision 278959)
+++ gcc/testsuite/g++.dg/init/reference2.C	(working copy)
@@ -8,6 +8,6 @@  template <int a1>
 void f()
 {
   typedef int& T;
-  T a = T();  // { dg-error "value-initialization of reference" }
+  T a = T();  // { dg-error "9:invalid value-initialization of reference" }
 }
 
Index: gcc/testsuite/g++.dg/parse/template2.C
===================================================================
--- gcc/testsuite/g++.dg/parse/template2.C	(revision 278959)
+++ gcc/testsuite/g++.dg/parse/template2.C	(working copy)
@@ -3,5 +3,6 @@  namespace N {
 }
 
 int main() {
-  N::C(); // { dg-error "template|deduction" }
+  N::C(); // { dg-error "6:cannot deduce template arguments" "" { target c++17 } }
+  // { dg-error "7:missing template arguments" "" { target c++14_down } .-1 }
 }
Index: gcc/testsuite/g++.dg/template/error8.C
===================================================================
--- gcc/testsuite/g++.dg/template/error8.C	(revision 278959)
+++ gcc/testsuite/g++.dg/template/error8.C	(working copy)
@@ -3,5 +3,6 @@ 
 template <typename T> struct S {};
 
 void f() {
-  throw S (); // { dg-error "template" }
+  throw S (); // { dg-error "9:cannot deduce template arguments" "" { target c++17 } }
+  // { dg-error "11:missing template arguments" "" { target c++14_down } .-1 }
 }
Index: gcc/testsuite/g++.old-deja/g++.ns/crash3.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.ns/crash3.C	(revision 278959)
+++ gcc/testsuite/g++.old-deja/g++.ns/crash3.C	(working copy)
@@ -6,5 +6,6 @@  namespace N {
 
 void f()
 {
-  N::S(); // { dg-error "" } invalid use of template
+  N::S(); // { dg-error "6:cannot deduce template arguments" "" { target c++17 } } invalid use of template
+  // { dg-error "7:missing template arguments" "" { target c++14_down } .-1 }
 }
Index: gcc/testsuite/g++.old-deja/g++.ns/template7.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.ns/template7.C	(revision 278959)
+++ gcc/testsuite/g++.old-deja/g++.ns/template7.C	(working copy)
@@ -8,5 +8,6 @@  namespace foo {
 }
 
 void baz() {
-  foo::bar(); // { dg-error "" } template used as expression
+  foo::bar(); // { dg-error "8:cannot deduce template arguments" "" { target c++17 } } template used as expression
+  // { dg-error "11:missing template arguments" "" { target c++14_down } .-1 }
 }
Index: gcc/testsuite/g++.old-deja/g++.pt/crash8.C
===================================================================
--- gcc/testsuite/g++.old-deja/g++.pt/crash8.C	(revision 278959)
+++ gcc/testsuite/g++.old-deja/g++.pt/crash8.C	(working copy)
@@ -21,10 +21,12 @@  void doit(T x) {
   q2 = TestClass2<T>();
 
   TestClass1<T> p1;
-  p1 = TestClass1(); // { dg-error "" } template used as expression
+  p1 = TestClass1(); // { dg-error "8:cannot deduce template arguments" "" { target c++17 } } template used as expression
+  // { dg-error "18:missing template arguments" "" { target c++14_down } .-1 }
 
   TestClass2<T> p2;
-  p2 = TestClass2(); // { dg-error "" } template used as expression
+  p2 = TestClass2(); // { dg-error "8:cannot deduce template arguments" "" { target c++17 } } template used as expression
+  // { dg-error "18:missing template arguments" "" { target c++14_down } .-1 }
 }
 
 int main() {
Index: libcc1/libcp1plugin.cc
===================================================================
--- libcc1/libcp1plugin.cc	(revision 278959)
+++ libcc1/libcp1plugin.cc	(working copy)
@@ -3155,7 +3155,7 @@  plugin_build_expression_list_expr (cc1_plugin::con
     case CHARS2 ('c', 'v'): // conversion with parenthesized expression list
       gcc_assert (TYPE_P (type));
       args = args_to_tree_list (values_in);
-      result = build_functional_cast (type, args, tf_error);
+      result = build_functional_cast (input_location, type, args, tf_error);
       break;
 
     case CHARS2 ('t', 'l'): // conversion with braced expression list