https://gcc.gnu.org/g:dd3f3c71df66ed6fd3872ab780f5813831100d1c
commit r15-6707-gdd3f3c71df66ed6fd3872ab780f5813831100d1c Author: Jason Merrill <ja...@redhat.com> Date: Mon Dec 23 19:57:56 2024 -0500 c++: fix conversion issues Some issues caught by a check from another patch: In the convert_like_internal bad_p handling, we are iterating from outside to inside, so once we recurse into convert_like we need to stop looping. In build_ramp_function, we're assigning REFERENCE_TYPE things, so we need to build the assignment directly rather than rely on functions that implement C++ semantics. In omp_declare_variant_finalize_one, the parameter object building failed to handle reference parms, and it seems simpler to just use build_stub_object like other parts of the compiler. gcc/cp/ChangeLog: * call.cc (convert_like_internal): Add missing break. * coroutines.cc (cp_coroutine_transform::build_ramp_function): Build INIT_EXPR directly. * decl.cc (omp_declare_variant_finalize_one): Use build_stub_object. gcc/testsuite/ChangeLog: * g++.dg/gomp/declare-variant-3.C: Don't depend on expr dump. * g++.dg/gomp/declare-variant-5.C: Likewise. Diff: --- gcc/cp/call.cc | 1 + gcc/cp/coroutines.cc | 4 ++-- gcc/cp/decl.cc | 9 ++------- gcc/testsuite/g++.dg/gomp/declare-variant-3.C | 4 ++-- gcc/testsuite/g++.dg/gomp/declare-variant-5.C | 4 ++-- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index 810594f40e18..47a125120241 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -8581,6 +8581,7 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum, /*issue_conversion_warnings=*/false, /*c_cast_p=*/false, /*nested_p=*/true, complain); + break; } else if (t->kind == ck_user || !t->bad_p) { diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index 18d217b0c64a..1dee3d25b9b4 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -5021,8 +5021,8 @@ cp_coroutine_transform::build_ramp_function () if (parm.rv_ref || parm.pt_ref) /* Initialise the frame reference field directly. */ - r = cp_build_modify_expr (loc, TREE_OPERAND (fld_idx, 0), - INIT_EXPR, arg, tf_warning_or_error); + r = build2 (INIT_EXPR, TREE_TYPE (arg), + TREE_OPERAND (fld_idx, 0), arg); else { r = forward_parm (arg); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 503ecd9387e8..288da65fd8db 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -8466,12 +8466,7 @@ omp_declare_variant_finalize_one (tree decl, tree attr) if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) parm = DECL_CHAIN (parm); for (; parm; parm = DECL_CHAIN (parm)) - if (type_dependent_expression_p (parm)) - vec_safe_push (args, build_constructor (TREE_TYPE (parm), NULL)); - else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (parm))) - vec_safe_push (args, build_local_temp (TREE_TYPE (parm))); - else - vec_safe_push (args, build_zero_cst (TREE_TYPE (parm))); + vec_safe_push (args, build_stub_object (TREE_TYPE (parm))); unsigned nappend_args = 0; tree append_args_list = TREE_CHAIN (TREE_CHAIN (chain)); @@ -8502,7 +8497,7 @@ omp_declare_variant_finalize_one (tree decl, tree attr) return true; } for (unsigned i = 0; i < nappend_args; i++) - vec_safe_push (args, build_zero_cst (TREE_TYPE (type))); + vec_safe_push (args, build_stub_object (TREE_TYPE (type))); } } diff --git a/gcc/testsuite/g++.dg/gomp/declare-variant-3.C b/gcc/testsuite/g++.dg/gomp/declare-variant-3.C index 8044cef91f20..376eefc2dc1f 100644 --- a/gcc/testsuite/g++.dg/gomp/declare-variant-3.C +++ b/gcc/testsuite/g++.dg/gomp/declare-variant-3.C @@ -86,7 +86,7 @@ struct E { int e; }; void fn19 (E, int); -#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error "could not convert '0' from 'int' to 'E'" } +#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error {could not convert '[^']*' from 'int' to 'E'} } void fn20 (int, E); struct F { operator int () const { return 42; } int f; }; @@ -95,7 +95,7 @@ void fn21 (int, F); #pragma omp declare variant ( fn21 ) match (user = { condition ( 1 - 1 ) } ) // { dg-error "variant 'void fn21\\\(int, F\\\)' and base 'void fn22\\\(F, F\\\)' have incompatible types" } void fn22 (F, F); -#pragma omp declare variant (fn19) match (user={condition(0)}) // { dg-error "could not convert '<anonymous>' from 'F' to 'E'" } +#pragma omp declare variant (fn19) match (user={condition(0)}) // { dg-error {could not convert '[^']*' from 'F' to 'E'} } void fn23 (F, int); void fn24 (int); diff --git a/gcc/testsuite/g++.dg/gomp/declare-variant-5.C b/gcc/testsuite/g++.dg/gomp/declare-variant-5.C index fa80c255c814..a52fa528e1ff 100644 --- a/gcc/testsuite/g++.dg/gomp/declare-variant-5.C +++ b/gcc/testsuite/g++.dg/gomp/declare-variant-5.C @@ -74,7 +74,7 @@ struct E { int e; }; void fn19 (E, int) {} -#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error "could not convert '0' from 'int' to 'E'" } +#pragma omp declare variant (fn19)match(user={condition(0)}) // { dg-error {could not convert '[^']*' from 'int' to 'E'} } void fn20 (int, E) {} struct F { operator int () const { return 42; } int f; }; @@ -83,7 +83,7 @@ void fn21 (int, F) {} #pragma omp declare variant ( fn21 ) match (user = { condition ( 1 - 1 ) } ) // { dg-error "variant 'void fn21\\\(int, F\\\)' and base 'void fn22\\\(F, F\\\)' have incompatible types" } void fn22 (F, F) {} -#pragma omp declare variant (fn19) match (user={condition(0)}) // { dg-error "could not convert '<anonymous>' from 'F' to 'E'" } +#pragma omp declare variant (fn19) match (user={condition(0)}) // { dg-error {could not convert '[^']*' from 'F' to 'E'} } void fn23 (F, int) {} void fn24 (int);