From ef796bef889d8a1590430a9da06c40ec4977d79e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 13 Feb 2015 17:07:30 -0500 Subject: [PATCH] re PR c++/65054 (internal compiler error: in maybe_constant_value, at cp/constexpr.c:3646) 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 | 6 ++++++ gcc/cp/constexpr.c | 1 - gcc/cp/pt.c | 17 ++++++++++++++++- gcc/cp/tree.c | 19 +++++-------------- gcc/testsuite/g++.dg/expr/ptr-arith1.C | 7 +++++++ 5 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 gcc/testsuite/g++.dg/expr/ptr-arith1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e6d306e6f76..0738e8b7b14 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2015-02-13 Jason Merrill + + PR c++/65054 + * pt.c (template_args_equal): Look through conversions here. + * tree.c (cp_tree_equal): Not here. + 2015-02-13 Paolo Carlini PR c++/60211 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 2b56cb2d62b..d415dd4e6d2 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3317dad35d7..9a00d0d30e6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index c51e42d2a40..c8e6f0c796f 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -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 index 00000000000..71e97f72b7b --- /dev/null +++ b/gcc/testsuite/g++.dg/expr/ptr-arith1.C @@ -0,0 +1,7 @@ +// PR c++/65054 + +const char * +foo (void) +{ + return ((char *const) "abc" + 1); +} -- 2.30.2