Commit b7fc43d7 by Richard Biener Committed by Richard Biener

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
parent c4d5c5e6
2016-12-16 Richard Biener <rguenther@suse.de> 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 PR middle-end/71632
* expr.c (expand_cond_expr_using_cmove): Bail out early if * expr.c (expand_cond_expr_using_cmove): Bail out early if
we end up recursing via TER. we end up recursing via TER.
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> 2016-12-15 Jakub Jelinek <jakub@redhat.com>
P0490R0 GB 20: decomposition declaration should commit to tuple P0490R0 GB 20: decomposition declaration should commit to tuple
......
...@@ -252,6 +252,16 @@ cp_type_dwarf_attribute (const_tree type, int attr) ...@@ -252,6 +252,16 @@ cp_type_dwarf_attribute (const_tree type, int attr)
return -1; 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. */ /* Stubs to keep c-opts.c happy. */
void void
push_file_scope (void) push_file_scope (void)
......
...@@ -30,6 +30,7 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t, ...@@ -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_decl_dwarf_attribute (const_tree, int);
extern int cp_type_dwarf_attribute (const_tree, int); extern int cp_type_dwarf_attribute (const_tree, int);
extern void cp_common_init_ts (void); 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 /* 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, 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); ...@@ -137,6 +138,9 @@ extern void cp_common_init_ts (void);
#define LANG_HOOKS_DECL_DWARF_ATTRIBUTE cp_decl_dwarf_attribute #define LANG_HOOKS_DECL_DWARF_ATTRIBUTE cp_decl_dwarf_attribute
#undef LANG_HOOKS_TYPE_DWARF_ATTRIBUTE #undef LANG_HOOKS_TYPE_DWARF_ATTRIBUTE
#define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE cp_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 #undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
#define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing #define LANG_HOOKS_OMP_PREDETERMINED_SHARING cxx_omp_predetermined_sharing
#undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR #undef LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR
......
...@@ -161,6 +161,8 @@ extern tree lhd_make_node (enum tree_code); ...@@ -161,6 +161,8 @@ extern tree lhd_make_node (enum tree_code);
/* Types hooks. There are no reasonable defaults for most of them, /* Types hooks. There are no reasonable defaults for most of them,
so we create a compile-time error instead. */ 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_MAKE_TYPE lhd_make_node
#define LANG_HOOKS_CLASSIFY_RECORD NULL #define LANG_HOOKS_CLASSIFY_RECORD NULL
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error #define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
...@@ -189,6 +191,7 @@ extern tree lhd_make_node (enum tree_code); ...@@ -189,6 +191,7 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_GET_DEBUG_TYPE NULL #define LANG_HOOKS_GET_DEBUG_TYPE NULL
#define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO NULL #define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO NULL
#define LANG_HOOKS_TYPE_DWARF_ATTRIBUTE lhd_type_dwarf_attribute #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 { \ #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
LANG_HOOKS_MAKE_TYPE, \ LANG_HOOKS_MAKE_TYPE, \
...@@ -212,7 +215,8 @@ extern tree lhd_make_node (enum tree_code); ...@@ -212,7 +215,8 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE, \ LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE, \
LANG_HOOKS_GET_DEBUG_TYPE, \ LANG_HOOKS_GET_DEBUG_TYPE, \
LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO, \ 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. */ /* Declaration hooks. */
......
...@@ -729,6 +729,15 @@ lhd_type_dwarf_attribute (const_tree, int) ...@@ -729,6 +729,15 @@ lhd_type_dwarf_attribute (const_tree, int)
return -1; 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. */ /* Returns true if the current lang_hooks represents the GNU C frontend. */
bool bool
......
...@@ -166,6 +166,10 @@ struct lang_hooks_for_types ...@@ -166,6 +166,10 @@ struct lang_hooks_for_types
/* Returns -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute /* Returns -1 if dwarf ATTR shouldn't be added for TYPE, or the attribute
value otherwise. */ value otherwise. */
int (*type_dwarf_attribute) (const_tree, int); 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. */ /* Language hooks related to decls and the symbol table. */
......
...@@ -1864,13 +1864,14 @@ finish_bitfield_representative (tree repr, tree field) ...@@ -1864,13 +1864,14 @@ finish_bitfield_representative (tree repr, tree field)
} }
else else
{ {
/* ??? If you consider that tail-padding of this struct might be /* Note that if the C++ FE sets up tail-padding to be re-used it
re-used when deriving from it we cannot really do the following creates a as-base variant of the type with TYPE_SIZE adjusted
and thus need to set maxsize to bitsize? Also we cannot accordingly. So it is safe to include tail-padding here. */
generally rely on maxsize to fold to an integer constant, so tree aggsize = lang_hooks.types.unit_size_without_reusable_padding
use bitsize as fallback for this case. */ (DECL_CONTEXT (field));
tree maxsize = size_diffop (TYPE_SIZE_UNIT (DECL_CONTEXT (field)), tree maxsize = size_diffop (aggsize, DECL_FIELD_OFFSET (repr));
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)) if (tree_fits_uhwi_p (maxsize))
maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT maxbitsize = (tree_to_uhwi (maxsize) * BITS_PER_UNIT
- tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr))); - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
......
2016-12-16 Richard Biener <rguenther@suse.de> 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 PR middle-end/71632
* gcc.dg/pr71632.c: New testcase. * gcc.dg/pr71632.c: New testcase.
......
/* { 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-*-* } } } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment