+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>
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");
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;
}
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;
}
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
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;
}
+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
--- /dev/null
+// 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" } }
+}
--- /dev/null
+// 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> ();
+}