diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b421705d973..40acfdf77e1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2001-08-03 Zack Weinberg + + * builtins.c (fold_builtin_constant_p): Return integer_zero_node + for complex expressions when cfun == 0. + * doc/extend.texi: Document that __builtin_constant_p can be + used in data initializers as well as functions. + 2001-08-03 Alexandre Oliva * config/mn10300/mn10300.h (CONDITIONAL_REGISTER_USAGE): Declare diff --git a/gcc/builtins.c b/gcc/builtins.c index 62e000058b9..08d2bb75e46 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -3793,10 +3793,14 @@ fold_builtin_constant_p (arglist) has side effects, show we don't know it to be a constant. Likewise if it's a pointer or aggregate type since in those case we only want literals, since those are only optimized - when generating RTL, not later. */ + when generating RTL, not later. + And finally, if we are compiling an initializer, not code, we + need to return a definite result now; there's not going to be any + more optimization done. */ if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected || AGGREGATE_TYPE_P (TREE_TYPE (arglist)) - || POINTER_TYPE_P (TREE_TYPE (arglist))) + || POINTER_TYPE_P (TREE_TYPE (arglist)) + || cfun == 0) return integer_zero_node; return 0; diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 787b722aa0e..b7c24961682 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3889,6 +3889,26 @@ never return 1 when you call the inline function with a string constant or compound literal (@pxref{Compound Literals}) and will not return 1 when you pass a constant numeric value to the inline function unless you specify the @option{-O} option. + +You may also use @code{__builtin_constant_p} in initializers for static +data. For instance, you can write + +@smallexample +static const int table[] = { + __builtin_constant_p (EXPRESSION) ? (EXPRESSION) : -1, + /* ... */ +}; +@end smallexample + +@noindent +This is an acceptable initializer even if @var{EXPRESSION} is not a +constant expression. GCC must be more conservative about evaluating the +built-in in this case, because it has no opportunity to perform +optimization. + +Previous versions of GCC did not accept this built-in in data +initializers. The earliest version where it is completely safe is +3.0.1. @end deftypefn @deftypefn {Built-in Function} long __builtin_expect (long @var{exp}, long @var{c}) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2424e7451f3..d0813ca70be 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-08-03 Zack Weinberg + + * gcc.dg/bconstp-1.c: New test. + 2001-08-03 Richard Henderson * g++.dg/eh/filter1.C, g++.dg/eh/filter2.C: New tests. diff --git a/gcc/testsuite/gcc.dg/bconstp-1.c b/gcc/testsuite/gcc.dg/bconstp-1.c new file mode 100644 index 00000000000..36831a5d6d5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/bconstp-1.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ + +/* This test checks that builtin_constant_p can be used safely in + initializers for static data. The macro X() defined below should + be an acceptable initializer expression no matter how complex its + argument is. */ + +extern int a; +extern int b; + +extern int foo(void); +extern int bar(void); + +#define X(exp) (__builtin_constant_p(exp) ? (exp) : -1) + +const short tests[] = { + X(0), + X(a), + X(0 && a), + X(a && b), + X(foo()), + X(0 && foo()), + X(a && foo()), + X(foo() && bar()) +};