Defer folding of *&.
authorJason Merrill <jason@redhat.com>
Mon, 13 Nov 2017 22:12:55 +0000 (17:12 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 13 Nov 2017 22:12:55 +0000 (17:12 -0500)
* typeck.c (cp_build_fold_indirect_ref): New.
(cp_build_indirect_ref_1): Split out from cp_build_indirect_ref.
Add 'fold' parameter.
* cp-tree.h: Declare cp_build_fold_indirect_ref.
* call.c, class.c, cp-ubsan.c, decl.c, except.c, init.c, lambda.c,
parser.c, rtti.c, tree.c, typeck.c, typeck2.c: Use it.
* parser.c (do_range_for_auto_deduction): Use RO_UNARY_STAR.
(cp_convert_range_for): Likewise.
* typeck2.c (build_x_arrow): Use RO_ARROW.

From-SVN: r254712

14 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cp-ubsan.c
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/lambda.c
gcc/cp/parser.c
gcc/cp/rtti.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/cp/typeck2.c

index 83cb401f51d3024e723efe5ea88ee2f82294bdc2..f71506b4ac2f08257b0fba084ab2eaaf85123d69 100644 (file)
@@ -1,5 +1,16 @@
 2017-11-13  Jason Merrill  <jason@redhat.com>
 
+       Defer folding of *&.
+       * typeck.c (cp_build_fold_indirect_ref): New.
+       (cp_build_indirect_ref_1): Split out from cp_build_indirect_ref.
+       Add 'fold' parameter.
+       * cp-tree.h: Declare cp_build_fold_indirect_ref.
+       * call.c, class.c, cp-ubsan.c, decl.c, except.c, init.c, lambda.c,
+       parser.c, rtti.c, tree.c, typeck.c, typeck2.c: Use it.
+       * parser.c (do_range_for_auto_deduction): Use RO_UNARY_STAR.
+       (cp_convert_range_for): Likewise.
+       * typeck2.c (build_x_arrow): Use RO_ARROW.
+
        * cp-ubsan.c (cp_ubsan_check_member_access_r): Fix handling of
        INDIRECT_REF of ADDR_EXPR.
 
index e6e0f9011668d6200d85e08be7a5481df174eb0d..e18f0770614e0264d5fcf193b370dec07b9e56ff 100644 (file)
@@ -8063,7 +8063,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       if (targ)
        arg = targ;
       else
-       arg = cp_build_indirect_ref (arg, RO_NULL, complain);
+       arg = cp_build_fold_indirect_ref (arg);
 
       /* In C++17 we shouldn't be copying a TARGET_EXPR except into a base
         subobject.  */
@@ -8100,9 +8100,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       else if ((trivial || TREE_CODE (arg) == TARGET_EXPR)
               && !unsafe_copy_elision_p (fa, arg))
        {
-         tree to = cp_stabilize_reference (cp_build_indirect_ref (fa,
-                                                                  RO_NULL,
-                                                                  complain));
+         tree to = cp_stabilize_reference (cp_build_fold_indirect_ref (fa));
 
          val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
          return val;
@@ -8114,7 +8112,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
           && !DECL_DELETED_FN (fn))
     {
       tree to = cp_stabilize_reference
-       (cp_build_indirect_ref (argarray[0], RO_NULL, complain));
+       (cp_build_fold_indirect_ref (argarray[0]));
       tree type = TREE_TYPE (to);
       tree as_base = CLASSTYPE_AS_BASE (type);
       tree arg = argarray[1];
@@ -8127,7 +8125,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
        }
       else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
        {
-         arg = cp_build_indirect_ref (arg, RO_NULL, complain);
+         arg = cp_build_fold_indirect_ref (arg);
          val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
          /* Handle NSDMI that refer to the object being initialized.  */
          replace_placeholders (arg, to);
@@ -8166,7 +8164,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
            return force_target_expr (DECL_CONTEXT (fn), void_node,
                                      no_cleanup_complain);
          else
-           return cp_build_indirect_ref (argarray[0], RO_NULL, complain);
+           return cp_build_fold_indirect_ref (argarray[0]);
        }
     }
 
