https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80886

            Bug ID: 80886
           Summary: __builtin_constant_p magic has broken at some point
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: q....@rsn-tech.co.uk
  Target Milestone: ---

I'm using g++ for an embedded system, and as is common with such things,
hardware addresses are provided as hex constants. I want to create pointers
from them, using constexpr because they are known at compile time.

Now the C++ Standard forbids reinterpret_cast<> or the equivalent in a
constexpr so it can't be done directly, which is annoying but that's the
Standard.

However, with older versions of g++, one could solve this with the magic use of
__builtin_constant_p() in a ternary expression. Thus:

test.cpp:
    #define CONST(x) (__builtin_constant_p(x) ? x : x)

    constexpr void *phardware {CONST ((void *) 0x1000)};

(This is sufficient for a complete test program, BTW)

This use appears to be documented, although it's not 100% clear. It's certainly
very desirable.

My cross-development system recently upgraded from 4.9.2 to 6.2.1 and the magic
has stopped working. The loss of magic holds in other 6.x versions I've tried,
but still works in clang 3.8.1 which is the latest version in my distro (Fedora
24)

Compilation results:

$ <4.9.2>-g++  -c -std=c++14 test.cpp
$

$ <6.2.1>-g++  -c -std=c++14 test.cpp
test.cpp:4:28: error: reinterpret_cast from integer to pointer
 constexpr void *phardware {CONST ((void *) 0x1000)};
                            ^~~~~~~~~~
test.cpp:2:45: note: in definition of macro 'CONST'
 #define CONST(x) (__builtin_constant_p(x) ? x : x)
$

Has this behaviour changed deliberately? As I say, it is contrary to the
Standard, but it would be disappointing to lose such a useful extension.

Reply via email to