]> git.ipfire.org Git - thirdparty/gcc.git/commit
c++: ICE with scoped enum in switch condition [PR103825]
authorMarek Polacek <polacek@redhat.com>
Fri, 29 Mar 2024 20:59:37 +0000 (16:59 -0400)
committerMarek Polacek <polacek@redhat.com>
Tue, 2 Apr 2024 18:19:16 +0000 (14:19 -0400)
commitdaa2e7c7ffe49b788357f7f2c9ef1c9b125c1f8c
tree35334bb61a3765945cccd9ce6f1e4418e2025894
parent5d7e9a35024f065b25f61747859c7cb7a770c92b
c++: ICE with scoped enum in switch condition [PR103825]

Here we ICE when gimplifying

  enum class Type { Pawn };
  struct Piece {
    Type type : 4;
  };
  void foo() {
    switch (Piece().type)
      case Type::Pawn:;
  }

because we ended up with TYPE_PRECISION (cond) < TYPE_PRECISION (case).
That's because the case expr type here is the unlowered type Type,
whereas the conditional's type is the lowered <unnamed-signed:4>.  This
is not supposed to happen: see the comment in pop_switch around the
is_bitfield_expr_with_lowered_type check.

But here we did not revert to the lowered SWITCH_STMT_TYPE, because
the conditional contains a TARGET_EXPR, which has side-effects, which
means that finish_switch_cond -> maybe_cleanup_point_expr wraps it
in a CLEANUP_POINT_EXPR.  And is_bitfield_expr_with_lowered_type does
not see through those.

PR c++/103825

gcc/cp/ChangeLog:

* typeck.cc (is_bitfield_expr_with_lowered_type): Handle
CLEANUP_POINT_EXPR.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/enum44.C: New test.
gcc/cp/typeck.cc
gcc/testsuite/g++.dg/cpp0x/enum44.C [new file with mode: 0644]