summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-24 16:31:31 +0000
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2003-04-24 16:31:31 +0000
commit72ea5dfc190eaf7ea3b04424feb7dbd4a6746fab (patch)
tree088ee373a82de7795017a0da0ea79afd28588cd0
parent5e69cae432c7787c9fc61e8b4ac3a04ddbc2b9b9 (diff)
downloadgcc-72ea5dfc190eaf7ea3b04424feb7dbd4a6746fab.tar.gz
cp:
PR c++/10337 * call.c (joust): Don't warn about conversion ops that are exact or cv-conversions. Rearrange to avoid multiple type comparisons. testsuite: PR c++/10337 * g++.dg/warn/conv1.C: New test. * g++.old-deja/g++.other/conv7.C: Adjust. * g++.old-deja/g++.other/overload14.C: Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66038 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c75
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/warn/conv1.C33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/conv7.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/overload14.C2
6 files changed, 89 insertions, 36 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 37955beae7b..403a6427017 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2003-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10337
+ * call.c (joust): Don't warn about conversion ops that are exact
+ or cv-conversions. Rearrange to avoid multiple type comparisons.
+
2003-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/10471
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 200aae721e7..ed97bcb95ec 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5757,44 +5757,51 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
either between a constructor and a conversion op, or between two
conversion ops. */
if (winner && cand1->second_conv
- && ((DECL_CONSTRUCTOR_P (cand1->fn)
- != DECL_CONSTRUCTOR_P (cand2->fn))
- /* Don't warn if the two conv ops convert to the same type... */
- || (! DECL_CONSTRUCTOR_P (cand1->fn)
- && ! same_type_p (TREE_TYPE (TREE_TYPE (cand1->fn)),
- TREE_TYPE (TREE_TYPE (cand2->fn))))))
- {
- int comp = compare_ics (cand1->second_conv, cand2->second_conv);
- if (comp != winner)
+ && (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn))
+ && winner != compare_ics (cand1->second_conv, cand2->second_conv))
+ {
+ struct z_candidate *w, *l;
+ bool give_warning = false;
+
+ if (winner == 1)
+ w = cand1, l = cand2;
+ else
+ w = cand2, l = cand1;
+
+ /* We don't want to complain about `X::operator T1 ()'
+ beating `X::operator T2 () const', when T2 is a no less
+ cv-qualified version of T1. */
+ if (DECL_CONTEXT (w->fn) == DECL_CONTEXT (l->fn)
+ && !DECL_CONSTRUCTOR_P (w->fn) && !DECL_CONSTRUCTOR_P (l->fn))
{
- struct z_candidate *w, *l;
- tree convn;
- if (winner == 1)
- w = cand1, l = cand2;
- else
- w = cand2, l = cand1;
- if (DECL_CONTEXT (cand1->fn) == DECL_CONTEXT (cand2->fn)
- && ! DECL_CONSTRUCTOR_P (cand1->fn)
- && ! DECL_CONSTRUCTOR_P (cand2->fn)
- && (convn = standard_conversion
- (TREE_TYPE (TREE_TYPE (l->fn)),
- TREE_TYPE (TREE_TYPE (w->fn)), NULL_TREE))
- && TREE_CODE (convn) == QUAL_CONV)
- /* Don't complain about `operator char *()' beating
- `operator const char *() const'. */;
- else if (warn)
+ tree t = TREE_TYPE (TREE_TYPE (l->fn));
+ tree f = TREE_TYPE (TREE_TYPE (w->fn));
+
+ if (TREE_CODE (t) == TREE_CODE (f) && POINTER_TYPE_P (t))
{
- tree source = source_type (TREE_VEC_ELT (w->convs, 0));
- if (! DECL_CONSTRUCTOR_P (w->fn))
- source = TREE_TYPE (source);
- warning ("choosing `%D' over `%D'", w->fn, l->fn);
- warning (" for conversion from `%T' to `%T'",
- source, TREE_TYPE (w->second_conv));
- warning (" because conversion sequence for the argument is better");
+ t = TREE_TYPE (t);
+ f = TREE_TYPE (f);
}
- else
- add_warning (w, l);
+ if (!comp_ptr_ttypes (t, f))
+ give_warning = true;
+ }
+ else
+ give_warning = true;
+
+ if (!give_warning)
+ /*NOP*/;
+ else if (warn)
+ {
+ tree source = source_type (TREE_VEC_ELT (w->convs, 0));
+ if (! DECL_CONSTRUCTOR_P (w->fn))
+ source = TREE_TYPE (source);
+ warning ("choosing `%D' over `%D'", w->fn, l->fn);
+ warning (" for conversion from `%T' to `%T'",
+ source, TREE_TYPE (w->second_conv));
+ warning (" because conversion sequence for the argument is better");
}
+ else
+ add_warning (w, l);
}
if (winner)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3195c2f56a3..303bbbc79e7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2003-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10337
+ * g++.dg/warn/conv1.C: New test.
+ * g++.old-deja/g++.other/conv7.C: Adjust.
+ * g++.old-deja/g++.other/overload14.C: Adjust.
+
2003-04-23 Mark Mitchell <mark@codesourcery.com>
PR c++/10471
diff --git a/gcc/testsuite/g++.dg/warn/conv1.C b/gcc/testsuite/g++.dg/warn/conv1.C
new file mode 100644
index 00000000000..d06cbd5863e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/conv1.C
@@ -0,0 +1,33 @@
+// { dg-do compile }
+
+// Copyright (C) 2003 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 20 Apr 2003 <nathan@codesourcery.com>
+
+// PR 10337, unneeded warning
+
+class A {
+ public:
+ A() {}
+};
+
+class B : public A {
+ public:
+ B() {}
+ void operator=(const A& b) {}
+ void operator=(const B& b) {}
+};
+
+class C {
+ public:
+ C() {}
+ operator B &() { return _b; }
+ operator const B &() const { return _b; }
+
+ B _b;
+};
+
+int main() {
+ B b;
+ C c;
+ b = c;
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/conv7.C b/gcc/testsuite/g++.old-deja/g++.other/conv7.C
index 0a7e76dfe3f..8bb534c2263 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/conv7.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/conv7.C
@@ -40,6 +40,6 @@ yyparse()
{
iterator_template<IdlDeclarator_bar,IdlDeclarator_bar&,foo*,foo*> declIter;
- const IdlDeclarator& declarator = *declIter; // WARNING - choosing
+ const IdlDeclarator& declarator = *declIter;
return 1;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/overload14.C b/gcc/testsuite/g++.old-deja/g++.other/overload14.C
index 8938ef1d7d4..6ef73a6f3e6 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/overload14.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/overload14.C
@@ -26,6 +26,6 @@ A::operator A::B ()
int main ()
{
- (A::C) A (); // WARNING -
+ (A::C) A ();
return 0;
}