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

            Bug ID: 83484
           Summary: constexpr not evaluated at compile time
           Product: gcc
           Version: 7.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

The following test case triggers a link failure because the constexpr are not
evaluated at compile time:

$ g++-8 tmp.cpp -Os -save-temps

tmp.o: In function `Port<7>::set(Port<7>::Value)':
tmp.cpp:(.text._ZN4PortILi7EE3setENS0_5ValueE[_ZN4PortILi7EE3setENS0_5ValueE]+0x2):
undefined reference to `Port<7>::High'
tmp.o: In function `main':
tmp.cpp:(.text.startup+0x3): undefined reference to `Port<7>::Low'
tmp.cpp:(.text.startup+0x1a): undefined reference to `Port<7>::High'
collect2: error: ld returned 1 exit status

== Test case ==

unsigned volatile PORTB;

template<int p>
struct Port
{
  enum class Value : unsigned { High, Low };
  static inline void set (Value);
  static constexpr Value High = Value::High;
  static constexpr Value Low = Value::Low;
};

template<> constexpr Port<7>::Value Port<7>::High;
template<> constexpr Port<7>::Value Port<7>::Low;

template<>
inline void Port<7>::set (Port<7>::Value value)
{
  if (High == value)
    PORTB |= 2;
  else
    PORTB &= ~2;
}

int main()
{
  Port<7>::set (Port<7>::Low);
  Port<7>::set (PORTB ? Port<7>::Low : Port<7>::High);
}

Apart from the link failure you see that even with optimizations turned on and
for an almost trivial function call like Port<7>::set (Port<7>::Low), the
compiler generates a call.  Fot some targets the compiler even generates calls
with just 2 instructions (one of which is a return statement).

So far I see this for v7 and v8 on x86_64 and avr.

Reply via email to