mirror of
https://forge.sourceware.org/marek/gcc.git
synced 2026-02-22 20:01:31 -05:00
c++: reference cast, conversion fn [PR113141]
The second testcase in 113141 is a separate issue: we first decide that the conversion is ill-formed, but then when recalculating the special c_cast_p handling makes us think it's OK. We don't want that, it should continue to fall back to the reinterpret_cast interpretation. And while we're here, let's warn that we're not using the conversion function. Note that the standard seems to say that in this case we should treat (Matrix &) as const_cast<Matrix &>(static_cast<const Matrix &>(X)), which would use the conversion operator, but that doesn't match existing practice, so let's resolve that another day. I've raised this issue with CWG; at the moment I lean toward never binding a temporary in a C-style cast to reference type, which would also be a change from existing practice. PR c++/113141 gcc/c-family/ChangeLog: * c.opt: Add -Wcast-user-defined. gcc/ChangeLog: * doc/invoke.texi: Document -Wcast-user-defined. gcc/cp/ChangeLog: * call.cc (reference_binding): For an invalid cast, warn and don't recalculate. gcc/testsuite/ChangeLog: * g++.dg/conversion/ref12.C: New test. Co-authored-by: Patrick Palka <ppalka@redhat.com>
This commit is contained in:
@@ -514,6 +514,10 @@ Wcast-qual
|
||||
C ObjC C++ ObjC++ Var(warn_cast_qual) Warning
|
||||
Warn about casts which discard qualifiers.
|
||||
|
||||
Wcast-user-defined
|
||||
C++ ObjC++ Var(warn_cast_user_defined) Warning Init(1)
|
||||
Warn about a cast to reference type that does not use a related user-defined conversion function.
|
||||
|
||||
Wcatch-value
|
||||
C++ ObjC++ Warning Alias(Wcatch-value=, 1, 0)
|
||||
Warn about catch handlers of non-reference type.
|
||||
|
||||
@@ -2034,7 +2034,17 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
|
||||
recalculate the second conversion sequence. */
|
||||
for (conversion *t = conv; t; t = next_conversion (t))
|
||||
if (t->kind == ck_user
|
||||
&& DECL_CONV_FN_P (t->cand->fn))
|
||||
&& c_cast_p && !maybe_valid_p)
|
||||
{
|
||||
if (complain & tf_warning)
|
||||
warning (OPT_Wcast_user_defined,
|
||||
"casting %qT to %qT does not use %qD",
|
||||
from, rto, t->cand->fn);
|
||||
/* Don't let recalculation try to make this valid. */
|
||||
break;
|
||||
}
|
||||
else if (t->kind == ck_user
|
||||
&& DECL_CONV_FN_P (t->cand->fn))
|
||||
{
|
||||
tree ftype = TREE_TYPE (TREE_TYPE (t->cand->fn));
|
||||
/* A prvalue of non-class type is cv-unqualified. */
|
||||
|
||||
@@ -9391,6 +9391,19 @@ In a cast involving pointer to member types this warning warns whenever
|
||||
the type cast is changing the pointer to member type.
|
||||
This warning is enabled by @option{-Wextra}.
|
||||
|
||||
@opindex Wcast-user-defined
|
||||
@opindex Wno-cast-user-defined
|
||||
@item -Wcast-user-defined
|
||||
Warn when a cast to reference type does not involve a user-defined
|
||||
conversion that the programmer might expect to be called.
|
||||
|
||||
@smallexample
|
||||
struct A @{ operator const int&(); @} a;
|
||||
auto r = (int&)a; // warning
|
||||
@end smallexample
|
||||
|
||||
This warning is enabled by default.
|
||||
|
||||
@opindex Wwrite-strings
|
||||
@opindex Wno-write-strings
|
||||
@item -Wwrite-strings
|
||||
|
||||
20
gcc/testsuite/g++.dg/conversion/ref12.C
Normal file
20
gcc/testsuite/g++.dg/conversion/ref12.C
Normal file
@@ -0,0 +1,20 @@
|
||||
// PR c++/113141
|
||||
|
||||
struct Matrix { };
|
||||
|
||||
struct TPoint3 { private: operator const Matrix(); };
|
||||
|
||||
void f(Matrix&);
|
||||
|
||||
int main() {
|
||||
TPoint3 X;
|
||||
Matrix& m = (Matrix &)X; // { dg-warning "does not use" }
|
||||
f((Matrix &)X); // { dg-warning "does not use" }
|
||||
}
|
||||
|
||||
struct A { private: operator const int&(); } a;
|
||||
int &r = (int&)a; // { dg-warning "does not use" }
|
||||
|
||||
struct B { B(int); };
|
||||
int i;
|
||||
B &br = (B&)i; // { dg-warning "does not use" }
|
||||
Reference in New Issue
Block a user