aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2020-07-05 20:50:52 +0200
committerHans-Peter Nilsson <hp@axis.com>2020-07-13 08:08:39 +0200
commita4aca1edaf37d43b2b7e9111825837a7a317b1b0 (patch)
treecc00c01e5050a71797365b84d0b943b1baec2f40 /gcc/expr.c
parent56d78c58c233a358c780571ad6fecbabdcff2407 (diff)
downloadgcc-a4aca1edaf37d43b2b7e9111825837a7a317b1b0.zip
gcc-a4aca1edaf37d43b2b7e9111825837a7a317b1b0.tar.gz
gcc-a4aca1edaf37d43b2b7e9111825837a7a317b1b0.tar.bz2
PR94600: fix volatile access to the whole of a compound object.
The store to the whole of each volatile object was picked apart like there had been an individual assignment to each of the fields. Reads were added as part of that; see PR for details. The reads from volatile memory were a clear bug; individual stores questionable. A separate patch clarifies the docs. gcc: 2020-07-09 Richard Biener <rguenther@suse.de> PR middle-end/94600 * expr.c (expand_constructor): Make a temporary also if we're storing to volatile memory. gcc/testsuite: 2020-07-09 Hans-Peter Nilsson <hp@axis.com> PR middle-end/94600 * gcc.dg/pr94600-1.c, gcc.dg/pr94600-2.c, gcc.dg/pr94600-3.c, gcc.dg/pr94600-4.c, gcc.dg/pr94600-5.c, gcc.dg/pr94600-6.c, gcc.dg/pr94600-7.c, gcc.dg/pr94600-8.c: New tests.
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index c7c3e9f..3d205ad 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8379,7 +8379,10 @@ expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (target == 0 || ! safe_from_p (target, exp, 1)
- || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM)
+ || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
+ /* Also make a temporary if the store is to volatile memory, to
+ avoid individual accesses to aggregate members. */
+ || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target)))
{
if (avoid_temp_mem)
return NULL_RTX;