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. Bootstrapped/regtested on x86_64-linux, ok for trunk? 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" } +};