On Tue, Sep 18, 2018 at 11:47 PM, Marek Polacek <pola...@redhat.com> wrote: > As I mentioned in the PR, [class.conv.fct] says "A conversion function is > never > used to convert a (possibly cv-qualified) object to the (possibly > cv-qualified) > same object type (or a reference to it), to a (possibly cv-qualified) base > class > of that type (or a reference to it), or to (possibly cv-qualified) void." but > I > noticed we weren't warning about > > struct X { > operator X(); > }; > > (and there are no tests for this case) because comparing types directly only > works for TYPE_CANONICAL, otherwise we have to use same_type_*. > > I'm also changing the warning about 'void' since we can't form a reference to > void. > > I'll also note that I think we should warn about this by default, not only > when -Wconversion is in effect.
Agreed, this should get a new flag that is on by default. > Bootstrapped/regtested on x86_64-linux, ok for trunk? OK. > 2018-09-18 Marek Polacek <pola...@redhat.com> > > PR c++/87357 - missing -Wconversion warning > * decl.c (grok_op_properties): Remove diagnostic parts mentioning > a conversion to a reference to void. Use > same_type_ignoring_top_level_qualifiers_p rather than comparing types > directly. > > * g++.dg/warn/Wconversion5.C: New test. > > diff --git gcc/cp/decl.c gcc/cp/decl.c > index 827c1720335..503b433cbd1 100644 > --- gcc/cp/decl.c > +++ gcc/cp/decl.c > @@ -13553,15 +13553,11 @@ grok_op_properties (tree decl, bool complain) > t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); > > if (VOID_TYPE_P (t)) > - warning_at (loc, OPT_Wconversion, > - ref > - ? G_("conversion to a reference to void " > - "will never use a type conversion operator") > - : G_("conversion to void " > - "will never use a type conversion operator")); > + warning_at (loc, OPT_Wconversion, "conversion to void " > + "will never use a type conversion operator"); > else if (class_type) > { > - if (t == class_type) > + if (same_type_ignoring_top_level_qualifiers_p (t, class_type)) > warning_at (loc, OPT_Wconversion, > ref > ? G_("conversion to a reference to the same type " > diff --git gcc/testsuite/g++.dg/warn/Wconversion5.C > gcc/testsuite/g++.dg/warn/Wconversion5.C > index e69de29bb2d..00b1ddab188 100644 > --- gcc/testsuite/g++.dg/warn/Wconversion5.C > +++ gcc/testsuite/g++.dg/warn/Wconversion5.C > @@ -0,0 +1,20 @@ > +// PR c++/87357 > +// { dg-do compile } > +// { dg-options "-Wconversion" } > + > +struct B { }; > + > +struct X : public B { > + operator X(); // { dg-warning "3:conversion to the same type will never > use a type conversion operator" } > + operator X&(); // { dg-warning "3:conversion to a reference to the same > type will never use a type conversion operator" } > + operator X() const; // { dg-warning "3:conversion to the same type will > never use a type conversion operator" } > + operator const X(); // { dg-warning "3:conversion to the same type will > never use a type conversion operator" } > + > + operator B(); // { dg-warning "3:conversion to a base class will never use > a type conversion operator" } > + operator B&(); // { dg-warning "3:conversion to a reference to a base > class will never use a type conversion operator" } > + operator B() const; // { dg-warning "3:conversion to a base class will > never use a type conversion operator" } > + operator const B(); // { dg-warning "3:conversion to a base class will > never use a type conversion operator" } > + > + operator void(); // { dg-warning "3:conversion to void will never use a > type conversion operator" } > + operator void() const; // { dg-warning "3:conversion to void will never > use a type conversion operator" } > +};