From b7fc43d7c747d190e197ca89cfce4f1d9def7c7e Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 16 Dec 2016 09:40:03 +0000 Subject: [PATCH] re PR c++/71694 (store-data race with bitfields and tail-padding in C++) 2016-12-16 Richard Biener PR c++/71694 * langhooks-def.h (lhd_unit_size_without_reusable_padding): Declare. (LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING): Define. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Adjust. * langhooks.h (struct lang_hooks_for_types): Add unit_size_without_reusable_padding. * langhooks.c (lhd_unit_size_without_reusable_padding): New. * stor-layout.c (finish_bitfield_representative): Use unit_size_without_reusable_padding langhook to decide on the last representatives size. cp/ * cp-objcp-common.h (cp_unit_size_without_reusable_padding): Declare. (LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING): Define. * cp-objcp-common.c (cp_unit_size_without_reusable_padding): New. * g++.dg/pr71694.C: New testcase. From-SVN: r243738 --- gcc/ChangeLog | 13 +++++++++++++ gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cp-objcp-common.c | 10 ++++++++++ gcc/cp/cp-objcp-common.h | 4 ++++ gcc/langhooks-def.h | 6 +++++- gcc/langhooks.c | 9 +++++++++ gcc/langhooks.h | 4 ++++ gcc/stor-layout.c | 15 ++++++++------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/pr71694.C | 27 +++++++++++++++++++++++++++ 10 files changed, 92 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr71694.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ca4f4f4..cf4e49a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,18 @@ 2016-12-16 Richard Biener + PR c++/71694 + * langhooks-def.h (lhd_unit_size_without_reusable_padding): Declare. + (LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING): Define. + (LANG_HOOKS_FOR_TYPES_INITIALIZER): Adjust. + * langhooks.h (struct lang_hooks_for_types): Add + unit_size_without_reusable_padding. + * langhooks.c (lhd_unit_size_without_reusable_padding): New. + * stor-layout.c (finish_bitfield_representative): Use + unit_size_without_reusable_padding langhook to decide on the + last representatives size. + +2016-12-16 Richard Biener + PR middle-end/71632 * expr.c (expand_cond_expr_using_cmove): Bail out early if we end up recursing via TER. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5c67132..757bcef99 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-12-16 Richard Biener + + PR c++/71694 + * cp-objcp-common.h (cp_unit_size_without_reusable_padding): Declare. + (LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING): Define. + * cp-objcp-common.c (cp_unit_size_without_reusable_padding): New. + 2016-12-15 Jakub Jelinek P0490R0 GB 20: decomposition declaration should commit to tuple diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 633831c..b78d24d 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -252,6 +252,16 @@ cp_type_dwarf_attribute (const_tree type, int attr) return -1; } +/* Return the unit size of TYPE without reusable tail padding. */ + +tree +cp_unit_size_without_reusable_padding (tree type) +{ + if (CLASS_TYPE_P (type)) + return CLASSTYPE_SIZE_UNIT (type); + return TYPE_SIZE_UNIT (type); +} + /* Stubs to keep c-opts.c happy. */ void push_file_scope (void) diff --git a/gcc/cp/cp-objcp-common.h b/gcc/cp/cp-objcp-common.h index 65ac95c..f0e45c5 100644 --- a/gcc/cp/cp-objcp-common.h +++ b/gcc/cp/cp-objcp-common.h @@ -30,6 +30,7 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, extern int cp_decl_dwarf_attribute (const_tree, int); extern int cp_type_dwarf_attribute (const_tree, int); extern void cp_common_init_ts (void); +extern tree cp_unit_size_without_reusable_padding (tree); /* Lang hooks that are shared between C++ and ObjC++ are defined here. Hooks specific to C++ or ObjC++ go in cp/cp-lang.c and objcp/objcp-lang.c, @@ -137,6 +138,9 @@ extern void cp_common_init_ts (void); #define LANG_HOOKS_DECL_DWARF_ATTRIBUTE cp_decl_dwarf_attribute #undef LANG_HOOKS_TYPE_DWARF_ATTRIBUTE #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE cp_type_dwarf_attribute +#undef LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING +#define LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING cp_unit_size_without_reusable_padding + #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index e4c0ffb..b25c5a7 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -161,6 +161,8 @@ extern tree lhd_make_node (enum tree_code); /* Types hooks. There are no reasonable defaults for most of them, so we create a compile-time error instead. */ +extern tree lhd_unit_size_without_reusable_padding (tree); + #define LANG_HOOKS_MAKE_TYPE lhd_make_node #define LANG_HOOKS_CLASSIFY_RECORD NULL #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error @@ -189,6 +191,7 @@ extern tree lhd_make_node (enum tree_code); #define LANG_HOOKS_GET_DEBUG_TYPE NULL #define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO NULL #define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE lhd_type_dwarf_attribute +#define LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING lhd_unit_size_without_reusable_padding #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \ LANG_HOOKS_MAKE_TYPE, \ @@ -212,7 +215,8 @@ extern tree lhd_make_node (enum tree_code); LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE, \ LANG_HOOKS_GET_DEBUG_TYPE, \ LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO, \ - LANG_HOOKS_TYPE_DWARF_ATTRIBUTE \ + LANG_HOOKS_TYPE_DWARF_ATTRIBUTE, \ + LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING \ } /* Declaration hooks. */ diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 1ce1962..260d33c 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -729,6 +729,15 @@ lhd_type_dwarf_attribute (const_tree, int) return -1; } +/* Default implementation of LANG_HOOKS_UNIT_SIZE_WITHOUT_REUSABLE_PADDING. + Just return TYPE_SIZE_UNIT unadjusted. */ + +tree +lhd_unit_size_without_reusable_padding (tree t) +{ + return TYPE_SIZE_UNIT (t); +} + /* Returns true if the current lang_hooks represents the GNU C frontend. */ bool diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 4e925ad6..19e3fa1 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -166,6 +166,10 @@ struct lang_hooks_for_types /* Returns -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute value otherwise. */ int (*type_dwarf_attribute) (const_tree, int); + + /* Returns a tree for the unit size of T excluding tail padding that + might be used by objects inheriting from T. */ + tree (*unit_size_without_reusable_padding) (tree); }; /* Language hooks related to decls and the symbol table. */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 5a4bcf1..0aa3861 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1864,13 +1864,14 @@ finish_bitfield_representative (tree repr, tree field) } else { - /* ??? If you consider that tail-padding of this struct might be - re-used when deriving from it we cannot really do the following - and thus need to set maxsize to bitsize? Also we cannot - generally rely on maxsize to fold to an integer constant, so - use bitsize as fallback for this case. */ - tree maxsize = size_diffop (TYPE_SIZE_UNIT (DECL_CONTEXT (field)), - DECL_FIELD_OFFSET (repr)); + /* Note that if the C++ FE sets up tail-padding to be re-used it + creates a as-base variant of the type with TYPE_SIZE adjusted + accordingly. So it is safe to include tail-padding here. */ + tree aggsize = lang_hooks.types.unit_size_without_reusable_padding + (DECL_CONTEXT (field)); + tree maxsize = size_diffop (aggsize, DECL_FIELD_OFFSET (repr)); + /* We cannot generally rely on maxsize to fold to an integer constant, + so use bitsize as fallback for this case. */ if (tree_fits_uhwi_p (maxsize)) maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr))); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8de3e18..8aa1ad9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 2016-12-16 Richard Biener + PR c++/71694 + * g++.dg/pr71694.C: New testcase. + +2016-12-16 Richard Biener + PR middle-end/71632 * gcc.dg/pr71632.c: New testcase. diff --git a/gcc/testsuite/g++.dg/pr71694.C b/gcc/testsuite/g++.dg/pr71694.C new file mode 100644 index 0000000..e79f62a --- /dev/null +++ b/gcc/testsuite/g++.dg/pr71694.C @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct B { + B() {} + int x; + int a : 6; + int b : 6; + int c : 6; +}; + +struct C : B { + char d; +}; + +C c; + +int main() +{ + /* We have to make sure to not cause a store data race between + c.c and c.d residing in the tail padding of B. */ + c.c = 1; + c.d = 2; +} + +/* In particular on x86 c.d should not be loaded/stored via movl. */ +/* { dg-final { scan-assembler-not "movl" { target { x86_64-*-* i?86-*-* } } } } */ -- 2.7.4