[Bug c++/62096] New: unexpected warning overflow in implicit constant conversion

2014-08-11 Thread travis.vitek at roguewave dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62096

Bug ID: 62096
   Summary: unexpected warning overflow in implicit constant
conversion
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: travis.vitek at roguewave dot com

The following test case generates a an unexpected warning.

[vitek@sidewinder] 350 % gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/amd/packages/mdx/redhat/compilers/gcc-4.9.0/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.9.0/configure --prefix=/build/gcc-4.9.0
--enable-languages=c,c++
Thread model: posix
gcc version 4.9.0 (GCC)
[vitek@sidewinder] 351 % cat t.cpp
enum E {
E_val  = 1,
};

inline constexpr E operator~(E e)
{
return E(~static_cast(e));
}

int main()
{
int val = ~E_val;
(void) val;
}
[vitek@sidewinder] 352 % g++ --pedantic -std=c++11 -c ./t.cpp
./t.cpp: In function 'int main()':
./t.cpp:12:16: warning: overflow in implicit constant conversion [-Woverflow]
 int val = ~E_val;
^
[vitek@sidewinder] 353 %


The issue seems to be related to the function being constexpr and the type of
the destination being int. If I remove the constexpr or change the destination
type (to long long or E), the warning goes away.


[Bug c++/62096] unexpected warning overflow in implicit constant conversion

2016-07-21 Thread travis.vitek at roguewave dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62096

--- Comment #4 from Travis Vitek  ---
I believe the underlying type of the unscoped enumeration `E' should be `int'.
According to 7.2 paragraph 7, the underlying type is

  .. implementation-defined which integral type is used
  as the underlying type except that the underlying
  type shall not be larger than int unless the value
  of an enumerator cannot fit in an int or unsigned int.

I've modified my test case slightly to verify that it is `int'.

[vitek@sidewinder] 71 % cat t.cpp
#include 

enum E {
E_val  = 1,
};

enum U {
U_val  = 4294967295,
};

inline constexpr E operator~(E e)
{
return E(~static_cast(e));
}

#define DEFINE_DETECT(T) const char* detect(T) { return #T; }
DEFINE_DETECT(bool)

DEFINE_DETECT(char)
DEFINE_DETECT(signed char)
DEFINE_DETECT(unsigned char)

DEFINE_DETECT(wchar_t)

DEFINE_DETECT(short)
DEFINE_DETECT(int)
DEFINE_DETECT(long)
DEFINE_DETECT(long long)

DEFINE_DETECT(unsigned int)
DEFINE_DETECT(unsigned short)
DEFINE_DETECT(unsigned long)
DEFINE_DETECT(unsigned long long)


int main()
{
printf ("%s\n", detect(E_val));
printf ("%s\n", detect(U_val));

int eval = ~E_val;
int uval = ~U_val;

(void) eval;
(void) uval;
}
[vitek@sidewinder] 72 % g++ --pedantic -std=c++11 t.cpp
t.cpp: In function 'int main()':
t.cpp:41:17: warning: overflow in implicit constant conversion [-Woverflow]
 int eval = ~E_val;
 ^
[vitek@sidewinder] 73 % ./a.out
int
unsigned int


[vitek@sidewinder] 74 %


If the underlying type of `E' is `int', then there should be no overflow when
converting back from `E' to `int', right? What am I missing?