This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix atomic builtins on arrays (PR target/82112)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Joseph Myers <joseph at codesourcery dot com>
- Cc: Marek Polacek <polacek at redhat dot com>, Jason Merrill <jason at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Thu, 7 Sep 2017 23:09:45 +0200
- Subject: Re: [PATCH] Fix atomic builtins on arrays (PR target/82112)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=jakub at redhat dot com
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C9E9F3E6
- References: <20170907084344.GT2323@tucnak> <alpine.DEB.2.20.1709071532100.21759@digraph.polyomino.org.uk>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Sep 07, 2017 at 03:35:00PM +0000, Joseph Myers wrote:
> > The powerpc patch I've just posted led me to try __atomic_* builtins
> > on arrays as in the testcase below. While it works fine if the
> > array is just on the first argument or in C, in C++ for arrays in 2nd
> > or 3rd argument the atomics are rejected (complaining that the argument
> > is not a pointer), while we should really have performed array-to-pointer
> > conversion first.
> >
> > Fixed thusly, bootstrapped/regtested on powerpc64-linux, ok for trunk?
>
> I don't think either the existing or new assertion that arrays only occur
> in C++ are correct. E.g. build the following with -std=gnu90 so
> non-lvalue arrays don't decay to pointers. (ICEs on such an assertion in
> get_atomic_generic_size with a trunk build as of a few days ago.)
>
> struct s { int c[10]; };
> struct s f (void);
> void
> g (void)
> {
> __atomic_load ( f().c, f().c, __ATOMIC_ACQUIRE);
> }
>
> (I think C90 non-lvalue arrays there are most appropriately an error,
> rather than attempting to make them decay to pointers after all.)
Ah, ok, so like this instead?
2017-09-07 Jakub Jelinek <jakub@redhat.com>
PR target/82112
* c-common.c (sync_resolve_size): Instead of c_dialect_cxx ()
assertion check that in the condition.
(get_atomic_generic_size): Likewise. Before testing if parameter
has pointer type, if it has array type, call for C++
default_conversion to perform array-to-pointer conversion.
* c-c++-common/pr82112.c: New test.
* gcc.dg/pr82112.c: New test.
--- gcc/c-family/c-common.c.jj 2017-09-06 16:23:25.285903973 +0200
+++ gcc/c-family/c-common.c 2017-09-07 22:55:18.836731301 +0200
@@ -6478,10 +6478,9 @@ sync_resolve_size (tree function, vec<tr
}
argtype = type = TREE_TYPE ((*params)[0]);
- if (TREE_CODE (type) == ARRAY_TYPE)
+ if (TREE_CODE (type) == ARRAY_TYPE && c_dialect_cxx ())
{
/* Force array-to-pointer decay for C++. */
- gcc_assert (c_dialect_cxx());
(*params)[0] = default_conversion ((*params)[0]);
type = TREE_TYPE ((*params)[0]);
}
@@ -6646,10 +6645,9 @@ get_atomic_generic_size (location_t loc,
/* Get type of first parameter, and determine its size. */
type_0 = TREE_TYPE ((*params)[0]);
- if (TREE_CODE (type_0) == ARRAY_TYPE)
+ if (TREE_CODE (type_0) == ARRAY_TYPE && c_dialect_cxx ())
{
/* Force array-to-pointer decay for C++. */
- gcc_assert (c_dialect_cxx());
(*params)[0] = default_conversion ((*params)[0]);
type_0 = TREE_TYPE ((*params)[0]);
}
@@ -6688,6 +6686,12 @@ get_atomic_generic_size (location_t loc,
/* __atomic_compare_exchange has a bool in the 4th position, skip it. */
if (n_param == 6 && x == 3)
continue;
+ if (TREE_CODE (type) == ARRAY_TYPE && c_dialect_cxx ())
+ {
+ /* Force array-to-pointer decay for C++. */
+ (*params)[x] = default_conversion ((*params)[x]);
+ type = TREE_TYPE ((*params)[x]);
+ }
if (!POINTER_TYPE_P (type))
{
error_at (loc, "argument %d of %qE must be a pointer type", x + 1,
--- gcc/testsuite/c-c++-common/pr82112.c.jj 2017-09-07 22:54:39.755185278 +0200
+++ gcc/testsuite/c-c++-common/pr82112.c 2017-09-07 22:54:39.755185278 +0200
@@ -0,0 +1,13 @@
+/* PR target/82112 */
+/* { dg-do compile } */
+
+int c[10], d[10], e[10], f[10], g[10], h[10], i[10], j[10], k[10], l[10];
+
+void
+foo (void)
+{
+ __atomic_load (c, d, __ATOMIC_ACQUIRE);
+ __atomic_store (e, f, __ATOMIC_SEQ_CST);
+ __atomic_exchange (g, h, i, __ATOMIC_RELAXED);
+ __atomic_compare_exchange (j, k, l, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
--- gcc/testsuite/gcc.dg/pr82112.c.jj 2017-09-07 22:55:59.917254104 +0200
+++ gcc/testsuite/gcc.dg/pr82112.c 2017-09-07 23:07:27.635458611 +0200
@@ -0,0 +1,21 @@
+/* PR target/82112 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu90" } */
+
+struct S { int a[10]; } bar (void);
+int b, c;
+
+void
+foo (void)
+{
+ __atomic_load (bar ().a, &b, __ATOMIC_ACQUIRE); /* { dg-error "argument 1 of .__atomic_load. must be a non-void pointer type" } */
+ __atomic_load (&b, bar ().a, __ATOMIC_ACQUIRE); /* { dg-error "argument 2 of .__atomic_load. must be a pointer type" } */
+ __atomic_store (bar ().a, &b, __ATOMIC_SEQ_CST); /* { dg-error "argument 1 of .__atomic_store. must be a non-void pointer type" } */
+ __atomic_store (&b, bar ().a, __ATOMIC_SEQ_CST); /* { dg-error "argument 2 of .__atomic_store. must be a pointer type" } */
+ __atomic_exchange (bar ().a, &b, &c, __ATOMIC_RELAXED); /* { dg-error "argument 1 of .__atomic_exchange. must be a non-void pointer type" } */
+ __atomic_exchange (&b, bar ().a, &c, __ATOMIC_RELAXED); /* { dg-error "argument 2 of .__atomic_exchange. must be a pointer type" } */
+ __atomic_exchange (&b, &c, bar ().a, __ATOMIC_RELAXED); /* { dg-error "argument 3 of .__atomic_exchange. must be a pointer type" } */
+ __atomic_compare_exchange (bar ().a, &b, &c, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED); /* { dg-error "argument 1 of .__atomic_compare_exchange. must be a non-void pointer type" } */
+ __atomic_compare_exchange (&b, bar ().a, &c, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED); /* { dg-error "argument 2 of .__atomic_compare_exchange. must be a pointer type" } */
+ __atomic_compare_exchange (&b, &c, bar ().a, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED); /* { dg-error "argument 3 of .__atomic_compare_exchange. must be a pointer type" } */
+}
Jakub