diff options
author | Jakub Jelinek <jakub@redhat.com> | 2018-01-13 18:00:43 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2018-01-13 18:00:43 +0100 |
commit | b4923738ef57a441f6f9248260848bde5af165fa (patch) | |
tree | 5e1b4802d2cab1d24b857680da9e4057d37fc2d7 /gcc | |
parent | 567a6e1cdb3cae09ae74bdd528fd31c0b4956ad2 (diff) | |
download | gcc-b4923738ef57a441f6f9248260848bde5af165fa.zip gcc-b4923738ef57a441f6f9248260848bde5af165fa.tar.gz gcc-b4923738ef57a441f6f9248260848bde5af165fa.tar.bz2 |
re PR c/83801 ([avr] String constant in __flash not put into .progmem)
PR c/83801
* c-tree.h (decl_constant_value_1): Add a bool argument.
* c-typeck.c (decl_constant_value_1): Add IN_INIT argument, allow
returning a CONSTRUCTOR if it is true. Use error_operand_p.
(decl_constant_value): Adjust caller.
* c-fold.c (c_fully_fold_internal): If in_init, pass true to
decl_constant_value_1 as IN_INIT. Otherwise, punt if
decl_constant_value returns initializer that has BLKmode or
array type.
(c_fully_fold_internal) <case COMPONENT_REF>: Fold if !lval.
* gcc.dg/pr83801.c: New test.
From-SVN: r256608
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c/c-fold.c | 12 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 2 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr83801.c | 27 |
6 files changed, 60 insertions, 7 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index d15073e..95404fb 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,16 @@ +2018-01-13 Jakub Jelinek <jakub@redhat.com> + + PR c/83801 + * c-tree.h (decl_constant_value_1): Add a bool argument. + * c-typeck.c (decl_constant_value_1): Add IN_INIT argument, allow + returning a CONSTRUCTOR if it is true. Use error_operand_p. + (decl_constant_value): Adjust caller. + * c-fold.c (c_fully_fold_internal): If in_init, pass true to + decl_constant_value_1 as IN_INIT. Otherwise, punt if + decl_constant_value returns initializer that has BLKmode or + array type. + (c_fully_fold_internal) <case COMPONENT_REF>: Fold if !lval. + 2018-01-03 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> diff --git a/gcc/c/c-fold.c b/gcc/c/c-fold.c index 5776f1b..12460bc 100644 --- a/gcc/c/c-fold.c +++ b/gcc/c/c-fold.c @@ -168,9 +168,15 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, if (VAR_P (expr) && !lval && (optimize || in_init)) { if (in_init) - ret = decl_constant_value_1 (expr); + ret = decl_constant_value_1 (expr, true); else - ret = decl_constant_value (expr); + { + ret = decl_constant_value (expr); + if (ret != expr + && (TYPE_MODE (TREE_TYPE (ret)) == BLKmode + || TREE_CODE (TREE_TYPE (ret)) == ARRAY_TYPE)) + return expr; + } /* Avoid unwanted tree sharing between the initializer and current function's body where the tree can be modified e.g. by the gimplifier. */ @@ -264,6 +270,8 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, TREE_READONLY (ret) = TREE_READONLY (expr); TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); } + if (!lval) + ret = fold (ret); goto out; case ARRAY_REF: diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 84b5b95..ae1a1e6 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -640,7 +640,7 @@ extern struct c_expr default_function_array_read_conversion (location_t, struct c_expr); extern struct c_expr convert_lvalue_to_rvalue (location_t, struct c_expr, bool, bool); -extern tree decl_constant_value_1 (tree); +extern tree decl_constant_value_1 (tree, bool); extern void mark_exp_read (tree); extern tree composite_type (tree, tree); extern tree build_component_ref (location_t, tree, tree, location_t); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 33b4364..e22bc74 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -1832,20 +1832,20 @@ c_size_in_bytes (const_tree type) /* Return either DECL or its known constant value (if it has one). */ tree -decl_constant_value_1 (tree decl) +decl_constant_value_1 (tree decl, bool in_init) { if (/* Note that DECL_INITIAL isn't valid for a PARM_DECL. */ TREE_CODE (decl) != PARM_DECL && !TREE_THIS_VOLATILE (decl) && TREE_READONLY (decl) && DECL_INITIAL (decl) != NULL_TREE - && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK + && !error_operand_p (DECL_INITIAL (decl)) /* This is invalid if initial value is not constant. If it has either a function call, a memory reference, or a variable, then re-evaluating it could give different results. */ && TREE_CONSTANT (DECL_INITIAL (decl)) /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) + && (in_init || TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)) return DECL_INITIAL (decl); return decl; } @@ -1858,7 +1858,7 @@ decl_constant_value (tree decl) { /* Don't change a variable array bound or initial value to a constant in a place where a variable is invalid. */ - return current_function_decl ? decl_constant_value_1 (decl) : decl; + return current_function_decl ? decl_constant_value_1 (decl, false) : decl; } /* Convert the array expression EXP to a pointer. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 04c613f..aee6b43 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-01-13 Jakub Jelinek <jakub@redhat.com> + + PR c/83801 + * gcc.dg/pr83801.c: New test. + 2018-01-13 Paul Thomas <pault@gcc.gnu.org> PR fortran/52162 diff --git a/gcc/testsuite/gcc.dg/pr83801.c b/gcc/testsuite/gcc.dg/pr83801.c new file mode 100644 index 0000000..d4ad89f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83801.c @@ -0,0 +1,27 @@ +/* PR c/83801 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-original" } */ + +static const char a[] = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; +static const char b = a[27]; +struct S { const char c[30]; const char d[30]; }; +static const struct S e[] = { { "01234567890123456789012345678", "90123456789012345678901234567" }, + { "89012345678901234567890123456", "78901234567890123456789012345" } }; +static const char f = e[1].c[4]; + +char +foo (int i) +{ + return a[i]; +} + +char +bar (int i) +{ + return e[0].d[i]; +} + +/* { dg-final { scan-tree-dump {a\[i]} "original" } } */ +/* { dg-final { scan-tree-dump-not {"01234567890123456789012345678901234567890123456789012345678901234567890123456789"\[i]} "original" } } */ +/* { dg-final { scan-tree-dump {e\[0]\.d\[i]} "original" } } */ +/* { dg-final { scan-tree-dump-not {"90123456789012345678901234567"\[i]} "original" } } */ |