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.
Confirmed (with -fsigned-char, -funsigned-char works ok).
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.
>which has implementation-defined behavior according to the C and C++ standards. But that does not mean it has an overflow though, right?
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.
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
Fixed for 4.7, planning to fix in 4.6.1.
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
Fixed for 4.6.1.