public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] PR c/14649: Constant folding builtins in initializers
@ 2004-06-07 15:32 Roger Sayle
  2004-06-07 16:45 ` Mark Mitchell
  2004-06-07 17:45 ` Joseph S. Myers
  0 siblings, 2 replies; 3+ messages in thread
From: Roger Sayle @ 2004-06-07 15:32 UTC (permalink / raw)
  To: gcc-patches; +Cc: Mark Mitchell


The following patch is my proposed solution to PR c/14649, which is a
C front-end problem where we currently fail to issue a "initializer
element is not constant" warning when we manage to constant fold a
mathematical builtin with constant arguments.

Although PR c/14649 is marked as a 3.4/3.5 regression and targetted at
3.4.1, the underlying problem is not restricted to atan(1.0), and its
possible to generate examples using sqrt, sin, floor or nan that affect
earlier GCC releases.


The solution used below is to test c-typechk.c's "require_constant_value"
variable, which indicates that we are currently parsing an initializer
that needs to be a compile-time constant.  Previously, build_binary_op
used "initializer_stack" to check whether it was processing an
initializer, but this fails to distinguish initialization of "auto"
variables at function scope, from global variables and "static" variables
at function scope.  Firstly, when constant folding such static/constant
initializers, we should be using "fold_initialization", that ignores the
possibility floating point exceptions or compile-time rounding modes.

Then to address the PR itself, we check whether "fold_initialization" on
a function call returns a constant expression.  If so, we've managed to
evaluation a GCC intrinsic at compile-time, and should issue a warning
at compile-time.  To provide a way to avoid such warnings/errors, these
diagnostics are only generated if the function isn't called as the
__builtin_foo form, allowing compile-time evalution of __builtin_sqrt
to be considered a GNU extension.  This avoids seriously breaking code
that may depend upon "const double nan = __builtin_nan("");".


Aside:
The correct way to address this issue is for the C front-end to follow
the models of the C++, Java, fortran, g77 and ada front-ends, and have
its parser work with a structure that wrap's a "tree" when parsing
expressions.

struct c_expr_tree {
  tree expr;
  bool is_const;
  bool is_lvalue;
  bool has_side_effects;
  bool no_warning;
} c_expr_tree;

This wrapper is only around the roots of the constructed/folded trees
during parsing, and isn't doesn't increase the size of a tree node or
appear internally within the tree.  Then build_binary_op, build_unary_op,
etc, combine c_expr_trees to return a resulting c_expr_tree.  Indeed
the c_expr_tree's may not even need to be dyanmically allocated but
exist in the stack frame of the parser.  This would allow us to determine
correctly whether an expression is constant by each of the ISO language
standards, allows us to throw away NON_LVALUE_EXPR nodes, avoids the
TREE_NO_WARNING hack added to fold_builtin, handles ternary operators
where the condition and one branch is constant, etc...

Unfortunately, such a C front-end parser rewrite isn't on the cards
for 3.4.1, a stable release branch almost a week away from release.



The following patch has been tested against mainline on i686-pc-linux-gnu
with a full "make bootstrap", all default languages, and regression tested
with a top-level "make -k check" with no new failures.  I'm currently
testing the same patch against the gcc-3_4-branch.

Ok for mainline?  Would a backport be suitable for 3.4.1?



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.

	* gcc.dg/pr14649-1.c: New test case.


Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.309
diff -c -3 -p -r1.309 c-typeck.c
*** c-typeck.c	6 Jun 2004 15:21:55 -0000	1.309
--- c-typeck.c	7 Jun 2004 01:42:57 -0000
*************** Software Foundation, 59 Temple Place - S
*** 50,55 ****
--- 50,58 ----
     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);
