PR debug/65821 - wrong location for main().
authorJason Merrill <jason@redhat.com>
Tue, 10 Apr 2018 17:19:09 +0000 (13:19 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 10 Apr 2018 17:19:09 +0000 (13:19 -0400)
* call.c (clear_location_r, convert_default_arg): Revert.
* tree.c (break_out_target_exprs): Add clear_location parm.
(struct bot_data): New.
(bot_manip): Clear location if requested.
* init.c (get_nsdmi): Pass clear_location.

From-SVN: r259291

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/tree.c

index b6e7ee4..0f93be7 100644 (file)
@@ -1,3 +1,12 @@
+2018-04-10  Jason Merrill  <jason@redhat.com>
+
+       PR debug/65821 - wrong location for main().
+       * call.c (clear_location_r, convert_default_arg): Revert.
+       * tree.c (break_out_target_exprs): Add clear_location parm.
+       (struct bot_data): New.
+       (bot_manip): Clear location if requested.
+       * init.c (get_nsdmi): Pass clear_location.
+
 2018-04-10  David Malcolm  <dmalcolm@redhat.com>
 
        PR c++/85110
index 9ecb91d..fb6d71d 100644 (file)
@@ -7296,21 +7296,6 @@ cxx_type_promotes_to (tree type)
   return promote;
 }
 
-/* walk_tree callback to override EXPR_LOCATION in an expression tree.  */
-
-tree
-clear_location_r (tree *tp, int *walk_subtrees, void */*data*/)
-{
-  if (!EXPR_P (*tp))
-    {
-      *walk_subtrees = 0;
-      return NULL_TREE;
-    }
-  if (EXPR_HAS_LOCATION (*tp))
-    SET_EXPR_LOCATION (*tp, input_location);
-  return NULL_TREE;
-}
-
 /* ARG is a default argument expression being passed to a parameter of
    the indicated TYPE, which is a parameter to FN.  PARMNUM is the
    zero-based argument number.  Do any required conversions.  Return
@@ -7374,11 +7359,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum,
   push_deferring_access_checks (dk_no_check);
   /* We must make a copy of ARG, in case subsequent processing
      alters any part of it.  */
-  arg = break_out_target_exprs (arg);
-
-  /* The use of a default argument has the location of the call, not where it
-     was originally written.  */
-  cp_walk_tree_without_duplicates (&arg, clear_location_r, NULL);
+  arg = break_out_target_exprs (arg, /*clear location*/true);
 
   arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
                                    ICR_DEFAULT_ARGUMENT, fn, parmnum,
index 7d3e017..d0f8760 100644 (file)
@@ -7060,7 +7060,7 @@ extern tree build_exception_variant               (tree, tree);
 extern tree bind_template_template_parm                (tree, tree);
 extern tree array_type_nelts_total             (tree);
 extern tree array_type_nelts_top               (tree);
-extern tree break_out_target_exprs             (tree);
+extern tree break_out_target_exprs             (tree, bool = false);
 extern tree build_ctor_subob_ref               (tree, tree, tree);
 extern tree replace_placeholders               (tree, tree, bool * = NULL);
 extern bool find_placeholders                  (tree);
index e52cd64..5bc8394 100644 (file)
@@ -634,7 +634,7 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
   bool simple_target = (init && SIMPLE_TARGET_EXPR_P (init));
   if (simple_target)
     init = TARGET_EXPR_INITIAL (init);
-  init = break_out_target_exprs (init);
+  init = break_out_target_exprs (init, /*loc*/true);
   if (simple_target && TREE_CODE (init) != CONSTRUCTOR)
     /* Now put it back so C++17 copy elision works.  */
     init = get_target_expr (init);
index 18e7793..dbe84c0 100644 (file)
@@ -2908,12 +2908,19 @@ array_type_nelts_total (tree type)
   return sz;
 }
 
+struct bot_data
+{
+  splay_tree target_remap;
+  bool clear_location;
+};
+
 /* Called from break_out_target_exprs via mapcar.  */
 
 static tree
-bot_manip (tree* tp, int* walk_subtrees, void* data)
+bot_manip (tree* tp, int* walk_subtrees, void* data_)
 {
-  splay_tree target_remap = ((splay_tree) data);
+  bot_data &data = *(bot_data*)data_;
+  splay_tree target_remap = data.target_remap;
   tree t = *tp;
 
   if (!TYPE_P (t) && TREE_CONSTANT (t) && !TREE_SIDE_EFFECTS (t))
@@ -2953,7 +2960,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
                         (splay_tree_key) TREE_OPERAND (t, 0),
                         (splay_tree_value) TREE_OPERAND (u, 0));
 
-      TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1));
+      TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1),
+                                                   data.clear_location);
       if (TREE_OPERAND (u, 1) == error_mark_node)
        return error_mark_node;
 
@@ -2993,6 +3001,8 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
   t = copy_tree_r (tp, walk_subtrees, NULL);
   if (TREE_CODE (*tp) == CALL_EXPR)
     set_flags_from_callee (*tp);
+  if (data.clear_location && EXPR_HAS_LOCATION (*tp))
+    SET_EXPR_LOCATION (*tp, input_location);
   return t;
 }
 
@@ -3001,9 +3011,10 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
    variables.  */
 
 static tree
-bot_replace (tree* t, int* /*walk_subtrees*/, void* data)
+bot_replace (tree* t, int* /*walk_subtrees*/, void* data_)
 {
-  splay_tree target_remap = ((splay_tree) data);
+  bot_data &data = *(bot_data*)data_;
+  splay_tree target_remap = data.target_remap;
 
   if (VAR_P (*t))
     {
@@ -3041,10 +3052,13 @@ bot_replace (tree* t, int* /*walk_subtrees*/, void* data)
 /* When we parse a default argument expression, we may create
    temporary variables via TARGET_EXPRs.  When we actually use the
    default-argument expression, we make a copy of the expression
-   and replace the temporaries with appropriate local versions.  */
+   and replace the temporaries with appropriate local versions.
+
+   If CLEAR_LOCATION is true, override any EXPR_LOCATION with
+   input_location.  */
 
 tree
-break_out_target_exprs (tree t)
+break_out_target_exprs (tree t, bool clear_location /* = false */)
 {
   static int target_remap_count;
   static splay_tree target_remap;
@@ -3053,9 +3067,10 @@ break_out_target_exprs (tree t)
     target_remap = splay_tree_new (splay_tree_compare_pointers,
                                   /*splay_tree_delete_key_fn=*/NULL,
                                   /*splay_tree_delete_value_fn=*/NULL);
-  if (cp_walk_tree (&t, bot_manip, target_remap, NULL) == error_mark_node)
+  bot_data data = { target_remap, clear_location };
+  if (cp_walk_tree (&t, bot_manip, &data, NULL) == error_mark_node)
     t = error_mark_node;
-  cp_walk_tree (&t, bot_replace, target_remap, NULL);
+  cp_walk_tree (&t, bot_replace, &data, NULL);
 
   if (!--target_remap_count)
     {