summaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2020-07-09 00:13:50 +0200
committerEric Botcazou <ebotcazou@gcc.gnu.org>2020-07-09 00:59:59 +0200
commitb541b871135cb8f261d079006c79698a82e3594d (patch)
treeea67db21fcba13c246749cf5e8eed64e59f77442 /gcc/c
parenta8b522311beef5e02de15427e924752ea02def2a (diff)
Make memory copy functions scalar storage order barriers
This addresses the issue raised about the usage of memory copy functions to toggle the scalar storage order. Recall that you cannot (the compiler errors out) take the address of a scalar which is stored in reverse order, but you can do it for the enclosing aggregate type., which means that you can also pass it to the memory copy functions. In this case, the optimizer may rewrite the copy into a scalar copy, which is a no-no. gcc/c-family/ChangeLog: * c.opt (Wscalar-storage-order): Add explicit variable. gcc/c/ChangeLog: * c-typeck.c (convert_for_assignment): If -Wscalar-storage-order is set, warn for conversion between pointers that point to incompatible scalar storage orders. gcc/ChangeLog: * gimple-fold.c (gimple_fold_builtin_memory_op): Do not fold if either type has reverse scalar storage order. * tree-ssa-sccvn.c (vn_reference_lookup_3): Do not propagate through a memory copy if either type has reverse scalar storage order. gcc/testsuite/ChangeLog: * gcc.dg/sso-11.c: New test. * gcc.dg/sso/sso.exp: Pass -Wno-scalar-storage-order. * gcc.dg/sso/memcpy-1.c: New test.
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/c-typeck.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 3be3690c6e2..b28c2c5ff62 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -7151,6 +7151,41 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
}
}
+ /* See if the pointers point to incompatible scalar storage orders. */
+ if (warn_scalar_storage_order
+ && (AGGREGATE_TYPE_P (ttl) && TYPE_REVERSE_STORAGE_ORDER (ttl))
+ != (AGGREGATE_TYPE_P (ttr) && TYPE_REVERSE_STORAGE_ORDER (ttr)))
+ {
+ switch (errtype)
+ {
+ case ic_argpass:
+ /* Do not warn for built-in functions, for example memcpy, since we
+ control how they behave and they can be useful in this area. */
+ if (TREE_CODE (rname) != FUNCTION_DECL || !DECL_IS_BUILTIN (rname))
+ warning_at (location, OPT_Wscalar_storage_order,
+ "passing argument %d of %qE from incompatible "
+ "scalar storage order", parmnum, rname);
+ break;
+ case ic_assign:
+ warning_at (location, OPT_Wscalar_storage_order,
+ "assignment to %qT from pointer type %qT with "
+ "incompatible scalar storage order", type, rhstype);
+ break;
+ case ic_init:
+ warning_at (location, OPT_Wscalar_storage_order,
+ "initialization of %qT from pointer type %qT with "
+ "incompatible scalar storage order", type, rhstype);
+ break;
+ case ic_return:
+ warning_at (location, OPT_Wscalar_storage_order,
+ "returning %qT from pointer type with incompatible "
+ "scalar storage order %qT", rhstype, type);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+
/* Any non-function converts to a [const][volatile] void *
and vice versa; otherwise, targets must be the same.
Meanwhile, the lhs target must have all the qualifiers of the rhs. */