* [C++ PATCH] [PR8271] Check cv-quals of methods while unifying
@ 2004-07-07 4:49 Giovanni Bajo
2004-07-07 18:22 ` Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Giovanni Bajo @ 2004-07-07 4:49 UTC (permalink / raw)
To: gcc-patches; +Cc: Jason Merrill
Hello,
the following testcase is invalid and incorrectly accepted by GCC right now:
------------------------------------------
struct A {
void foo(void) const;
};
template <class T>
void bar(void (T::*)(void)) {}
int main() {
bar(&A::foo);
}
------------------------------------------
I discussed the validity of this with Jason on IRC, and we agree that it is
indeed invalid. The relevant pass seems to be 9.3.1/3 where the standard says
the cv-qualifiers of member functions affect both the implicit pointer-to-this
in the argument list *and* the function type.
So, if we try to unify "void (A::*)(void) const" and "void (T::*)(void)", we
ultimately must try to unify the function types: the return type and argument
list types can be obviously unified (including the implicit this pointer: we
can deduce "const A*" from "T*" with T=const A), but the whole function type
cannot because of the cv-quals. In fact, the function type of &A::foo is "void
(*)(void) const", which is different from "void (*)(void)". Another way to
approacching this is with an obvious analogy with pointer-to-members:
unification of "const int A::*" and "int T::*" must obviously fail.
Currently, GCC unifies the function types using type_unification_real (plus
manually handling the return type). This handles only a part of the problem,
because unification of pointers-to-this with different cv-quals is allowed in
some cases (as already mentioned: "T*" and "const A*" can be unified). So my
patch explicitly tests cv-quals of methods and makes the unification fails if
they don't match.
This patch has been tested on i686-pc-linux-gnu with no new regressions. I
discussed a little with Jason whether we want to patch
build_method_type_directly to copy the cv-quals within the METHOD_TYPE node.
This would avoid that ugly chain of macros in my patch (and other parts of the
frontend) to access them. I tried patching it but there were fallouts in
cp/mangle.c and similar, so I did not bother at this point.
OK for mainline?
Giovanni Bajo
cp/
PR c++/8271
* pt.c (unify) <METHOD_TYPE>: Check if cv-qualifiers match.
testsuite/
PR c++/8271
* g++.dg/template/ptrmem11.C: New test.
Index: pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.876
diff -c -3 -p -r1.876 pt.c
*** pt.c 26 Jun 2004 21:11:19 -0000 1.876
--- pt.c 7 Jul 2004 02:44:22 -0000
*************** unify (tree tparms, tree targs, tree par
*** 9961,9966 ****
--- 9970,10002 ----
return 0;
case METHOD_TYPE:
+ if (TREE_CODE (arg) != TREE_CODE (parm))
+ return 1;
+
+ /* CV qualifications for methods can never be deduced, they
+ must match exactly. Consider this:
+
+ struct A {
+ void foo(void) const;
+ }
+ template <class T> void bar(void (T::*)(void));
+
+ If we try to call "bar(&A::foo)", the call must fail (just
+ like we cannot unify "int A::*" with "const int A::*"). But
+ if we do not check explicitly for this situation, we would
+ call type_unification_real, which would try to unify the
+ implicit pointer-to-this in the parameter list of the argument
+ ("const A*") to the one in the parameter ("T*"). This would
+ succeed with "T = const A" (as we allow less qualifiers in
+ the template parameter), but it is wrong. */
+ if (!check_cv_quals_for_unify
+ (strict_in,
+ TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (arg))),
+ TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (parm)))))
+ return 1;
+
+ /* fall-through. */
+
case FUNCTION_TYPE:
if (TREE_CODE (arg) != TREE_CODE (parm))
return 1;
// { dg-do compile }
// Origin: Wolfgang Bangerth <bangerth at ticam dot utexas dot edu>
// and Rene Fonseca <fonseca at mip dot sdu dot dk>
// PR c++/8271: Check cv-qualifiers while unifying pointer to member
// functions.
struct MyClass {
void mMethod() throw() {}
void cMethod() const throw() {}
void vMethod() volatile throw() {}
void cvMethod() const volatile throw() {}
};
template<class CLASS>
void mFunction(void (CLASS::* method)()) {}
template<class CLASS>
void cFunction(void (CLASS::* method)() const) {}
template<class CLASS>
void vFunction(void (CLASS::* method)() volatile) {}
template<class CLASS>
void cvFunction(void (CLASS::* method)() const volatile) {}
int main() {
mFunction(&MyClass::mMethod);
mFunction(&MyClass::cMethod); // { dg-error "no matching function" }
mFunction(&MyClass::vMethod); // { dg-error "no matching function" }
mFunction(&MyClass::cvMethod); // { dg-error "no matching function" }
cFunction(&MyClass::mMethod); // { dg-error "no matching function" }
cFunction(&MyClass::cMethod);
cFunction(&MyClass::vMethod); // { dg-error "no matching function" }
cFunction(&MyClass::cvMethod); // { dg-error "no matching function" }
vFunction(&MyClass::mMethod); // { dg-error "no matching function" }
vFunction(&MyClass::cMethod); // { dg-error "no matching function" }
vFunction(&MyClass::vMethod);
vFunction(&MyClass::cvMethod); // { dg-error "no matching function" }
cvFunction(&MyClass::mMethod); // { dg-error "no matching function" }
cvFunction(&MyClass::cMethod); // { dg-error "no matching function" }
cvFunction(&MyClass::vMethod); // { dg-error "no matching function" }
cvFunction(&MyClass::cvMethod);
return 0;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [C++ PATCH] [PR8271] Check cv-quals of methods while unifying
2004-07-07 4:49 [C++ PATCH] [PR8271] Check cv-quals of methods while unifying Giovanni Bajo
@ 2004-07-07 18:22 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2004-07-07 18:22 UTC (permalink / raw)
To: Giovanni Bajo; +Cc: gcc-patches
On Wed, 7 Jul 2004 05:33:50 +0200, "Giovanni Bajo" <giovannibajo@libero.it> wrote:
> This patch has been tested on i686-pc-linux-gnu with no new regressions. I
> discussed a little with Jason whether we want to patch
> build_method_type_directly to copy the cv-quals within the METHOD_TYPE node.
> This would avoid that ugly chain of macros in my patch (and other parts of the
> frontend) to access them. I tried patching it but there were fallouts in
> cp/mangle.c and similar, so I did not bother at this point.
I still think that's the right way to fix the problem. As you pointed out,
the member function has const-qualified type, and the trees should reflect
that.
I'm not surprised that there are mangler issues, but that shouldn't be hard
to fix.
> OK for mainline?
No.
Jason
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-07-07 17:58 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-07 4:49 [C++ PATCH] [PR8271] Check cv-quals of methods while unifying Giovanni Bajo
2004-07-07 18:22 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).