aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2004-06-07 18:49:36 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2004-06-07 18:49:36 +0000
commitbf730f15c50fab842ac222b8e60d62737d5f0d9a (patch)
tree15790a9a0fa2a93d8ffe3c058372c43f8aef3c20
parentcb6231728e5b5cd61ef549354378252bfa92aabb (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/c-typeck.c26
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr14649-1.c16
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;
+}
+