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

            Bug ID: 118029
           Summary: Wrong location info in caret diagnostic about enum &=
                    enum|enum
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Keywords: diagnostic
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: redi at gcc dot gnu.org
  Target Milestone: ---

enum E { E0, E1, E2 };
E operator|(E lhs, E rhs) { return E(int(lhs) | int(rhs)); }

void f(E e)
{
  e &= E1;
  e &= E1|E2;
}

This gives two errors, as expected:

e2.cc: In function ‘void f(E)’:
e2.cc:6:5: error: invalid conversion from ‘int’ to ‘E’ [-fpermissive]
    6 |   e &= E1;
      |   ~~^~~~~
      |     |
      |     int
e2.cc:7:11: error: invalid conversion from ‘int’ to ‘E’ [-fpermissive]
    7 |   e &= E1|E2;
      |           ^~
      |           |
      |           int


The first error highlights the entire expression which is fine.

The second one highlights E2 which is highly confusing, since neither E2 nor
E1|E2 has type int. The overloaded operator| ensures that E1|E2 has type E and
so the error on line 7 is exactly equivalent to the one on line 6.

I would expect line 7 to show something closer to the error for line 6, i.e.

    7 |   e &= E1|E2;
      |   ~~^~~~~~~~
      |     |
      |     int

However, neither of the errors is really that helpful. Where is the 'int'
coming from? The user has to know that the &= expression works like e = (e &
E1) where (e & E1) is valid but produces an int, and that the problem is in the
assignment of an int to e.


EDG gives a much better error here:

"e2.cc", line 6: error: this operation on an enumerated type requires an
          applicable user-defined operator function
    e &= E1;
      ^

"e2.cc", line 7: error: this operation on an enumerated type requires an
          applicable user-defined operator function
    e &= E1|E2;
      ^

2 errors detected in the compilation of "e2.cc".

This describes the actual issue: the built-in &= simply doesn't work for
enumeration types.  This is much more helpful than saying 'int' can't convert
to E when there's no 'int' visible in the code.

Ideally we'd say something similar, but in the absence of a clear explanation
of the problem, we should not highlight an incorrect subexpression.

Reply via email to