public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4660] c++: improve fold-expr location
@ 2023-10-16 15:11 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2023-10-16 15:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:7550130c8620085c4efdde3575190588795f9b61

commit r14-4660-g7550130c8620085c4efdde3575190588795f9b61
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Oct 4 17:20:40 2023 -0400

    c++: improve fold-expr location
    
    I want to distinguish between constraint && and fold-expressions there of
    written by the user and those implied by template parameter
    type-constraints; to that end, let's improve our EXPR_LOCATION for an
    explicit fold-expression.
    
    The fold3.C change is needed because this moves the caret from the end of
    the expression to the operator, which means the location of the error refers
    to the macro invocation rather than the macro definition; both locations are
    still printed, but which one is an error and which a note changes.
    
    gcc/cp/ChangeLog:
    
            * parser.cc (cp_parser_fold_expression): Track location range.
            * semantics.cc (finish_unary_fold_expr)
            (finish_left_unary_fold_expr, finish_right_unary_fold_expr)
            (finish_binary_fold_expr): Add location parm.
            * constraint.cc (finish_shorthand_constraint): Pass it.
            * pt.cc (convert_generic_types_to_packs): Likewise.
            * cp-tree.h: Adjust.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/concepts/diagnostic3.C: Add expected column.
            * g++.dg/cpp1z/fold3.C: Adjust diagnostic lines.

Diff:
---
 gcc/cp/cp-tree.h                            |  6 +--
 gcc/cp/constraint.cc                        |  3 +-
 gcc/cp/parser.cc                            | 16 ++++++--
 gcc/cp/pt.cc                                |  4 +-
 gcc/cp/semantics.cc                         | 25 ++++++------
 gcc/testsuite/g++.dg/concepts/diagnostic3.C |  4 +-
 gcc/testsuite/g++.dg/cpp1z/fold3.C          | 62 ++++++++++++++---------------
 7 files changed, 66 insertions(+), 54 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6e34952da999..efcd2de54e53 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8209,9 +8209,9 @@ extern void maybe_warn_about_useless_cast       (location_t, tree, tree,
 						 tsubst_flags_t);
 extern tree cp_perform_integral_promotions      (tree, tsubst_flags_t);
 
-extern tree finish_left_unary_fold_expr      (tree, int);
-extern tree finish_right_unary_fold_expr     (tree, int);
-extern tree finish_binary_fold_expr          (tree, tree, int);
+extern tree finish_left_unary_fold_expr      (location_t, tree, int);
+extern tree finish_right_unary_fold_expr     (location_t, tree, int);
+extern tree finish_binary_fold_expr          (location_t, tree, tree, int);
 extern tree treat_lvalue_as_rvalue_p	     (tree, bool);
 extern bool decl_in_std_namespace_p	     (tree);
 extern void maybe_warn_pessimizing_move	     (tree, tree, bool);
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c9e4e7043cdc..64b64e178570 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1607,7 +1607,8 @@ finish_shorthand_constraint (tree decl, tree constr)
 
   /* Make the check a fold-expression if needed.  */
   if (apply_to_each_p && declared_pack_p)
-    check = finish_left_unary_fold_expr (check, TRUTH_ANDIF_EXPR);
+    check = finish_left_unary_fold_expr (DECL_SOURCE_LOCATION (decl),
+					 check, TRUTH_ANDIF_EXPR);
 
   return check;
 }
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index f3abae716fe2..59b9852895ec 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -5533,6 +5533,8 @@ static cp_expr
 cp_parser_fold_expression (cp_parser *parser, tree expr1)
 {
   cp_id_kind pidk;
+  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
+  const cp_token *token = nullptr;
 
   // Left fold.
   if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
@@ -5540,6 +5542,7 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1)
       if (expr1)
 	return error_mark_node;
       cp_lexer_consume_token (parser->lexer);
+      token = cp_lexer_peek_token (parser->lexer);
       int op = cp_parser_fold_operator (parser);
       if (op == ERROR_MARK)
         {
@@ -5551,10 +5554,11 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1)
 					     false, &pidk);
       if (expr == error_mark_node)
         return error_mark_node;
-      return finish_left_unary_fold_expr (expr, op);
+      loc = make_location (token->location, loc, parser->lexer);
+      return finish_left_unary_fold_expr (loc, expr, op);
     }
 
-  const cp_token* token = cp_lexer_peek_token (parser->lexer);
+  token = cp_lexer_peek_token (parser->lexer);
   int op = cp_parser_fold_operator (parser);
   if (op == ERROR_MARK)
     {
@@ -5585,7 +5589,10 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1)
 
   // Right fold.
   if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
