Bug 47504 - [C++0x] some constexpr calculations erroneously overflow when using negative numbers
[C++0x] some constexpr calculations erroneously overflow when using negative ...
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: c++
4.6.0
: P3 normal
: 4.6.1
Assigned To: Jason Merrill
: rejects-valid
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-01-28 04:03 UTC by Simon Hill
Modified: 2011-03-29 14:51 UTC (History)
2 users (show)

See Also:
Host:
Target: x86_64-unknown-linux-gnu
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-01-28 10:59:58


Attachments
overflow.cpp (114 bytes, text/x-c++src)
2011-01-28 04:03 UTC, Simon Hill
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Hill 2011-01-28 04:03:04 UTC
Created attachment 23148 [details]
overflow.cpp

Easiest to describe via code:

overflow.cpp
=================================================
char constexpr sub(char arg)
  { return char(arg - char(1)); }

int main()
  { static char constexpr m = sub(-1); }
=================================================
g++ overflow.cpp --std=c++0x
=================================================
overflow.cpp: In function ‘int main()’:
overflow.cpp:5:36: error: overflow in constant expression [-fpermissive]

This is simply attempting to subtract 1 from -1, using "char"s.
I cannot see any reason why this should trigger an overflow error.
I have attempted to cast every intermediate state to char to avoid any unintended casts.
The code is as simple as I could get it while still triggering the seemingly erroneous overflow.

Compiles OK using int instead of char. (int can still erroneously overflow in other circumstances, though. Would examples be useful?).
Compiles OK using 1 instead of -1.
Compiles OK using a literal -1 instead of a parameter.
Compiles OK if main()::m isn't constexpr.

Attached source code, but it's probably easier to just copy/paste the above.


SPECS:
gcc: version 4.6.0 2010-12-30 (experimental) (svn = 168358)
 - manually patched by (http://gcc.gnu.org/ml/gcc-patches/2007-04/msg00620.html)
 - patch shouldn't have any effect here.
ubuntu: 10.10 (64 bit)
intel: core2 duo

Are any other specs relevant here, such as GMP. (Note: my GMP is the standard one).


I searched other constexpr bugs here - AFAIK none appear to be about overflow.
Comment 1 Richard Biener 2011-01-28 10:59:58 UTC
Confirmed (with -fsigned-char, -funsigned-char works ok).
Comment 2 Jason Merrill 2011-03-16 23:34:25 UTC
This is happening because convert_to_integer is doing what seems to me like an invalid transformation: it forces the arithmetic to be done in unsigned char, so we end up with char((unsigned char)-2), or char(254), which has implementation-defined behavior according to the C and C++ standards.

This seems to have been introduced with the fix for PR 25125.
Comment 3 Andrew Pinski 2011-03-16 23:43:38 UTC
>which has implementation-defined behavior according to the C and C++ standards.

But that does not mean it has an overflow though, right?
Comment 4 Jason Merrill 2011-03-17 03:14:22 UTC
True, the language standards seem to distinguish between this and the overflow you get from saying INT_MAX+1.  But GCC internals do not make this distinction; in either case, we end up setting TREE_OVERFLOW in force_fit_type_double.  Given that, I would prefer to avoid this transformation.
Comment 5 Jason Merrill 2011-03-17 22:00:51 UTC
Author: jason
Date: Thu Mar 17 22:00:47 2011
New Revision: 171116

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171116
Log:
	PR c++/47504
	* semantics.c (cxx_eval_constant_expression) [NOP_EXPR]: Don't let
	the conversion set TREE_OVERFLOW.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-overflow2.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C
Comment 6 Jason Merrill 2011-03-18 02:49:36 UTC
Fixed for 4.7, planning to fix in 4.6.1.
Comment 7 Jason Merrill 2011-03-29 14:24:24 UTC
Author: jason
Date: Tue Mar 29 14:24:19 2011
New Revision: 171664

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171664
Log:
	PR c++/47504
	* semantics.c (cxx_eval_constant_expression) [NOP_EXPR]: Don't let
	the conversion set TREE_OVERFLOW.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-overflow2.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/semantics.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-data2.C
Comment 8 Jason Merrill 2011-03-29 14:37:13 UTC
Fixed for 4.6.1.