diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-04-10 08:33:26 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-04-10 08:33:26 +0200 |
commit | f7e8cd25dd6df6eb5958ff35a60d4de5787f72a2 (patch) | |
tree | 1f84c60ffe349e6fb707d5f769e5b1d782d93b1e /gcc | |
parent | 13aac201baed695d6dc1646e4e07f19e24b3da00 (diff) | |
download | gcc-f7e8cd25dd6df6eb5958ff35a60d4de5787f72a2.zip gcc-f7e8cd25dd6df6eb5958ff35a60d4de5787f72a2.tar.gz gcc-f7e8cd25dd6df6eb5958ff35a60d4de5787f72a2.tar.bz2 |
re PR c++/56895 (ICE: unexpected expression of kind arrow_expr)
PR c++/56895
* typeck.c (cp_build_binary_op): Call fold_non_dependent_expr_sfinae
first before calling maybe_constant_value for warn_for_div_by_zero
or invalid shift count warning purposes.
* g++.dg/template/arrow3.C: New test.
From-SVN: r197660
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/arrow3.C | 38 |
4 files changed, 61 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c01fb3c..767b2c3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2013-04-10 Jakub Jelinek <jakub@redhat.com> + + PR c++/56895 + * typeck.c (cp_build_binary_op): Call fold_non_dependent_expr_sfinae + first before calling maybe_constant_value for warn_for_div_by_zero + or invalid shift count warning purposes. + 2013-04-09 Jason Merrill <jason@redhat.com> PR c++/25466 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 4a577e2..2f60b10 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4047,8 +4047,9 @@ cp_build_binary_op (location_t location, || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)) { enum tree_code tcode0 = code0, tcode1 = code1; + tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); - warn_for_div_by_zero (location, maybe_constant_value (op1)); + warn_for_div_by_zero (location, maybe_constant_value (cop1)); if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE) tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0))); @@ -4084,7 +4085,11 @@ cp_build_binary_op (location_t location, case TRUNC_MOD_EXPR: case FLOOR_MOD_EXPR: - warn_for_div_by_zero (location, maybe_constant_value (op1)); + { + tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none); + + warn_for_div_by_zero (location, maybe_constant_value (cop1)); + } if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE @@ -4132,7 +4137,8 @@ cp_build_binary_op (location_t location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { - tree const_op1 = maybe_constant_value (op1); + tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none); + const_op1 = maybe_constant_value (const_op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; @@ -4178,7 +4184,8 @@ cp_build_binary_op (location_t location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { - tree const_op1 = maybe_constant_value (op1); + tree const_op1 = fold_non_dependent_expr_sfinae (op1, tf_none); + const_op1 = maybe_constant_value (const_op1); if (TREE_CODE (const_op1) != INTEGER_CST) const_op1 = op1; result_type = type0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f2b55b..6b44c64 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-04-10 Jakub Jelinek <jakub@redhat.com> + + PR c++/56895 + * g++.dg/template/arrow3.C: New test. + 2013-04-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * gcc.target/arm/minmax_minus.c: New test. diff --git a/gcc/testsuite/g++.dg/template/arrow3.C b/gcc/testsuite/g++.dg/template/arrow3.C new file mode 100644 index 0000000..b2029ba --- /dev/null +++ b/gcc/testsuite/g++.dg/template/arrow3.C @@ -0,0 +1,38 @@ +// PR c++/56895 +// { dg-do compile } + +extern struct A { bool foo (); A bar (); } *a; + +template <int> +int +baz1 () +{ + return 2 << (a->bar().foo() ? 1 : 0); +} + +template <int> +int +baz2 () +{ + return 2 >> (a->bar().foo() ? 1 : 0); +} + +template <int> +int +baz3 () +{ + return 10 / (a->bar().foo() ? 1 : 2); +} + +template <int> +int +baz4 () +{ + return 10 % (a->bar().foo() ? 1 : 0); +} + +int +test () +{ + return baz1<0> () + baz2<0> () + baz3<0> () + baz4<0> (); +} |