static const double Eps = .0000001; static const double Tol = 1.0+Eps; int main(int, char *[]) { return 0; } Fedora 9. Works fine on MacOs 10.5 with gcc 4.0. setting Eps to be an integral value (but keeping its type to be double) makes the ICE go away.
t.c:5: error: initializer for floating value is not a floating constant t.c:5: internal compiler error: tree check: expected real_cst, have plus_expr in output_constant, at varasm.c:4429 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
The following line triggers the ICE since GCC 4.1.0: ================================ const double c = .1, d = c+1; ================================
I think the primary question is, do we expect -frounding-math to force this to be evaluated at runtime or not? If it should be evaluated at runtime, then I'd say initializer_constant_valid_p should reject PLUS_EXPR and MINUS_EXPR with FLOAT_TYPE_P (endtype) (and maybe also narrowing casts like (float) double) if flag_rounding_math. If it shouldn't be evaluated at runtime, we'd need to figure out where to call (perhaps recursively) the fold*initializer calls - that's something only the C FE uses, but not C++.
Subject: Re: [4.2/4.3/4.4 regression] ICE with "-frounding-math -g" On Thu, 14 Aug 2008, jakub at gcc dot gnu dot org wrote: > I think the primary question is, do we expect -frounding-math to force this to > be evaluated at runtime or not? For C, it's evaluated at compile time per Annex F, so the question is what makes most sense in a specifically C++ context.
Yeah. In C we won't see addition or subtraction of 2 FLOAT_TYPE_P constants in initializer_constant_valid_p, as it has been folded.
Maybe my comment is going to be out of scope, but the question is also to know what the "primary question" is here, that is, what usage is supposed to be supported by -frounding-math. g++ currently accepts code like the following (in non-pedantic mode) : template <int i> struct A {}; A<(int) (1.5-2.0)> a; I am not sure it would be wise to have -frounding-math break this (I understand that this would be a consequence of one of Jakub's proposals). There are users who would like to see constant propagation of floats, obviously, even with -frounding-math. (see also C++0x's constexpr which requires this ability, I think). And there are users who would like to have constant propagation aware of the rounding mode (either deferring the computation at runtime, and/or have a way to tell the compiler which rounding mode to use at compile-time). It's also related to the FENV_ACCESS pragma. The current behavior of -frounding-math which keeps on propagating floats constants is not nice for interval arithmetic code (the main user of -frounding-math I guess?): you need to protect against the compiler in ways which affects performance (and code clarity like introducing volatiles or other workarounds in odd places...). The fact that -frounding-math affects the whole translation unit is also problematic. Usually, it's only in very particular places that you need to tell the compiler that a block of code needs such an attention. Ideally, for me, one should have the option to tell the compiler that a block of code (e.g. using the new option attributes, or a pragma a la FENV_ACCESS), or maybe even a single operation, depends on a non-default rounding-mode, hence stopping inexact constant propagation and other transformations. As a bonus, it would be great to also have a way to tell the compiler that the rounding-mode to be used is known at compile-time. One could add another option e.g. -frounding-math-at-runtime to distinguish the two behaviors mentioned by Jakub, but IMO this would not be helpful for the users who want to mix the 2 features in the same translation unit. My 2 cents.
Interestingly enough this is only broken on the trunk for me, where we reject the code. /abuild/rguenther/trunk-g/gcc/t.ii:1: error: initializer for floating value is not a floating constant /abuild/rguenther/trunk-g/gcc/t.ii:1: confused by earlier errors, bailing out Can we decide what is the bug here and appropriately split this bug into rejects-valid or accepts-invalid for gcc < 4.4 and ice-on-{in}valid for 4.4? Due to the unclear status and mixing stuff I leave this P3.
With respect to Comment #4: I see no reason for C++ to be different than C in this respect, and thus I see no reason not to perform the computation at compile-time. In general, although some in the committees do not seem to care, users expect C to be a subset of C++. Certainly, wherever the standards permit us to do so, we should make GNU C and GNU C++ behave identically; compiling C code as C++ with the same toolset and getting different results leads to user surprise.
Incidentally, I submitted to WG21 a few days ago a proposal which will appear in the coming mid-term mailing as N2811, named "Directed Rounding Arithmetic Operations". In the meantime, you can find it here: http://www-sop.inria.fr/members/Sylvain.Pion/cxx/rounded_operations_N2811.pdf This document proposes the addition of functions like: -------------------------------------------------------------- template < float_round_style r, FloatingPointLike T, FloatingPointLike U > requires True<(r != round_indeterminate)> constexpr auto add(T t, U u) -> decltype(t + u); Returns: The addition of t and u rounded according to r. -------------------------------------------------------------- (and similarly for sub, mul, div, sqrt, fma, and int<->float and float<->float conversions). With these, it would be possible to explictly attach a rounding mode to an operation in the source code. Moreover, their constexpr nature would mean that they would work for compile-time constants as well. This would require a bit of help from the compiler. That would mean that code which cares about rounding modes would have a way to say so, and then, other codes can more easily be dealt with (that is: no need to bother thinking about the effect of -frounding-math on compile-time constants computations). (comments on the proposal are welcome, BTW)
Closing 4.2 branch.
GCC 4.3.4 is being released, adjusting target milestone.
t.cc:5:1: error: initializer for floating value is not a floating constant t.cc:5:1: internal compiler error: tree check: expected real_cst, have plus_expr in output_constant, at varasm.c:4545 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. The ICE is still there ...
Subject: Bug 36912 Author: jason Date: Wed Nov 4 23:13:23 2009 New Revision: 153921 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153921 Log: PR c++/36912 * varasm.c (initializer_constant_valid_p): A PLUS_EXPR or MINUS_EXPR of REAL_TYPE is not a valid constant initializer. (output_constant): Avoid crash after error. Added: trunk/gcc/testsuite/g++.dg/init/static-init2.C Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/varasm.c
Subject: Bug 36912 Author: jason Date: Thu Nov 5 13:11:42 2009 New Revision: 153936 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153936 Log: PR c++/36912 * varasm.c (initializer_constant_valid_p): A PLUS_EXPR or MINUS_EXPR of REAL_TYPE is not a valid constant initializer. (output_constant): Avoid crash after error. Added: trunk/gcc/testsuite/g++.dg/init/static-init2.C Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/varasm.c
Subject: Bug 36912 Author: jason Date: Thu Nov 5 14:47:24 2009 New Revision: 153941 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153941 Log: PR c++/36912 * varasm.c (initializer_constant_valid_p): A PLUS_EXPR or MINUS_EXPR of REAL_TYPE is not a valid constant initializer. (output_constant): Avoid crash after error. Added: branches/gcc-4_4-branch/gcc/testsuite/g++.dg/init/static-init2.C Modified: branches/gcc-4_4-branch/gcc/ChangeLog branches/gcc-4_4-branch/gcc/testsuite/ChangeLog branches/gcc-4_4-branch/gcc/varasm.c
Subject: Bug 36912 Author: jason Date: Thu Nov 5 16:32:36 2009 New Revision: 153947 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153947 Log: PR c++/36912 * varasm.c (initializer_constant_valid_p): A PLUS_EXPR or MINUS_EXPR of REAL_TYPE is not a valid constant initializer. (output_constant): Avoid crash after error. Added: branches/gcc-4_3-branch/gcc/testsuite/g++.dg/init/static-init2.C Modified: branches/gcc-4_3-branch/gcc/ChangeLog branches/gcc-4_3-branch/gcc/testsuite/ChangeLog branches/gcc-4_3-branch/gcc/varasm.c
Fixed. Discussion of changes to folding behavior with -frounding-math can continue somewhere else.