*************** build_function_call (tree function, tree
*** 1892,1898 ****
    result = build (CALL_EXPR, TREE_TYPE (fntype),
  		  function, coerced_params, NULL_TREE);
    TREE_SIDE_EFFECTS (result) = 1;
!   result = fold (result);

    if (VOID_TYPE_P (TREE_TYPE (result)))
      return result;
--- 1895,1912 ----
    result = build (CALL_EXPR, TREE_TYPE (fntype),
  		  function, coerced_params, NULL_TREE);
    TREE_SIDE_EFFECTS (result) = 1;
!
!   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;
*************** build_unary_op (enum tree_code code, tre
*** 2585,2591 ****

    if (argtype == 0)
      argtype = TREE_TYPE (arg);
!   return fold (build1 (code, argtype, arg));
  }

  /* Return nonzero if REF is an lvalue valid for this language.
--- 2599,2606 ----

    if (argtype == 0)
      argtype = TREE_TYPE (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.
*************** static int constructor_depth;
*** 4227,4235 ****
  /* 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) {...}.  */
--- 4242,4247 ----
*************** build_binary_op (enum tree_code code, tr
*** 7194,7201 ****
      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);

      if (final_type != 0)
        result = convert (final_type, result);
--- 7206,7213 ----
      tree result = build (resultcode, build_type, op0, op1);

      /* Treat expressions in initializers specially as they can't trap.  */
!     result = require_constant_value ? fold_initializer (result)
! 				    : fold (result);

      if (final_type != 0)
        result = convert (final_type, result);


/* 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;
}


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] PR c/14649: Constant folding builtins in initializers
  2004-06-07 15:32 [PATCH] PR c/14649: Constant folding builtins in initializers Roger Sayle
@ 2004-06-07 16:45 ` Mark Mitchell
  2004-06-07 17:45 ` Joseph S. Myers
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Mitchell @ 2004-06-07 16:45 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches

Roger Sayle wrote:

> The following patch is my proposed solution to PR c/14649, which is a
> C front-end problem where we currently fail to issue a "initializer
> element is not constant" warning when we manage to constant fold a
> mathematical builtin with constant arguments.

Thanks.

This patch looks OK to me, but (IIRC) you're not a C front-end 
maintainer, and neither am I, so let's have one of them sign off. 
Assuming this goes in on the mainline, it's also OK for 3.4.1.

-- 
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] PR c/14649: Constant folding builtins in initializers
  2004-06-07 15:32 [PATCH] PR c/14649: Constant folding builtins in initializers Roger Sayle
  2004-06-07 16:45 ` Mark Mitchell
@ 2004-06-07 17:45 ` Joseph S. Myers
  1 sibling, 0 replies; 3+ messages in thread
From: Joseph S. Myers @ 2004-06-07 17:45 UTC (permalink / raw)
  To: Roger Sayle; +Cc: gcc-patches, Mark Mitchell

On Mon, 7 Jun 2004, Roger Sayle wrote:

> exist in the stack frame of the parser.  This would allow us to determine
> correctly whether an expression is constant by each of the ISO language
> standards, allows us to throw away NON_LVALUE_EXPR nodes, avoids the
> TREE_NO_WARNING hack added to fold_builtin, handles ternary operators
> where the condition and one branch is constant, etc...

... get rid of TREE_COMPLEXITY, fix bug 11250, etc. - see my proposal in
comment#15 to bug 14711 (and elsewhere).  (is_const would probably be more
like half a dozen flags rather than one, and you need to wrap type names
as well as expressions to get the constant expression rules correct; see
my discussion of constant expression issues
<http://groups.google.com/groups?selm=buh3kg%24623%241%40pegasus.csx.cam.ac.uk>.)

> Ok for mainline?  Would a backport be suitable for 3.4.1?

OK for mainline and 3.4 branch.

-- 
Joseph S. Myers
jsm@polyomino.org.uk

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2004-06-07 16:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-07 15:32 [PATCH] PR c/14649: Constant folding builtins in initializers Roger Sayle
2004-06-07 16:45 ` Mark Mitchell
2004-06-07 17:45 ` Joseph S. Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).