diff options
author | Marek Polacek <polacek@redhat.com> | 2015-03-20 21:53:40 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2015-03-20 21:53:40 +0000 |
commit | f594abf4b9ebf0976c6dbebc9abd51e0abd2da48 (patch) | |
tree | 9fd7386d7df1c1a211bdaee788626840958f801d /gcc/cp | |
parent | 730c436a33f0978a689c866df072ea3540ed037d (diff) | |
download | gcc-f594abf4b9ebf0976c6dbebc9abd51e0abd2da48.zip gcc-f594abf4b9ebf0976c6dbebc9abd51e0abd2da48.tar.gz gcc-f594abf4b9ebf0976c6dbebc9abd51e0abd2da48.tar.bz2 |
re PR c++/65398 ([C++11] GCC rejects constexpr variable definitions with valid initialization)
PR c++/65398
* constexpr.c (cxx_fold_indirect_ref): Transform *(&A[i] p+ j) into
A[i + j].
* g++.dg/cpp0x/pr65398.C: New test.
From-SVN: r221544
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 21 |
2 files changed, 27 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dadf673..9bc6337 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2015-03-20 Marek Polacek <polacek@redhat.com> + PR c++/65398 + * constexpr.c (cxx_fold_indirect_ref): Transform *(&A[i] p+ j) into + A[i + j]. + +2015-03-20 Marek Polacek <polacek@redhat.com> + PR c++/65072 * typeck.c (lookup_anon_field): Make sure we're dealing with the main variant. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 1b5f50c..37b619d 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2427,6 +2427,27 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) break; } } + /* *(&A[i] p+ j) => A[i + j] */ + else if (TREE_CODE (op00) == ARRAY_REF + && TREE_CODE (TREE_OPERAND (op00, 1)) == INTEGER_CST + && TREE_CODE (op01) == INTEGER_CST) + { + tree t = fold_convert_loc (loc, ssizetype, + TREE_OPERAND (op00, 1)); + tree nelts + = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (op00, 0))); + /* Don't fold an out-of-bound access. */ + if (!tree_int_cst_le (t, nelts)) + 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), + TYPE_SIZE_UNIT (type)); + t = size_binop_loc (loc, PLUS_EXPR, op01, t); + return build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (op00, 0), + t, NULL_TREE, NULL_TREE); + } } } /* *(foo *)fooarrptr => (*fooarrptr)[0] */ |