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

            Bug ID: 72777
           Summary: broken error message with reference in constexpr
                    arguments in c++11 mode
           Product: gcc
           Version: 6.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bloerwald at googlemail dot com
  Target Milestone: ---

The error message for modifying a reference argument in a constexpr is not
exactly perfect, and degrades horribly when using indirection to access the
reference:

    struct integral { int value; };

    #ifdef fun
    constexpr int& value_of (integral& x) { return x.value; }
    #else
    #define value_of(x) x.value
    #endif

    constexpr int dop (integral& lhs, integral& rhs)
    {
      return value_of (lhs) -= value_of (rhs);
    }

$ c++ tmp.cpp -o/dev/null -c --std=c++11 -Ufun
tmp.cpp: In function ‘constexpr int dop(integral&, integral&)’:
tmp.cpp:15:1: error: expression ‘(lhs.integral::value = (lhs.integral::value -
rhs.integral::value))’ is not a constant-expression
 }
 ^

Note that it is not only not pointing to the actually bad expression, but also
shows `(l = (l - r))` instead of `l -= r` which the user wrote. Using the
value_of function instead of direct .value access somehow adds an <anonymous>
and completely breaks the expression:

$ c++ tmp.cpp -o/dev/null -c --std=c++11 -Dfun
tmp.cpp: In function ‘constexpr int dop(integral&, integral&)’:
tmp.cpp:11:1: error: expression ‘(value_of((* & lhs)) = (value_of((* & rhs)),
(value_of((* & lhs)) - <anonymous>)))’ is not a constant-expression
 }
 ^

which after stripping roughly is `(l = (r, l - <anonymous>))`.  

Note that --std=c++14 lets everything compile just fine (I guess due to the
relaxation of constexpr rules). I am not sure if this is valid c++14 though.

Reply via email to