Import gcc-4.7.2 to new vendor branch
[dragonfly.git] / contrib / gcc-4.7 / gcc / c-family / c-omp.c
1 /* This file contains routines to construct GNU OpenMP constructs,
2    called from parsing in the C and C++ front ends.
3
4    Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
5    Free Software Foundation, Inc.
6    Contributed by Richard Henderson <rth@redhat.com>,
7                   Diego Novillo <dnovillo@redhat.com>.
8
9 This file is part of GCC.
10
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
14 version.
15
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19 for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3.  If not see
23 <http://www.gnu.org/licenses/>.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tree.h"
29 #include "c-common.h"
30 #include "gimple.h"             /* For create_tmp_var_raw.  */
31 #include "langhooks.h"
32
33
34 /* Complete a #pragma omp master construct.  STMT is the structured-block
35    that follows the pragma.  LOC is the l*/
36
37 tree
38 c_finish_omp_master (location_t loc, tree stmt)
39 {
40   tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
41   SET_EXPR_LOCATION (t, loc);
42   return t;
43 }
44
45 /* Complete a #pragma omp critical construct.  STMT is the structured-block
46    that follows the pragma, NAME is the identifier in the pragma, or null
47    if it was omitted.  LOC is the location of the #pragma.  */
48
49 tree
50 c_finish_omp_critical (location_t loc, tree body, tree name)
51 {
52   tree stmt = make_node (OMP_CRITICAL);
53   TREE_TYPE (stmt) = void_type_node;
54   OMP_CRITICAL_BODY (stmt) = body;
55   OMP_CRITICAL_NAME (stmt) = name;
56   SET_EXPR_LOCATION (stmt, loc);
57   return add_stmt (stmt);
58 }
59
60 /* Complete a #pragma omp ordered construct.  STMT is the structured-block
61    that follows the pragma.  LOC is the location of the #pragma.  */
62
63 tree
64 c_finish_omp_ordered (location_t loc, tree stmt)
65 {
66   tree t = build1 (OMP_ORDERED, void_type_node, stmt);
67   SET_EXPR_LOCATION (t, loc);
68   return add_stmt (t);
69 }
70
71
72 /* Complete a #pragma omp barrier construct.  LOC is the location of
73    the #pragma.  */
74
75 void
76 c_finish_omp_barrier (location_t loc)
77 {
78   tree x;
79
80   x = builtin_decl_explicit (BUILT_IN_GOMP_BARRIER);
81   x = build_call_expr_loc (loc, x, 0);
82   add_stmt (x);
83 }
84
85
86 /* Complete a #pragma omp taskwait construct.  LOC is the location of the
87    pragma.  */
88
89 void
90 c_finish_omp_taskwait (location_t loc)
91 {
92   tree x;
93
94   x = builtin_decl_explicit (BUILT_IN_GOMP_TASKWAIT);
95   x = build_call_expr_loc (loc, x, 0);
96   add_stmt (x);
97 }
98
99
100 /* Complete a #pragma omp taskyield construct.  LOC is the location of the
101    pragma.  */
102
103 void
104 c_finish_omp_taskyield (location_t loc)
105 {
106   tree x;
107
108   x = builtin_decl_explicit (BUILT_IN_GOMP_TASKYIELD);
109   x = build_call_expr_loc (loc, x, 0);
110   add_stmt (x);
111 }
112
113
114 /* Complete a #pragma omp atomic construct.  For CODE OMP_ATOMIC
115    the expression to be implemented atomically is LHS opcode= RHS. 
116    For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
117    opcode= RHS with the new or old content of LHS returned.
118    LOC is the location of the atomic statement.  The value returned
119    is either error_mark_node (if the construct was erroneous) or an
120    OMP_ATOMIC* node which should be added to the current statement
121    tree with add_stmt.  */
122
123 tree
124 c_finish_omp_atomic (location_t loc, enum tree_code code,
125                      enum tree_code opcode, tree lhs, tree rhs,
126                      tree v, tree lhs1, tree rhs1)
127 {
128   tree x, type, addr;
129
130   if (lhs == error_mark_node || rhs == error_mark_node
131       || v == error_mark_node || lhs1 == error_mark_node
132       || rhs1 == error_mark_node)
133     return error_mark_node;
134
135   /* ??? According to one reading of the OpenMP spec, complex type are
136      supported, but there are no atomic stores for any architecture.
137      But at least icc 9.0 doesn't support complex types here either.
138      And lets not even talk about vector types...  */
139   type = TREE_TYPE (lhs);
140   if (!INTEGRAL_TYPE_P (type)
141       && !POINTER_TYPE_P (type)
142       && !SCALAR_FLOAT_TYPE_P (type))
143     {
144       error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
145       return error_mark_node;
146     }
147
148   /* ??? Validate that rhs does not overlap lhs.  */
149
150   /* Take and save the address of the lhs.  From then on we'll reference it
151      via indirection.  */
152   addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
153   if (addr == error_mark_node)
154     return error_mark_node;
155   addr = save_expr (addr);
156   if (TREE_CODE (addr) != SAVE_EXPR
157       && (TREE_CODE (addr) != ADDR_EXPR
158           || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
159     {
160       /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
161          it even after unsharing function body.  */
162       tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
163       DECL_CONTEXT (var) = current_function_decl;
164       addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
165     }
166   lhs = build_indirect_ref (loc, addr, RO_NULL);
167
168   if (code == OMP_ATOMIC_READ)
169     {
170       x = build1 (OMP_ATOMIC_READ, type, addr);
171       SET_EXPR_LOCATION (x, loc);
172       return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
173                                 loc, x, NULL_TREE);
174       return x;
175     }
176
177   /* There are lots of warnings, errors, and conversions that need to happen
178      in the course of interpreting a statement.  Use the normal mechanisms
179      to do this, and then take it apart again.  */
180   x = build_modify_expr (input_location, lhs, NULL_TREE, opcode,
181                          input_location, rhs, NULL_TREE);
182   if (x == error_mark_node)
183     return error_mark_node;
184   gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
185   rhs = TREE_OPERAND (x, 1);
186
187   /* Punt the actual generation of atomic operations to common code.  */
188   if (code == OMP_ATOMIC)
189     type = void_type_node;
190   x = build2 (code, type, addr, rhs);
191   SET_EXPR_LOCATION (x, loc);
192
193   /* Generally it is hard to prove lhs1 and lhs are the same memory
194      location, just diagnose different variables.  */
195   if (rhs1
196       && TREE_CODE (rhs1) == VAR_DECL
197       && TREE_CODE (lhs) == VAR_DECL
198       && rhs1 != lhs)
199     {
200       if (code == OMP_ATOMIC)
201         error_at (loc, "%<#pragma omp atomic update%> uses two different variables for memory");
202       else
203         error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
204       return error_mark_node;
205     }
206
207   if (code != OMP_ATOMIC)
208     {
209       /* Generally it is hard to prove lhs1 and lhs are the same memory
210          location, just diagnose different variables.  */
211       if (lhs1 && TREE_CODE (lhs1) == VAR_DECL && TREE_CODE (lhs) == VAR_DECL)
212         {
213           if (lhs1 != lhs)
214             {
215               error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
216               return error_mark_node;
217             }
218         }
219       x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
220                              loc, x, NULL_TREE);
221       if (rhs1 && rhs1 != lhs)
222         {
223           tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
224           if (rhs1addr == error_mark_node)
225             return error_mark_node;
226           x = omit_one_operand_loc (loc, type, x, rhs1addr);
227         }
228       if (lhs1 && lhs1 != lhs)
229         {
230           tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, 0);
231           if (lhs1addr == error_mark_node)
232             return error_mark_node;
233           if (code == OMP_ATOMIC_CAPTURE_OLD)
234             x = omit_one_operand_loc (loc, type, x, lhs1addr);
235           else
236             {
237               x = save_expr (x);
238               x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
239             }
240         }
241     }
242   else if (rhs1 && rhs1 != lhs)
243     {
244       tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
245       if (rhs1addr == error_mark_node)
246         return error_mark_node;
247       x = omit_one_operand_loc (loc, type, x, rhs1addr);
248     }
249
250   return x;
251 }
252
253
254 /* Complete a #pragma omp flush construct.  We don't do anything with
255    the variable list that the syntax allows.  LOC is the location of
256    the #pragma.  */
257
258 void
259 c_finish_omp_flush (location_t loc)
260 {
261   tree x;
262
263   x = builtin_decl_explicit (BUILT_IN_SYNC_SYNCHRONIZE);
264   x = build_call_expr_loc (loc, x, 0);
265   add_stmt (x);
266 }
267
268
269 /* Check and canonicalize #pragma omp for increment expression.
270    Helper function for c_finish_omp_for.  */
271
272 static tree
273 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
274 {
275   tree t;
276
277   if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
278       || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
279     return error_mark_node;
280
281   if (exp == decl)
282     return build_int_cst (TREE_TYPE (exp), 0);
283
284   switch (TREE_CODE (exp))
285     {
286     CASE_CONVERT:
287       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
288       if (t != error_mark_node)
289         return fold_convert_loc (loc, TREE_TYPE (exp), t);
290       break;
291     case MINUS_EXPR:
292       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
293       if (t != error_mark_node)
294         return fold_build2_loc (loc, MINUS_EXPR,
295                             TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
296       break;
297     case PLUS_EXPR:
298       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
299       if (t != error_mark_node)
300         return fold_build2_loc (loc, PLUS_EXPR,
301                             TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
302       t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
303       if (t != error_mark_node)
304         return fold_build2_loc (loc, PLUS_EXPR,
305                             TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
306       break;
307     case COMPOUND_EXPR:
308       {
309         /* cp_build_modify_expr forces preevaluation of the RHS to make
310            sure that it is evaluated before the lvalue-rvalue conversion
311            is applied to the LHS.  Reconstruct the original expression.  */
312         tree op0 = TREE_OPERAND (exp, 0);
313         if (TREE_CODE (op0) == TARGET_EXPR
314             && !VOID_TYPE_P (TREE_TYPE (op0)))
315           {
316             tree op1 = TREE_OPERAND (exp, 1);
317             tree temp = TARGET_EXPR_SLOT (op0);
318             if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary
319                 && TREE_OPERAND (op1, 1) == temp)
320               {
321                 op1 = copy_node (op1);
322                 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
323                 return check_omp_for_incr_expr (loc, op1, decl);
324               }
325           }
326         break;
327       }
328     default:
329       break;
330     }
331
332   return error_mark_node;
333 }
334
335 /* Validate and emit code for the OpenMP directive #pragma omp for.
336    DECLV is a vector of iteration variables, for each collapsed loop.
337    INITV, CONDV and INCRV are vectors containing initialization
338    expressions, controlling predicates and increment expressions.
339    BODY is the body of the loop and PRE_BODY statements that go before
340    the loop.  */
341
342 tree
343 c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
344                   tree incrv, tree body, tree pre_body)
345 {
346   location_t elocus;
347   bool fail = false;
348   int i;
349
350   gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
351   gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
352   gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
353   for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
354     {
355       tree decl = TREE_VEC_ELT (declv, i);
356       tree init = TREE_VEC_ELT (initv, i);
357       tree cond = TREE_VEC_ELT (condv, i);
358       tree incr = TREE_VEC_ELT (incrv, i);
359
360       elocus = locus;
361       if (EXPR_HAS_LOCATION (init))
362         elocus = EXPR_LOCATION (init);
363
364       /* Validate the iteration variable.  */
365       if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
366           && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
367         {
368           error_at (elocus, "invalid type for iteration variable %qE", decl);
369           fail = true;
370         }
371
372       /* In the case of "for (int i = 0...)", init will be a decl.  It should
373          have a DECL_INITIAL that we can turn into an assignment.  */
374       if (init == decl)
375         {
376           elocus = DECL_SOURCE_LOCATION (decl);
377
378           init = DECL_INITIAL (decl);
379           if (init == NULL)
380             {
381               error_at (elocus, "%qE is not initialized", decl);
382               init = integer_zero_node;
383               fail = true;
384             }
385
386           init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
387                                     /* FIXME diagnostics: This should
388                                        be the location of the INIT.  */
389                                     elocus,
390                                     init,
391                                     NULL_TREE);
392         }
393       gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
394       gcc_assert (TREE_OPERAND (init, 0) == decl);
395
396       if (cond == NULL_TREE)
397         {
398           error_at (elocus, "missing controlling predicate");
399           fail = true;
400         }
401       else
402         {
403           bool cond_ok = false;
404
405           if (EXPR_HAS_LOCATION (cond))
406             elocus = EXPR_LOCATION (cond);
407
408           if (TREE_CODE (cond) == LT_EXPR
409               || TREE_CODE (cond) == LE_EXPR
410               || TREE_CODE (cond) == GT_EXPR
411               || TREE_CODE (cond) == GE_EXPR
412               || TREE_CODE (cond) == NE_EXPR
413               || TREE_CODE (cond) == EQ_EXPR)
414             {
415               tree op0 = TREE_OPERAND (cond, 0);
416               tree op1 = TREE_OPERAND (cond, 1);
417
418               /* 2.5.1.  The comparison in the condition is computed in
419                  the type of DECL, otherwise the behavior is undefined.
420
421                  For example:
422                  long n; int i;
423                  i < n;
424
425                  according to ISO will be evaluated as:
426                  (long)i < n;
427
428                  We want to force:
429                  i < (int)n;  */
430               if (TREE_CODE (op0) == NOP_EXPR
431                   && decl == TREE_OPERAND (op0, 0))
432                 {
433                   TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
434                   TREE_OPERAND (cond, 1)
435                     = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
436                                    TREE_OPERAND (cond, 1));
437                 }
438               else if (TREE_CODE (op1) == NOP_EXPR
439                        && decl == TREE_OPERAND (op1, 0))
440                 {
441                   TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
442                   TREE_OPERAND (cond, 0)
443                     = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
444                                    TREE_OPERAND (cond, 0));
445                 }
446
447               if (decl == TREE_OPERAND (cond, 0))
448                 cond_ok = true;
449               else if (decl == TREE_OPERAND (cond, 1))
450                 {
451                   TREE_SET_CODE (cond,
452                                  swap_tree_comparison (TREE_CODE (cond)));
453                   TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
454                   TREE_OPERAND (cond, 0) = decl;
455                   cond_ok = true;
456                 }
457
458               if (TREE_CODE (cond) == NE_EXPR
459                   || TREE_CODE (cond) == EQ_EXPR)
460                 {
461                   if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
462                     cond_ok = false;
463                   else if (operand_equal_p (TREE_OPERAND (cond, 1),
464                                             TYPE_MIN_VALUE (TREE_TYPE (decl)),
465                                             0))
466                     TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
467                                          ? GT_EXPR : LE_EXPR);
468                   else if (operand_equal_p (TREE_OPERAND (cond, 1),
469                                             TYPE_MAX_VALUE (TREE_TYPE (decl)),
470                                             0))
471                     TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
472                                          ? LT_EXPR : GE_EXPR);
473                   else
474                     cond_ok = false;
475                 }
476             }
477
478           if (!cond_ok)
479             {
480               error_at (elocus, "invalid controlling predicate");
481               fail = true;
482             }
483         }
484
485       if (incr == NULL_TREE)
486         {
487           error_at (elocus, "missing increment expression");
488           fail = true;
489         }
490       else
491         {
492           bool incr_ok = false;
493
494           if (EXPR_HAS_LOCATION (incr))
495             elocus = EXPR_LOCATION (incr);
496
497           /* Check all the valid increment expressions: v++, v--, ++v, --v,
498              v = v + incr, v = incr + v and v = v - incr.  */
499           switch (TREE_CODE (incr))
500             {
501             case POSTINCREMENT_EXPR:
502             case PREINCREMENT_EXPR:
503             case POSTDECREMENT_EXPR:
504             case PREDECREMENT_EXPR:
505               if (TREE_OPERAND (incr, 0) != decl)
506                 break;
507
508               incr_ok = true;
509               if (POINTER_TYPE_P (TREE_TYPE (decl))
510                   && TREE_OPERAND (incr, 1))
511                 {
512                   tree t = fold_convert_loc (elocus,
513                                              sizetype, TREE_OPERAND (incr, 1));
514
515                   if (TREE_CODE (incr) == POSTDECREMENT_EXPR
516                       || TREE_CODE (incr) == PREDECREMENT_EXPR)
517                     t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t);
518                   t = fold_build_pointer_plus (decl, t);
519                   incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
520                 }
521               break;
522
523             case MODIFY_EXPR:
524               if (TREE_OPERAND (incr, 0) != decl)
525                 break;
526               if (TREE_OPERAND (incr, 1) == decl)
527                 break;
528               if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
529                   && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
530                       || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
531                 incr_ok = true;
532               else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
533                         || (TREE_CODE (TREE_OPERAND (incr, 1))
534                             == POINTER_PLUS_EXPR))
535                        && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
536                 incr_ok = true;
537               else
538                 {
539                   tree t = check_omp_for_incr_expr (elocus,
540                                                     TREE_OPERAND (incr, 1),
541                                                     decl);
542                   if (t != error_mark_node)
543                     {
544                       incr_ok = true;
545                       t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
546                       incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
547                     }
548                 }
549               break;
550
551             default:
552               break;
553             }
554           if (!incr_ok)
555             {
556               error_at (elocus, "invalid increment expression");
557               fail = true;
558             }
559         }
560
561       TREE_VEC_ELT (initv, i) = init;
562       TREE_VEC_ELT (incrv, i) = incr;
563     }
564
565   if (fail)
566     return NULL;
567   else
568     {
569       tree t = make_node (OMP_FOR);
570
571       TREE_TYPE (t) = void_type_node;
572       OMP_FOR_INIT (t) = initv;
573       OMP_FOR_COND (t) = condv;
574       OMP_FOR_INCR (t) = incrv;
575       OMP_FOR_BODY (t) = body;
576       OMP_FOR_PRE_BODY (t) = pre_body;
577
578       SET_EXPR_LOCATION (t, locus);
579       return add_stmt (t);
580     }
581 }
582
583
584 /* Divide CLAUSES into two lists: those that apply to a parallel
585    construct, and those that apply to a work-sharing construct.  Place
586    the results in *PAR_CLAUSES and *WS_CLAUSES respectively.  In
587    addition, add a nowait clause to the work-sharing list.  LOC is the
588    location of the OMP_PARALLEL*.  */
589
590 void
591 c_split_parallel_clauses (location_t loc, tree clauses,
592                           tree *par_clauses, tree *ws_clauses)
593 {
594   tree next;
595
596   *par_clauses = NULL;
597   *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
598
599   for (; clauses ; clauses = next)
600     {
601       next = OMP_CLAUSE_CHAIN (clauses);
602
603       switch (OMP_CLAUSE_CODE (clauses))
604         {
605         case OMP_CLAUSE_PRIVATE:
606         case OMP_CLAUSE_SHARED:
607         case OMP_CLAUSE_FIRSTPRIVATE:
608         case OMP_CLAUSE_LASTPRIVATE:
609         case OMP_CLAUSE_REDUCTION:
610         case OMP_CLAUSE_COPYIN:
611         case OMP_CLAUSE_IF:
612         case OMP_CLAUSE_NUM_THREADS:
613         case OMP_CLAUSE_DEFAULT:
614           OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
615           *par_clauses = clauses;
616           break;
617
618         case OMP_CLAUSE_SCHEDULE:
619         case OMP_CLAUSE_ORDERED:
620         case OMP_CLAUSE_COLLAPSE:
621           OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
622           *ws_clauses = clauses;
623           break;
624
625         default:
626           gcc_unreachable ();
627         }
628     }
629 }
630
631 /* True if OpenMP sharing attribute of DECL is predetermined.  */
632
633 enum omp_clause_default_kind
634 c_omp_predetermined_sharing (tree decl)
635 {
636   /* Variables with const-qualified type having no mutable member
637      are predetermined shared.  */
638   if (TREE_READONLY (decl))
639     return OMP_CLAUSE_DEFAULT_SHARED;
640
641   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
642 }