|  | // { dg-do run } | 
|  |  | 
|  | #include <omp.h> | 
|  | #include <assert.h> | 
|  |  | 
|  | struct B | 
|  | { | 
|  | static int ic, dc, xc, ac, cc; | 
|  |  | 
|  | B(); | 
|  | B(const B &); | 
|  | ~B(); | 
|  | B& operator=(const B &); | 
|  | void doit(); | 
|  | static void clear(); | 
|  | }; | 
|  |  | 
|  | int B::ic; | 
|  | int B::dc; | 
|  | int B::xc; | 
|  | int B::cc; | 
|  | int B::ac; | 
|  |  | 
|  | B::B() | 
|  | { | 
|  | #pragma omp atomic | 
|  | ic++; | 
|  | } | 
|  |  | 
|  | B::~B() | 
|  | { | 
|  | #pragma omp atomic | 
|  | dc++; | 
|  | } | 
|  |  | 
|  | B::B(const B &) | 
|  | { | 
|  | #pragma omp atomic | 
|  | cc++; | 
|  | } | 
|  |  | 
|  | B& B::operator=(const B &) | 
|  | { | 
|  | #pragma omp atomic | 
|  | ac++; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | void B::doit() | 
|  | { | 
|  | #pragma omp atomic | 
|  | xc++; | 
|  | } | 
|  |  | 
|  | void B::clear() | 
|  | { | 
|  | ic = 0; | 
|  | dc = 0; | 
|  | cc = 0; | 
|  | ac = 0; | 
|  | xc = 0; | 
|  | } | 
|  |  | 
|  | static int n; | 
|  |  | 
|  | void f1(B &a) | 
|  | { | 
|  | B b; | 
|  | B &c = b; | 
|  | #pragma omp parallel default(none) private(a, c) shared (n) | 
|  | { | 
|  | #pragma omp master | 
|  | n = omp_get_num_threads (); | 
|  | a.doit(); | 
|  | c.doit(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void f2(B &a) | 
|  | { | 
|  | B b; | 
|  | B &c = b; | 
|  | #pragma omp parallel default(none) firstprivate(a, c) shared(n) | 
|  | { | 
|  | #pragma omp master | 
|  | n = omp_get_num_threads (); | 
|  | a.doit(); | 
|  | c.doit(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void f3(B &a) | 
|  | { | 
|  | B b; | 
|  | B &c = b; | 
|  | #pragma omp parallel default(none) shared(n, a, c) | 
|  | { | 
|  | #pragma omp master | 
|  | n = omp_get_num_threads (); | 
|  | #pragma omp for lastprivate (a, c) | 
|  | for (int i = 0; i < omp_get_num_threads (); i++) | 
|  | { | 
|  | a.doit(); | 
|  | c.doit(); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void f4() | 
|  | { | 
|  | B b; | 
|  | B &c = b; | 
|  | #pragma omp parallel default(none) private (c) shared (n) | 
|  | { | 
|  | B d; | 
|  | B &e = d; | 
|  | #pragma omp single copyprivate (c, e) | 
|  | { | 
|  | c.doit(); | 
|  | e.doit(); | 
|  | } | 
|  | c.doit(); | 
|  | e.doit(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void f5(B (&a)[2]) | 
|  | { | 
|  | B b[2]; | 
|  | B (&c)[2] = b; | 
|  | #pragma omp parallel default(none) private(a, c) shared (n) | 
|  | { | 
|  | #pragma omp master | 
|  | n = omp_get_num_threads (); | 
|  | a[0].doit(); | 
|  | a[1].doit(); | 
|  | c[0].doit(); | 
|  | c[1].doit(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void f6(B (&a)[2]) | 
|  | { | 
|  | B b[2]; | 
|  | B (&c)[2] = b; | 
|  | #pragma omp parallel default(none) firstprivate(a, c) shared (n) | 
|  | { | 
|  | #pragma omp master | 
|  | n = omp_get_num_threads (); | 
|  | a[0].doit(); | 
|  | a[1].doit(); | 
|  | c[0].doit(); | 
|  | c[1].doit(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void f7(B (&a)[2]) | 
|  | { | 
|  | B b[2]; | 
|  | B (&c)[2] = b; | 
|  | #pragma omp parallel default(none) shared(n, a, c) | 
|  | { | 
|  | #pragma omp master | 
|  | n = omp_get_num_threads (); | 
|  | #pragma omp for lastprivate (a, c) | 
|  | for (int i = 0; i < omp_get_num_threads (); i++) | 
|  | { | 
|  | a[0].doit(); | 
|  | a[1].doit(); | 
|  | c[0].doit(); | 
|  | c[1].doit(); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void f8() | 
|  | { | 
|  | B b[2]; | 
|  | B (&c)[2] = b; | 
|  | #pragma omp parallel default(none) private (c) shared (n) | 
|  | { | 
|  | B d[2]; | 
|  | B (&e)[2] = d; | 
|  | #pragma omp single copyprivate (c, e) | 
|  | { | 
|  | c[0].doit(); | 
|  | c[1].doit(); | 
|  | e[0].doit(); | 
|  | e[1].doit(); | 
|  | } | 
|  | c[0].doit(); | 
|  | c[1].doit(); | 
|  | e[0].doit(); | 
|  | e[1].doit(); | 
|  | } | 
|  | } | 
|  |  | 
|  | int main() | 
|  | { | 
|  | { | 
|  | B a; | 
|  | f1(a); | 
|  | } | 
|  | assert (B::xc == 2*n && B::ic == 2*n+2 && B::dc == 2*n+2 && B::ac == 0 && B::cc == 0); | 
|  | B::clear(); | 
|  | { | 
|  | B a; | 
|  | f2(a); | 
|  | } | 
|  | assert (B::xc == 2*n && B::ic == 2 && B::dc == 2*n+2 && B::ac == 0 && B::cc == 2*n); | 
|  | B::clear(); | 
|  | { | 
|  | B a; | 
|  | f3(a); | 
|  | } | 
|  | assert (B::xc == 2*n && B::ic == 2*n+2 && B::dc == 2*n+2 && B::ac == 2 && B::cc == 0); | 
|  | B::clear(); | 
|  | f4(); | 
|  | assert (B::xc == 2*n+2 && B::ic == 2*n+1 && B::dc == 2*n+1 && B::ac == 2*n-2 && B::cc == 0); | 
|  | B::clear(); | 
|  | { | 
|  | B a[2]; | 
|  | f5(a); | 
|  | } | 
|  | assert (B::xc == 4*n && B::ic == 4*n+4 && B::dc == 4*n+4 && B::ac == 0 && B::cc == 0); | 
|  | B::clear(); | 
|  | { | 
|  | B a[2]; | 
|  | f6(a); | 
|  | } | 
|  | assert (B::xc == 4*n && B::ic == 4 && B::dc == 4*n+4 && B::ac == 0 && B::cc == 4*n); | 
|  | B::clear(); | 
|  | { | 
|  | B a[2]; | 
|  | f7(a); | 
|  | } | 
|  | assert (B::xc == 4*n && B::ic == 4*n+4 && B::dc == 4*n+4 && B::ac == 4 && B::cc == 0); | 
|  | B::clear(); | 
|  | f8(); | 
|  | assert (B::xc == 4*n+4 && B::ic == 4*n+2 && B::dc == 4*n+2 && B::ac == 4*n-4 && B::cc == 0); | 
|  | return 0; | 
|  | } |