On 10/23/2015 01:25 PM, Cesar Philippidis wrote: > On 10/22/2015 01:52 AM, Jakub Jelinek wrote: >> On Wed, Oct 21, 2015 at 03:18:55PM -0400, Nathan Sidwell wrote: >>> This patch is the C++ changes matching the C ones of patch 4. In >>> finish_omp_clauses, the gang, worker, & vector clauses are handled the same >>> as OpenMP's 'num_threads' clause. One change to num_threads is the >>> augmentation of a diagnostic to add %<...%> markers to the clause name. >> >> Indeed, lots of older OpenMP diagnostics is missing %<...%> markers around >> keywords. Something to fix eventually. > > I updated omp tasks and teams in semantics.c. > >>> 2015-10-20 Cesar Philippidis <ce...@codesourcery.com> >>> Thomas Schwinge <tho...@codesourcery.com> >>> James Norris <jnor...@codesourcery.com> >>> Joseph Myers <jos...@codesourcery.com> >>> Julian Brown <jul...@codesourcery.com> >>> Nathan Sidwell <nat...@codesourcery.com> >>> >>> * parser.c (cp_parser_omp_clause_name): Add auto, gang, seq, >>> vector, worker. >>> (cp_parser_oacc_simple_clause): New. >>> (cp_parser_oacc_shape_clause): New. >> >> What I've said for the C FE patch, plus: >> >>> + if (cp_lexer_next_token_is (lexer, CPP_NAME) >>> + || cp_lexer_next_token_is (lexer, CPP_KEYWORD)) >>> + { >>> + tree name_kind = cp_lexer_peek_token (lexer)->u.value; >>> + const char *p = IDENTIFIER_POINTER (name_kind); >>> + if (kind == OMP_CLAUSE_GANG && strcmp ("static", p) == 0) >> >> As static is a keyword, wouldn't it be better to just handle that case >> using cp_lexer_next_token_is_keyword (lexer, RID_STATIC)? >> >> Also, what is the exact grammar of the shape arguments? >> Would be nice to describe the grammar, in the grammar you just say >> expression, at least for vector/worker, which is clearly not accurate. >> >> It seems the intent is that num: or length: or static: is optional, right? >> But if that is the case, you should treat those as parsed only if followed >> by :. While static is a keyword, so you can't have a variable called like >> that, having vector(length) or vector(num) should not be rejected. >> So, I would have expected that it should test if it is RID_STATIC >> followed by CPP_COLON (and only in that case consume those tokens), >> or CPP_NAME of id followed by CPP_COLON (and only in that case consume those >> tokens), otherwise parse it as assignment expression. > > That function now peeks ahead to look for a colon, so now it can handle > variables with the name of clause keywords. > >> The C FE may have similar issue. Plus of course there should be testsuite >> coverage for all the weird cases. > > I included a new test in a different patch because it's common to both c > and c++. > >>> + case OMP_CLAUSE_GANG: >>> + case OMP_CLAUSE_VECTOR: >>> + case OMP_CLAUSE_WORKER: >>> + /* Operand 0 is the num: or length: argument. */ >>> + t = OMP_CLAUSE_OPERAND (c, 0); >>> + if (t == NULL_TREE) >>> + break; >>> + >>> + t = maybe_convert_cond (t); >> >> Can you explain the maybe_convert_cond calls (in both cases here, >> plus the preexisting in OMP_CLAUSE_VECTOR_LENGTH)? >> The reason why it is used for OpenMP if and final clauses is that those have >> a condition argument, either the condition is zero or non-zero (so >> effectively it is turned into a bool). >> But aren't the gang/vector/worker/vector_length arguments integers rather >> than conditions? I'd expect that finish_omp_clauses should verify >> those operands are indeed integral expressions (if that is the requirement >> in the standard), as it is something that for C++ can't be verified during >> parsing, if arbitrary expressions are parsed there. > > It's probably a copy-and-paste error. This functionality was added > incrementally. I removed that check. > >>> @@ -5959,32 +5990,58 @@ finish_omp_clauses (tree clauses, bool a >>> break; >>> >>> case OMP_CLAUSE_NUM_THREADS: >>> - t = OMP_CLAUSE_NUM_THREADS_EXPR (c); >>> - if (t == error_mark_node) >>> - remove = true; >>> - else if (!type_dependent_expression_p (t) >>> - && !INTEGRAL_TYPE_P (TREE_TYPE (t))) >>> - { >>> - error ("num_threads expression must be integral"); >>> - remove = true; >>> - } >>> - else >>> - { >>> - t = mark_rvalue_use (t); >>> - if (!processing_template_decl) >>> - { >>> - t = maybe_constant_value (t); >>> - if (TREE_CODE (t) == INTEGER_CST >>> - && tree_int_cst_sgn (t) != 1) >>> - { >>> - warning_at (OMP_CLAUSE_LOCATION (c), 0, >>> - "%<num_threads%> value must be positive"); >>> - t = integer_one_node; >>> - } >>> - t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); >>> - } >>> - OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; >>> - } >>> + case OMP_CLAUSE_NUM_GANGS: >>> + case OMP_CLAUSE_NUM_WORKERS: >>> + case OMP_CLAUSE_VECTOR_LENGTH: >> >> If you are already merging some of the similar handling, please >> handle OMP_CLAUSE_NUM_TEAMS and OMP_CLAUSE_NUM_TASKS the same way. > > I did that, but I also had to adjust the expected errors in a couple of > existing gomp test cases. > > Is this patch OK for trunk?
This patch teaches the the loop shape function how to be more careful with commas. Most of the errors in the c++ front end are similar their counterparts in c, except for those when the c++ front end thinks a stray colon is an errant scope resolution operation. For those types of failures, I just used a generic regex for the dg-error. Consequently, this patch shares the same loop-shape.c test case that I included in the c patch. Is this OK for trunk? Cesar
2015-10-23 Cesar Philippidis <ce...@codesourcery.com> Thomas Schwinge <tho...@codesourcery.com> James Norris <jnor...@codesourcery.com> Joseph Myers <jos...@codesourcery.com> Julian Brown <jul...@codesourcery.com> Nathan Sidwell <nat...@codesourcery.com> Bernd Schmidt <bschm...@redhat.com> * parser.c (cp_parser_omp_clause_name): Add auto, gang, seq, vector, worker. (cp_parser_oacc_simple_clause): New. (cp_parser_oacc_shape_clause): New. (cp_parser_oacc_all_clauses): Add auto, gang, seq, vector, worker. (OACC_LOOP_CLAUSE_MASK): Likewise. * semantics.c (finish_omp_clauses): Add auto, gang, seq, vector, worker. Unify the handling to teams, tasks and vector_length with the other loop shape clauses. 2015-10-23 Nathan Sidwell <nat...@codesourcery.com> Cesar Philippidis <ce...@codesourcery.com> gcc/testsuite/ * g++.dg/g++.dg/gomp/pr33372-1.C: Adjust diagnostic. * gcc/testsuite/g++.dg/gomp/pr33372-3.C: Likewise. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8dbff11..2970ec2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2015-10-22 Jason Merrill <ja...@redhat.com> + + * call.c (add_template_conv_candidate): Pass DEDUCE_CALL. + (add_template_candidate_real): Handle it. + * pt.c (fn_type_unification): Handle it. + + * call.c (add_conv_candidate): Remove first_arg parm. + (add_template_conv_candidate): Likewise. + (add_template_candidate_real): Don't pass it. + (build_op_call_1): Likewise. + 2015-10-22 Richard Biener <rguent...@suse.de> * semantics.c (cp_finish_omp_clause_depend_sink): Properly convert diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 55b3c8c..5b57dc9 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -178,9 +178,6 @@ static struct z_candidate *add_template_candidate static struct z_candidate *add_template_candidate_real (struct z_candidate **, tree, tree, tree, tree, const vec<tree, va_gc> *, tree, tree, tree, int, tree, unification_kind_t, tsubst_flags_t); -static struct z_candidate *add_template_conv_candidate - (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, - tree, tree, tree, tsubst_flags_t); static void add_builtin_candidates (struct z_candidate **, enum tree_code, enum tree_code, tree, tree *, int, tsubst_flags_t); @@ -192,7 +189,7 @@ static void build_builtin_candidate (struct z_candidate **, tree, tree, tree, tree *, tree *, int, tsubst_flags_t); static struct z_candidate *add_conv_candidate - (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, tree, + (struct z_candidate **, tree, tree, const vec<tree, va_gc> *, tree, tree, tsubst_flags_t); static struct z_candidate *add_function_candidate (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, tree, @@ -2176,7 +2173,7 @@ add_function_candidate (struct z_candidate **candidates, static struct z_candidate * add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, - tree first_arg, const vec<tree, va_gc> *arglist, + const vec<tree, va_gc> *arglist, tree access_path, tree conversion_path, tsubst_flags_t complain) { @@ -2190,7 +2187,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, parmlist = TREE_TYPE (parmlist); parmlist = TYPE_ARG_TYPES (parmlist); - len = vec_safe_length (arglist) + (first_arg != NULL_TREE ? 1 : 0) + 1; + len = vec_safe_length (arglist) + 1; convs = alloc_conversions (len); parmnode = parmlist; viable = 1; @@ -2208,10 +2205,8 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, if (i == 0) arg = obj; - else if (i == 1 && first_arg != NULL_TREE) - arg = first_arg; else - arg = (*arglist)[i - (first_arg != NULL_TREE ? 1 : 0) - 1]; + arg = (*arglist)[i - 1]; argtype = lvalue_type (arg); if (i == 0) @@ -2260,7 +2255,7 @@ add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj, reason = arity_rejection (NULL_TREE, i + remaining, len); } - return add_candidate (candidates, totype, first_arg, arglist, len, convs, + return add_candidate (candidates, totype, obj, arglist, len, convs, access_path, conversion_path, viable, reason, flags); } @@ -3032,6 +3027,9 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, { if (first_arg_without_in_chrg != NULL_TREE) first_arg_without_in_chrg = NULL_TREE; + else if (return_type && strict == DEDUCE_CALL) + /* We're deducing for a call to the result of a template conversion + function, so the args don't contain 'this'; leave them alone. */; else ++skip_without_in_chrg; } @@ -3122,7 +3120,7 @@ add_template_candidate_real (struct z_candidate **candidates, tree tmpl, if (obj != NULL_TREE) /* Aha, this is a conversion function. */ - cand = add_conv_candidate (candidates, fn, obj, first_arg, arglist, + cand = add_conv_candidate (candidates, fn, obj, arglist, access_path, conversion_path, complain); else cand = add_function_candidate (candidates, fn, ctype, @@ -3172,18 +3170,23 @@ add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype, flags, NULL_TREE, strict, complain); } +/* Create an overload candidate for the conversion function template TMPL, + returning RETURN_TYPE, which will be invoked for expression OBJ to produce a + pointer-to-function which will in turn be called with the argument list + ARGLIST, and add it to CANDIDATES. This does not change ARGLIST. FLAGS is + passed on to implicit_conversion. */ static struct z_candidate * add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, - tree obj, tree first_arg, + tree obj, const vec<tree, va_gc> *arglist, tree return_type, tree access_path, tree conversion_path, tsubst_flags_t complain) { return add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE, - first_arg, arglist, return_type, access_path, - conversion_path, 0, obj, DEDUCE_CONV, + NULL_TREE, arglist, return_type, access_path, + conversion_path, 0, obj, DEDUCE_CALL, complain); } @@ -4335,11 +4338,11 @@ build_op_call_1 (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain) if (TREE_CODE (fn) == TEMPLATE_DECL) add_template_conv_candidate - (&candidates, fn, obj, NULL_TREE, *args, totype, + (&candidates, fn, obj, *args, totype, /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE, complain); else - add_conv_candidate (&candidates, fn, obj, NULL_TREE, + add_conv_candidate (&candidates, fn, obj, *args, /*conversion_path=*/NULL_TREE, /*access_path=*/NULL_TREE, complain); } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7555bf3..eaccf4b 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -29064,7 +29064,9 @@ cp_parser_omp_clause_name (cp_parser *parser) { pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE; - if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF)) + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO)) + result = PRAGMA_OACC_CLAUSE_AUTO; + else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF)) result = PRAGMA_OMP_CLAUSE_IF; else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT)) result = PRAGMA_OMP_CLAUSE_DEFAULT; @@ -29122,7 +29124,9 @@ cp_parser_omp_clause_name (cp_parser *parser) result = PRAGMA_OMP_CLAUSE_FROM; break; case 'g': - if (!strcmp ("grainsize", p)) + if (!strcmp ("gang", p)) + result = PRAGMA_OACC_CLAUSE_GANG; + else if (!strcmp ("grainsize", p)) result = PRAGMA_OMP_CLAUSE_GRAINSIZE; break; case 'h': @@ -29212,6 +29216,8 @@ cp_parser_omp_clause_name (cp_parser *parser) result = PRAGMA_OMP_CLAUSE_SECTIONS; else if (!strcmp ("self", p)) result = PRAGMA_OACC_CLAUSE_SELF; + else if (!strcmp ("seq", p)) + result = PRAGMA_OACC_CLAUSE_SEQ; else if (!strcmp ("shared", p)) result = PRAGMA_OMP_CLAUSE_SHARED; else if (!strcmp ("simd", p)) @@ -29238,7 +29244,9 @@ cp_parser_omp_clause_name (cp_parser *parser) result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR; break; case 'v': - if (!strcmp ("vector_length", p)) + if (!strcmp ("vector", p)) + result = PRAGMA_OACC_CLAUSE_VECTOR; + else if (!strcmp ("vector_length", p)) result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH; else if (flag_cilkplus && !strcmp ("vectorlength", p)) result = PRAGMA_CILK_CLAUSE_VECTORLENGTH; @@ -29246,6 +29254,8 @@ cp_parser_omp_clause_name (cp_parser *parser) case 'w': if (!strcmp ("wait", p)) result = PRAGMA_OACC_CLAUSE_WAIT; + else if (!strcmp ("worker", p)) + result = PRAGMA_OACC_CLAUSE_WORKER; break; } } @@ -29582,6 +29592,158 @@ cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list) return list; } +/* OpenACC 2.0: + auto + independent + nohost + seq */ + +static tree +cp_parser_oacc_simple_clause (cp_parser *ARG_UNUSED (parser), + enum omp_clause_code code, + tree list, location_t location) +{ + check_no_duplicate_clause (list, code, omp_clause_code_name[code], location); + tree c = build_omp_clause (location, code); + OMP_CLAUSE_CHAIN (c) = list; + return c; +} + +/* OpenACC: + + gang [( gang-arg-list )] + worker [( [num:] int-expr )] + vector [( [length:] int-expr )] + + where gang-arg is one of: + + [num:] int-expr + static: size-expr + + and size-expr may be: + + * + int-expr +*/ + +static tree +cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind, + const char *str, tree list) +{ + const char *id = "num"; + cp_lexer *lexer = parser->lexer; + tree op0 = NULL_TREE, op1 = NULL_TREE, c; + location_t loc = cp_lexer_peek_token (lexer)->location; + + if (kind == OMP_CLAUSE_VECTOR) + id = "length"; + + if (cp_lexer_next_token_is (lexer, CPP_OPEN_PAREN)) + { + tree *op_to_parse = &op0; + cp_token *next; + + cp_lexer_consume_token (lexer); + + do + { + /* Consume a comma if present. */ + if (cp_lexer_next_token_is (lexer, CPP_COMMA)) + { + if (op0 == NULL && op1 == NULL) + { + cp_parser_error (parser, "unexpected argument"); + goto cleanup_error; + } + + cp_lexer_consume_token (lexer); + } + + next = cp_lexer_peek_token (lexer); + loc = next->location; + op_to_parse = &op0; + + /* First extract any length:, num: and static: arguments. */ + + /* Gang static argument. */ + if (cp_lexer_next_token_is (lexer, CPP_KEYWORD) + && cp_lexer_next_token_is_keyword (lexer, RID_STATIC)) + { + if (kind != OMP_CLAUSE_GANG) + { + cp_parser_error (parser, "invalid %<static%> argument"); + goto cleanup_error; + } + + cp_lexer_consume_token (lexer); + + if (!cp_parser_require (parser, CPP_COLON, RT_COLON)) + goto cleanup_error; + + op_to_parse = &op1; + if (*op_to_parse != NULL) + { + cp_parser_error (parser, "too many %<static%> arguements"); + goto cleanup_error; + } + + /* Check for the '*' argument. */ + if (cp_lexer_next_token_is (lexer, CPP_MULT)) + { + cp_lexer_consume_token (lexer); + *op_to_parse = integer_minus_one_node; + continue; + } + } + /* Worker num: argument and vector length: arguments. */ + else if (cp_lexer_next_token_is (lexer, CPP_NAME) + && strcmp (id, IDENTIFIER_POINTER (next->u.value)) == 0 + && cp_lexer_nth_token_is (lexer, 2, CPP_COLON)) + { + cp_lexer_consume_token (lexer); /* id */ + cp_lexer_consume_token (lexer); /* ':' */ + } + + /* Now collect the actual argument. */ + + if (*op_to_parse != NULL_TREE) + { + cp_parser_error (parser, "unexpected argument"); + goto cleanup_error; + } + + + tree expr = cp_parser_assignment_expression (parser, NULL, false, + false); + if (expr == error_mark_node) + goto cleanup_error; + + mark_exp_read (expr); + *op_to_parse = expr; + } + while (cp_lexer_next_token_is (lexer, CPP_COMMA) + && !cp_lexer_next_token_is (lexer, CPP_CLOSE_PAREN)); + + if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN)) + goto cleanup_error; + } + + check_no_duplicate_clause (list, kind, str, loc); + + c = build_omp_clause (loc, kind); + if (op0) + OMP_CLAUSE_OPERAND (c, 0) = op0; + if (op1) + OMP_CLAUSE_OPERAND (c, 1) = op1; + OMP_CLAUSE_CHAIN (c) = list; + + return c; + + cleanup_error: + cp_parser_skip_to_closing_parenthesis (parser, false, false, true); + return list; +} + /* OpenACC: vector_length ( expression ) */ @@ -31306,6 +31468,11 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask, clauses = cp_parser_oacc_clause_async (parser, clauses); c_name = "async"; break; + case PRAGMA_OACC_CLAUSE_AUTO: + clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_AUTO, + clauses, here); + c_name = "auto"; + break; case PRAGMA_OACC_CLAUSE_COLLAPSE: clauses = cp_parser_omp_clause_collapse (parser, clauses, here); c_name = "collapse"; @@ -31338,6 +31505,11 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask, clauses = cp_parser_oacc_data_clause_deviceptr (parser, clauses); c_name = "deviceptr"; break; + case PRAGMA_OACC_CLAUSE_GANG: + c_name = "gang"; + clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_GANG, + c_name, clauses); + break; case PRAGMA_OACC_CLAUSE_HOST: clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses); c_name = "host"; @@ -31382,6 +31554,16 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask, clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses); c_name = "self"; break; + case PRAGMA_OACC_CLAUSE_SEQ: + clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ, + clauses, here); + c_name = "seq"; + break; + case PRAGMA_OACC_CLAUSE_VECTOR: + c_name = "vector"; + clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_VECTOR, + c_name, clauses); + break; case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH: clauses = cp_parser_oacc_clause_vector_length (parser, clauses); c_name = "vector_length"; @@ -31390,6 +31572,11 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask, clauses = cp_parser_oacc_clause_wait (parser, clauses); c_name = "wait"; break; + case PRAGMA_OACC_CLAUSE_WORKER: + c_name = "worker"; + clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_WORKER, + c_name, clauses); + break; default: cp_parser_error (parser, "expected %<#pragma acc%> clause"); goto saw_error; @@ -34339,6 +34526,11 @@ cp_parser_oacc_kernels (cp_parser *parser, cp_token *pragma_tok) #define OACC_LOOP_CLAUSE_MASK \ ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \ + | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \ | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)) static tree diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 142245a..ffe02da 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17235,7 +17235,9 @@ pack_deducible_p (tree parm, tree fn) DEDUCE_CALL: We are deducing arguments for a function call, as in - [temp.deduct.call]. + [temp.deduct.call]. If RETURN_TYPE is non-null, we are + deducing arguments for a call to the result of a conversion + function template, as in [over.call.object]. DEDUCE_CONV: We are deducing arguments for a conversion function, as in @@ -17402,7 +17404,15 @@ fn_type_unification (tree fn, /* Never do unification on the 'this' parameter. */ parms = skip_artificial_parms_for (fn, TYPE_ARG_TYPES (fntype)); - if (return_type) + if (return_type && strict == DEDUCE_CALL) + { + /* We're deducing for a call to the result of a template conversion + function. The parms we really want are in return_type. */ + if (POINTER_TYPE_P (return_type)) + return_type = TREE_TYPE (return_type); + parms = TYPE_ARG_TYPES (return_type); + } + else if (return_type) { tree *new_args; diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 11315d9..153a970 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5911,6 +5911,31 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) bitmap_set_bit (&firstprivate_head, DECL_UID (t)); goto handle_field_decl; + case OMP_CLAUSE_GANG: + case OMP_CLAUSE_VECTOR: + case OMP_CLAUSE_WORKER: + /* Operand 0 is the num: or length: argument. */ + t = OMP_CLAUSE_OPERAND (c, 0); + if (t == NULL_TREE) + break; + + if (!processing_template_decl) + t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); + OMP_CLAUSE_OPERAND (c, 0) = t; + + if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_GANG) + break; + + /* Ooperand 1 is the gang static: argument. */ + t = OMP_CLAUSE_OPERAND (c, 1); + if (t == NULL_TREE) + break; + + if (!processing_template_decl) + t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); + OMP_CLAUSE_OPERAND (c, 1) = t; + break; + case OMP_CLAUSE_LASTPRIVATE: t = omp_clause_decl_field (OMP_CLAUSE_DECL (c)); if (t) @@ -5965,14 +5990,37 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) OMP_CLAUSE_FINAL_EXPR (c) = t; break; + case OMP_CLAUSE_NUM_TASKS: + case OMP_CLAUSE_NUM_TEAMS: case OMP_CLAUSE_NUM_THREADS: - t = OMP_CLAUSE_NUM_THREADS_EXPR (c); + case OMP_CLAUSE_NUM_GANGS: + case OMP_CLAUSE_NUM_WORKERS: + case OMP_CLAUSE_VECTOR_LENGTH: + t = OMP_CLAUSE_OPERAND (c, 0); if (t == error_mark_node) remove = true; else if (!type_dependent_expression_p (t) && !INTEGRAL_TYPE_P (TREE_TYPE (t))) { - error ("num_threads expression must be integral"); + switch (OMP_CLAUSE_CODE (c)) + { + case OMP_CLAUSE_NUM_TASKS: + error ("%<num_tasks%> expression must be integral"); break; + case OMP_CLAUSE_NUM_TEAMS: + error ("%<num_teams%> expression must be integral"); break; + case OMP_CLAUSE_NUM_THREADS: + error ("%<num_threads%> expression must be integral"); break; + case OMP_CLAUSE_NUM_GANGS: + error ("%<num_gangs%> expression must be integral"); break; + case OMP_CLAUSE_NUM_WORKERS: + error ("%<num_workers%> expression must be integral"); + break; + case OMP_CLAUSE_VECTOR_LENGTH: + error ("%<vector_length%> expression must be integral"); + break; + default: + error ("invalid argument"); + } remove = true; } else @@ -5984,13 +6032,40 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) if (TREE_CODE (t) == INTEGER_CST && tree_int_cst_sgn (t) != 1) { - warning_at (OMP_CLAUSE_LOCATION (c), 0, - "%<num_threads%> value must be positive"); + switch (OMP_CLAUSE_CODE (c)) + { + case OMP_CLAUSE_NUM_TASKS: + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "%<num_tasks%> value must be positive"); + break; + case OMP_CLAUSE_NUM_TEAMS: + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "%<num_teams%> value must be positive"); + break; + case OMP_CLAUSE_NUM_THREADS: + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "%<num_threads%> value must be" + "positive"); break; + case OMP_CLAUSE_NUM_GANGS: + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "%<num_gangs%> value must be positive"); + break; + case OMP_CLAUSE_NUM_WORKERS: + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "%<num_workers%> value must be" + "positive"); break; + case OMP_CLAUSE_VECTOR_LENGTH: + warning_at (OMP_CLAUSE_LOCATION (c), 0, + "%<vector_length%> value must be" + "positive"); break; + default: + error ("invalid argument"); + } t = integer_one_node; } t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); } - OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; + OMP_CLAUSE_OPERAND (c, 0) = t; } break; @@ -6062,35 +6137,6 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) } break; - case OMP_CLAUSE_NUM_TEAMS: - t = OMP_CLAUSE_NUM_TEAMS_EXPR (c); - if (t == error_mark_node) - remove = true; - else if (!type_dependent_expression_p (t) - && !INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - error ("%<num_teams%> expression must be integral"); - remove = true; - } - else - { - t = mark_rvalue_use (t); - if (!processing_template_decl) - { - t = maybe_constant_value (t); - if (TREE_CODE (t) == INTEGER_CST - && tree_int_cst_sgn (t) != 1) - { - warning_at (OMP_CLAUSE_LOCATION (c), 0, - "%<num_teams%> value must be positive"); - t = integer_one_node; - } - t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); - } - OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t; - } - break; - case OMP_CLAUSE_ASYNC: t = OMP_CLAUSE_ASYNC_EXPR (c); if (t == error_mark_node) @@ -6110,16 +6156,6 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) } break; - case OMP_CLAUSE_VECTOR_LENGTH: - t = OMP_CLAUSE_VECTOR_LENGTH_EXPR (c); - t = maybe_convert_cond (t); - if (t == error_mark_node) - remove = true; - else if (!processing_template_decl) - t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); - OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = t; - break; - case OMP_CLAUSE_WAIT: t = OMP_CLAUSE_WAIT_EXPR (c); if (t == error_mark_node) @@ -6547,35 +6583,6 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) } goto check_dup_generic; - case OMP_CLAUSE_NUM_TASKS: - t = OMP_CLAUSE_NUM_TASKS_EXPR (c); - if (t == error_mark_node) - remove = true; - else if (!type_dependent_expression_p (t) - && !INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - error ("%<num_tasks%> expression must be integral"); - remove = true; - } - else - { - t = mark_rvalue_use (t); - if (!processing_template_decl) - { - t = maybe_constant_value (t); - if (TREE_CODE (t) == INTEGER_CST - && tree_int_cst_sgn (t) != 1) - { - warning_at (OMP_CLAUSE_LOCATION (c), 0, - "%<num_tasks%> value must be positive"); - t = integer_one_node; - } - t = fold_build_cleanup_point_expr (TREE_TYPE (t), t); - } - OMP_CLAUSE_NUM_TASKS_EXPR (c) = t; - } - break; - case OMP_CLAUSE_GRAINSIZE: t = OMP_CLAUSE_GRAINSIZE_EXPR (c); if (t == error_mark_node) @@ -6694,6 +6701,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd) case OMP_CLAUSE_SIMD: case OMP_CLAUSE_DEFAULTMAP: case OMP_CLAUSE__CILK_FOR_COUNT_: + case OMP_CLAUSE_AUTO: + case OMP_CLAUSE_SEQ: break; case OMP_CLAUSE_INBRANCH: