@@ -8692,7 +8692,12 @@ c_parser_omp_clause_private (c_parser *p
reduction ( reduction-operator : variable-list )
reduction-operator:
- One of: + * - & ^ | && || */
+ One of: + * - & ^ | && ||
+
+ OpenMP 3.1:
+
+ reduction-operator:
+ One of: + * - & ^ | && || max min */
static tree
c_parser_omp_clause_reduction (c_parser *parser, tree list)
@@ -8728,10 +8733,26 @@ c_parser_omp_clause_reduction (c_parser
case CPP_OR_OR:
code = TRUTH_ORIF_EXPR;
break;
+ case CPP_NAME:
+ {
+ const char *p
+ = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "min") == 0)
+ {
+ code = MIN_EXPR;
+ break;
+ }
+ if (strcmp (p, "max") == 0)
+ {
+ code = MAX_EXPR;
+ break;
+ }
+ }
+ /* FALLTHRU */
default:
c_parser_error (parser,
"expected %<+%>, %<*%>, %<-%>, %<&%>, "
- "%<^%>, %<|%>, %<&&%>, or %<||%>");
+ "%<^%>, %<|%>, %<&&%>, %<||%>, %<min%> or %<max%>");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
return list;
}
@@ -10441,6 +10441,8 @@ c_finish_omp_clauses (tree clauses)
case PLUS_EXPR:
case MULT_EXPR:
case MINUS_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
break;
case BIT_AND_EXPR:
r_name = "&";
@@ -23683,7 +23683,12 @@ cp_parser_omp_clause_ordered (cp_parser
reduction ( reduction-operator : variable-list )
reduction-operator:
- One of: + * - & ^ | && || */
+ One of: + * - & ^ | && ||
+
+ OpenMP 3.1:
+
+ reduction-operator:
+ One of: + * - & ^ | && || min max */
static tree
cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
@@ -23720,9 +23725,26 @@ cp_parser_omp_clause_reduction (cp_parse
case CPP_OR_OR:
code = TRUTH_ORIF_EXPR;
break;
+ case CPP_NAME:
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp (p, "min") == 0)
+ {
+ code = MIN_EXPR;
+ break;
+ }
+ if (strcmp (p, "max") == 0)
+ {
+ code = MAX_EXPR;
+ break;
+ }
+ }
+ /* FALLTHROUGH */
default:
cp_parser_error (parser, "expected %<+%>, %<*%>, %<-%>, %<&%>, %<^%>, "
- "%<|%>, %<&&%>, or %<||%>");
+ "%<|%>, %<&&%>, %<||%>, %<min%> or %<max%>");
resync_fail:
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
@@ -3893,6 +3893,8 @@ finish_omp_clauses (tree clauses)
case PLUS_EXPR:
case MULT_EXPR:
case MINUS_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
break;
default:
error ("%qE has invalid type for %<reduction(%s)%>",
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int j;
+float f;
+
+int
+main ()
+{
+ j = -10000;
+ f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+ return 0;
+}
@@ -0,0 +1,54 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+
+template <typename I, typename F>
+void
+foo ()
+{
+ I j = -10000;
+ F f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+}
+
+int
+main ()
+{
+ int j = -10000;
+ float f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+ foo <int, float> ();
+ foo <long, double> ();
+ foo <long long, long double> ();
+ return 0;
+}