aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2024-12-23 19:57:56 -0500
committerJason Merrill <jason@redhat.com>2025-01-08 16:34:58 -0500
commitdd3f3c71df66ed6fd3872ab780f5813831100d1c (patch)
tree340d2b2733ba7b87e2eaeede49508c175594cee2
parent7eec6fedf457883adc8222b2f4a3230311f8f25f (diff)
downloadgcc-dd3f3c71df66ed6fd3872ab780f5813831100d1c.zip
gcc-dd3f3c71df66ed6fd3872ab780f5813831100d1c.tar.gz
gcc-dd3f3c71df66ed6fd3872ab780f5813831100d1c.tar.bz2
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.
-rw-r--r--gcc/cp/call.cc1
-rw-r--r--gcc/cp/coroutines.cc4
-rw-r--r--gcc/cp/decl.cc9
-rw-r--r--gcc/testsuite/g++.dg/gomp/declare-variant-3.C4
-rw-r--r--gcc/testsuite/g++.dg/gomp/declare-variant-5.C4
5 files changed, 9 insertions, 13 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 810594f..47a1251 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 18d217b..1dee3d2 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 503ecd9..288da65 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 8044cef..376eefc 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 fa80c25..a52fa52 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);