call.c (resolve_args): Use cp_expr_loc_or_input_loc in one place.
authorPaolo Carlini <paolo.carlini@oracle.com>
Mon, 7 Oct 2019 15:37:52 +0000 (15:37 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Mon, 7 Oct 2019 15:37:52 +0000 (15:37 +0000)
/cp
2019-10-07  Paolo Carlini  <paolo.carlini@oracle.com>

* call.c (resolve_args): Use cp_expr_loc_or_input_loc in one place.
* decl.c (grokdeclarator): Use id_loc in one place.
* decl2.c (build_anon_union_vars): Use DECL_SOURCE_LOCATION.
* parser.c (cp_parser_delete_expression): Fix the location of the
returned expression.
(cp_parser_throw_expression): Likewise.
* pt.c (determine_specialization): Use DECL_SOURCE_LOCATION.

/testsuite
2019-10-07  Paolo Carlini  <paolo.carlini@oracle.com>

* g++.dg/diagnostic/not-a-function-template-1.C: New.
* g++.dg/template/crash107.C: Adjust expected location.
* g++.dg/template/dependent-expr1.C: Check locations.
* g++.dg/template/error17.C: Check location.

From-SVN: r276661

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/crash107.C
gcc/testsuite/g++.dg/template/dependent-expr1.C
gcc/testsuite/g++.dg/template/error17.C

index b40825ee8696c98e1d5803ab2cebdb9b4475971b..90cab94e88ea5ffa6536b68486ab1e0868f76fb2 100644 (file)
@@ -1,3 +1,13 @@
+2019-10-07  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * call.c (resolve_args): Use cp_expr_loc_or_input_loc in one place.
+       * decl.c (grokdeclarator): Use id_loc in one place.
+       * decl2.c (build_anon_union_vars): Use DECL_SOURCE_LOCATION.
+       * parser.c (cp_parser_delete_expression): Fix the location of the
+       returned expression.
+       (cp_parser_throw_expression): Likewise.
+       * pt.c (determine_specialization): Use DECL_SOURCE_LOCATION.
+
 2019-10-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/91369 - Implement P0784R7: constexpr new
index 56dcbd391c139dd615b34f3378a121d72e7e8770..6c9acac4614d27fec215be22d3a09dc921815518 100644 (file)
@@ -4381,7 +4381,8 @@ resolve_args (vec<tree, va_gc> *args, tsubst_flags_t complain)
       else if (VOID_TYPE_P (TREE_TYPE (arg)))
        {
          if (complain & tf_error)
-           error ("invalid use of void expression");
+           error_at (cp_expr_loc_or_input_loc (arg),
+                     "invalid use of void expression");
          return NULL;
        }
       else if (invalid_nonstatic_memfn_p (EXPR_LOCATION (arg), arg, complain))
index ea9a0011e24a635cfc290ef7bd22c35e1f876f05..e4053679362af84302d1dfb557a3241ac120fa54 100644 (file)
@@ -12754,8 +12754,8 @@ grokdeclarator (const cp_declarator *declarator,
                tree tmpl = TREE_OPERAND (unqualified_id, 0);
                if (variable_template_p (tmpl))
                  {
-                   error ("specialization of variable template %qD "
-                          "declared as function", tmpl);
+                   error_at (id_loc, "specialization of variable template "
+                             "%qD declared as function", tmpl);
                    inform (DECL_SOURCE_LOCATION (tmpl),
                            "variable template declared here");
                    return error_mark_node;
index 8f935e8656d36289841fca0c230b9944ecbb72ff..a28e7762a34cbc1a7330b455512fa5ba20aa66bf 100644 (file)
@@ -1608,7 +1608,8 @@ build_anon_union_vars (tree type, tree object)
      just give an error.  */
   if (TREE_CODE (type) != UNION_TYPE)
     {
-      error ("anonymous struct not inside named type");
+      error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+               "anonymous struct not inside named type");
       return error_mark_node;
     }
 
index 018a03d4965655333012e762aba69870535256e3..c61e0b2cb9d0cbee372610f45041ba5f68beb284 100644 (file)
@@ -9014,6 +9014,7 @@ cp_parser_delete_expression (cp_parser* parser)
   bool global_scope_p;
   bool array_p;
   tree expression;
+  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
 
   /* Look for the optional `::' operator.  */
   global_scope_p
@@ -9043,8 +9044,18 @@ cp_parser_delete_expression (cp_parser* parser)
   if (cp_parser_non_integral_constant_expression (parser, NIC_DEL))
     return error_mark_node;
 
-  return delete_sanity (expression, NULL_TREE, array_p, global_scope_p,
-                       tf_warning_or_error);
+  /* Construct a location e.g.:
+       delete [ ] ptr
+       ^~~~~~~~~~~~~~
+     with caret == start at the start of the "delete" token, and
+     the end at the end of the final token we consumed.  */
+  location_t combined_loc = make_location (start_loc, start_loc,
+                                          parser->lexer);
+  expression = delete_sanity (expression, NULL_TREE, array_p,
+                             global_scope_p, tf_warning_or_error);
+  protected_set_expr_location (expression, combined_loc);
+
+  return expression;
 }
 
 /* Returns 1 if TOKEN may start a cast-expression and isn't '++', '--',
@@ -25827,6 +25838,7 @@ cp_parser_throw_expression (cp_parser* parser)
 {
   tree expression;
   cp_token* token;
+  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
 
   cp_parser_require_keyword (parser, RID_THROW, RT_THROW);
   token = cp_lexer_peek_token (parser->lexer);
@@ -25842,7 +25854,17 @@ cp_parser_throw_expression (cp_parser* parser)
   else
     expression = cp_parser_assignment_expression (parser);
 
-  return build_throw (expression);
+  /* Construct a location e.g.:
+       throw x
+       ^~~~~~~
+     with caret == start at the start of the "throw" token, and
+     the end at the end of the final token we consumed.  */
+  location_t combined_loc = make_location (start_loc, start_loc,
+                                          parser->lexer);
+  expression = build_throw (expression);
+  protected_set_expr_location (expression, combined_loc);
+
+  return expression;
 }
 
 /* GNU Extensions */
