diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/c/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c11-atomic-1.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c11-atomic-4.c | 92 |
5 files changed, 121 insertions, 5 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index fb9fda3..f99f426 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2015-12-22 Marek Polacek <polacek@redhat.com> + + PR c/69002 + * c-typeck.c (build_component_ref): Warn when acessing elements of + atomic structures or unions. + 2015-12-21 David Malcolm <dmalcolm@redhat.com> * c-typeck.c: Include "gcc-rich-location.h". diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index a97774f..928fcd5 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2349,6 +2349,18 @@ build_component_ref (location_t loc, tree datum, tree component) return error_mark_node; } + /* Accessing elements of atomic structures or unions is undefined + behavior (C11 6.5.2.3#5). */ + if (TYPE_ATOMIC (type) && c_inhibit_evaluation_warnings == 0) + { + if (code == RECORD_TYPE) + warning_at (loc, 0, "accessing a member %qE of an atomic " + "structure %qE", component, datum); + else + warning_at (loc, 0, "accessing a member %qE of an atomic " + "union %qE", component, datum); + } + /* Chain the COMPONENT_REFs if necessary down to the FIELD. This might be better solved in future the way the C++ front end does it - by giving the anonymous entities each a diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d5c679e..50733e6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-12-22 Marek Polacek <polacek@redhat.com> + + PR c/69002 + * gcc.dg/c11-atomic-1.c: Add dg-warnings. + * gcc.dg/c11-atomic-4.c: New test. + 2015-12-22 Sujoy Saraswati <sujoy.saraswati@hpe.com> * gcc.dg/pr61441.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/c11-atomic-1.c b/gcc/testsuite/gcc.dg/c11-atomic-1.c index c7f9a1e..9702a10 100644 --- a/gcc/testsuite/gcc.dg/c11-atomic-1.c +++ b/gcc/testsuite/gcc.dg/c11-atomic-1.c @@ -61,15 +61,15 @@ func (_Atomic volatile long al1) accessing elements of atomic structures and unions is at translation or execution time; presume here that it's at execution time. */ - t1.i = at1.i; - at1.i = t1.i; - atp1->i = t1.i; + t1.i = at1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */ + at1.i = t1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */ + atp1->i = t1.i; /* { dg-warning "accessing a member .i. of an atomic structure" } */ au1 = u1; u1 = au1; av1 = v1; v1 = av1; - v1.i = av1.i; - av1.i = v1.i; + v1.i = av1.i; /* { dg-warning "accessing a member .i. of an atomic union" } */ + av1.i = v1.i; /* { dg-warning "accessing a member .i. of an atomic union" } */ /* _Atomic is valid on register variables, even if not particularly useful. */ register _Atomic volatile int ra1 = 1, ra2 = 2; diff --git a/gcc/testsuite/gcc.dg/c11-atomic-4.c b/gcc/testsuite/gcc.dg/c11-atomic-4.c new file mode 100644 index 0000000..81003aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-atomic-4.c @@ -0,0 +1,92 @@ +/* PR c/69002 */ +/* Test we diagnose accessing elements of atomic structures or unions, + which is undefined behavior (C11 6.5.2.3#5). */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +struct S { int x; }; +union U { int x; }; + +int +fn1 (_Atomic struct S p) +{ + int e = 0 && p.x; + return p.x + e; /* { dg-warning "accessing a member .x. of an atomic structure" } */ +} + +int +fn2 (_Atomic struct S *p) +{ + int e = 1 || p->x; + return p->x + e; /* { dg-warning "accessing a member .x. of an atomic structure" } */ +} + +void +fn3 (_Atomic struct S p, int x) +{ + p.x = x; /* { dg-warning "accessing a member .x. of an atomic structure" } */ +} + +void +fn4 (_Atomic struct S *p, int x) +{ + p->x = x; /* { dg-warning "accessing a member .x. of an atomic structure" } */ +} + +int +fn5 (_Atomic struct S p) +{ + /* This is OK: Members can be safely accessed using a non-atomic + object which is assigned to or from the atomic object. */ + struct S s = p; + return s.x; +} + +int +fn6 (_Atomic struct S *p) +{ + struct S s = *p; + return s.x; +} + +int +fn7 (_Atomic union U p) +{ + int e = 0 && p.x; + return p.x + e; /* { dg-warning "accessing a member .x. of an atomic union" } */ +} + +int +fn8 (_Atomic union U *p) +{ + int e = 1 || p->x; + return p->x + e; /* { dg-warning "accessing a member .x. of an atomic union" } */ +} + +void +fn9 (_Atomic union U p, int x) +{ + p.x = x; /* { dg-warning "accessing a member .x. of an atomic union" } */ +} + +void +fn10 (_Atomic union U *p, int x) +{ + p->x = x; /* { dg-warning "accessing a member .x. of an atomic union" } */ +} + +int +fn11 (_Atomic union U p) +{ + /* This is OK: Members can be safely accessed using a non-atomic + object which is assigned to or from the atomic object. */ + union U s = p; + return s.x; +} + +int +fn12 (_Atomic union U *p) +{ + union U s = *p; + return s.x; +} |