The following code is accepted and compiled without error by G++: int main() { const float f1 = 0.0; constexpr float f2 = f1; return 0; } Note that the declaration of f2 as constexpr requires f1 to be a constant expression, which it isn't, according to ยง5.19/2: ====(QUOTE)======== A condition-expression is a core constant expression unless it involves [...] [..9th item..] - an lvalue-to-rvalue conversion (4.1) unless it is applied to [...] a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expresion, or [...] ====(ENDQUOTE)==== So if f1 had been declared as const int, the code would be acceptable, but there is no such exception for floating point (or any other non-integral or non-enum type). Tested with a 20130708 snapshot checkout from the master branch of the git-mirror of the repository. (I'll test with a more recent version soon.)
It's accepted even with -pedantic
Confirmed that the problem exists in the most recent version of GCC 4.9, i.e. a 20130725 snapshot from the master branch.
*** Bug 59676 has been marked as a duplicate of this bug. ***
This was introduced by the fix for bug 21089; decay_conversion and convert_like_real shouldn't be pulling values out of variables that are not decl_const_var_p. The trick is fixing that without breaking the static initialization optimization that 21089 is about. I guess allowing maybe_constant_init to be more aggressive than *_constant_value is the way to approach this.
I think this should be put on hold, since EWG told CWG in Rapperswil that const floats should perform the same magic as const ints do, see http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1826 which EWG suggested CWG to reopen and resolve.
In other words, EWG wants the standard to be changed so that GCC's behavior actually becomes conforming, as far as I understand the intent.
Author: jason Date: Wed Nov 19 22:06:17 2014 New Revision: 217814 URL: https://gcc.gnu.org/viewcvs?rev=217814&root=gcc&view=rev Log: PR c++/57979 * init.c (decl_really_constant_value): Rename from integral_constant_value. (scalar_constant_value): Similar but limited to scalar results. (decl_constant_value_safe): Remove. (constant_value_1): Respect return_aggregate_cst_ok_p. * typeck.c (decay_conversion): Use scalar_constant_value. * call.c (convert_like_real): Likewise. * cvt.c (ocp_convert): No need to check CLASS_TYPE_P. * typeck.c (decay_conversion): Or ARRAY_TYPE. * constexpr.c (struct constexpr_ctx): Add strict field. (cxx_eval_constant_expression) [VAR_DECL]: Use it to select between decl_constant_value and decl_really_constant_value. (cxx_eval_outermost_constant_expr): Add strict parm. (maybe_constant_init): Not strict. (potential_constant_expression_1): Add strict parm. Shorten most internal calls with RECUR macro. * cp-tree.h, pt.c, semantics.c: Adjust. Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/constexpr.c trunk/gcc/cp/cp-tree.h trunk/gcc/cp/cvt.c trunk/gcc/cp/decl.c trunk/gcc/cp/init.c trunk/gcc/cp/pt.c trunk/gcc/cp/semantics.c trunk/gcc/cp/typeck.c trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-object2.C trunk/gcc/testsuite/g++.dg/cpp0x/nullptr06.C
(In reply to Ville Voutilainen from comment #5) > I think this should be put on hold, since EWG told CWG in Rapperswil > that const floats should perform the same magic as const ints do, see > http://open-std.org/JTC1/SC22/WG21/docs/cwg_closed.html#1826 > which EWG suggested CWG to reopen and resolve. I had already done most of the work before you made this comment. :) You might want to ping Mike about that again, as I don't think it came up in core at the Urbana meeting. Fixed for gcc 5.