gcc/cp/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 May 2014 14:18:44 +0000 (14:18 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 May 2014 14:18:44 +0000 (14:18 +0000)
PR bootstrap/61210
* pt.c (tsubst_copy, tsubst_omp_for_iterator, tsubst_expr)
(tsubst_copy_and_build): Perform recursive substitutions in a
deterministic order.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@210645 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c

index b15a9c9..6886b96 100644 (file)
@@ -1,3 +1,10 @@
+2014-05-20  Richard Sandiford  <rsandifo@linux.vnet.ibm.com>
+
+       PR bootstrap/61210
+       * pt.c (tsubst_copy, tsubst_omp_for_iterator, tsubst_expr)
+       (tsubst_copy_and_build): Perform recursive substitutions in a
+       deterministic order.
+
 2014-05-20  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58664
index d712583..fca1ab3 100644 (file)
@@ -12734,9 +12734,11 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case IMPLICIT_CONV_EXPR:
     case CONVERT_EXPR:
     case NOP_EXPR:
-      return build1
-       (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
+      {
+       tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       return build1 (code, type, op0);
+      }
 
     case SIZEOF_EXPR:
       if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
@@ -12804,9 +12806,11 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case REALPART_EXPR:
     case IMAGPART_EXPR:
     case PAREN_EXPR:
-      return build1
-       (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
+      {
+       tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       return build1 (code, type, op0);
+      }
 
     case COMPONENT_REF:
       {
@@ -12880,24 +12884,26 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case PREINCREMENT_EXPR:
     case POSTDECREMENT_EXPR:
     case POSTINCREMENT_EXPR:
-      return build_nt
-       (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
+      {
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       return build_nt (code, op0, op1);
+      }
 
     case SCOPE_REF:
-      return build_qualified_name (/*type=*/NULL_TREE,
-                                  tsubst_copy (TREE_OPERAND (t, 0),
-                                               args, complain, in_decl),
-                                  tsubst_copy (TREE_OPERAND (t, 1),
-                                               args, complain, in_decl),
-                                  QUALIFIED_NAME_IS_TEMPLATE (t));
+      {
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       return build_qualified_name (/*type=*/NULL_TREE, op0, op1,
+                                    QUALIFIED_NAME_IS_TEMPLATE (t));
+      }
 
     case ARRAY_REF:
-      return build_nt
-       (ARRAY_REF,
-        tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
-        NULL_TREE, NULL_TREE);
+      {
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       return build_nt (ARRAY_REF, op0, op1, NULL_TREE, NULL_TREE);
+      }
 
     case CALL_EXPR:
       {
@@ -12915,29 +12921,29 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
     case PSEUDO_DTOR_EXPR:
     case VEC_PERM_EXPR:
       {
-       r = build_nt
-         (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-          tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
-          tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       tree op2 = tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl);
+       r = build_nt (code, op0, op1, op2);
        TREE_NO_WARNING (r) = TREE_NO_WARNING (t);
        return r;
       }
 
     case NEW_EXPR:
       {
-       r = build_nt
-       (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl));
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       tree op2 = tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl);
+       r = build_nt (code, op0, op1, op2);
        NEW_EXPR_USE_GLOBAL (r) = NEW_EXPR_USE_GLOBAL (t);
        return r;
       }
 
     case DELETE_EXPR:
       {
-       r = build_nt
-       (code, tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       r = build_nt (code, op0, op1);
        DELETE_EXPR_USE_GLOBAL (r) = DELETE_EXPR_USE_GLOBAL (t);
        DELETE_EXPR_USE_VEC (r) = DELETE_EXPR_USE_VEC (t);
        return r;
@@ -13017,10 +13023,11 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       gcc_unreachable ();
 
     case VA_ARG_EXPR:
-      return build_x_va_arg (EXPR_LOCATION (t),
-                            tsubst_copy (TREE_OPERAND (t, 0), args, complain,
-                                         in_decl),
-                            tsubst (TREE_TYPE (t), args, complain, in_decl));
+      {
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       return build_x_va_arg (EXPR_LOCATION (t), op0, type);
+      }
 
     case CLEANUP_POINT_EXPR:
       /* We shouldn't have built any of these during initial template
@@ -13029,13 +13036,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       gcc_unreachable ();
 
     case OFFSET_REF:
-      r = build2
-       (code, tsubst (TREE_TYPE (t), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl),
-        tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
-      PTRMEM_OK_P (r) = PTRMEM_OK_P (t);
-      mark_used (TREE_OPERAND (r, 1));
-      return r;
+      {
+       tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+       tree op1 = tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl);
+       r = build2 (code, type, op0, op1);
+       PTRMEM_OK_P (r) = PTRMEM_OK_P (t);
+       mark_used (TREE_OPERAND (r, 1));
+       return r;
+      }
 
     case EXPR_PACK_EXPANSION:
       error ("invalid use of pack expansion expression");
@@ -13270,10 +13279,12 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
       cond = RECUR (TREE_VEC_ELT (OMP_FOR_COND (t), i));
       incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
       if (TREE_CODE (incr) == MODIFY_EXPR)
-       incr = build_x_modify_expr (EXPR_LOCATION (incr),
-                                   RECUR (TREE_OPERAND (incr, 0)), NOP_EXPR,
-                                   RECUR (TREE_OPERAND (incr, 1)),
-                                   complain);
+       {
+         tree lhs = RECUR (TREE_OPERAND (incr, 0));
+         tree rhs = RECUR (TREE_OPERAND (incr, 1));
+         incr = build_x_modify_expr (EXPR_LOCATION (incr), lhs,
+                                     NOP_EXPR, rhs, complain);
+       }
       else
        incr = RECUR (incr);
       TREE_VEC_ELT (declv, i) = decl;
@@ -13319,9 +13330,11 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
     }
   cond = TREE_VEC_ELT (OMP_FOR_COND (t), i);
   if (COMPARISON_CLASS_P (cond))
-    cond = build2 (TREE_CODE (cond), boolean_type_node,
-                  RECUR (TREE_OPERAND (cond, 0)),
-                  RECUR (TREE_OPERAND (cond, 1)));
+    {
+      tree op0 = RECUR (TREE_OPERAND (cond, 0));
+      tree op1 = RECUR (TREE_OPERAND (cond, 1));
+      cond = build2 (TREE_CODE (cond), boolean_type_node, op0, op1);
+    }
   else
     cond = RECUR (cond);
   incr = TREE_VEC_ELT (OMP_FOR_INCR (t), i);
@@ -13339,11 +13352,12 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
          || TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR)
        {
          tree rhs = TREE_OPERAND (incr, 1);
-         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
-                        RECUR (TREE_OPERAND (incr, 0)),
+         tree lhs = RECUR (TREE_OPERAND (incr, 0));
+         tree rhs0 = RECUR (TREE_OPERAND (rhs, 0));
+         tree rhs1 = RECUR (TREE_OPERAND (rhs, 1));
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl), lhs,
                         build2 (TREE_CODE (rhs), TREE_TYPE (decl),
-                                RECUR (TREE_OPERAND (rhs, 0)),
-                                RECUR (TREE_OPERAND (rhs, 1))));
+                                rhs0, rhs1));
        }
       else
        incr = RECUR (incr);
@@ -13363,11 +13377,12 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree initv,
                   || (TREE_CODE (TREE_OPERAND (incr, 2)) == MINUS_EXPR)))
        {
          tree rhs = TREE_OPERAND (incr, 2);
-         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl),
-                        RECUR (TREE_OPERAND (incr, 0)),
+         tree lhs = RECUR (TREE_OPERAND (incr, 0));
+         tree rhs0 = RECUR (TREE_OPERAND (rhs, 0));
+         tree rhs1 = RECUR (TREE_OPERAND (rhs, 1));
+         incr = build2 (MODIFY_EXPR, TREE_TYPE (decl), lhs,
                         build2 (TREE_CODE (rhs), TREE_TYPE (decl),
-                                RECUR (TREE_OPERAND (rhs, 0)),
-                                RECUR (TREE_OPERAND (rhs, 1))));
+                                rhs0, rhs1));
        }
       else
        incr = RECUR (incr);
@@ -13645,9 +13660,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case CASE_LABEL_EXPR:
-      finish_case_label (EXPR_LOCATION (t),
-                        RECUR (CASE_LOW (t)),
-                        RECUR (CASE_HIGH (t)));
+      {
+       tree low = RECUR (CASE_LOW (t));
+       tree high = RECUR (CASE_HIGH (t));
+       finish_case_label (EXPR_LOCATION (t), low, high);
+      }
       break;
 
     case LABEL_EXPR:
@@ -13674,14 +13691,18 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case ASM_EXPR:
-      tmp = finish_asm_stmt
-       (ASM_VOLATILE_P (t),
-        RECUR (ASM_STRING (t)),
-        tsubst_copy_asm_operands (ASM_OUTPUTS (t), args, complain, in_decl),
-        tsubst_copy_asm_operands (ASM_INPUTS (t), args, complain, in_decl),
-        tsubst_copy_asm_operands (ASM_CLOBBERS (t), args, complain, in_decl),
-        tsubst_copy_asm_operands (ASM_LABELS (t), args, complain, in_decl));
       {
+       tree string = RECUR (ASM_STRING (t));
+       tree outputs = tsubst_copy_asm_operands (ASM_OUTPUTS (t), args,
+                                                complain, in_decl);
+       tree inputs = tsubst_copy_asm_operands (ASM_INPUTS (t), args,
+                                               complain, in_decl);
+       tree clobbers = tsubst_copy_asm_operands (ASM_CLOBBERS (t), args,
+                                                 complain, in_decl);
+       tree labels = tsubst_copy_asm_operands (ASM_LABELS (t), args,
+                                               complain, in_decl);
+       tmp = finish_asm_stmt (ASM_VOLATILE_P (t), string, outputs, inputs,
+                              clobbers, labels);
        tree asm_expr = tmp;
        if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR)
          asm_expr = TREE_OPERAND (asm_expr, 0);
@@ -13978,8 +13999,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
       break;
 
     case MUST_NOT_THROW_EXPR:
-      RETURN (build_must_not_throw_expr (RECUR (TREE_OPERAND (t, 0)),
-                                       RECUR (MUST_NOT_THROW_COND (t))));
+      {
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       tree cond = RECUR (MUST_NOT_THROW_COND (t));
+       RETURN (build_must_not_throw_expr (op0, cond));
+      }
 
     case EXPR_PACK_EXPANSION:
       error ("invalid use of pack expansion expression");
@@ -14246,9 +14270,11 @@ tsubst_copy_and_build (tree t,
       }
 
     case NOP_EXPR:
-      RETURN (build_nop
-       (tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0))));
+      {
+       tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       RETURN (build_nop (type, op0));
+      }
 
     case IMPLICIT_CONV_EXPR:
       {
@@ -14262,10 +14288,11 @@ tsubst_copy_and_build (tree t,
       }
 
     case CONVERT_EXPR:
-      RETURN (build1
-       (CONVERT_EXPR,
-        tsubst (TREE_TYPE (t), args, complain, in_decl),
-        RECUR (TREE_OPERAND (t, 0))));
+      {
+       tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       RETURN (build1 (CONVERT_EXPR, type, op0));
+      }
 
     case CAST_EXPR:
     case REINTERPRET_CAST_EXPR:
@@ -14330,12 +14357,12 @@ tsubst_copy_and_build (tree t,
     case REALPART_EXPR:
     case IMAGPART_EXPR:
       RETURN (build_x_unary_op (input_location, TREE_CODE (t),
-                              RECUR (TREE_OPERAND (t, 0)),
+                               RECUR (TREE_OPERAND (t, 0)),
                                complain|decltype_flag));
 
     case FIX_TRUNC_EXPR:
       RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
-                               0, complain));
+                                0, complain));
 
     case ADDR_EXPR:
       op1 = TREE_OPERAND (t, 0);
@@ -14385,13 +14412,15 @@ tsubst_copy_and_build (tree t,
       {
        warning_sentinel s1(warn_type_limits);
        warning_sentinel s2(warn_div_by_zero);
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       tree op1 = RECUR (TREE_OPERAND (t, 1));
        tree r = build_x_binary_op
          (input_location, TREE_CODE (t),
-          RECUR (TREE_OPERAND (t, 0)),
+          op0,
           (TREE_NO_WARNING (TREE_OPERAND (t, 0))
            ? ERROR_MARK
            : TREE_CODE (TREE_OPERAND (t, 0))),
-          RECUR (TREE_OPERAND (t, 1)),
+          op1,
           (TREE_NO_WARNING (TREE_OPERAND (t, 1))
            ? ERROR_MARK
            : TREE_CODE (TREE_OPERAND (t, 1))),
@@ -14404,8 +14433,11 @@ tsubst_copy_and_build (tree t,
       }
 
     case POINTER_PLUS_EXPR:
-      return fold_build_pointer_plus (RECUR (TREE_OPERAND (t, 0)),
-                                     RECUR (TREE_OPERAND (t, 1)));
+      {
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       tree op1 = RECUR (TREE_OPERAND (t, 1));
+       return fold_build_pointer_plus (op0, op1);
+      }
 
     case SCOPE_REF:
       RETURN (tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
@@ -14515,11 +14547,10 @@ tsubst_copy_and_build (tree t,
     case MODOP_EXPR:
       {
        warning_sentinel s(warn_div_by_zero);
+       tree lhs = RECUR (TREE_OPERAND (t, 0));
+       tree rhs = RECUR (TREE_OPERAND (t, 2));
        tree r = build_x_modify_expr
-         (EXPR_LOCATION (t),
-          RECUR (TREE_OPERAND (t, 0)),
-          TREE_CODE (TREE_OPERAND (t, 1)),
-          RECUR (TREE_OPERAND (t, 2)),
+         (EXPR_LOCATION (t), lhs, TREE_CODE (TREE_OPERAND (t, 1)), rhs,
           complain|decltype_flag);
        /* TREE_NO_WARNING must be set if either the expression was
           parenthesized or it uses an operator such as >>= rather
@@ -14578,10 +14609,9 @@ tsubst_copy_and_build (tree t,
              }
          }
 
-       ret = build_new (&placement_vec,
-                        tsubst (TREE_OPERAND (t, 1), args, complain, in_decl),
-                        RECUR (TREE_OPERAND (t, 2)),
-                        &init_vec,
+       tree op1 = tsubst (TREE_OPERAND (t, 1), args, complain, in_decl);
+       tree op2 = RECUR (TREE_OPERAND (t, 2));
+       ret = build_new (&placement_vec, op1, op2, &init_vec,
                         NEW_EXPR_USE_GLOBAL (t),
                         complain);
 
@@ -14594,12 +14624,14 @@ tsubst_copy_and_build (tree t,
       }
 
     case DELETE_EXPR:
-     RETURN (delete_sanity
-       (RECUR (TREE_OPERAND (t, 0)),
-       RECUR (TREE_OPERAND (t, 1)),
-       DELETE_EXPR_USE_VEC (t),
-       DELETE_EXPR_USE_GLOBAL (t),
-       complain));
+      {
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       tree op1 = RECUR (TREE_OPERAND (t, 1));
+       RETURN (delete_sanity (op0, op1,
+                              DELETE_EXPR_USE_VEC (t),
+                              DELETE_EXPR_USE_GLOBAL (t),
+                              complain));
+      }
 
     case COMPOUND_EXPR:
       {
@@ -14866,11 +14898,13 @@ tsubst_copy_and_build (tree t,
       }
 
     case PSEUDO_DTOR_EXPR:
-      RETURN (finish_pseudo_destructor_expr
-             (RECUR (TREE_OPERAND (t, 0)),
-              RECUR (TREE_OPERAND (t, 1)),
-              tsubst (TREE_OPERAND (t, 2), args, complain, in_decl),
-              input_location));
+      {
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       tree op1 = RECUR (TREE_OPERAND (t, 1));
+       tree op2 = tsubst (TREE_OPERAND (t, 2), args, complain, in_decl);
+       RETURN (finish_pseudo_destructor_expr (op0, op1, op2,
+                                              input_location));
+      }
 
     case TREE_LIST:
       {
@@ -15194,9 +15228,11 @@ tsubst_copy_and_build (tree t,
       }
 
     case VA_ARG_EXPR:
-      RETURN (build_x_va_arg (EXPR_LOCATION (t),
-                            RECUR (TREE_OPERAND (t, 0)),
-                            tsubst (TREE_TYPE (t), args, complain, in_decl)));
+      {
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+       RETURN (build_x_va_arg (EXPR_LOCATION (t), op0, type));
+      }
 
     case OFFSETOF_EXPR:
       RETURN (finish_offsetof (RECUR (TREE_OPERAND (t, 0))));
@@ -15305,11 +15341,13 @@ tsubst_copy_and_build (tree t,
       RETURN (finish_parenthesized_expr (RECUR (TREE_OPERAND (t, 0))));
 
     case VEC_PERM_EXPR:
-      RETURN (build_x_vec_perm_expr (input_location,
-               RECUR (TREE_OPERAND (t, 0)),
-               RECUR (TREE_OPERAND (t, 1)),
-               RECUR (TREE_OPERAND (t, 2)),
-               complain));
+      {
+       tree op0 = RECUR (TREE_OPERAND (t, 0));
+       tree op1 = RECUR (TREE_OPERAND (t, 1));
+       tree op2 = RECUR (TREE_OPERAND (t, 2));
+       RETURN (build_x_vec_perm_expr (input_location, op0, op1, op2,
+                                      complain));
+      }
 
     default:
       /* Handle Objective-C++ constructs, if appropriate.  */