aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-12-16 09:40:03 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-12-16 09:40:03 +0000
commitb7fc43d7c747d190e197ca89cfce4f1d9def7c7e (patch)
treee7a4831ca7b46e08d1f5bc38c1d4f221aa7cfbbe /gcc
parentc4d5c5e6ac73cac2b89d039eff9874ff80742589 (diff)
downloadgcc-b7fc43d7c747d190e197ca89cfce4f1d9def7c7e.zip
gcc-b7fc43d7c747d190e197ca89cfce4f1d9def7c7e.tar.gz
gcc-b7fc43d7c747d190e197ca89cfce4f1d9def7c7e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-objcp-common.c10
-rw-r--r--gcc/cp/cp-objcp-common.h4
-rw-r--r--gcc/langhooks-def.h6
-rw-r--r--gcc/langhooks.c9
-rw-r--r--gcc/langhooks.h4
-rw-r--r--gcc/stor-layout.c15
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/pr71694.C27
10 files changed, 92 insertions, 8 deletions
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 <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
* 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 <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
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 <rguenther@suse.de>
+ PR c++/71694
+ * g++.dg/pr71694.C: New testcase.
+
+2016-12-16 Richard Biener <rguenther@suse.de>
+
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-*-* } } } } */