-    return finish_right_unary_fold_expr (expr1, op);
+    {
+      loc = make_location (token->location, loc, parser->lexer);
+      return finish_right_unary_fold_expr (loc, expr1, op);
+    }
 
   if (cp_lexer_next_token_is_not (parser->lexer, token->type))
     {
@@ -5598,7 +5605,8 @@ cp_parser_fold_expression (cp_parser *parser, tree expr1)
   tree expr2 = cp_parser_cast_expression (parser, false, false, false, &pidk);
   if (expr2 == error_mark_node)
     return error_mark_node;
-  return finish_binary_fold_expr (expr1, expr2, op);
+  loc = make_location (token->location, loc, parser->lexer);
+  return finish_binary_fold_expr (loc, expr1, expr2, op);
 }
 
 /* Parse a primary-expression.
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 73ac1cb597cd..7cbf903ae29b 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31423,7 +31423,9 @@ convert_generic_types_to_packs (tree parm, int start_idx, int end_idx)
 	{
 	  tree id = unpack_concept_check (constr);
 	  TREE_VEC_ELT (TREE_OPERAND (id, 1), 0) = t;
-	  tree fold = finish_left_unary_fold_expr (constr, TRUTH_ANDIF_EXPR);
+	  location_t loc = DECL_SOURCE_LOCATION (TYPE_NAME (t));
+	  tree fold = finish_left_unary_fold_expr (loc, constr,
+						   TRUTH_ANDIF_EXPR);
 	  TEMPLATE_PARM_CONSTRAINTS (node) = fold;
 
 	  /* If there was a constraint, we also need to replace that in
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 80ef1364e339..2a0cf963e91b 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -12605,7 +12605,7 @@ capture_decltype (tree decl)
    this is a right unary fold. Otherwise it is a left unary fold. */
 
 static tree
-finish_unary_fold_expr (tree expr, int op, tree_code dir)
+finish_unary_fold_expr (location_t loc, tree expr, int op, tree_code dir)
 {
   /* Build a pack expansion (assuming expr has pack type).  */
   if (!uses_parameter_packs (expr))
@@ -12618,7 +12618,7 @@ finish_unary_fold_expr (tree expr, int op, tree_code dir)
 
   /* Build the fold expression.  */
   tree code = build_int_cstu (integer_type_node, abs (op));
-  tree fold = build_min_nt_loc (input_location, dir, code, pack);
+  tree fold = build_min_nt_loc (loc, dir, code, pack);
   FOLD_EXPR_MODIFY_P (fold) = (op < 0);
   TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
 						    FOLD_EXPR_OP (fold),
@@ -12627,27 +12627,28 @@ finish_unary_fold_expr (tree expr, int op, tree_code dir)
 }
 
 tree
-finish_left_unary_fold_expr (tree expr, int op)
+finish_left_unary_fold_expr (location_t loc, tree expr, int op)
 {
-  return finish_unary_fold_expr (expr, op, UNARY_LEFT_FOLD_EXPR);
+  return finish_unary_fold_expr (loc, expr, op, UNARY_LEFT_FOLD_EXPR);
 }
 
 tree
-finish_right_unary_fold_expr (tree expr, int op)
+finish_right_unary_fold_expr (location_t loc, tree expr, int op)
 {
-  return finish_unary_fold_expr (expr, op, UNARY_RIGHT_FOLD_EXPR);
+  return finish_unary_fold_expr (loc, expr, op, UNARY_RIGHT_FOLD_EXPR);
 }
 
 /* Build a binary fold expression over EXPR1 and EXPR2. The
    associativity of the fold is determined by EXPR1 and EXPR2 (whichever
    has an unexpanded parameter pack). */
 
