* constexpr.c (cxx_eval_indirect_ref): Try folding first.
authorJason Merrill <jason@redhat.com>
Sun, 31 May 2015 20:36:26 +0000 (16:36 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 31 May 2015 20:36:26 +0000 (16:36 -0400)
From-SVN: r223902

gcc/cp/ChangeLog
gcc/cp/constexpr.c

index 5029f8320b910f94246a45a16ec439ff8452abde..467449c5fbd314562c7a3f5fc2ae03c767742210 100644 (file)
@@ -1,5 +1,7 @@
 2015-05-31  Jason Merrill  <jason@redhat.com>
 
+       * constexpr.c (cxx_eval_indirect_ref): Try folding first.
+
        PR c++/66320
        * constexpr.c (cxx_eval_constant_expression): Treat a placeholder
        with the wrong type as non-constant.
index f343ea7eae0a06fa2450ac0a379c376af2ac31c6..ff5489fe029c9d69f3a623fc1395f9430f24b0ad 100644 (file)
@@ -2427,42 +2427,55 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
                       bool *non_constant_p, bool *overflow_p)
 {
   tree orig_op0 = TREE_OPERAND (t, 0);
-  tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
-                                          /*lval*/false, non_constant_p,
-                                          overflow_p);
   bool empty_base = false;
-  tree r;
-
-  /* Don't VERIFY_CONSTANT here.  */
-  if (*non_constant_p)
-    return t;
-
-  r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
-                            &empty_base);
 
-  if (r)
-    r = cxx_eval_constant_expression (ctx, r,
-                                     lval, non_constant_p, overflow_p);
-  else
+  /* First try to simplify it directly.  */
+  tree r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), orig_op0,
+                                 &empty_base);
+  if (!r)
     {
-      tree sub = op0;
-      STRIP_NOPS (sub);
-      if (TREE_CODE (sub) == ADDR_EXPR)
+      /* If that didn't work, evaluate the operand first.  */
+      tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
+                                              /*lval*/false, non_constant_p,
+                                              overflow_p);
+      /* Don't VERIFY_CONSTANT here.  */
+      if (*non_constant_p)
+       return t;
+
+      r = cxx_fold_indirect_ref (EXPR_LOCATION (t), TREE_TYPE (t), op0,
+                                &empty_base);
+      if (r == NULL_TREE)
        {
          /* We couldn't fold to a constant value.  Make sure it's not
             something we should have been able to fold.  */
-         gcc_assert (!same_type_ignoring_top_level_qualifiers_p
-                     (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
-         /* DR 1188 says we don't have to deal with this.  */
-         if (!ctx->quiet)
-           error ("accessing value of %qE through a %qT glvalue in a "
-                  "constant expression", build_fold_indirect_ref (sub),
-                  TREE_TYPE (t));
-         *non_constant_p = true;
+         tree sub = op0;
+         STRIP_NOPS (sub);
+         if (TREE_CODE (sub) == ADDR_EXPR)
+           {
+             gcc_assert (!same_type_ignoring_top_level_qualifiers_p
+                         (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
+             /* DR 1188 says we don't have to deal with this.  */
+             if (!ctx->quiet)
+               error ("accessing value of %qE through a %qT glvalue in a "
+                      "constant expression", build_fold_indirect_ref (sub),
+                      TREE_TYPE (t));
+             *non_constant_p = true;
+             return t;
+           }
+
+         if (lval && op0 != orig_op0)
+           return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
+         if (!lval)
+           VERIFY_CONSTANT (t);
          return t;
        }
     }
 
+  r = cxx_eval_constant_expression (ctx, r,
+                                   lval, non_constant_p, overflow_p);
+  if (*non_constant_p)
+    return t;
+
   /* If we're pulling out the value of an empty base, make sure
      that the whole object is constant and then return an empty
      CONSTRUCTOR.  */
@@ -2473,14 +2486,6 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
       TREE_CONSTANT (r) = true;
     }
 
-  if (r == NULL_TREE)
-    {
-      if (lval && op0 != orig_op0)
-       return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
-      if (!lval)
-       VERIFY_CONSTANT (t);
-      return t;
-    }
   return r;
 }