re PR c++/65054 (internal compiler error: in maybe_constant_value, at cp/constexpr...
authorJason Merrill <jason@redhat.com>
Fri, 13 Feb 2015 22:07:30 +0000 (17:07 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 13 Feb 2015 22:07:30 +0000 (17:07 -0500)
PR c++/65054
* pt.c (template_args_equal): Look through conversions here.
* tree.c (cp_tree_equal): Not here.

From-SVN: r220697

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/pt.c
gcc/cp/tree.c
gcc/testsuite/g++.dg/expr/ptr-arith1.C [new file with mode: 0644]

index e6d306e6f768950c025fa0f3aa7b2ead8502a233..0738e8b7b143fef79d409271158abb05cc63c6df 100644 (file)
@@ -1,3 +1,9 @@
+2015-02-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/65054
+       * pt.c (template_args_equal): Look through conversions here.
+       * tree.c (cp_tree_equal): Not here.
+
 2015-02-13  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/60211
index 2b56cb2d62bb83c53c72644d183580975282780d..d415dd4e6d27c41cb281a6450d2956edcc1c0b50 100644 (file)
@@ -3638,7 +3638,6 @@ maybe_constant_value (tree t, tree decl)
 
   r = cxx_eval_outermost_constant_expr (t, true, true, decl);
 #ifdef ENABLE_CHECKING
-  /* cp_tree_equal looks through NOPs, so allow them.  */
   gcc_assert (r == t
              || CONVERT_EXPR_P (t)
              || TREE_CODE (t) == VIEW_CONVERT_EXPR
index 3317dad35d79d6cfba5fb90df6f5cc7fa895252c..9a00d0d30e6b79e85fe088dfd272f42189e44bb6 100644 (file)
@@ -7324,7 +7324,22 @@ template_args_equal (tree ot, tree nt)
   else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
     return 0;
   else
-    return cp_tree_equal (ot, nt);
+    {
+      /* Try to treat a template non-type argument that has been converted
+        to the parameter type as equivalent to one that hasn't yet.  */
+      for (enum tree_code code1 = TREE_CODE (ot);
+          CONVERT_EXPR_CODE_P (code1)
+            || code1 == NON_LVALUE_EXPR;
+          code1 = TREE_CODE (ot))
+       ot = TREE_OPERAND (ot, 0);
+      for (enum tree_code code2 = TREE_CODE (nt);
+          CONVERT_EXPR_CODE_P (code2)
+            || code2 == NON_LVALUE_EXPR;
+          code2 = TREE_CODE (nt))
+       nt = TREE_OPERAND (nt, 0);
+
+      return cp_tree_equal (ot, nt);
+    }
 }
 
 /* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets of
index c51e42d2a40590b473d2d3f9a5ad59d900e53daa..c8e6f0c796f68fb2a8288397920bf07d333c0a4b 100644 (file)
@@ -2745,20 +2745,8 @@ cp_tree_equal (tree t1, tree t2)
   if (!t1 || !t2)
     return false;
 
-  for (code1 = TREE_CODE (t1);
-       CONVERT_EXPR_CODE_P (code1)
-        || code1 == NON_LVALUE_EXPR;
-       code1 = TREE_CODE (t1))
-    t1 = TREE_OPERAND (t1, 0);
-  for (code2 = TREE_CODE (t2);
-       CONVERT_EXPR_CODE_P (code2)
-        || code2 == NON_LVALUE_EXPR;
-       code2 = TREE_CODE (t2))
-    t2 = TREE_OPERAND (t2, 0);
-
-  /* They might have become equal now.  */
-  if (t1 == t2)
-    return true;
+  code1 = TREE_CODE (t1);
+  code2 = TREE_CODE (t2);
 
   if (code1 != code2)
     return false;
@@ -2996,6 +2984,9 @@ cp_tree_equal (tree t1, tree t2)
     case DYNAMIC_CAST_EXPR:
     case IMPLICIT_CONV_EXPR:
     case NEW_EXPR:
+    CASE_CONVERT:
+    case NON_LVALUE_EXPR:
+    case VIEW_CONVERT_EXPR:
       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
        return false;
       /* Now compare operands as usual.  */
diff --git a/gcc/testsuite/g++.dg/expr/ptr-arith1.C b/gcc/testsuite/g++.dg/expr/ptr-arith1.C
new file mode 100644 (file)
index 0000000..71e97f7
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/65054
+
+const char *
+foo (void)
+{
+  return ((char *const) "abc" + 1);
+}