Bug 69138 - Woverflow not triggered for constexpr within template class
Summary: Woverflow not triggered for constexpr within template class
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: constexpr
  Show dependency treegraph
 
Reported: 2016-01-04 17:09 UTC by Krzysztof Wesołowski
Modified: 2021-12-22 02:47 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.9.3, 5.3.0, 6.0
Last reconfirmed: 2016-01-21 00:00:00


Attachments
Another way to show this bug (231 bytes, text/x-csrc)
2017-03-12 10:39 UTC, Xi Ruoyao
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Krzysztof Wesołowski 2016-01-04 17:09:45 UTC
When i have following code:

#include <stdint.h>
static constexpr uint8_t small_global = 0xFFFFFFFF;

class A {
    static constexpr uint8_t small_within_class = 0xFFFFFFFF;
};


template<typename T>
class B {
    static constexpr uint8_t small_within_templated_class = 0xFFFFFFFF;
};

B<int> b;

It only produces warnings for first two cases.

Online compiler with test case: https://goo.gl/aGL0n4
Comment 1 Marek Polacek 2016-01-21 13:34:14 UTC
Confirmed.
Comment 2 Martin Sebor 2016-04-27 20:35:40 UTC
I don't think the test case necessarily demonstrates a bug. The implicit instantiation of B<int> that's triggered by the definition of an object of the specialization "causes the implicit instantiation of the declarations, but not of the definitions, [...] of the class [...] static data members; and
it causes the implicit instantiation of the definitions of unscoped member enumerations and member anonymous unions."

That being said, I think the bug can be reproduced by instantiating (e.g., by virtue of using) B<int>::small_within_templated_class, for example like so:

template <typename T>
class B {
  static constexpr uint8_t small_within_templated_class = 0xFFFFFFFF;
};

constexpr uint8_t i = B<int>::small_within_templated_class;
Comment 3 Xi Ruoyao 2017-03-12 10:32:07 UTC
> template <typename T>
> class B {
>   static constexpr uint8_t small_within_templated_class = 0xFFFFFFFF;
> };
> 
> constexpr uint8_t i = B<int>::small_within_templated_class;

"s/class/struct/" to make member public. This case is NOT warned. But
clang++ warns:

~~~
pr69138-1.cpp:4:59: warning: implicit conversion from 'unsigned int' to
      'const uint8_t' (aka 'const unsigned char') changes value from 4294967295
      to 255 [-Wconstant-conversion]
  static constexpr uint8_t small_within_templated_class = 0xFFFFFFFF;
                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~   ^~~~~~~~~~
1 warning generated.
~~~
Comment 4 Xi Ruoyao 2017-03-12 10:39:44 UTC
Created attachment 40950 [details]
Another way to show this bug

This test case also exploits this bug.

In this lim<long> should be the same as limlong, but g++ (trunk) only
warns about the latter:

~~~
pr69138-2.cpp: In function 'long unsigned int limlong(bool)':
pr69138-2.cpp:23:16: warning: integer overflow in expression [-Woverflow]
     return b ? -limits<long>::min : limits<long>::max;
~~~

No warnings generated for lim<long>(bool).