constexpr.c (cxx_fold_indirect_ref): Use similar_type_p.
authorJason Merrill <jason@redhat.com>
Fri, 27 Sep 2019 18:23:10 +0000 (14:23 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 27 Sep 2019 18:23:10 +0000 (14:23 -0400)
* constexpr.c (cxx_fold_indirect_ref): Use similar_type_p.

Merging the similar_type_p change to the concepts branch broke a cmcstl2
testcase; investigating led me to this small testcase which has always
failed on trunk.

(cxx_eval_indirect_ref): Likewise.  Improve error location.

From-SVN: r276192

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp0x/constexpr-const2.C [new file with mode: 0644]

index 8e92d91ef8e6592c1a9aef8b2ee99307dcf1bf4d..20f543ea716792fb20dbf6241cc0acaf18bdf740 100644 (file)
@@ -1,5 +1,8 @@
 2019-09-27  Jason Merrill  <jason@redhat.com>
 
+       * constexpr.c (cxx_fold_indirect_ref): Use similar_type_p.
+       (cxx_eval_indirect_ref): Likewise.  Improve error location.
+
        * cp-tree.h (class iloc_sentinel): New.
        * decl.c (grokdeclarator, finish_enum_value_list): Use it.
        * mangle.c (mangle_decl_string): Use it.
index 58db691e134e7372a641b2a2fe9a33d968939b2a..cb5484f4b72d55740fc77b7388974939c45fe9ad 100644 (file)
@@ -3388,7 +3388,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
       if (TREE_CODE (op) == CONST_DECL)
        return DECL_INITIAL (op);
       /* *&p => p;  make sure to handle *&"str"[cst] here.  */
-      if (same_type_ignoring_tlq_and_bounds_p (optype, type))
+      if (similar_type_p (optype, type))
        {
          tree fop = fold_read_from_constant_string (op);
          if (fop)
@@ -3398,8 +3398,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
        }
       /* *(foo *)&fooarray => fooarray[0] */
       else if (TREE_CODE (optype) == ARRAY_TYPE
-              && (same_type_ignoring_top_level_qualifiers_p
-                  (type, TREE_TYPE (optype))))
+              && similar_type_p (type, TREE_TYPE (optype)))
        {
          tree type_domain = TYPE_DOMAIN (optype);
          tree min_val = size_zero_node;
@@ -3410,13 +3409,11 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
        }
       /* *(foo *)&complexfoo => __real__ complexfoo */
       else if (TREE_CODE (optype) == COMPLEX_TYPE
-              && (same_type_ignoring_top_level_qualifiers_p
-                  (type, TREE_TYPE (optype))))
+              && similar_type_p (type, TREE_TYPE (optype)))
        return fold_build1_loc (loc, REALPART_EXPR, type, op);
       /* *(foo *)&vectorfoo => BIT_FIELD_REF<vectorfoo,...> */
       else if (VECTOR_TYPE_P (optype)
-              && (same_type_ignoring_top_level_qualifiers_p
-                  (type, TREE_TYPE (optype))))
+              && similar_type_p (type, TREE_TYPE (optype)))
        {
          tree part_width = TYPE_SIZE (type);
          tree index = bitsize_int (0);
@@ -3440,8 +3437,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
            if (TREE_CODE (field) == FIELD_DECL
                && TREE_TYPE (field) != error_mark_node
                && integer_zerop (byte_position (field))
-               && (same_type_ignoring_top_level_qualifiers_p
-                   (TREE_TYPE (field), type)))
+               && similar_type_p (TREE_TYPE (field), type))
              return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE);
        }
     }
@@ -3460,8 +3456,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
 
          /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF<vectorfoo,...> */
          if (VECTOR_TYPE_P (op00type)
-             && same_type_ignoring_top_level_qualifiers_p
-                                               (type, TREE_TYPE (op00type))
+             && similar_type_p (type, TREE_TYPE (op00type))
              /* POINTER_PLUS_EXPR second operand is sizetype, unsigned,
                 but we want to treat offsets with MSB set as negative.
                 For the code below negative offsets are invalid and
@@ -3486,8 +3481,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
            }
          /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
          else if (TREE_CODE (op00type) == COMPLEX_TYPE
-                  && (same_type_ignoring_top_level_qualifiers_p
-                      (type, TREE_TYPE (op00type))))
+                  && similar_type_p (type, TREE_TYPE (op00type)))
            {
              if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)),
                            const_op01))
@@ -3495,8 +3489,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
            }
          /* ((foo *)&fooarray)[1] => fooarray[1] */
          else if (TREE_CODE (op00type) == ARRAY_TYPE
-                  && (same_type_ignoring_top_level_qualifiers_p
-                      (type, TREE_TYPE (op00type))))
+                  && similar_type_p (type, TREE_TYPE (op00type)))
            {
              tree type_domain = TYPE_DOMAIN (op00type);
              tree min_val = size_zero_node;
@@ -3531,8 +3524,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
                if (TREE_CODE (field) == FIELD_DECL
                    && TREE_TYPE (field) != error_mark_node
                    && tree_int_cst_equal (byte_position (field), op01)
-                   && (same_type_ignoring_top_level_qualifiers_p
-                       (TREE_TYPE (field), type)))
+                   && similar_type_p (TREE_TYPE (field), type))
                  return fold_build3 (COMPONENT_REF, type, op00,
                                      field, NULL_TREE);
            }
@@ -3540,8 +3532,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
     }
   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
   else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
-          && (same_type_ignoring_top_level_qualifiers_p
-              (type, TREE_TYPE (TREE_TYPE (subtype)))))
+          && similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
     {
       tree type_domain;
       tree min_val = size_zero_node;
@@ -3611,13 +3602,14 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
          STRIP_NOPS (sub);
          if (TREE_CODE (sub) == ADDR_EXPR)
            {
-             gcc_assert (!same_type_ignoring_top_level_qualifiers_p
+             gcc_assert (!similar_type_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));
+               error_at (cp_expr_loc_or_input_loc (t),
+                         "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;
            }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-const2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-const2.C
new file mode 100644 (file)
index 0000000..7aa16a3
--- /dev/null
@@ -0,0 +1,6 @@
+// { dg-do compile { target c++11 } }
+
+int i = 42;
+constexpr int *p = &i;
+constexpr int const *const *q = &p;
+constexpr int const *r = *q;