-tree
-finish_binary_fold_expr (tree pack, tree init, int op, tree_code dir)
+static tree
+finish_binary_fold_expr (location_t loc, tree pack, tree init,
+			 int op, tree_code dir)
 {
   pack = make_pack_expansion (pack);
   tree code = build_int_cstu (integer_type_node, abs (op));
-  tree fold = build_min_nt_loc (input_location, dir, code, pack, init);
+  tree fold = build_min_nt_loc (loc, dir, code, pack, init);
   FOLD_EXPR_MODIFY_P (fold) = (op < 0);
   TREE_TYPE (fold) = build_dependent_operator_type (NULL_TREE,
 						    FOLD_EXPR_OP (fold),
@@ -12656,16 +12657,16 @@ finish_binary_fold_expr (tree pack, tree init, int op, tree_code dir)
 }
 
 tree
-finish_binary_fold_expr (tree expr1, tree expr2, int op)
+finish_binary_fold_expr (location_t loc, tree expr1, tree expr2, int op)
 {
   // Determine which expr has an unexpanded parameter pack and
   // set the pack and initial term.
   bool pack1 = uses_parameter_packs (expr1);
   bool pack2 = uses_parameter_packs (expr2);
   if (pack1 && !pack2)
-    return finish_binary_fold_expr (expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR);
+    return finish_binary_fold_expr (loc, expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR);
   else if (pack2 && !pack1)
-    return finish_binary_fold_expr (expr2, expr1, op, BINARY_LEFT_FOLD_EXPR);
+    return finish_binary_fold_expr (loc, expr2, expr1, op, BINARY_LEFT_FOLD_EXPR);
   else
     {
       if (pack1)
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic3.C b/gcc/testsuite/g++.dg/concepts/diagnostic3.C
index 410651a9c1ad..52b2f23c95e5 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic3.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic3.C
@@ -7,7 +7,7 @@ template<typename T>
   concept foo = (bool)(foo_v<T> | foo_v<T&>);
 
 template<typename... Ts>
-requires (foo<Ts> && ...) // { dg-message "with Ts = .int, char... evaluated to .false." }
+requires (foo<Ts> && ...) // { dg-message "19:with Ts = .int, char... evaluated to .false." }
 void
 bar()
 { }
@@ -16,7 +16,7 @@ template<int>
 struct S { };
 
 template<int... Is>
-requires (foo<S<Is>> && ...) // { dg-message "with Is = .2, 3, 4... evaluated to .false." }
+requires (foo<S<Is>> && ...) // { dg-message "22:with Is = .2, 3, 4... evaluated to .false." }
 void
 baz()
 { }
diff --git a/gcc/testsuite/g++.dg/cpp1z/fold3.C b/gcc/testsuite/g++.dg/cpp1z/fold3.C
index 787bf792be9b..a2561410ec47 100644
--- a/gcc/testsuite/g++.dg/cpp1z/fold3.C
+++ b/gcc/testsuite/g++.dg/cpp1z/fold3.C
@@ -7,44 +7,44 @@
 
 #define MAKE_FN(name, op) \
   template<typename... Ts> \
-    constexpr auto name (Ts... ts) { return (... op ts); } // { dg-error "empty" }
+    constexpr auto name (Ts... ts) { return (... op ts); } // { dg-message "" }
 
-MAKE_FN (add, +);
-MAKE_FN (sub, -);
-MAKE_FN (mul, *);
-MAKE_FN (div, /);
-MAKE_FN (mod, %);
-MAKE_FN (bxor, ^);
-MAKE_FN (bor, |);
-MAKE_FN (band, &);
-MAKE_FN (lsh, <<);
-MAKE_FN (rsh, >>);
+MAKE_FN (add, +);		// { dg-message "" }
+MAKE_FN (sub, -);		// { dg-message "" }
+MAKE_FN (mul, *);		// { dg-message "" }
+MAKE_FN (div, /);		// { dg-message "" }
+MAKE_FN (mod, %);		// { dg-message "" }
+MAKE_FN (bxor, ^);		// { dg-message "" }
+MAKE_FN (bor, |);		// { dg-message "" }
+MAKE_FN (band, &);		// { dg-message "" }
+MAKE_FN (lsh, <<);		// { dg-message "" }
+MAKE_FN (rsh, >>);		// { dg-message "" }
 
-MAKE_FN (assign, =);
-MAKE_FN (addi, +=);
-MAKE_FN (subi, -=);
-MAKE_FN (muli, *=);
-MAKE_FN (divi, /=);
-MAKE_FN (modi, %=);
-MAKE_FN (bxori, ^=);
-MAKE_FN (bori, |=);
-MAKE_FN (bandi, &=);
-MAKE_FN (lshi, <<=);
-MAKE_FN (rshi, >>=);
+MAKE_FN (assign, =);		// { dg-message "" }
+MAKE_FN (addi, +=);		// { dg-message "" }
+MAKE_FN (subi, -=);		// { dg-message "" }
+MAKE_FN (muli, *=);		// { dg-message "" }
+MAKE_FN (divi, /=);		// { dg-message "" }
+MAKE_FN (modi, %=);		// { dg-message "" }
+MAKE_FN (bxori, ^=);		// { dg-message "" }
+MAKE_FN (bori, |=);		// { dg-message "" }
+MAKE_FN (bandi, &=);		// { dg-message "" }
+MAKE_FN (lshi, <<=);		// { dg-message "" }
+MAKE_FN (rshi, >>=);		// { dg-message "" }
 
-MAKE_FN (eq, ==);
-MAKE_FN (ne, !=);
-MAKE_FN (lt, <);
-MAKE_FN (gt, >);
-MAKE_FN (le, <);
-MAKE_FN (ge, >);
+MAKE_FN (eq, ==);		// { dg-message "" }
+MAKE_FN (ne, !=);		// { dg-message "" }
+MAKE_FN (lt, <);		// { dg-message "" }
+MAKE_FN (gt, >);		// { dg-message "" }
+MAKE_FN (le, <);		// { dg-message "" }
+MAKE_FN (ge, >);		// { dg-message "" }
 
 MAKE_FN (land, &&);
 MAKE_FN (lor, ||);
 
 MAKE_FN (comma, COMMA);
-MAKE_FN (dot_star, .*);
-MAKE_FN (arrow_star, ->*);
+MAKE_FN (dot_star, .*);		// { dg-message "" }
+MAKE_FN (arrow_star, ->*);	// { dg-message "" }
 
 int main() {
   static_assert(land() == true, "");
@@ -52,7 +52,7 @@ int main() {
   comma(); // No value to theck
 
   // These are all errors, but the error is emitted at the point
-  // of instantiation (line 10).
+  // of macro definition or expansion above.
   add();			// { dg-message "required from here" }
   mul();			// { dg-message "required from here" }
   bor();			// { dg-message "required from here" }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-10-16 15:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-16 15:11 [gcc r14-4660] c++: improve fold-expr location Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).