re PR c++/71694 (store-data race with bitfields and tail-padding in C++)

2016-12-16  Richard Biener  <rguenther@suse.de>

	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
This commit is contained in:
Richard Biener 2016-12-16 09:40:03 +00:00 committed by Richard Biener
parent c4d5c5e6ac
commit b7fc43d7c7
10 changed files with 92 additions and 8 deletions

View file

@ -1,3 +1,16 @@
2016-12-16 Richard Biener <rguenther@suse.de>
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 <rguenther@suse.de>
PR middle-end/71632

View file

@ -1,3 +1,10 @@
2016-12-16 Richard Biener <rguenther@suse.de>
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 <jakub@redhat.com>
P0490R0 GB 20: decomposition declaration should commit to tuple

View file

@ -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)

View file

@ -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

View file

@ -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. */

View file

@ -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

View file

@ -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. */

View file

@ -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)));

View file

@ -1,3 +1,8 @@
2016-12-16 Richard Biener <rguenther@suse.de>
PR c++/71694
* g++.dg/pr71694.C: New testcase.
2016-12-16 Richard Biener <rguenther@suse.de>
PR middle-end/71632

View file

@ -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-*-* } } } } */