diff options
author | Marek Polacek <polacek@redhat.com> | 2020-03-16 10:17:11 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2020-03-24 19:36:20 -0400 |
commit | 75b7b7fdc4597170f24c069ea13aa3e14f37fde7 (patch) | |
tree | 1f95379bc8eea238569ba3cb1f53c3751c8d273e /gcc | |
parent | fddfd3ce555965864b6116cf541f6355d2057d3d (diff) | |
download | gcc-75b7b7fdc4597170f24c069ea13aa3e14f37fde7.zip gcc-75b7b7fdc4597170f24c069ea13aa3e14f37fde7.tar.gz gcc-75b7b7fdc4597170f24c069ea13aa3e14f37fde7.tar.bz2 |
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<long int&>(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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/call.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/conversion/op7.C | 22 |
4 files changed, 36 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f867d0e..4332b07 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2020-03-24 Marek Polacek <polacek@redhat.com> + + 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 <jason@redhat.com> PR c++/94186 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 65a3ea3..bae4b2c 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 858ad07..bd2e45d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-24 Marek Polacek <polacek@redhat.com> + + PR c++/94190 - wrong no post-decrement operator error in template. + * g++.dg/conversion/op7.C: New test. + 2020-03-24 Christophe Lyon <christophe.lyon@linaro.org> * 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 0000000..c6401d1 --- /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<int> void +foo () +{ + b--; + ++b; + --b; + b++; + !b; + ~b; + +b; + -b; +} + +void +bar () +{ + foo<0> (); +} |