1 // RUN: %clang_cc1 -verify -fopenmp=libiomp5 -ferror-limit 100 %s
2 
foo()3 int foo() {
4 L1:
5   foo();
6 #pragma omp atomic
7   // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
8   {
9     foo();
10     goto L1; // expected-error {{use of undeclared label 'L1'}}
11   }
12   goto L2; // expected-error {{use of undeclared label 'L2'}}
13 #pragma omp atomic
14   // expected-error@+1 {{the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x', where x is an l-value expression with scalar type}}
15   {
16     foo();
17   L2:
18     foo();
19   }
20 
21   return 0;
22 }
23 
24 struct S {
25   int a;
26 };
27 
readint()28 int readint() {
29   int a = 0, b = 0;
30 // Test for atomic read
31 #pragma omp atomic read
32   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
33   // expected-note@+1 {{expected an expression statement}}
34   ;
35 #pragma omp atomic read
36   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
37   // expected-note@+1 {{expected built-in assignment operator}}
38   foo();
39 #pragma omp atomic read
40   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
41   // expected-note@+1 {{expected built-in assignment operator}}
42   a += b;
43 #pragma omp atomic read
44   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
45   // expected-note@+1 {{expected lvalue expression}}
46   a = 0;
47 #pragma omp atomic read
48   a = b;
49   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
50 #pragma omp atomic read read
51   a = b;
52 
53   return 0;
54 }
55 
readS()56 int readS() {
57   struct S a, b;
58   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'read' clause}}
59 #pragma omp atomic read read
60   // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}}
61   // expected-note@+1 {{expected expression of scalar type}}
62   a = b;
63 
64   return a.a;
65 }
66 
writeint()67 int writeint() {
68   int a = 0, b = 0;
69 // Test for atomic write
70 #pragma omp atomic write
71   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
72   // expected-note@+1 {{expected an expression statement}}
73   ;
74 #pragma omp atomic write
75   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
76   // expected-note@+1 {{expected built-in assignment operator}}
77   foo();
78 #pragma omp atomic write
79   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
80   // expected-note@+1 {{expected built-in assignment operator}}
81   a += b;
82 #pragma omp atomic write
83   a = 0;
84 #pragma omp atomic write
85   a = b;
86   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
87 #pragma omp atomic write write
88   a = b;
89 
90   return 0;
91 }
92 
writeS()93 int writeS() {
94   struct S a, b;
95   // expected-error@+1 {{directive '#pragma omp atomic' cannot contain more than one 'write' clause}}
96 #pragma omp atomic write write
97   // expected-error@+2 {{the statement for 'atomic write' must be an expression statement of form 'x = expr;', where x is a lvalue expression with scalar type}}
98   // expected-note@+1 {{expected expression of scalar type}}
99   a = b;
100 
101   return a.a;
102 }
103