(C++) Patch to conversion op lookup

Jason Merrill jason@redhat.com
Sat Oct 21 14:43:00 GMT 2000


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;
+ }


More information about the Gcc-patches mailing list