Bug 57979 - G++ accepts constant expression defined using floating point non-constexpr glvalue
Summary: G++ accepts constant expression defined using floating point non-constexpr gl...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.0
: P3 normal
Target Milestone: 5.0
Assignee: Jason Merrill
URL:
Keywords:
: 59676 (view as bug list)
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2013-07-25 08:13 UTC by Johannes Goller
Modified: 2014-11-20 03:43 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-07-25 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Goller 2013-07-25 08:13:00 UTC
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.)
Comment 1 Jonathan Wakely 2013-07-25 08:20:33 UTC
It's accepted even with -pedantic
Comment 2 Johannes Goller 2013-07-25 09:15:58 UTC
Confirmed that the problem exists in the most recent version of GCC 4.9, i.e. a 20130725 snapshot from the master branch.
Comment 3 Paolo Carlini 2014-09-05 09:38:12 UTC
*** Bug 59676 has been marked as a duplicate of this bug. ***
Comment 4 Jason Merrill 2014-11-18 14:03:12 UTC
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.
Comment 5 Ville Voutilainen 2014-11-18 14:16:07 UTC
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.
Comment 6 Ville Voutilainen 2014-11-18 14:17:41 UTC
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.
Comment 7 Jason Merrill 2014-11-19 22:06:49 UTC
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
Comment 8 Jason Merrill 2014-11-20 03:43:41 UTC
(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.