diff options
author | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-04-12 21:10:58 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-04-12 21:10:58 +0200 |
commit | 6338536c1e438e49c67271708d45b95306506cfd (patch) | |
tree | a98d933aa30f555ca23fa7b9fe11b58553b4fcb5 | |
parent | b8d6284e3a998ac0985943e590c8aff10cd77a99 (diff) | |
download | gcc-6338536c1e438e49c67271708d45b95306506cfd.zip gcc-6338536c1e438e49c67271708d45b95306506cfd.tar.gz gcc-6338536c1e438e49c67271708d45b95306506cfd.tar.bz2 |
re PR c++/65736 (ICE (in process_init_constructor_array, at cp/typeck2.c:1263))
PR c++/65736
* constexpr.c (cxx_eval_pointer_plus_expression): Don't fold for VLAs,
don't fold if op01 isn't divisible by TYPE_SIZE_UNIT. Convert
the expression to the original type at the end.
* g++.dg/cpp0x/pr65736.C: New test.
From-SVN: r222022
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr65736.C | 5 |
5 files changed, 34 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d65662f..aa9349a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,7 +2,7 @@ * doc/contrib.texi (Contributors): Add Maxim Kuvyrkov. -2015-04-11 Jan Hubicka <hubicka@ucw.cz> +2015-04-11 Jan Hubicka <hubicka@ucw.cz> PR ipa/65743 * ipa-inline-transform.c (speculation_removed): Remove static var. @@ -12,8 +12,8 @@ * ipa-prop.c (ipa_make_edge_direct_to_target): Do not consider non-invariants. -2015-04-11 Jan Hubicka <hubicka@ucw.cz> - Martin Liska <mliska@suse.cz> +2015-04-11 Jan Hubicka <hubicka@ucw.cz> + Martin Liska <mliska@suse.cz> PR ipa/65722 * ipa-icf.c (sem_item::compare_cgraph_references): function and diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 91ddee0..e5a6ae2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2015-04-12 Jakub Jelinek <jakub@redhat.com> + + PR c++/65736 + * constexpr.c (cxx_eval_pointer_plus_expression): Don't fold for VLAs, + don't fold if op01 isn't divisible by TYPE_SIZE_UNIT. Convert + the expression to the original type at the end. + 2015-04-09 Jakub Jelinek <jakub@redhat.com> PR c++/65690 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index f5be8df..2952cbe 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2929,6 +2929,7 @@ cxx_eval_pointer_plus_expression (const constexpr_ctx *ctx, tree t, bool lval, bool *non_constant_p, bool *overflow_p) { + tree orig_type = TREE_TYPE (t); tree op00 = TREE_OPERAND (t, 0); tree op01 = TREE_OPERAND (t, 1); location_t loc = EXPR_LOCATION (t); @@ -2945,7 +2946,9 @@ cxx_eval_pointer_plus_expression (const constexpr_ctx *ctx, tree t, /* &A[i] p+ j => &A[i + j] */ if (TREE_CODE (op00) == ARRAY_REF && TREE_CODE (TREE_OPERAND (op00, 1)) == INTEGER_CST - && TREE_CODE (op01) == INTEGER_CST) + && TREE_CODE (op01) == INTEGER_CST + && TYPE_SIZE_UNIT (TREE_TYPE (op00)) + && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (op00))) == INTEGER_CST) { tree type = TREE_TYPE (op00); t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (op00, 1)); @@ -2953,15 +2956,21 @@ cxx_eval_pointer_plus_expression (const constexpr_ctx *ctx, tree t, /* Don't fold an out-of-bound access. */ if (!tree_int_cst_le (t, nelts)) return NULL_TREE; + op01 = cp_fold_convert (ssizetype, op01); + /* Don't fold if op01 can't be divided exactly by TYPE_SIZE_UNIT. + constexpr int A[1]; ... (char *)&A[0] + 1 */ + if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype, + op01, TYPE_SIZE_UNIT (type)))) + return NULL_TREE; /* Make sure to treat the second operand of POINTER_PLUS_EXPR as signed. */ - op01 = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, - cp_fold_convert (ssizetype, op01), + op01 = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, op01, TYPE_SIZE_UNIT (type)); t = size_binop_loc (loc, PLUS_EXPR, op01, t); t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (op00, 0), t, NULL_TREE, NULL_TREE); t = cp_build_addr_expr (t, tf_warning_or_error); + t = cp_fold_convert (orig_type, t); return cxx_eval_constant_expression (ctx, t, lval, non_constant_p, overflow_p); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 401bf14..ea6b3a4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ -2015-04-11 Jan Hubicka <hubicka@ucw.cz> - Martin Liska <mliska@suse.cz> +2015-04-12 Jakub Jelinek <jakub@redhat.com> + + PR c++/65736 + * g++.dg/cpp0x/pr65736.C: New test. + +2015-04-11 Jan Hubicka <hubicka@ucw.cz> + Martin Liska <mliska@suse.cz> PR ipa/65722 * g++.dg/ipa/pr65722.C: New testcase. diff --git a/gcc/testsuite/g++.dg/cpp0x/pr65736.C b/gcc/testsuite/g++.dg/cpp0x/pr65736.C new file mode 100644 index 0000000..6e9c7fb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/pr65736.C @@ -0,0 +1,5 @@ +// PR c++/65736 +// { dg-do compile { target c++11 } } + +int a[1]; +char *b[1] { (char *)&a[0] + 1 }; |