From: Marek Polacek Date: Mon, 16 Mar 2020 14:17:11 +0000 (-0400) Subject: c++: Fix wrong no post-decrement operator error in template [PR94190] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=75b7b7fdc4597170f24c069ea13aa3e14f37fde7;p=gcc.git c++: Fix wrong no post-decrement operator error in template [PR94190] Now that convert_like creates an IMPLICIT_CONV_EXPR when it converts something that involves a class in a template, we must be prepared to handle it. In this test, we have a class S and we're converting it to long int& using a user-defined conversion since we're performing -- on it. So cp_build_unary_op/POSTDECREMENT_EXPR calls build_expr_type_conversion which gets the IMPLICIT_CONV_EXPR. Before the convert_like change it got *S::operator long int &(&b) whose type is long int but now it gets IMPLICIT_CONV_EXPR(b) whose type is a reference type. But the !MAYBE_CLASS_TYPE_P switch doesn't handle reference types and so we complain. Fixed by calling convert_from_reference on the result of convert_like. PR c++/94190 - wrong no post-decrement operator error in template. * call.c (convert_like_real): Use convert_from_reference on the result. * g++.dg/conversion/op7.C: New test. --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f867d0e4e1a..4332b07cc5f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2020-03-24 Marek Polacek + + PR c++/94190 - wrong no post-decrement operator error in template. + * call.c (convert_like_real): Use convert_from_reference on the result. + 2020-03-24 Jason Merrill PR c++/94186 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 65a3ea35dee..bae4b2c0f52 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7389,7 +7389,10 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, if (processing_template_decl && convs->kind != ck_identity && (CLASS_TYPE_P (totype) || CLASS_TYPE_P (TREE_TYPE (expr)))) - return build1 (IMPLICIT_CONV_EXPR, totype, expr); + { + expr = build1 (IMPLICIT_CONV_EXPR, totype, expr); + return convs->kind == ck_ref_bind ? expr : convert_from_reference (expr); + } switch (convs->kind) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 858ad070d62..bd2e45dcb2d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-24 Marek Polacek + + PR c++/94190 - wrong no post-decrement operator error in template. + * g++.dg/conversion/op7.C: New test. + 2020-03-24 Christophe Lyon * gcc/arm/vfp-1.c: Use arm_fp__ok effective-target. diff --git a/gcc/testsuite/g++.dg/conversion/op7.C b/gcc/testsuite/g++.dg/conversion/op7.C new file mode 100644 index 00000000000..c6401d109b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/conversion/op7.C @@ -0,0 +1,22 @@ +// PR c++/94190 - wrong no post-decrement operator error in template. + +struct S { operator long & (); } b; + +template void +foo () +{ + b--; + ++b; + --b; + b++; + !b; + ~b; + +b; + -b; +} + +void +bar () +{ + foo<0> (); +}