Hi! We've also agreed that score arguments need to be non-negative.
Implemented thusly, bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk. 2019-11-14 Jakub Jelinek <ja...@redhat.com> * c-parser.c (c_parser_omp_context_selector): Don't require score argument to fit into shwi, just to be INTEGER_CST. Diagnose negative score. * parser.c (cp_parser_omp_context_selector): Don't require score argument to fit into shwi, just to be INTEGER_CST. Diagnose negative score. * pt.c (tsubst_attribute): Likewise. * c-c++-common/gomp/declare-variant-2.c: Add test for non-integral score and for negative score. * c-c++-common/gomp/declare-variant-3.c: Add test for zero score. * g++.dg/gomp/declare-variant-8.C: Add test for negative and zero scores. --- gcc/c/c-parser.c.jj 2019-11-13 12:41:14.625947998 +0100 +++ gcc/c/c-parser.c 2019-11-13 14:12:45.650550207 +0100 @@ -19594,9 +19594,12 @@ c_parser_omp_context_selector (c_parser mark_exp_read (score); score = c_fully_fold (score, false, NULL); if (!INTEGRAL_TYPE_P (TREE_TYPE (score)) - || !tree_fits_shwi_p (score)) + || TREE_CODE (score) != INTEGER_CST) error_at (token->location, "score argument must be " "constant integer expression"); + else if (tree_int_cst_sgn (score) < 0) + error_at (token->location, "score argument must be " + "non-negative"); else properties = tree_cons (get_identifier (" score"), score, properties); --- gcc/cp/parser.c.jj 2019-11-13 13:35:50.337188794 +0100 +++ gcc/cp/parser.c 2019-11-13 14:16:48.423864195 +0100 @@ -40565,11 +40565,16 @@ cp_parser_omp_context_selector (cp_parse if (score != error_mark_node) { score = fold_non_dependent_expr (score); - if (!value_dependent_expression_p (score) - && (!INTEGRAL_TYPE_P (TREE_TYPE (score)) - || !tree_fits_shwi_p (score))) + if (value_dependent_expression_p (score)) + properties = tree_cons (get_identifier (" score"), + score, properties); + else if (!INTEGRAL_TYPE_P (TREE_TYPE (score)) + || TREE_CODE (score) != INTEGER_CST) error_at (token->location, "score argument must be " "constant integer expression"); + else if (tree_int_cst_sgn (score) < 0) + error_at (token->location, "score argument must be " + "non-negative"); else properties = tree_cons (get_identifier (" score"), score, properties); --- gcc/cp/pt.c.jj 2019-11-13 13:47:08.181894187 +0100 +++ gcc/cp/pt.c 2019-11-13 14:20:48.433220170 +0100 @@ -11172,7 +11172,9 @@ tsubst_attribute (tree t, tree *decl_p, v = tsubst_expr (v, args, complain, in_decl, true); v = fold_non_dependent_expr (v); if (!INTEGRAL_TYPE_P (TREE_TYPE (v)) - || !tree_fits_shwi_p (v)) + || (TREE_PURPOSE (t3) == score + ? TREE_CODE (v) != INTEGER_CST + : !tree_fits_shwi_p (v))) { location_t loc = cp_expr_loc_or_loc (TREE_VALUE (t3), @@ -11189,6 +11191,16 @@ tsubst_attribute (tree t, tree *decl_p, "integer expression"); return NULL_TREE; } + else if (TREE_PURPOSE (t3) == score + && tree_int_cst_sgn (v) < 0) + { + location_t loc + = cp_expr_loc_or_loc (TREE_VALUE (t3), + match_loc); + error_at (loc, "score argument must be " + "non-negative"); + return NULL_TREE; + } TREE_VALUE (t3) = v; } } --- gcc/testsuite/c-c++-common/gomp/declare-variant-2.c.jj 2019-11-13 14:27:37.000000000 +0100 +++ gcc/testsuite/c-c++-common/gomp/declare-variant-2.c 2019-11-13 14:58:08.550213556 +0100 @@ -153,3 +153,7 @@ void f74 (void); void f75 (void); #pragma omp declare variant (f1) match(implementation={atomic_default_mem_order("relaxed")}) /* { dg-error "expected identifier before string constant" } */ void f76 (void); +#pragma omp declare variant (f1) match(user={condition(score(&f76):1)}) /* { dg-error "score argument must be constant integer expression" "" { target { ! c++98_only } } } */ +void f77 (void); /* { dg-error "cannot appear in a constant-expression" "" { target c++98_only } .-1 } */ +#pragma omp declare variant (f1) match(user={condition(score(-130):1)}) /* { dg-error "score argument must be non-negative" } */ +void f78 (void); --- gcc/testsuite/c-c++-common/gomp/declare-variant-3.c.jj 2019-11-13 14:03:04.100379844 +0100 +++ gcc/testsuite/c-c++-common/gomp/declare-variant-3.c 2019-11-13 14:51:25.514331617 +0100 @@ -147,3 +147,5 @@ void f76 (void); void f77 (void); #pragma omp declare variant (f13) match (implementation={vendor(nvidia)}) void f78 (void); +#pragma omp declare variant (f13) match (user={condition(score(0):0)}) +void f79 (void); --- gcc/testsuite/g++.dg/gomp/declare-variant-8.C.jj 2019-11-05 08:40:54.489135162 +0100 +++ gcc/testsuite/g++.dg/gomp/declare-variant-8.C 2019-11-13 14:58:23.317989388 +0100 @@ -9,10 +9,20 @@ void f03 (); #pragma omp declare variant (f03) match (user={condition(score((T) 1):1)}) // { dg-error "score argument must be constant integer expression" } template <typename T> void f04 (); +void f05 (); +#pragma omp declare variant (f05) match (user={condition(score(N):1)}) // { dg-error "score argument must be non-negative" } +template <int N> +void f06 (); +void f07 (); +#pragma omp declare variant (f05) match (user={condition(score(N):1)}) +template <int N> +void f08 (); void test () { f02 <double> (); f04 <float> (); + f06 <-1> (); + f08 <0> (); } Jakub