aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/cpp0x
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-03-29 16:59:37 -0400
committerMarek Polacek <polacek@redhat.com>2024-04-02 14:19:16 -0400
commitdaa2e7c7ffe49b788357f7f2c9ef1c9b125c1f8c (patch)
tree35334bb61a3765945cccd9ce6f1e4418e2025894 /gcc/testsuite/g++.dg/cpp0x
parent5d7e9a35024f065b25f61747859c7cb7a770c92b (diff)
downloadgcc-daa2e7c7ffe49b788357f7f2c9ef1c9b125c1f8c.zip
gcc-daa2e7c7ffe49b788357f7f2c9ef1c9b125c1f8c.tar.gz
gcc-daa2e7c7ffe49b788357f7f2c9ef1c9b125c1f8c.tar.bz2
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.
Diffstat (limited to 'gcc/testsuite/g++.dg/cpp0x')
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/enum44.C30
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum44.C b/gcc/testsuite/g++.dg/cpp0x/enum44.C
new file mode 100644
index 0000000..92408c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum44.C
@@ -0,0 +1,30 @@
+// PR c++/103825
+// { dg-do compile { target c++11 } }
+
+enum class Type { Pawn };
+struct Piece {
+ Type type : 4;
+};
+
+void
+foo ()
+{
+ switch (Piece().type)
+ case Type::Pawn:;
+
+ auto x = Piece().type;
+ switch (x)
+ case Type::Pawn:;
+}
+
+enum class En {A};
+struct St {En field :1;};
+
+void
+bar ()
+{
+ volatile St s = {En::A};
+ switch(s.field) {
+ case En::A : break;
+ }
+}