decl.c (omp_declare_variant_finalize_one): Call declare_simd_adjust_this not just on the context...

* decl.c (omp_declare_variant_finalize_one): Call
	declare_simd_adjust_this not just on the context, but also on the
	variant-id expression for methods.  Don't call
	cp_get_callee_fndecl_nofold, call cp_get_callee and only if it is
	safe cp_get_fndecl_from_callee.  Don't try to print as %qD
	NULL in diagnostics.
	* pt.c (tsubst_attribute): Handle "omp declare variant base"
	attribute.
	(tsubst_function_decl): Call omp_declare_variant_finalize
	if there are any "omp declare variant base" attributes left.

	* g++.dg/gomp/declare-variant-7.C: New test.
	* g++.dg/gomp/declare-variant-8.C: New test.

From-SVN: r277814
This commit is contained in:
Jakub Jelinek 2019-11-05 08:46:03 +01:00
parent 2b13f5a622
commit 80d7f5d322
6 changed files with 204 additions and 5 deletions

View file

@ -1,7 +1,20 @@
2019-11-05 Jakub Jelinek <jakub@redhat.com>
* decl.c (omp_declare_variant_finalize_one): Call
declare_simd_adjust_this not just on the context, but also on the
variant-id expression for methods. Don't call
cp_get_callee_fndecl_nofold, call cp_get_callee and only if it is
safe cp_get_fndecl_from_callee. Don't try to print as %qD
NULL in diagnostics.
* pt.c (tsubst_attribute): Handle "omp declare variant base"
attribute.
(tsubst_function_decl): Call omp_declare_variant_finalize
if there are any "omp declare variant base" attributes left.
2019-11-04 Kamlesh Kumar <kamleshbhalui@gmail.com>
PR c++/91979 - mangling nullptr expression
* cp/mangle.c (write_template_arg_literal): Handle nullptr
* mangle.c (write_template_arg_literal): Handle nullptr
mangling.
2019-11-04 Jason Merrill <jason@redhat.com>

View file

@ -7099,8 +7099,12 @@ static bool
omp_declare_variant_finalize_one (tree decl, tree attr)
{
if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
walk_tree (&TREE_VALUE (TREE_VALUE (attr)), declare_simd_adjust_this,
DECL_ARGUMENTS (decl), NULL);
{
walk_tree (&TREE_VALUE (TREE_VALUE (attr)), declare_simd_adjust_this,
DECL_ARGUMENTS (decl), NULL);
walk_tree (&TREE_PURPOSE (TREE_VALUE (attr)), declare_simd_adjust_this,
DECL_ARGUMENTS (decl), NULL);
}
tree ctx = TREE_VALUE (TREE_VALUE (attr));
tree simd = omp_get_context_selector (ctx, "construct", "simd");
@ -7179,7 +7183,16 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
if (variant == error_mark_node && !processing_template_decl)
return true;
variant = cp_get_callee_fndecl_nofold (variant);
variant = cp_get_callee (variant);
if (variant)
{
if (TREE_CODE (variant) == FUNCTION_DECL)
;
else if (TREE_TYPE (variant) && INDIRECT_TYPE_P (TREE_TYPE (variant)))
variant = cp_get_fndecl_from_callee (variant, false);
else
variant = NULL_TREE;
}
input_location = save_loc;
@ -7211,7 +7224,7 @@ omp_declare_variant_finalize_one (tree decl, tree attr)
}
else if (!processing_template_decl)
{
error_at (varid_loc, "could not find variant %qD declaration", variant);
error_at (varid_loc, "could not find variant declaration");
return true;
}

View file

