diff options
author | Roger Sayle <roger@eyesopen.com> | 2004-06-07 18:49:36 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2004-06-07 18:49:36 +0000 |
commit | bf730f15c50fab842ac222b8e60d62737d5f0d9a (patch) | |
tree | 15790a9a0fa2a93d8ffe3c058372c43f8aef3c20 /gcc | |
parent | cb6231728e5b5cd61ef549354378252bfa92aabb (diff) | |
download | gcc-bf730f15c50fab842ac222b8e60d62737d5f0d9a.zip gcc-bf730f15c50fab842ac222b8e60d62737d5f0d9a.tar.gz gcc-bf730f15c50fab842ac222b8e60d62737d5f0d9a.tar.bz2 |
re PR c/14649 (atan(1.0) should not be a constant expression)
PR c/14649
* c-typeck.c (require_constant_value, require_constant_elements):
Move declarations to the top of the file.
(build_function_call): If we require a constant value, fold with
fold_initializer. If the result is a constant, and the function
wasn't called using __builtin_foo, issue a pedantic warning.
(build_unary_op): If we require a constant value, fold tree with
fold_initializer.
(build_binary_op): Use require_constant_value to determine whether
to call fold or fold_initializer.
* gcc.dg/pr14649-1.c: New test case.
From-SVN: r82705
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c-typeck.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr14649-1.c | 16 |
4 files changed, 53 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e42f1cc..ba13ae7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2004-06-07 Roger Sayle <roger@eyesopen.com> + + PR c/14649 + * c-typeck.c (require_constant_value, require_constant_elements): + Move declarations to the top of the file. + (build_function_call): If we require a constant value, fold with + fold_initializer. If the result is a constant, and the function + wasn't called using __builtin_foo, issue a pedantic warning. + (build_unary_op): If we require a constant value, fold tree with + fold_initializer. + (build_binary_op): Use require_constant_value to determine whether + to call fold or fold_initializer. + 2004-06-07 Richard Henderson <rth@redhat.com> * gimple-low.c (struct lower_data): Add the_return_label and diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 0f77d8c..3b8cb4b 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -50,6 +50,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA message within this initializer. */ static int missing_braces_mentioned; +static int require_constant_value; +static int require_constant_elements; + static tree qualify_type (tree, tree); static int tagged_types_tu_compatible_p (tree, tree, int); static int comp_target_types (tree, tree, int); @@ -1893,7 +1896,18 @@ build_function_call (tree function, tree params) result = build (CALL_EXPR, TREE_TYPE (fntype), function, coerced_params, NULL_TREE); TREE_SIDE_EFFECTS (result) = 1; - result = fold (result); + + if (require_constant_value) + { + result = fold_initializer (result); + + if (TREE_CONSTANT (result) + && (name == NULL_TREE + || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0)) + pedwarn_init ("initializer element is not constant"); + } + else + result = fold (result); if (VOID_TYPE_P (TREE_TYPE (result))) return result; @@ -2586,7 +2600,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag) if (argtype == 0) argtype = TREE_TYPE (arg); - return fold (build1 (code, argtype, arg)); + val = build1 (code, argtype, arg); + return require_constant_value ? fold_initializer (val) : fold (val); } /* Return nonzero if REF is an lvalue valid for this language. @@ -4228,9 +4243,6 @@ static int constructor_depth; /* 0 if implicitly pushing constructor levels is allowed. */ int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */ -static int require_constant_value; -static int require_constant_elements; - /* DECL node for which an initializer is being read. 0 means we are reading a constructor expression such as (struct foo) {...}. */ @@ -7195,8 +7207,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1, tree result = build (resultcode, build_type, op0, op1); /* Treat expressions in initializers specially as they can't trap. */ - result = initializer_stack ? fold_initializer (result) - : fold (result); + result = require_constant_value ? fold_initializer (result) + : fold (result); if (final_type != 0) result = convert (final_type, result); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8063bac..cbb0c49 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-07 Roger Sayle <roger@eyesopen.com> + + PR c/14649 + * gcc.dg/pr14649-1.c: New test case. + 2004-06-07 Richard Henderson <rth@redhat.com> * gcc.dg/tree-ssa/20030728-1.c: Fixup return value to not match diff --git a/gcc/testsuite/gcc.dg/pr14649-1.c b/gcc/testsuite/gcc.dg/pr14649-1.c new file mode 100644 index 0000000..83a9f57 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr14649-1.c @@ -0,0 +1,16 @@ +/* PR c/14649 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +double atan(double); + +const double pi = 4*atan(1.0); /* { dg-warning "(not constant)|(near initialization)" } */ + +const double ok = 4*__builtin_atan(1.0); + +double foo() +{ + double ok2 = 4*atan(1.0); + return ok2; +} + |