summaryrefslogtreecommitdiff
path: root/gdb/enum-flags-selftests.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/enum-flags-selftests.c')
-rw-r--r--gdb/enum-flags-selftests.c60
1 files changed, 44 insertions, 16 deletions
diff --git a/gdb/enum-flags-selftests.c b/gdb/enum-flags-selftests.c
index b4a5f0762dc..7f1488ea005 100644
--- a/gdb/enum-flags-selftests.c
+++ b/gdb/enum-flags-selftests.c
@@ -146,7 +146,7 @@ CHECK_VALID (true, RE, RE (1))
CHECK_VALID (true, RE, RE (RE2 ()))
CHECK_VALID (false, void, RE (EF2 ()))
CHECK_VALID (true, RE, RE (RE ()))
-CHECK_VALID (true, RE, RE (EF ()))
+CHECK_VALID (false, void, RE (EF ()))
/* other -> EF. */
@@ -268,23 +268,30 @@ CHECK_VALID (true, EF, ~EF ())
/* Check ternary operator. This exercises implicit conversions. */
-/* Invalid since each type can be converted to the other. */
-/* GCC 4.8 incorrectly fails to compile this test with:
- error: operands to ?: have different types ‘enum_flags<RE>’ and ‘RE’
- Confirmed to compile/pass with gcc 4.9, 5.3 and clang 3.7.
-*/
-#if GCC_VERSION >= 4009
-CHECK_VALID (false, void, true ? EF () : RE ())
-CHECK_VALID (false, void, true ? RE () : EF ())
-#endif
+CHECK_VALID (true, EF, true ? EF () : RE ())
+CHECK_VALID (true, EF, true ? RE () : EF ())
+
+/* Both enums should have the same underlying type. Pick any. */
+typedef std::underlying_type<RE>::type und;
/* These are valid, but it's not a big deal since you won't be able to
- assign the resulting int to an enum or an enum_flags without a
- cast. */
-CHECK_VALID (true, int, true ? EF () : EF2 ())
-CHECK_VALID (true, int, true ? EF2 () : EF ())
-CHECK_VALID (true, int, true ? EF () : RE2 ())
-CHECK_VALID (true, int, true ? RE2 () : EF ())
+ assign the resulting integer to an enum or an enum_flags without a
+ cast.
+
+ The latter two tests are disabled on older GCCs because they
+ incorrectly fail to compile with gcc 4.8 and 4.9 at least, with:
+
+ no known conversion from ‘enum_flags<RE>::underlying_type {aka
+ unsigned int}’ to ‘enum_flags_tests::RE2’
+
+ They've been confirmed to compile/pass with gcc 5.3, gcc 7.1 and
+ clang 3.7. */
+CHECK_VALID (true, und, true ? EF () : EF2 ())
+CHECK_VALID (true, und, true ? EF2 () : EF ())
+#if GCC_VERSION >= 5003
+CHECK_VALID (true, und, true ? EF () : RE2 ())
+CHECK_VALID (true, und, true ? RE2 () : EF ())
+#endif
/* Unfortunately this can't work due to the way C++ computes the
return type of the ternary conditional operator. int isn't
@@ -487,13 +494,34 @@ self_test ()
}
/* Check the ternary operator. */
+
{
+ /* raw enum, raw enum */
constexpr test_flags f1 = true ? FLAG1 : FLAG2;
STATIC_SELF_CHECK (f1 == FLAG1);
constexpr test_flags f2 = false ? FLAG1 : FLAG2;
STATIC_SELF_CHECK (f2 == FLAG2);
}
+ {
+ /* enum flags, raw enum */
+ constexpr test_flags src = FLAG1;
+ constexpr test_flags f1 = true ? src : FLAG2;
+ STATIC_SELF_CHECK (f1 == FLAG1);
+ constexpr test_flags f2 = false ? src : FLAG2;
+ STATIC_SELF_CHECK (f2 == FLAG2);
+ }
+
+ {
+ /* enum flags, enum flags */
+ constexpr test_flags src1 = FLAG1;
+ constexpr test_flags src2 = FLAG2;
+ constexpr test_flags f1 = true ? src1 : src2;
+ STATIC_SELF_CHECK (f1 == src1);
+ constexpr test_flags f2 = false ? src1 : src2;
+ STATIC_SELF_CHECK (f2 == src2);
+ }
+
/* Check that we can use operator| in switch cases, where only
constants are allowed. This should work because operator| is
constexpr. */