This is the mail archive of the
gdb-cvs@sourceware.org
mailing list for the GDB project.
[binutils-gdb] Deleted branch palves/cxx-enum-flags
- From: Pedro Alves <palves at sourceware dot org>
- To: bfd-cvs at sourceware dot org, gdb-cvs at sourceware dot org
- Date: 4 Nov 2016 09:59:03 -0000
- Subject: [binutils-gdb] Deleted branch palves/cxx-enum-flags
The branch 'palves/cxx-enum-flags' was deleted.
It previously pointed to:
1d71bdc... enum_flags: Fix ternary operator and remove implicit conver
Diff:
!!! WARNING: THE FOLLOWING COMMITS ARE NO LONGER ACCESSIBLE (LOST):
-------------------------------------------------------------------
1d71bdc... enum_flags: Fix ternary operator and remove implicit conver
6f0f2be... enum_flags: Fix problems and add comprehensive unit tests
commit 1d71bdc242616819a8d4ace8d7a703fdbd90e602
Author: Pedro Alves <palves@redhat.com>
Date: Fri Nov 4 02:02:39 2016 +0000
enum_flags: Fix ternary operator and remove implicit convertion to raw enum
The unit tests added by the previous patch revealed that this useful
use case doesn't work:
enum flag { FLAG1 = 1, FLAG2 = 2 };
enum_flags<flag> src = FLAG1;
enum_flags<flag> f1 = condition ? src : FLAG2;
It fails to compile because enum_flags<flag> and flag are convertible
to each other.
Turns out that making enum_flags be implicitly convertible to the
backing raw enum type was not a good idea.
If we make it convertible to the underlying type instead, we fix that
ternary operator use case, and, we find cases throughout the codebase
that should be using the enum_flags but were using the raw backing
enum instead. So it's a good change overall.
There's one case in compile/compile-c-types.c where we need to call a
function in a C API that expects the raw enum. To address cases like
that, this adds a "raw()" method to enum_flags. This way we can keep
using the safer enum_flags to construct the value, and then be
explicit when we need to get at the raw enum.
Tested with gcc 4.8, 4.9, 5.3, 7 (trunk) and clang 3.7.
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>
* common/enum-flags.h (enum_flags::operator&=): Change parameter
type to enum_flags from enum_type and adjust.
(enum_flags::operator|=): Likewise.
(enum_flags::operator^=): Likewise.
(enum_flags::operator enum_type): Delete.
(enum_flags::raw): New method.
(ENUM_FLAGS_GEN_BINOP): Adjust operator functions.
* compile/compile-c-types.c (convert_qualified): Use
enum_flags::raw.
* enum-flags-selftests.c Adjust ternary operator CHECK_VALID
tests.
(selftests::enum_flags_tests::self_test): Add more ternary
operator tests.
* record-btrace.c (btrace_thread_flag_to_str): Change parameter's
type to btrace_thread_flags from btrace_thread_flag.
(record_btrace_cancel_resume, record_btrace_step_thread): Change
local's type to btrace_thread_flags from btrace_thread_flag. Add
cast in DEBUG call.
commit 6f0f2be472d6e7dd37bf82841002674fa759b1b2
Author: Pedro Alves <palves@redhat.com>
Date: Fri Nov 4 02:00:54 2016 +0000
enum_flags: Fix problems and add comprehensive unit tests
This patch starts by adding comprehensive unit tests for enum_flags.
It adds:
- tests of normal expected uses of the API.
- checks that _invalid_ uses of the API would fail to compile. I.e.,
it validates that enum_flags really is a strong type, and that
incorrect mixing of enum types would be caught at compile time. It
pulls that off making use of SFINEA and C++11's decltype/constexpr.
This revealed many holes in the enum_flags API. For example, the f1
assignment below currently incorrectly fails to compile:
enum_flags<flags> f1 = FLAG1;
enum_flags<flags> f2 = FLAG2 | f1;
This hole and more are all plugged by this patch, by reworking how the
enum_flags operators are implemented, and making use of C++11's
feature of being able to delete methods/functions.
This makes most of the enum_flags operators constexpr. Beyond
enabling more compiler optimizations and enabling the new unit tests,
this has other advantages, like making it possible to use operator|
with enum_flags values in switch cases, where only compile-time
constants are allowed:
enum_flags<flags> f = FLAG1 | FLAG2;
switch (f)
{
case FLAG1 | FLAG2:
break;
}
Currently that fails to compile.
This adds a STATIC_SELF_TEST macro to selftest.h, which is a variant
of SELF_TEST, but uses C++11's static_assert to do checking at compile
time.
To avoid potential ODR violations, since the tests add enums with
short names that could easily conflict with other names, the new
selftests are placed in a namespace (selftests::enum_flags_tests). I
think that's a good practice that we should start following. This
required splitting the global operator overload enablement out of the
DEF_ENUM_FLAGS_TYPE macro into a separate macro, because
DEF_ENUM_FLAGS_TYPE wants to create the enum flags typedef in the
global namespace too.
Tested with gcc 4.8, 4.9, 5.3, 7 (trunk) and clang 3.7.
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>
* Makefile.in (COMMON_OBS): Add enum-flags-selftests.o.
* common/enum-flags.h (ENABLE_ENUM_FLAGS_OPERATORS): New, factored
out from DEF_ENUM_FLAGS_TYPE.
(enum_flags::underlying_value): Delete.
(enum_flags::enum_flags): Use default.
(enum_flags::operator=): Delete.
(enum_flags::enum_flags(enum_type e)): Now constexpr.
(enum_flags::enum_flags(enum_flags::zero_type *zero)): Likewise.
(enum_flags::operator&=(enum_type e)): No longer implement in
terms of the underlying type here.
(enum_flags::operator|=(enum_type e)): Likewise.
(enum_flags::operator^=(enum_type e)): Likewise.
(enum_flags::enum_type ()): Now constexpr.
(enum_flags::enum_flags operator&(enum_type e)): Delete.
(enum_flags::operator|(enum_type e)): Delete.
(enum_flags::operator^(enum_type e)): Delete.
(enum_flags::operator~()): Now constexpr.
(operator&, operator|, operator^): Delete.
(ENUM_FLAGS_GEN_BINOP, ENUM_FLAGS_GEN_COMPOUND_ASSIGN): New,
reimplementing global operators.
(operator~): Now constexpr and reimplemented.
(operator<<, operator>>): New deleted functions.
* enum-flags-selftests.c: New file.
* go-exp.y (parse_string_or_char): Add cast to int.
* selftest.h (SC_STRINGIZE_1, SC_STRINGIZE)
(STATIC_SELF_CHECK_FAIL_MSG, STATIC_SELF_CHECK): New.