mirror of git://gcc.gnu.org/git/gcc.git
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:
parent
c4d5c5e6ac
commit
b7fc43d7c7
|
|
@ -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>
|
2016-12-16 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR middle-end/71632
|
PR middle-end/71632
|
||||||
|
|
|
||||||
|
|
@ -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>
|
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)
|
||||||
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,
|
||||||
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);
|
||||||
#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);
|
||||||
|
|
||||||
/* 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);
|
||||||
#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);
|
||||||
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)
|
||||||
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
|
||||||
/* 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)
|
||||||
}
|
}
|
||||||
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)));
|
||||||
|
|
|
||||||
|
|
@ -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>
|
2016-12-16 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR middle-end/71632
|
PR middle-end/71632
|
||||||
|
|
|
||||||
|
|
@ -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-*-* } } } } */
|
||||||
Loading…
Reference in New Issue