index 98e62c6ad45009b0710e57060cd8a1c998bc9dd4..586a32c436f7960fa172d43af8d47dff15027e20 100644 (file)
@@ -425,7 +425,7 @@ build_base_path (enum tree_code code,
         interesting to the optimizers anyway.  */
       && !has_empty)
     {
-      expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+      expr = cp_build_fold_indirect_ref (expr);
       expr = build_simple_base_path (expr, binfo);
       if (rvalue)
        expr = move (expr);
@@ -452,7 +452,7 @@ build_base_path (enum tree_code code,
          t = TREE_TYPE (TYPE_VFIELD (current_class_type));
          t = build_pointer_type (t);
          v_offset = fold_convert (t, current_vtt_parm);
-         v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
+         v_offset = cp_build_fold_indirect_ref (v_offset);
        }
       else
        {
@@ -465,8 +465,7 @@ build_base_path (enum tree_code code,
              if (t == NULL_TREE)
                t = expr;
            }
-         v_offset = build_vfield_ref (cp_build_indirect_ref (t, RO_NULL,
-                                                             complain),
+         v_offset = build_vfield_ref (cp_build_fold_indirect_ref (t),
          TREE_TYPE (TREE_TYPE (expr)));
        }
 
@@ -477,7 +476,7 @@ build_base_path (enum tree_code code,
       v_offset = build1 (NOP_EXPR,
                         build_pointer_type (ptrdiff_type_node),
                         v_offset);
-      v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain);
+      v_offset = cp_build_fold_indirect_ref (v_offset);
       TREE_CONSTANT (v_offset) = 1;
 
       offset = convert_to_integer (ptrdiff_type_node,
@@ -516,7 +515,7 @@ build_base_path (enum tree_code code,
  indout:
   if (!want_pointer)
     {
-      expr = cp_build_indirect_ref (expr, RO_NULL, complain);
+      expr = cp_build_fold_indirect_ref (expr);
       if (rvalue)
        expr = move (expr);
     }
@@ -552,7 +551,7 @@ build_simple_base_path (tree expr, tree binfo)
         in the back end.  */
       temp = unary_complex_lvalue (ADDR_EXPR, expr);
       if (temp)
-       expr = cp_build_indirect_ref (temp, RO_NULL, tf_warning_or_error);
+       expr = cp_build_fold_indirect_ref (temp);
 
       return expr;
     }
@@ -745,8 +744,7 @@ build_vfn_ref (tree instance_ptr, tree idx)
 {
   tree aref;
 
-  aref = build_vtbl_ref_1 (cp_build_indirect_ref (instance_ptr, RO_NULL,
-                                                  tf_warning_or_error), 
+  aref = build_vtbl_ref_1 (cp_build_fold_indirect_ref (instance_ptr),
                            idx);
 
   /* When using function descriptors, the address of the
index 874cbcbd2bd78ea66f99958fb6b92b74c2372cba..ea61e87b2ec81e512c0dcbfb1130d212fd94753c 100644 (file)
@@ -7056,6 +7056,7 @@ extern tree build_x_indirect_ref          (location_t, tree,
                                                 ref_operator, tsubst_flags_t);
 extern tree cp_build_indirect_ref              (tree, ref_operator,
                                                  tsubst_flags_t);
+extern tree cp_build_fold_indirect_ref         (tree);
 extern tree build_array_ref                    (location_t, tree, tree);
 extern tree cp_build_array_ref                 (location_t, tree, tree,
                                                 tsubst_flags_t);
index 73198b9cff266d3b4f8f7fc36501d44fb20ebb4b..c87c0303f57d841f1c8b0098df5d015a851f4194 100644 (file)
@@ -298,8 +298,7 @@ cp_ubsan_dfs_initialize_vtbl_ptrs (tree binfo, void *data)
 
       /* Compute the location of the vtpr.  */
       tree vtbl_ptr
-       = build_vfield_ref (cp_build_indirect_ref (base_ptr, RO_NULL,
-                                                  tf_warning_or_error),
+       = build_vfield_ref (cp_build_fold_indirect_ref (base_ptr),
                            TREE_TYPE (binfo));
       gcc_assert (vtbl_ptr != error_mark_node);
 
index 0ce8f2d343589677e7e8113179a345f8f5b69a37..54077d5e331aa608a97b1d568f576991b59adc98 100644 (file)
@@ -14899,7 +14899,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
       gcc_assert (TYPE_PTR_P (TREE_TYPE (t)));
 
       cp_function_chain->x_current_class_ref
-       = cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
+       = cp_build_fold_indirect_ref (t);
       /* Set this second to avoid shortcut in cp_build_indirect_ref.  */
       cp_function_chain->x_current_class_ptr = t;
 
index ecc8941984b317b4140d21f94935ae7ffd8f1d33..47f267ffb93d93063ee8892c6a2d1456ef43ae3b 100644 (file)
@@ -664,7 +664,7 @@ build_throw (tree exp)
       CLEANUP_EH_ONLY (allocate_expr) = 1;
 
       object = build_nop (build_pointer_type (temp_type), ptr);
-      object = cp_build_indirect_ref (object, RO_NULL, tf_warning_or_error);
+      object = cp_build_fold_indirect_ref (object);
 
       /* And initialize the exception object.  */
       if (CLASS_TYPE_P (temp_type))
index 1fcd91d108db64eb7ee9a08510923cde1525d9ad..1084ab1aa013a1f51f03cec977736623730adb8a 100644 (file)
@@ -1260,8 +1260,7 @@ emit_mem_initializers (tree mem_inits)
          base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
                                       subobject, 1, tf_warning_or_error);
          expand_aggr_init_1 (subobject, NULL_TREE,
-                             cp_build_indirect_ref (base_addr, RO_NULL,
-                                                     tf_warning_or_error),
+                             cp_build_fold_indirect_ref (base_addr),
                              arguments,
                              flags,
                               tf_warning_or_error);
@@ -1351,7 +1350,7 @@ expand_virtual_init (tree binfo, tree decl)
       /* Compute the value to use, when there's a VTT.  */
       vtt_parm = current_vtt_parm;
       vtbl2 = fold_build_pointer_plus (vtt_parm, vtt_index);
-      vtbl2 = cp_build_indirect_ref (vtbl2, RO_NULL, tf_warning_or_error);
+      vtbl2 = cp_build_fold_indirect_ref (vtbl2);
       vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
 
       /* The actual initializer is the VTT value only in the subobject
@@ -1361,8 +1360,7 @@ expand_virtual_init (tree binfo, tree decl)
     }
 
   /* Compute the location of the vtpr.  */
-  vtbl_ptr = build_vfield_ref (cp_build_indirect_ref (decl, RO_NULL, 
-                                                      tf_warning_or_error),
+  vtbl_ptr = build_vfield_ref (cp_build_fold_indirect_ref (decl),
                               TREE_TYPE (binfo));
   gcc_assert (vtbl_ptr != error_mark_node);
 
@@ -3268,7 +3266,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
                                                alloc_node, cookie_ptr);
       size_ptr_type = build_pointer_type (sizetype);
       cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
-      cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
+      cookie = cp_build_fold_indirect_ref (cookie_ptr);
 
       cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
 
@@ -3280,7 +3278,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
                                                NEGATE_EXPR, sizetype,
                                                size_in_bytes (sizetype)));
 
-         cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
+         cookie = cp_build_fold_indirect_ref (cookie_ptr);
          cookie = build2 (MODIFY_EXPR, sizetype, cookie,
                           size_in_bytes (elt_type));
          cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
@@ -3326,7 +3324,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
             the initializer anyway since we're going to throw it away and
             rebuild it at instantiation time, so just build up a single
             constructor call to get any appropriate diagnostics.  */
-         init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
+         init_expr = cp_build_fold_indirect_ref (data_addr);
          if (type_build_ctor_call (elt_type))
            init_expr = build_special_member_call (init_expr,
                                                   complete_ctor_identifier,
@@ -3384,7 +3382,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
        }
       else
        {
-         init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
+         init_expr = cp_build_fold_indirect_ref (data_addr);
 
          if (type_build_ctor_call (type) && !explicit_value_init_p)
            {
@@ -4507,7 +4505,7 @@ build_vec_init (tree base, tree maxindex, tree init,
     {
       atype = build_pointer_type (atype);
       stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
-      stmt_expr = cp_build_indirect_ref (stmt_expr, RO_NULL, complain);
+      stmt_expr = cp_build_fold_indirect_ref (stmt_expr);
       TREE_NO_WARNING (stmt_expr) = 1;
     }
 
@@ -4661,8 +4659,7 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
       /* Make sure the destructor is callable.  */
       if (type_build_dtor_call (type))
        {
-         expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL,
-                                                        complain),
+         expr = build_dtor_call (cp_build_fold_indirect_ref (addr),
                                  sfk_complete_destructor, flags, complain);
          if (expr == error_mark_node)
            return error_mark_node;
@@ -4738,7 +4735,7 @@ build_delete (tree otype, tree addr, special_function_kind auto_delete,
                                complain);
        }
 
-      expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL, complain),
+      expr = build_dtor_call (cp_build_fold_indirect_ref (addr),
                              auto_delete, flags, complain);
       if (expr == error_mark_node)
        return error_mark_node;
@@ -4918,7 +4915,7 @@ build_vec_delete (tree base, tree maxindex,
                                 sizetype, TYPE_SIZE_UNIT (sizetype));
       cookie_addr = fold_build_pointer_plus (fold_convert (size_ptr_type, base),
                                             cookie_addr);
-      maxindex = cp_build_indirect_ref (cookie_addr, RO_NULL, complain);
+      maxindex = cp_build_fold_indirect_ref (cookie_addr);
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
index bb6c68a100a078c8715c0067860cc201d8adfccb..7c8b64094096f5901f13a1866b4a36faa6915f53 100644 (file)
@@ -557,8 +557,7 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
        {
          gcc_assert (POINTER_TYPE_P (type));
          type = TREE_TYPE (type);
-         initializer = cp_build_indirect_ref (initializer, RO_NULL,
-                                              tf_warning_or_error);
+         initializer = cp_build_fold_indirect_ref (initializer);
        }
 
       if (dependent_type_p (type))
@@ -862,8 +861,7 @@ maybe_resolve_dummy (tree object, bool add_capture_p)
   if (tree lam = resolvable_dummy_lambda (object))
     if (tree cap = lambda_expr_this_capture (lam, add_capture_p))
       if (cap != error_mark_node)
-       object = build_x_indirect_ref (EXPR_LOCATION (object), cap,
-                                      RO_NULL, tf_warning_or_error);
+       object = build_fold_indirect_ref (cap);
 
   return object;
 }
@@ -1154,8 +1152,7 @@ maybe_add_lambda_conv_op (tree type)
         return expression for a deduced return call op to allow for simple
         implementation of the conversion operator.  */
 
-      tree instance = cp_build_indirect_ref (thisarg, RO_NULL,
-                                            tf_warning_or_error);
+      tree instance = cp_build_fold_indirect_ref (thisarg);
       tree objfn = build_min (COMPONENT_REF, NULL_TREE,
                              instance, DECL_NAME (callop), NULL_TREE);
       int nargs = list_length (DECL_ARGUMENTS (callop)) - 1;
index 77b96376e1367b920887117f09574ef6ea36a261..1860bf0f175356774183fe99a5133ec70f84939a 100644 (file)
@@ -11931,7 +11931,8 @@ do_range_for_auto_deduction (tree decl, tree range_expr)
        {
          iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE,
                                  iter_type);
-         iter_decl = build_x_indirect_ref (input_location, iter_decl, RO_NULL,
+         iter_decl = build_x_indirect_ref (input_location, iter_decl,
+                                           RO_UNARY_STAR,
                                            tf_warning_or_error);
          TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
                                                iter_decl, auto_node);
@@ -12048,7 +12049,7 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
 
   /* The declaration is initialized with *__begin inside the loop body.  */
   cp_finish_decl (range_decl,
-                 build_x_indirect_ref (input_location, begin, RO_NULL,
+                 build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
                                        tf_warning_or_error),
                  /*is_constant_init*/false, NULL_TREE,
                  LOOKUP_ONLYCONVERTING);
@@ -20843,7 +20844,7 @@ inject_this_parameter (tree ctype, cp_cv_quals quals)
   /* Clear this first to avoid shortcut in cp_build_indirect_ref.  */
   current_class_ptr = NULL_TREE;
   current_class_ref
-    = cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
+    = cp_build_fold_indirect_ref (this_parm);
   current_class_ptr = this_parm;
 }
 
index 10ecbfd95892469a8a80342a9d99de2b394d5497..b158507d7a8e905dbcde902e5c2b2bbaf58053ce 100644 (file)
@@ -206,8 +206,7 @@ build_headof (tree exp)
   index = build_int_cst (NULL_TREE,
                         -2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE);
 
-  offset = build_vtbl_ref (cp_build_indirect_ref (exp, RO_NULL, 
-                                                  tf_warning_or_error), 
+  offset = build_vtbl_ref (cp_build_fold_indirect_ref (exp),
                            index);
 
   type = cp_build_qualified_type (ptr_type_node,
@@ -303,7 +302,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst_flags_t complain)
     /* Otherwise return the type_info for the static type of the expr.  */
     t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
 
-  return cp_build_indirect_ref (t, RO_NULL, complain);
+  return cp_build_fold_indirect_ref (t);
 }
 
 static bool
@@ -365,7 +364,7 @@ build_typeid (tree exp, tsubst_flags_t complain)
       exp = cp_build_addr_expr (exp, complain);
       exp = save_expr (exp);
       cond = cp_convert (boolean_type_node, exp, complain);
-      exp = cp_build_indirect_ref (exp, RO_NULL, complain);
+      exp = cp_build_fold_indirect_ref (exp);
     }
 
   exp = get_tinfo_decl_dynamic (exp, complain);
@@ -529,7 +528,7 @@ get_typeid (tree type, tsubst_flags_t complain)
   if (!type)
     return error_mark_node;
 
-  return cp_build_indirect_ref (get_tinfo_ptr (type), RO_NULL, complain);
+  return cp_build_fold_indirect_ref (get_tinfo_ptr (type));
 }
 
 /* Check whether TEST is null before returning RESULT.  If TEST is used in
index b63f2ae4c5d269a13220ce8dfae8aa0afd52dc39..c60d54ab01fb498d1b030a0f2fd5a51db01c3598 100644 (file)
@@ -3841,7 +3841,7 @@ tree
 build_dummy_object (tree type)
 {
   tree decl = build1 (CONVERT_EXPR, build_pointer_type (type), void_node);
-  return cp_build_indirect_ref (decl, RO_NULL, tf_warning_or_error);
+  return cp_build_fold_indirect_ref (decl);
 }
 
 /* We've gotten a reference to a member of TYPE.  Return *this if appropriate,
@@ -5011,7 +5011,7 @@ stabilize_expr (tree exp, tree* initp)
       exp = cp_build_addr_expr (exp, tf_warning_or_error);
       init_expr = get_target_expr (exp);
       exp = TARGET_EXPR_SLOT (init_expr);
-      exp = cp_build_indirect_ref (exp, RO_NULL, tf_warning_or_error);
+      exp = cp_build_fold_indirect_ref (exp);
       if (xval)
        exp = move (exp);
     }
index 38ec363dc95a1b2c14eef9262dfb12333a1702de..f9a5f85146355082348e09531b89f82e909238bb 100644 (file)
@@ -2356,7 +2356,7 @@ build_class_member_access_expr (cp_expr object, tree member,
   {
     tree temp = unary_complex_lvalue (ADDR_EXPR, object);
     if (temp)
-      object = cp_build_indirect_ref (temp, RO_NULL, complain);
+      object = cp_build_fold_indirect_ref (temp);
   }
 
   /* In [expr.ref], there is an explicit list of the valid choices for
@@ -3035,20 +3035,19 @@ build_x_indirect_ref (location_t loc, tree expr, ref_operator errorstring,
     return rval;
 }
 
-/* Helper function called from c-common.  */
-tree
-build_indirect_ref (location_t /*loc*/,
-                   tree ptr, ref_operator errorstring)
-{
-  return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
-}
+/* The implementation of the above, and of indirection implied by other
+   constructs.  If DO_FOLD is true, fold away INDIRECT_REF of ADDR_EXPR.  */
 
