simd_loop_messages.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. // RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
  2. // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s
  3. // RUN: %clang_cc1 -fsyntax-only -fopenmp -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s -fopenmp-version=50 -DOMP50
  4. // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -x c++ -std=c++11 -fexceptions -fcxx-exceptions -verify %s -fopenmp-version=50 -DOMP50
  5. static int sii;
  6. // expected-note@+1 {{defined as threadprivate or thread local}}
  7. #pragma omp threadprivate(sii)
  8. static int globalii;
  9. struct S {
  10. // expected-note@+1 {{static data member is predetermined as shared}}
  11. static int ssi;
  12. };
  13. int test_iteration_spaces() {
  14. const int N = 100;
  15. float a[N], b[N], c[N];
  16. int ii, jj, kk;
  17. float fii;
  18. double dii;
  19. #pragma omp simd linear(S::ssi)
  20. for (S::ssi = 0; S::ssi < 10; ++S::ssi)
  21. ;
  22. // expected-error@+1 {{shared variable cannot be private}}
  23. #pragma omp simd private(S::ssi)
  24. for (S::ssi = 0; S::ssi < 10; ++S::ssi)
  25. ;
  26. #pragma omp simd // no messages expected
  27. for (S::ssi = 0; S::ssi < 10; ++S::ssi)
  28. ;
  29. #pragma omp simd
  30. for (int i = 0; i < 10; i+=1) {
  31. c[i] = a[i] + b[i];
  32. }
  33. #pragma omp simd
  34. for (char i = 0; i < 10; i++) {
  35. c[i] = a[i] + b[i];
  36. }
  37. #pragma omp simd
  38. for (char i = 0; i < 10; i+='\1') {
  39. c[i] = a[i] + b[i];
  40. }
  41. #pragma omp simd
  42. for (long long i = 0; i < 10; i++) {
  43. c[i] = a[i] + b[i];
  44. }
  45. // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'double'}}
  46. #pragma omp simd
  47. for (long long i = 0; i < 10; i+=1.5) {
  48. c[i] = a[i] + b[i];
  49. }
  50. #pragma omp simd
  51. for (long long i = 0; i < 'z'; i+=1u) {
  52. c[i] = a[i] + b[i];
  53. }
  54. // expected-error@+2 {{variable must be of integer or random access iterator type}}
  55. #pragma omp simd
  56. for (float fi = 0; fi < 10.0; fi++) {
  57. c[(int)fi] = a[(int)fi] + b[(int)fi];
  58. }
  59. // expected-error@+2 {{variable must be of integer or random access iterator type}}
  60. #pragma omp simd
  61. for (double fi = 0; fi < 10.0; fi++) {
  62. c[(int)fi] = a[(int)fi] + b[(int)fi];
  63. }
  64. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  65. #pragma omp simd
  66. for (int &ref = ii; ref < 10; ref++) {
  67. }
  68. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  69. #pragma omp simd
  70. for (int i; i < 10; i++)
  71. c[i] = a[i];
  72. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  73. #pragma omp simd
  74. for (int i = 0, j = 0; i < 10; ++i)
  75. c[i] = a[i];
  76. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  77. #pragma omp simd
  78. for (;ii < 10; ++ii)
  79. c[ii] = a[ii];
  80. // expected-warning@+3 {{expression result unused}}
  81. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  82. #pragma omp simd
  83. for (ii + 1;ii < 10; ++ii)
  84. c[ii] = a[ii];
  85. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  86. #pragma omp simd
  87. for (c[ii] = 0;ii < 10; ++ii)
  88. c[ii] = a[ii];
  89. // Ok to skip parenthesises.
  90. #pragma omp simd
  91. for (((ii)) = 0;ii < 10; ++ii)
  92. c[ii] = a[ii];
  93. // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
  94. #pragma omp simd
  95. for (int i = 0; i; i++)
  96. c[i] = a[i];
  97. // expected-error@+3 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
  98. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'i'}}
  99. #pragma omp simd
  100. for (int i = 0; jj < kk; ii++)
  101. c[i] = a[i];
  102. // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
  103. #pragma omp simd
  104. for (int i = 0; !!i; i++)
  105. c[i] = a[i];
  106. // Ok
  107. #pragma omp simd
  108. for (int i = 0; i != 1; i++)
  109. c[i] = a[i];
  110. // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'i'}}
  111. #pragma omp simd
  112. for (int i = 0; ; i++)
  113. c[i] = a[i];
  114. // Ok.
  115. #pragma omp simd
  116. for (int i = 11; i > 10; i--)
  117. c[i] = a[i];
  118. // Ok.
  119. #pragma omp simd
  120. for (int i = 0; i < 10; ++i)
  121. c[i] = a[i];
  122. // Ok.
  123. #pragma omp simd
  124. for (ii = 0; ii < 10; ++ii)
  125. c[ii] = a[ii];
  126. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  127. #pragma omp simd
  128. for (ii = 0; ii < 10; ++jj)
  129. c[ii] = a[jj];
  130. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  131. #pragma omp simd
  132. for (ii = 0; ii < 10; ++ ++ ii)
  133. c[ii] = a[ii];
  134. // Ok but undefined behavior (in general, cannot check that incr
  135. // is really loop-invariant).
  136. #pragma omp simd
  137. for (ii = 0; ii < 10; ii = ii + ii)
  138. c[ii] = a[ii];
  139. // expected-error@+2 {{expression must have integral or unscoped enumeration type, not 'float'}}
  140. #pragma omp simd
  141. for (ii = 0; ii < 10; ii = ii + 1.0f)
  142. c[ii] = a[ii];
  143. // Ok - step was converted to integer type.
  144. #pragma omp simd
  145. for (ii = 0; ii < 10; ii = ii + (int)1.1f)
  146. c[ii] = a[ii];
  147. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  148. #pragma omp simd
  149. for (ii = 0; ii < 10; jj = ii + 2)
  150. c[ii] = a[ii];
  151. // expected-warning@+3 {{relational comparison result unused}}
  152. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  153. #pragma omp simd
  154. for (ii = 0; ii < 10; jj > kk + 2)
  155. c[ii] = a[ii];
  156. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  157. #pragma omp simd
  158. for (ii = 0; ii < 10;)
  159. c[ii] = a[ii];
  160. // expected-warning@+3 {{expression result unused}}
  161. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  162. #pragma omp simd
  163. for (ii = 0; ii < 10; !ii)
  164. c[ii] = a[ii];
  165. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  166. #pragma omp simd
  167. for (ii = 0; ii < 10; ii ? ++ii : ++jj)
  168. c[ii] = a[ii];
  169. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'ii'}}
  170. #pragma omp simd
  171. for (ii = 0; ii < 10; ii = ii < 10)
  172. c[ii] = a[ii];
  173. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  174. // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
  175. #pragma omp simd
  176. for (ii = 0; ii < 10; ii = ii + 0)
  177. c[ii] = a[ii];
  178. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  179. // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
  180. #pragma omp simd
  181. for (ii = 0; ii < 10; ii = ii + (int)(0.8 - 0.45))
  182. c[ii] = a[ii];
  183. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  184. // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
  185. #pragma omp simd
  186. for (ii = 0; (ii) < 10; ii-=25)
  187. c[ii] = a[ii];
  188. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  189. // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
  190. #pragma omp simd
  191. for (ii = 0; (ii < 10); ii-=0)
  192. c[ii] = a[ii];
  193. // expected-note@+3 {{loop step is expected to be negative due to this condition}}
  194. // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
  195. #pragma omp simd
  196. for (ii = 0; ii > 10; (ii+=0))
  197. c[ii] = a[ii];
  198. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  199. // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
  200. #pragma omp simd
  201. for (ii = 0; ii < 10; (ii) = (1-1)+(ii))
  202. c[ii] = a[ii];
  203. // expected-note@+3 {{loop step is expected to be negative due to this condition}}
  204. // expected-error@+2 {{increment expression must cause 'ii' to decrease on each iteration of OpenMP for loop}}
  205. #pragma omp simd
  206. for ((ii = 0); ii > 10; (ii-=0))
  207. c[ii] = a[ii];
  208. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  209. // expected-error@+2 {{increment expression must cause 'ii' to increase on each iteration of OpenMP for loop}}
  210. #pragma omp simd
  211. for (ii = 0; (ii < 10); (ii-=0))
  212. c[ii] = a[ii];
  213. #ifndef OMP50
  214. // expected-note@+3 {{defined as private}}
  215. // expected-error@+3 {{loop iteration variable in the associated loop of 'omp simd' directive may not be private, predetermined as linear}}
  216. #endif // OMP50
  217. #pragma omp simd private(ii)
  218. for (ii = 0; ii < 10; ii++)
  219. c[ii] = a[ii];
  220. #ifndef OMP50
  221. // expected-note@+3 {{defined as lastprivate}}
  222. // expected-error@+3 {{loop iteration variable in the associated loop of 'omp simd' directive may not be lastprivate, predetermined as linear}}
  223. #endif // OMP50
  224. #pragma omp simd lastprivate(ii)
  225. for (ii = 0; ii < 10; ii++)
  226. c[ii] = a[ii];
  227. // expected-error@+1 {{unexpected OpenMP clause 'shared' in directive '#pragma omp simd'}}
  228. #pragma omp simd shared(ii)
  229. for (ii = 0; ii < 10; ii++)
  230. c[ii] = a[ii];
  231. #pragma omp simd linear(ii)
  232. for (ii = 0; ii < 10; ii++)
  233. c[ii] = a[ii];
  234. #pragma omp simd lastprivate(ii) linear(jj) collapse(2) // expected-note {{defined as linear}}
  235. for (ii = 0; ii < 10; ii++)
  236. for (jj = 0; jj < 10; jj++) // expected-error {{loop iteration variable in the associated loop of 'omp simd' directive may not be linear, predetermined as lastprivate}}
  237. c[ii] = a[jj];
  238. #pragma omp parallel
  239. {
  240. // expected-error@+2 {{loop iteration variable in the associated loop of 'omp simd' directive may not be threadprivate or thread local, predetermined as linear}}
  241. #pragma omp simd
  242. for (sii = 0; sii < 10; sii+=1)
  243. c[sii] = a[sii];
  244. }
  245. #pragma omp parallel
  246. {
  247. #pragma omp simd
  248. for (globalii = 0; globalii < 10; globalii+=1)
  249. c[globalii] = a[globalii];
  250. }
  251. #pragma omp parallel
  252. {
  253. #pragma omp simd collapse(2)
  254. for (ii = 0; ii < 10; ii += 1)
  255. for (globalii = 0; globalii < 10; globalii += 1)
  256. c[globalii] += a[globalii] + ii;
  257. }
  258. // expected-error@+2 {{statement after '#pragma omp simd' must be a for loop}}
  259. #pragma omp simd
  260. for (auto &item : a) {
  261. item = item + 1;
  262. }
  263. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  264. // expected-error@+2 {{increment expression must cause 'i' to increase on each iteration of OpenMP for loop}}
  265. #pragma omp simd
  266. for (unsigned i = 9; i < 10; i--) {
  267. c[i] = a[i] + b[i];
  268. }
  269. int (*lb)[4] = nullptr;
  270. #pragma omp simd
  271. for (int (*p)[4] = lb; p < lb + 8; ++p) {
  272. }
  273. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  274. #pragma omp simd
  275. for (int a{0}; a<10; ++a) {
  276. }
  277. return 0;
  278. }
  279. // Iterators allowed in openmp for-loops.
  280. namespace std {
  281. struct random_access_iterator_tag { };
  282. template <class Iter> struct iterator_traits {
  283. typedef typename Iter::difference_type difference_type;
  284. typedef typename Iter::iterator_category iterator_category;
  285. };
  286. template <class Iter>
  287. typename iterator_traits<Iter>::difference_type
  288. distance(Iter first, Iter last) { return first - last; }
  289. }
  290. class Iter0 {
  291. public:
  292. Iter0() { }
  293. Iter0(const Iter0 &) { }
  294. Iter0 operator ++() { return *this; }
  295. Iter0 operator --() { return *this; }
  296. Iter0 operator + (int delta) { return *this; }
  297. bool operator <(Iter0 a) { return true; }
  298. };
  299. // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'Iter0' for 1st argument}}
  300. int operator -(Iter0 a, Iter0 b) { return 0; }
  301. class Iter1 {
  302. public:
  303. Iter1(float f=0.0f, double d=0.0) { }
  304. Iter1(const Iter1 &) { }
  305. Iter1 operator ++() { return *this; }
  306. Iter1 operator --() { return *this; }
  307. bool operator <(Iter1 a) { return true; }
  308. bool operator >=(Iter1 a) { return false; }
  309. };
  310. class GoodIter {
  311. public:
  312. GoodIter() { }
  313. GoodIter(const GoodIter &) { }
  314. GoodIter(int fst, int snd) { }
  315. GoodIter &operator =(const GoodIter &that) { return *this; }
  316. GoodIter &operator =(const Iter0 &that) { return *this; }
  317. GoodIter &operator +=(int x) { return *this; }
  318. explicit GoodIter(void *) { }
  319. GoodIter operator ++() { return *this; }
  320. GoodIter operator --() { return *this; }
  321. bool operator !() { return true; }
  322. bool operator <(GoodIter a) { return true; }
  323. bool operator <=(GoodIter a) { return true; }
  324. bool operator >=(GoodIter a) { return false; }
  325. typedef int difference_type;
  326. typedef std::random_access_iterator_tag iterator_category;
  327. };
  328. // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
  329. int operator -(GoodIter a, GoodIter b) { return 0; }
  330. // expected-note@+1 2 {{candidate function not viable: requires single argument 'a', but 2 arguments were provided}}
  331. GoodIter operator -(GoodIter a) { return a; }
  332. // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'GoodIter' for 1st argument}}
  333. GoodIter operator -(GoodIter a, int v) { return GoodIter(); }
  334. GoodIter operator +(GoodIter a, int v) { return GoodIter(); }
  335. // expected-note@+1 2 {{candidate function not viable: no known conversion from 'Iter1' to 'int' for 1st argument}}
  336. GoodIter operator -(int v, GoodIter a) { return GoodIter(); }
  337. GoodIter operator +(int v, GoodIter a) { return GoodIter(); }
  338. int test_with_random_access_iterator() {
  339. GoodIter begin, end;
  340. Iter0 begin0, end0;
  341. #pragma omp simd
  342. for (GoodIter I = begin; I < end; ++I)
  343. ++I;
  344. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  345. #pragma omp simd
  346. for (GoodIter &I = begin; I < end; ++I)
  347. ++I;
  348. #pragma omp simd
  349. for (GoodIter I = begin; I >= end; --I)
  350. ++I;
  351. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  352. #pragma omp simd
  353. for (GoodIter I(begin); I < end; ++I)
  354. ++I;
  355. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  356. #pragma omp simd
  357. for (GoodIter I(nullptr); I < end; ++I)
  358. ++I;
  359. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  360. #pragma omp simd
  361. for (GoodIter I(0); I < end; ++I)
  362. ++I;
  363. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  364. #pragma omp simd
  365. for (GoodIter I(1,2); I < end; ++I)
  366. ++I;
  367. #pragma omp simd
  368. for (begin = GoodIter(0); begin < end; ++begin)
  369. ++begin;
  370. #pragma omp simd
  371. for (begin = GoodIter(1,2); begin < end; ++begin)
  372. ++begin;
  373. // expected-error@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  374. #pragma omp simd
  375. for (++begin; begin < end; ++begin)
  376. ++begin;
  377. #pragma omp simd
  378. for (begin = end; begin < end; ++begin)
  379. ++begin;
  380. // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
  381. #pragma omp simd
  382. for (GoodIter I = begin; I - I; ++I)
  383. ++I;
  384. // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
  385. #pragma omp simd
  386. for (GoodIter I = begin; begin < end; ++I)
  387. ++I;
  388. // expected-error@+2 {{condition of OpenMP for loop must be a relational comparison ('<', '<=', '>', or '>=') of loop variable 'I'}}
  389. #pragma omp simd
  390. for (GoodIter I = begin; !I; ++I)
  391. ++I;
  392. // expected-note@+3 {{loop step is expected to be negative due to this condition}}
  393. // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
  394. #pragma omp simd
  395. for (GoodIter I = begin; I >= end; I = I + 1)
  396. ++I;
  397. #pragma omp simd
  398. for (GoodIter I = begin; I >= end; I = I - 1)
  399. ++I;
  400. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
  401. #pragma omp simd
  402. for (GoodIter I = begin; I >= end; I = -I)
  403. ++I;
  404. // expected-note@+3 {{loop step is expected to be negative due to this condition}}
  405. // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
  406. #pragma omp simd
  407. for (GoodIter I = begin; I >= end; I = 2 + I)
  408. ++I;
  409. // expected-error@+2 {{increment clause of OpenMP for loop must perform simple addition or subtraction on loop variable 'I'}}
  410. #pragma omp simd
  411. for (GoodIter I = begin; I >= end; I = 2 - I)
  412. ++I;
  413. #pragma omp simd
  414. for (Iter0 I = begin0; I < end0; ++I)
  415. ++I;
  416. // Initializer is constructor without params.
  417. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  418. #pragma omp simd
  419. for (Iter0 I; I < end0; ++I)
  420. ++I;
  421. Iter1 begin1, end1;
  422. // expected-error@+3 {{invalid operands to binary expression ('Iter1' and 'Iter1')}}
  423. // expected-error@+2 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
  424. #pragma omp simd
  425. for (Iter1 I = begin1; I < end1; ++I)
  426. ++I;
  427. // expected-note@+3 {{loop step is expected to be negative due to this condition}}
  428. // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
  429. #pragma omp simd
  430. for (Iter1 I = begin1; I >= end1; ++I)
  431. ++I;
  432. // Initializer is constructor with all default params.
  433. // expected-error@+4 {{invalid operands to binary expression ('Iter1' and 'float')}}
  434. // expected-error@+3 {{could not calculate number of iterations calling 'operator-' with upper and lower loop bounds}}
  435. // expected-warning@+2 {{initialization clause of OpenMP for loop is not in canonical form ('var = init' or 'T var = init')}}
  436. #pragma omp simd
  437. for (Iter1 I; I < end1; ++I) {
  438. }
  439. return 0;
  440. }
  441. template <typename IT, int ST> class TC {
  442. public:
  443. int dotest_lt(IT begin, IT end) {
  444. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  445. // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
  446. #pragma omp simd
  447. for (IT I = begin; I < end; I = I + ST) {
  448. ++I;
  449. }
  450. // expected-note@+3 {{loop step is expected to be positive due to this condition}}
  451. // expected-error@+2 {{increment expression must cause 'I' to increase on each iteration of OpenMP for loop}}
  452. #pragma omp simd
  453. for (IT I = begin; I <= end; I += ST) {
  454. ++I;
  455. }
  456. #pragma omp simd
  457. for (IT I = begin; I < end; ++I) {
  458. ++I;
  459. }
  460. }
  461. static IT step() {
  462. return IT(ST);
  463. }
  464. };
  465. template <typename IT, int ST=0> int dotest_gt(IT begin, IT end) {
  466. // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
  467. // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
  468. #pragma omp simd
  469. for (IT I = begin; I >= end; I = I + ST) {
  470. ++I;
  471. }
  472. // expected-note@+3 2 {{loop step is expected to be negative due to this condition}}
  473. // expected-error@+2 2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
  474. #pragma omp simd
  475. for (IT I = begin; I >= end; I += ST) {
  476. ++I;
  477. }
  478. // expected-note@+3 {{loop step is expected to be negative due to this condition}}
  479. // expected-error@+2 {{increment expression must cause 'I' to decrease on each iteration of OpenMP for loop}}
  480. #pragma omp simd
  481. for (IT I = begin; I >= end; ++I) {
  482. ++I;
  483. }
  484. #pragma omp simd
  485. for (IT I = begin; I < end; I+=TC<int,ST>::step()) {
  486. ++I;
  487. }
  488. }
  489. void test_with_template() {
  490. GoodIter begin, end;
  491. TC<GoodIter, 100> t1;
  492. TC<GoodIter, -100> t2;
  493. t1.dotest_lt(begin, end);
  494. t2.dotest_lt(begin, end); // expected-note {{in instantiation of member function 'TC<GoodIter, -100>::dotest_lt' requested here}}
  495. dotest_gt(begin, end); // expected-note {{in instantiation of function template specialization 'dotest_gt<GoodIter, 0>' requested here}}
  496. dotest_gt<unsigned, 10>(0, 100); // expected-note {{in instantiation of function template specialization 'dotest_gt<unsigned int, 10>' requested here}}
  497. }
  498. void test_loop_break() {
  499. const int N = 100;
  500. float a[N], b[N], c[N];
  501. #pragma omp simd
  502. for (int i = 0; i < 10; i++) {
  503. c[i] = a[i] + b[i];
  504. for (int j = 0; j < 10; ++j) {
  505. if (a[i] > b[j])
  506. break; // OK in nested loop
  507. }
  508. switch(i) {
  509. case 1:
  510. b[i]++;
  511. break;
  512. default:
  513. break;
  514. }
  515. if (c[i] > 10)
  516. break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
  517. if (c[i] > 11)
  518. break; // expected-error {{'break' statement cannot be used in OpenMP for loop}}
  519. }
  520. #pragma omp simd
  521. for (int i = 0; i < 10; i++) {
  522. for (int j = 0; j < 10; j++) {
  523. c[i] = a[i] + b[i];
  524. if (c[i] > 10) {
  525. if (c[i] < 20) {
  526. break; // OK
  527. }
  528. }
  529. }
  530. }
  531. }
  532. void test_loop_eh() {
  533. const int N = 100;
  534. float a[N], b[N], c[N];
  535. #pragma omp simd
  536. for (int i = 0; i < 10; i++) {
  537. c[i] = a[i] + b[i];
  538. try { // expected-error {{'try' statement cannot be used in OpenMP simd region}}
  539. for (int j = 0; j < 10; ++j) {
  540. if (a[i] > b[j])
  541. throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
  542. }
  543. throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
  544. }
  545. catch (float f) {
  546. if (f > 0.1)
  547. throw a[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
  548. return; // expected-error {{cannot return from OpenMP region}}
  549. }
  550. switch(i) {
  551. case 1:
  552. b[i]++;
  553. break;
  554. default:
  555. break;
  556. }
  557. for (int j = 0; j < 10; j++) {
  558. if (c[i] > 10)
  559. throw c[i]; // expected-error {{'throw' statement cannot be used in OpenMP simd region}}
  560. }
  561. }
  562. if (c[9] > 10)
  563. throw c[9]; // OK
  564. #pragma omp simd
  565. for (int i = 0; i < 10; ++i) {
  566. struct S {
  567. void g() { throw 0; }
  568. };
  569. }
  570. }