diff options
Diffstat (limited to 'gdb/enum-flags-selftests.c')
-rw-r--r-- | gdb/enum-flags-selftests.c | 60 |
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. */ |