index 67b3b63cdfe07fee766c394ad8de9f66e04f5920..6310e7b399beb5abda2daae854e6cd8cee6597dd 100644 (file)
@@ -2137,7 +2137,8 @@ determine_specialization (tree template_id,
 
   if (TREE_CODE (decl) == FUNCTION_DECL && !is_overloaded_fn (fns))
     {
-      error ("%qD is not a function template", fns);
+      error_at (DECL_SOURCE_LOCATION (decl),
+               "%qD is not a function template", fns);
       return error_mark_node;
     }
   else if (VAR_P (decl) && !variable_template_p (fns))
@@ -2416,7 +2417,8 @@ determine_specialization (tree template_id,
       error ("template-id %qD for %q+D does not match any template "
             "declaration", template_id, decl);
       if (header_count && header_count != template_count + 1)
-       inform (input_location, "saw %d %<template<>%>, need %d for "
+       inform (DECL_SOURCE_LOCATION (decl),
+               "saw %d %<template<>%>, need %d for "
                "specializing a member function template",
                header_count, template_count + 1);
       else
index 01253be441d21323038c2f6e4d90daa59e498716..e851acdd47f003ac9dc94e3f71460b19f237b3a0 100644 (file)
@@ -1,3 +1,10 @@
+2019-10-07  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * g++.dg/diagnostic/not-a-function-template-1.C: New.
+       * g++.dg/template/crash107.C: Adjust expected location.
+       * g++.dg/template/dependent-expr1.C: Check locations.
+       * g++.dg/template/error17.C: Check location.
+
 2019-10-07  Richard Sandiford  <richard.sandiford@arm.com>
 
        PR target/91994
diff --git a/gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C b/gcc/testsuite/g++.dg/diagnostic/not-a-function-template-1.C
new file mode 100644 (file)
index 0000000..caf8afa
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile { target c++14 } }
+
+template<typename> int A;  // { dg-message "24:variable template" }
+
+template int A<>();  // { dg-error "14:template<class>" }
+
+struct B {
+  friend int A<>();  // { dg-error "14:specialization" }
+};
index cecf90132444351d2a31edc072a2c21bdc133b6e..3b0b4e8211f30798b9f0b0c64abaf9979a40ec0c 100644 (file)
@@ -6,8 +6,8 @@
 template<typename FP_> struct Vec { // { dg-message "note" }
     Vec& operator^=(Vec& rhs)     {
         union {
-            struct {FP_ x,y,z;};
-        }; // { dg-error "anonymous struct" }
+            struct {FP_ x,y,z;}; // { dg-error "20:anonymous struct" }
+        };
         X = y*rhs.z() - z*rhs.y(); // { dg-error "not declared|no member" }
     }
     Vec& operator^(Vec& rhs) {
index 79649861ba47e3107b324d03029c46c8ba996333..eda7526e1b12a506aa60733917afb723a49bc446 100644 (file)
@@ -19,11 +19,11 @@ namespace std
     Foo (sizeof (x));
     Foo (__alignof__ (I));
     Foo (__alignof__ (x));
-    Foo (x->~I ()); // { dg-error "" }
+    Foo (x->~I ()); // { dg-error "16:invalid" }
     //    Foo (typeid (I));
-    Foo (delete x); // { dg-error "" }
-    Foo (delete[] x); // { dg-error "" }
-    Foo (throw x); // { dg-error "" }
+    Foo (delete x); // { dg-error "10:invalid" }
+    Foo (delete[] x); // { dg-error "10:invalid" }
+    Foo (throw x); // { dg-error "10:invalid" }
   }
 
 }
index 30a693f84d123e87c3ea375abc731ef85050477c..5b3281a1779c388a245a8bdfd39b78c2ad61104d 100644 (file)
@@ -5,5 +5,5 @@ void
 foo()
 {
   union { struct { }; }; // { dg-error "prohibits anonymous struct" "anon" }
-  // { dg-error "not inside" "not inside" { target *-*-* } .-1 }
+  // { dg-error "18:anonymous struct not inside" "not inside" { target *-*-* } .-1 }
 }