@ -11119,6 +11119,76 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
else
val = NULL_TREE;
}
else if (flag_openmp
&& is_attribute_p ("omp declare variant base",
get_attribute_name (t)))
{
++cp_unevaluated_operand;
tree varid
= tsubst_expr (TREE_PURPOSE (val), args, complain,
in_decl, /*integral_constant_expression_p=*/false);
--cp_unevaluated_operand;
tree chain = TREE_CHAIN (val);
location_t match_loc = cp_expr_loc_or_input_loc (TREE_PURPOSE (chain));
tree ctx = copy_list (TREE_VALUE (val));
tree simd = get_identifier ("simd");
tree score = get_identifier (" score");
tree condition = get_identifier ("condition");
for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1))
{
const char *set = IDENTIFIER_POINTER (TREE_PURPOSE (t1));
TREE_VALUE (t1) = copy_list (TREE_VALUE (t1));
for (tree t2 = TREE_VALUE (t1); t2; t2 = TREE_CHAIN (t2))
{
if (TREE_PURPOSE (t2) == simd && set[0] == 'c')
{
tree clauses = TREE_VALUE (t2);
clauses = tsubst_omp_clauses (clauses,
C_ORT_OMP_DECLARE_SIMD, args,
complain, in_decl);
c_omp_declare_simd_clauses_to_decls (*decl_p, clauses);
clauses = finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
TREE_VALUE (t2) = clauses;
}
else
{
TREE_VALUE (t2) = copy_list (TREE_VALUE (t2));
for (tree t3 = TREE_VALUE (t2); t3; t3 = TREE_CHAIN (t3))
if (TREE_VALUE (t3))
{
bool allow_string
= ((TREE_PURPOSE (t2) != condition || set[0] != 'u')
&& TREE_PURPOSE (t3) != score);
if (TREE_CODE (t3) == STRING_CST && allow_string)
continue;
tree v = TREE_VALUE (t3);
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))
{
location_t loc
= cp_expr_loc_or_loc (TREE_VALUE (t3),
match_loc);
if (TREE_PURPOSE (t3) == score)
error_at (loc, "score argument must be "
"constant integer expression");
else if (allow_string)
error_at (loc, "property must be constant "
"integer expression or string "
"literal");
else
error_at (loc, "property must be constant "
"integer expression");
return NULL_TREE;
}
TREE_VALUE (t3) = v;
}
}
}
}
val = tree_cons (varid, ctx, chain);
}
/* If the first attribute argument is an identifier, don't
pass it through tsubst. Attributes like mode, format,
cleanup and several target specific attributes expect it
@ -13579,6 +13649,11 @@ tsubst_function_decl (tree t, tree args, tsubst_flags_t complain,
apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0,
args, complain, in_decl);
if (flag_openmp)
if (tree attr = lookup_attribute ("omp declare variant base",
DECL_ATTRIBUTES (r)))
omp_declare_variant_finalize (r, attr);
return r;
}

View file

@ -1,3 +1,8 @@
2019-11-05 Jakub Jelinek <jakub@redhat.com>
* g++.dg/gomp/declare-variant-7.C: New test.
* g++.dg/gomp/declare-variant-8.C: New test.
2019-11-04 Eric Botcazou <ebotcazou@adacore.com>
PR testsuite/92302

View file

@ -0,0 +1,75 @@
// Test parsing of #pragma omp declare variant
// { dg-do compile }
// { dg-additional-options "-fdump-tree-gimple" }
void f01 ();
#pragma omp declare variant (f01) match (user={condition(1)},device={arch(x86_64)})
template <int N>
void f02 ();
void f03 ();
#pragma omp declare variant (f03) match (user={condition(score(N+2):N)})
template <int N>
void f04 ();
template <int N>
void f05 ();
#pragma omp declare variant (f05<N>) match (user={condition((T)N)},implementation={vendor(gnu)})
template <int N, typename T>
void f06 ();
void f07 ();
#pragma omp declare variant (f07) match (user={condition(score(N+2):N)})
template <int N>
void f08 ();
template <int N>
void f09 ();
#pragma omp declare variant (f09<N>) match (user={condition((T) N)})
template <int N, typename T>
void f10 ();
template <int N>
struct S
{
template <typename T>
void f11 (T) {}
#pragma omp declare variant (f11<T>) match (user={condition(score(N):N)})
template <typename T>
void f12 (T) {}
template <typename T>
void f13 (T);
#pragma omp declare variant (f13<T>) match (user={condition(score(N):N)})
template <typename T>
void f14 (T);
int s;
};
template <int N>
struct T
{
template <typename T>
void f15 (T) {}
#pragma omp declare variant (f15<T>) match (user={condition(score(N):N)})
template <typename T>
void f16 (T) {}
template <typename T>
void f17 (T);
#pragma omp declare variant (f17<T>) match (user={condition(score(N):N)})
template <typename T>
void f18 (T);
int t;
};
void
test ()
{
f02<1> (); // { dg-final { scan-tree-dump-times "f01 \\\(\\\);" 1 "gimple" { target { { i?86-*-* x86_64-*-* } && lp64 } } } }
// { dg-final { scan-tree-dump-times "f02<1> \\\(\\\);" 1 "gimple" { target { { i?86-*-* x86_64-*-* } && { ! lp64 } } } } }
// { dg-final { scan-tree-dump-times "f02<1> \\\(\\\);" 1 "gimple" { target { ! { i?86-*-* x86_64-*-* } } } } }
f04<1> (); // { dg-final { scan-tree-dump-times "f03 \\\(\\\);" 1 "gimple" } }
f06<1, long> (); // { dg-final { scan-tree-dump-times "f05<1> \\\(\\\);" 1 "gimple" } }
f08<0> (); // { dg-final { scan-tree-dump-times "f08<0> \\\(\\\);" 1 "gimple" } }
f10<0, short int> (); // { dg-final { scan-tree-dump-times "f10<0, short int> \\\(\\\);" 1 "gimple" } }
S<1> s;
s.f12 (0); // { dg-final { scan-tree-dump-times "S<1>::f11<int> \\\(&s, 0\\\);" 1 "gimple" } }
s.f12 (0.0); // { dg-final { scan-tree-dump-times "S<1>::f11<double> \\\(&s, 0.0\\\);" 1 "gimple" } }
s.f14 (0LL); // { dg-final { scan-tree-dump-times "S<1>::f13<long long int> \\\(&s, 0\\\);" 1 "gimple" } }
T<0> t;
t.f16 (s); // { dg-final { scan-tree-dump-times "T<0>::f16<S<1> > \\\(&t, s\\\);" 1 "gimple" } }
t.f18 (s); // { dg-final { scan-tree-dump-times "T<0>::f18<S<1> > \\\(&t, s\\\);" 1 "gimple" } }
}

View file

@ -0,0 +1,18 @@
// Test parsing of #pragma omp declare variant
// { dg-do compile }
void f01 ();
#pragma omp declare variant (f01) match (user={condition((T) 1)}) // { dg-error "property must be constant integer expression" }
template <typename T>
void f02 ();
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
test ()
{
f02 <double> ();
f04 <float> ();
}