-tree
-cp_build_indirect_ref (tree ptr, ref_operator errorstring, 
-                       tsubst_flags_t complain)
+static tree
+cp_build_indirect_ref_1 (tree ptr, ref_operator errorstring,
+                        tsubst_flags_t complain, bool do_fold)
 {
   tree pointer, type;
 
+  /* RO_NULL should only be used with the folding entry points below, not
+     cp_build_indirect_ref.  */
+  gcc_checking_assert (errorstring != RO_NULL || do_fold);
+
   if (ptr == current_class_ptr
       || (TREE_CODE (ptr) == NOP_EXPR
          && TREE_OPERAND (ptr, 0) == current_class_ptr
@@ -3092,7 +3091,7 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
             error ("%qT is not a pointer-to-object type", type);
          return error_mark_node;
        }
-      else if (TREE_CODE (pointer) == ADDR_EXPR
+      else if (do_fold && TREE_CODE (pointer) == ADDR_EXPR
               && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
        /* The POINTER was something like `&x'.  We simplify `*&x' to
           `x'.  */
@@ -3141,6 +3140,34 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
   return error_mark_node;
 }
 
+/* Entry point used by c-common, which expects folding.  */
+
+tree
+build_indirect_ref (location_t /*loc*/,
+                   tree ptr, ref_operator errorstring)
+{
+  return cp_build_indirect_ref_1 (ptr, errorstring, tf_warning_or_error, true);
+}
+
+/* Entry point used by internal indirection needs that don't correspond to any
+   syntactic construct.  */
+
+tree
+cp_build_fold_indirect_ref (tree pointer)
+{
+  return cp_build_indirect_ref_1 (pointer, RO_NULL, tf_warning_or_error, true);
+}
+
+/* Entry point used by indirection needs that correspond to some syntactic
+   construct.  */
+
+tree
+cp_build_indirect_ref (tree ptr, ref_operator errorstring,
+                      tsubst_flags_t complain)
+{
+  return cp_build_indirect_ref_1 (ptr, errorstring, complain, false);
+}
+
 /* This handles expressions of the form "a[i]", which denotes
    an array reference.
 
@@ -3477,13 +3504,13 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
       /* Next extract the vtable pointer from the object.  */
       vtbl = build1 (NOP_EXPR, build_pointer_type (vtbl_ptr_type_node),
                     instance_ptr);
-      vtbl = cp_build_indirect_ref (vtbl, RO_NULL, complain);
+      vtbl = cp_build_fold_indirect_ref (vtbl);
       if (vtbl == error_mark_node)
        return error_mark_node;
 
       /* Finally, extract the function pointer from the vtable.  */
       e2 = fold_build_pointer_plus_loc (input_location, vtbl, idx);
-      e2 = cp_build_indirect_ref (e2, RO_NULL, complain);
+      e2 = cp_build_fold_indirect_ref (e2);
       if (e2 == error_mark_node)
        return error_mark_node;
       TREE_CONSTANT (e2) = 1;
index e8e1339543197b6ba3181dc2a31a32ae4db1ad6f..e135b0de363503bfa1e89dcd97d977e466020c91 100644 (file)
@@ -1792,7 +1792,7 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
          return expr;
        }
 
-      return cp_build_indirect_ref (last_rval, RO_NULL, complain);
+      return cp_build_indirect_ref (last_rval, RO_ARROW, complain);
     }
 
   if (complain & tf_error)
@@ -1893,7 +1893,7 @@ build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
         value stored in the pointer-to-data-member.  */
       ptype = build_pointer_type (type);
       datum = fold_build_pointer_plus (fold_convert (ptype, datum), component);
-      datum = cp_build_indirect_ref (datum, RO_NULL, complain);
+      datum = cp_build_fold_indirect_ref (datum);
       if (datum == error_mark_node)
        return error_mark_node;