re PR c/14649 (atan(1.0) should not be a constant expression)
authorRoger Sayle <roger@eyesopen.com>
Mon, 7 Jun 2004 18:49:36 +0000 (18:49 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 7 Jun 2004 18:49:36 +0000 (18:49 +0000)
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

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr14649-1.c [new file with mode: 0644]

index e42f1ccb11119a28ec8584d002f237cd5f819aec..ba13ae70377aac5a1ea8088274cf8abcb47b548c 100644 (file)
@@ -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
index 0f77d8c33972ef9b937f14f7bf5c477238405144..3b8cb4b2c8c3620ae0b3b0747015ff04e5680ee6 100644 (file)
@@ -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);
index 8063bac70f159dc31c9ee48aea27bc3bbc7ca87d..cbb0c496b23fe5988adc340aae8e3e4569c3b8bc 100644 (file)
@@ -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 (file)
index 0000000..83a9f57
--- /dev/null
@@ -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;
+}
+