diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/btrace.c | 4 | ||||
-rw-r--r-- | gdb/common/enum-flags.h | 26 | ||||
-rw-r--r-- | gdb/compile/compile-c-types.c | 2 | ||||
-rw-r--r-- | gdb/enum-flags-selftests.c | 60 | ||||
-rw-r--r-- | gdb/record-btrace.c | 10 |
5 files changed, 67 insertions, 35 deletions
diff --git a/gdb/btrace.c b/gdb/btrace.c index 39d537c368d..2717ae2370c 100644 --- a/gdb/btrace.c +++ b/gdb/btrace.c @@ -229,7 +229,7 @@ ftrace_new_function (struct btrace_function *prev, static void ftrace_update_caller (struct btrace_function *bfun, struct btrace_function *caller, - enum btrace_function_flag flags) + btrace_function_flags flags) { if (bfun->up != NULL) ftrace_debug (bfun, "updating caller"); @@ -246,7 +246,7 @@ ftrace_update_caller (struct btrace_function *bfun, static void ftrace_fixup_caller (struct btrace_function *bfun, struct btrace_function *caller, - enum btrace_function_flag flags) + btrace_function_flags flags) { struct btrace_function *prev, *next; diff --git a/gdb/common/enum-flags.h b/gdb/common/enum-flags.h index becd2c74ece..50c60b4468f 100644 --- a/gdb/common/enum-flags.h +++ b/gdb/common/enum-flags.h @@ -114,24 +114,28 @@ public: : m_enum_value ((enum_type) 0) {} - enum_flags &operator&= (enum_type e) + enum_flags &operator&= (enum_flags e) { - m_enum_value = (enum_type) (m_enum_value & e); + m_enum_value = (enum_type) (m_enum_value & e.m_enum_value); return *this; } - enum_flags &operator|= (enum_type e) + enum_flags &operator|= (enum_flags e) { - m_enum_value = (enum_type) (m_enum_value | e); + m_enum_value = (enum_type) (m_enum_value | e.m_enum_value); return *this; } - enum_flags &operator^= (enum_type e) + enum_flags &operator^= (enum_flags e) { - m_enum_value = (enum_type) (m_enum_value ^ e); + m_enum_value = (enum_type) (m_enum_value ^ e.m_enum_value); return *this; } - /* Allow conversion to the enum type. */ - constexpr operator enum_type () const + /* Like raw enums, allow conversion to the underlying type. */ + constexpr operator underlying_type () const + { return m_enum_value; } + + /* Get the underlying value as a raw enum. */ + constexpr enum_type raw () const { return m_enum_value; } /* Binary operations involving some unrelated type (which would be a @@ -167,19 +171,19 @@ private: template <typename enum_type> \ constexpr typename enum_flags_type<enum_type>::type \ OPERATOR_OP (enum_flags<enum_type> e1, enum_type e2) \ - { return enum_type (e1) OP e2; } \ + { return e1.raw () OP e2; } \ \ /* enum_flags on the RHS. */ \ template <typename enum_type> \ constexpr typename enum_flags_type<enum_type>::type \ OPERATOR_OP (enum_type e1, enum_flags<enum_type> e2) \ - { return e1 OP enum_type (e2); } \ + { return e1 OP e2.raw (); } \ \ /* enum_flags on both LHS/RHS. */ \ template <typename enum_type> \ constexpr typename enum_flags_type<enum_type>::type \ OPERATOR_OP (enum_flags<enum_type> e1, enum_flags<enum_type> e2) \ - { return enum_type (e1) OP enum_type (e2); } \ + { return e1.raw () OP e2.raw (); } \ \ /* Delete cases involving unrelated types. */ \ \ diff --git a/gdb/compile/compile-c-types.c b/gdb/compile/compile-c-types.c index 505bce68448..6cf1dc79661 100644 --- a/gdb/compile/compile-c-types.c +++ b/gdb/compile/compile-c-types.c @@ -306,7 +306,7 @@ convert_qualified (struct compile_c_instance *context, struct type *type) return C_CTX (context)->c_ops->build_qualified_type (C_CTX (context), unqual_converted, - quals); + quals.raw ()); } /* Convert a complex type to its gcc representation. */ 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. */ diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c index 7c0e39f4af4..f68ce3c7119 100644 --- a/gdb/record-btrace.c +++ b/gdb/record-btrace.c @@ -1863,7 +1863,7 @@ record_btrace_to_get_tailcall_unwinder (struct target_ops *self) /* Return a human-readable string for FLAG. */ static const char * -btrace_thread_flag_to_str (enum btrace_thread_flag flag) +btrace_thread_flag_to_str (btrace_thread_flags flag) { switch (flag) { @@ -2165,7 +2165,7 @@ record_btrace_commit_resume (struct target_ops *ops) static void record_btrace_cancel_resume (struct thread_info *tp) { - enum btrace_thread_flag flags; + btrace_thread_flags flags; flags = tp->btrace.flags & (BTHR_MOVE | BTHR_STOP); if (flags == 0) @@ -2173,7 +2173,7 @@ record_btrace_cancel_resume (struct thread_info *tp) DEBUG ("cancel resume thread %s (%s): %x (%s)", print_thread_id (tp), - target_pid_to_str (tp->ptid), flags, + target_pid_to_str (tp->ptid), (unsigned) flags, btrace_thread_flag_to_str (flags)); tp->btrace.flags &= ~(BTHR_MOVE | BTHR_STOP); @@ -2398,7 +2398,7 @@ record_btrace_step_thread (struct thread_info *tp) { struct btrace_thread_info *btinfo; struct target_waitstatus status; - enum btrace_thread_flag flags; + btrace_thread_flags flags; btinfo = &tp->btrace; @@ -2406,7 +2406,7 @@ record_btrace_step_thread (struct thread_info *tp) btinfo->flags &= ~(BTHR_MOVE | BTHR_STOP); DEBUG ("stepping thread %s (%s): %x (%s)", print_thread_id (tp), - target_pid_to_str (tp->ptid), flags, + target_pid_to_str (tp->ptid), (unsigned) flags, btrace_thread_flag_to_str (flags)); /* We can't step without an execution history. */ |