This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) Patch to conversion op lookup
- To: gcc-patches at gcc dot gnu dot org
- Subject: (C++) Patch to conversion op lookup
- From: Jason Merrill <jason at redhat dot com>
- Date: Sat, 21 Oct 2000 17:39:10 -0400
- CC: aldyh at redhat dot com
This patch fixes lookup for conversion op types to be like that used
for an explicit class scope after an '->'. It also fixes the lookup
for the latter, which has been silently broken for a while (to favor
the class-scope lookup).
Test is g++.other/lookup19.C.
2000-10-21 Jason Merrill <jason@redhat.com>
* parse.y (operator): Set got_object from got_scope.
Set looking_for_typename.
* decl.c (lookup_name_real): Clear val after setting from_obj.
Reorganize diagnostic.
Index: cp/parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/parse.y,v
retrieving revision 1.197
diff -c -p -r1.197 parse.y
*** cp/parse.y 2000/10/13 06:26:43 1.197
--- cp/parse.y 2000/10/21 21:39:39
*************** conversion_declarator:
*** 3745,3753 ****
operator:
OPERATOR
! { saved_scopes = tree_cons (got_scope, got_object, saved_scopes);
! got_scope = NULL_TREE; got_object = NULL_TREE; }
;
unoperator:
{ got_scope = TREE_PURPOSE (saved_scopes);
got_object = TREE_VALUE (saved_scopes);
--- 3745,3759 ----
operator:
OPERATOR
! {
! saved_scopes = tree_cons (got_scope, got_object, saved_scopes);
! /* We look for conversion-type-id's in both the class and current
! scopes, just as for ID in 'ptr->ID::'. */
! looking_for_typename = 1; got_object = got_scope;
! got_scope = NULL_TREE;
! }
;
+
unoperator:
{ got_scope = TREE_PURPOSE (saved_scopes);
got_object = TREE_VALUE (saved_scopes);
*************** operator_name:
*** 3821,3827 ****
{ $$ = frob_opname (ansi_opname (VEC_NEW_EXPR)); }
| operator DELETE '[' ']' unoperator
{ $$ = frob_opname (ansi_opname (VEC_DELETE_EXPR)); }
- /* Names here should be looked up in class scope ALSO. */
| operator type_specifier_seq conversion_declarator unoperator
{ $$ = frob_opname (grokoptypename ($2.t, $3)); }
| operator error unoperator
--- 3827,3832 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.701
diff -c -p -r1.701 decl.c
*** cp/decl.c 2000/10/20 16:06:05 1.701
--- cp/decl.c 2000/10/21 21:39:42
*************** lookup_name_real (name, prefer_type, non
*** 5946,5952 ****
if (got_scope)
goto done;
else if (got_object && val)
! from_obj = val;
}
else
{
--- 5946,5955 ----
if (got_scope)
goto done;
else if (got_object && val)
! {
! from_obj = val;
! val = NULL_TREE;
! }
}
else
{
*************** lookup_name_real (name, prefer_type, non
*** 6015,6027 ****
{
if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
&& TREE_CODE (val) == TYPE_DECL
! && TREE_TYPE (from_obj) != TREE_TYPE (val))
! {
! cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')",
! name, got_object, TREE_TYPE (from_obj));
! cp_pedwarn (" does not match lookup in the current scope (`%#T')",
! TREE_TYPE (val));
! }
/* We don't change val to from_obj if got_object depends on
template parms because that breaks implicit typename for
--- 6018,6029 ----
{
if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
&& TREE_CODE (val) == TYPE_DECL
! && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
! cp_pedwarn ("\
! lookup of `%D' in the scope of `%#T' (`%#T') \
! does not match lookup in the current scope (`%#T')",
! name, got_object, TREE_TYPE (from_obj),
! TREE_TYPE (val));
/* We don't change val to from_obj if got_object depends on
template parms because that breaks implicit typename for
Index: testsuite/g++.old-deja/g++.other/lookup19.C
===================================================================
RCS file: lookup19.C
diff -N lookup19.C
*** /dev/null Tue May 5 13:32:27 1998
--- testsuite/g++.old-deja/g++.other/lookup19.C Sat Oct 21 14:39:42 2000
***************
*** 0 ****
--- 1,54 ----
+ // Test for proper handling of type lookup for conversion operator names.
+ // Build don't link:
+
+ // Test 1: Only at file scope
+ typedef int B;
+ struct A
+ {
+ int B;
+ operator B *();
+ };
+
+ A::operator B * ()
+ {
+ return 0;
+ }
+
+ // Test 2: Only at class scope
+ struct C
+ {
+ typedef int D;
+ operator D *();
+ };
+
+ int D;
+ C::operator D * ()
+ {
+ return 0;
+ }
+
+ // Test 3: Matching
+ struct E
+ {
+ typedef int F;
+ operator F *();
+ };
+
+ typedef int F;
+ E::operator F * ()
+ {
+ return 0;
+ }
+
+ // Test 4: Conflicting
+ struct G
+ {
+ typedef int H;
+ operator H *();
+ };
+
+ typedef double H;
+ G::operator H * () // ERROR - mismatch
+ {
+ return 0;
+ }