public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Patch] PR c++/26256
@ 2010-05-11 19:44 Fabien Chêne
  2010-05-16 19:20 ` Fabien Chêne
  2010-06-08 21:50 ` Jason Merrill
  0 siblings, 2 replies; 40+ messages in thread
From: Fabien Chêne @ 2010-05-11 19:44 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1953 bytes --]

Hello,

Here is a patch to fix PR c++/26256, which deals with using
declarations. I've tried a naive approach: basically, when a field
decl is ambiguous, lookup_member (invoked with protect = 1) returns a
TREE_LIST. So when we are in this case, I have implemented a lookup in
the object scope, which try to disambiguate the field decl using
'using decl'. If the lookup succeeds, just return the selected field
decl in the TREE_LIST.

I've also implemented the dual fix for type fields. The principle is
the same than above, if a field type is ambiguous, lookup_name_real
returns a TREE_LIST. In this case, we have to do a lookup in the
appropriate class scope, and return the selected field type in the
TREE_LIST if the lookup succeds.

Thought ?

Bootstrapped with all default languages, tested x86_64/Linux.

gcc/testsuite/ChangeLog:

2010-05-11  Fabien Chêne  <fabien.chene@gmail.com>
	PR c++/26256
	* g++.dg/lookup/using23.C: New.
	* g++.dg/lookup/using24.C: New.
	* g++.dg/lookup/using25.C: New.
	* g++.dg/lookup/using26.C: New.
	* g++.dg/lookup/using27.C: New.
	* g++.dg/debug/using4.C: New.
	* g++.dg/debug/using5.C: New.


gcc/cp/ChangeLog:

2010-05-11  Fabien Chêne  <fabien.chene@gmail.com>
	PR c++/26256
	* cp-tree.h (disambiguate_with_using_decl): Declare.
	* name-lookup.c (disambiguate_with_using_decl): Define. Try to
	disambiguate a field type or a field decl with using declarations.
	* search.c (lookup-member): Call disambiguate_with_using_decl when
	a field decl is ambiguous.
	* parser.c (cp_parser_lookup_name): Call
	disambiguate_with_using_decl when a field type is ambiguous.
	* class.c (count_fields): Ignore using declarations.
	(add_fields_to_record_type): Likewise.
	(check_field_decls): Keep using declarations.

gcc/ChangeLog:

2010-05-11  Fabien Chêne  <fabien.chene@gmail.com>
	PR c++/26256
	* dbxout.c (dbxout_type_fields): Ignore using declarations.

-- 
Fabien

[-- Attachment #2: pr26256.patch --]
[-- Type: application/octet-stream, Size: 10399 bytes --]

Index: gcc/testsuite/g++.dg/debug/using4.C
===================================================================
--- gcc/testsuite/g++.dg/debug/using4.C	(revision 0)
+++ gcc/testsuite/g++.dg/debug/using4.C	(revision 0)
@@ -0,0 +1,24 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+    typedef char type;
+};
+
+struct B
+{
+    typedef int type;
+};
+
+struct C : A, B
+{
+    using A::type;
+    type f (type);
+};
+
+C::type C::f( type ) 
+{
+    type c = 'e';
+    return c;
+}
Index: gcc/testsuite/g++.dg/debug/using5.C
===================================================================
--- gcc/testsuite/g++.dg/debug/using5.C	(revision 0)
+++ gcc/testsuite/g++.dg/debug/using5.C	(revision 0)
@@ -0,0 +1,23 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+    int i;
+};
+
+struct B
+{
+    int i;
+};
+
+struct C : A, B
+{
+    using B::i;
+    int f ();
+};
+
+int C::f() 
+{
+    return i;
+}
Index: gcc/testsuite/g++.dg/lookup/using24.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using24.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using24.C	(revision 0)
@@ -0,0 +1,24 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct ListDProto {
+    unsigned length();
+    bool empty();
+    void clear();
+    void first();
+    void next();
+    enum Action { NORMAL, REMOVE_CURRENT };
+};
+struct SetLD: ListDProto {
+    void remove()
+    {ListDProto::Action a = this->NORMAL;}
+    ListDProto::length;
+    ListDProto::empty;
+    ListDProto::clear;
+    ListDProto::first;
+    ListDProto::next;
+
+    using ListDProto::NORMAL;
+    using ListDProto::REMOVE_CURRENT;
+};
+
Index: gcc/testsuite/g++.dg/lookup/using25.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using25.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using25.C	(revision 0)
@@ -0,0 +1,28 @@
+// PR c++/26256
+// { dg-do run }
+
+struct A 
+{
+    int next; 
+};
+
+struct B 
+{
+    int next; 
+};
+
+struct C : public A, public B 
+{
+    using A::next; 
+};
+
+void foo(C& c) { c.next = 42; }
+
+int main()
+{
+    C c;
+    foo (c);
+    c.B::next = 12;
+    if (c.next != 42 || c.A::next != 42 || c.B::next != 12)
+    	__builtin_abort();
+}
Index: gcc/testsuite/g++.dg/lookup/using26.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using26.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using26.C	(revision 0)
@@ -0,0 +1,27 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A 
+{
+    double next; 
+};
+
+struct B 
+{
+private:
+    int next; // { dg-error "private" }
+};
+
+struct C
+{
+    int next;
+};
+
+struct D : A, B, C // { dg-error "context" }
+{
+    using B::next;
+    void f()
+    {
+	next = 12;
+    }
+};
Index: gcc/testsuite/g++.dg/lookup/using23.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using23.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using23.C	(revision 0)
@@ -0,0 +1,21 @@
+// PR c++/26256
+// { dg-do compile }
+
+struct A
+{
+private:
+    typedef int type; // { dg-error "private" }
+};
+
+struct B
+{
+    typedef double type;
+};
+
+struct C : A, B // { dg-error "context" }
+{
+    using A::type; 
+    type d; // { dg-error "context" }
+};
+
+
Index: gcc/testsuite/g++.dg/lookup/using27.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/using27.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/using27.C	(revision 0)
@@ -0,0 +1,49 @@
+// PR c++/26256
+// { dg-do run }
+
+struct A
+{
+    typedef int type;
+};
+
+struct B
+{
+    typedef double type;
+};
+
+struct C : A, B
+{
+    using A::type;
+    type d;
+
+    void f()
+    {
+	type e;
+	if (sizeof (type) != sizeof (A::type))
+	    __builtin_abort();
+    }
+
+    void g();
+};
+
+void C::g()
+{
+    type x;
+    if (sizeof (type) != sizeof (A::type))
+    	__builtin_abort();
+}
+
+int main ()
+{
+    if (sizeof (C::type) != sizeof (A::type))
+    	__builtin_abort();
+
+    if (sizeof (C::d) != sizeof (A::type))
+    	__builtin_abort();
+
+    C::type x;
+    C c;
+    c.f();
+    c.g();
+}
+
Index: gcc/cp/class.c
===================================================================
--- gcc/cp/class.c	(revision 158572)
+++ gcc/cp/class.c	(working copy)
@@ -2704,6 +2704,8 @@ count_fields (tree fields)
   int n_fields = 0;
   for (x = fields; x; x = TREE_CHAIN (x))
     {
+      if (TREE_CODE (x) == USING_DECL)
+	continue;
       if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
 	n_fields += count_fields (TYPE_FIELDS (TREE_TYPE (x)));
       else
@@ -2721,6 +2723,9 @@ add_fields_to_record_type (tree fields, 
   tree x;
   for (x = fields; x; x = TREE_CHAIN (x))
     {
+      if (TREE_CODE (x) == USING_DECL)
+	continue;
+
       if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
 	idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
       else
@@ -2935,15 +2940,8 @@ check_field_decls (tree t, tree *access_
 
       if (TREE_CODE (x) == USING_DECL)
 	{
-	  /* Prune the access declaration from the list of fields.  */
-	  *field = TREE_CHAIN (x);
-
 	  /* Save the access declarations for our caller.  */
 	  *access_decls = tree_cons (NULL_TREE, x, *access_decls);
-
-	  /* Since we've reset *FIELD there's no reason to skip to the
-	     next field.  */
-	  next = field;
 	  continue;
 	}
 
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 158572)
+++ gcc/cp/parser.c	(working copy)
@@ -1,6 +1,6 @@
 /* C++ Parser.
    Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005, 2007, 2008, 2009  Free Software Foundation, Inc.
+   2005, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
    Written by Mark Mitchell <mark@codesourcery.com>.
 
    This file is part of GCC.
@@ -18121,6 +18121,9 @@ cp_parser_lookup_name (cp_parser *parser
   if (is_template)
     decl = maybe_get_template_decl_from_type_decl (decl);
 
+  /* Handle using decls. */
+  decl = disambiguate_with_using_decl (decl, parser->qualifying_scope);
+
   /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
   if (TREE_CODE (decl) == TREE_LIST)
     {
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 158572)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -4648,6 +4648,7 @@ extern tree check_for_out_of_scope_varia
 extern void print_other_binding_stack		(struct cp_binding_level *);
 extern tree maybe_push_decl			(tree);
 extern tree current_decl_namespace		(void);
+extern tree disambiguate_with_using_decl        (tree, tree);
 
 /* decl.c */
 extern tree poplevel				(int, int, int);
Index: gcc/cp/search.c
===================================================================
--- gcc/cp/search.c	(revision 158572)
+++ gcc/cp/search.c	(working copy)
@@ -1,7 +1,7 @@
 /* Breadth-first and depth-first routines for
    searching multiple-inheritance lattice for GNU C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   1999, 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -1225,6 +1225,17 @@ lookup_member (tree xbasetype, tree name
 	protect = 0;
     }
 
+  if (protect == 1 && lfi.ambiguous)
+    {
+      tree disamb = disambiguate_with_using_decl (lfi.ambiguous, 
+						  TREE_TYPE (basetype_path));
+      if (TREE_CODE (disamb) != TREE_LIST)
+	{
+	  rval = disamb;
+	  errstr = 0;
+	}
+    }
+
   /* [class.access]
 
      In the case of overloaded function names, access control is
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 158572)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -5509,4 +5509,60 @@ cp_emit_debug_info_for_using (tree t, tr
       }
 }
 
+/* Try to disambiguate an ambiguous DECL, with using
+   declarations. Returns DECL if DECL cannot be disambiguated,
+   otherwise returns the selected candidate (not a TREE_LIST). The
+   lookup is done in SCOPE if it is not a NULL_TREE, otherwise, in
+   current_class_type if it is not a NULL_TREE. */
+tree
+disambiguate_with_using_decl (tree decl, tree scope)
+{
+  int candidates = 0;
+  tree decl_after_using = NULL_TREE;
+  tree field = NULL_TREE;
+  tree decl_scope = NULL_TREE;
+
+  if (TREE_CODE (decl) != TREE_LIST)
+    return decl;
+      
+  if (scope)
+    decl_scope = scope;
+  else if (current_class_type)
+    decl_scope = current_class_type;
+  /* else if (object_scope) */
+  /*   decl_scope = TREE_TYPE (object_scope); */
+
+  if (decl_scope == NULL_TREE
+      || !CLASS_TYPE_P (decl_scope))
+    return decl;
+
+  for (field = TYPE_FIELDS (decl_scope);
+       field;
+       field = TREE_CHAIN (field))
+    {
+      if (TREE_CODE (field) == USING_DECL)
+	{
+	  tree using_decl = USING_DECL_DECLS (field);
+	  tree fn;
+	  for (fn = decl; fn != NULL_TREE; fn = TREE_CHAIN (fn))
+	    {
+	      if (same_type_p ( TREE_TYPE (TREE_VALUE (fn)),
+				TREE_TYPE (using_decl)))
+		{
+		  decl_after_using = tree_cons (NULL_TREE,
+						using_decl,
+						decl_after_using);
+		  ++ candidates;
+		  break;
+		}
+	    }
+	}
+    }
+
+  if (candidates == 1)
+      decl = TREE_VALUE (decl_after_using);
+  return decl;
+}
+
+
 #include "gt-cp-name-lookup.h"
Index: gcc/dbxout.c
===================================================================
--- gcc/dbxout.c	(revision 158572)
+++ gcc/dbxout.c	(working copy)
@@ -1,6 +1,6 @@
 /* Output dbx-format symbol table information from GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -1431,6 +1431,8 @@ dbxout_type_fields (tree type)
       if (TREE_CODE (tem) == TYPE_DECL
 	  /* Omit here the nameless fields that are used to skip bits.  */
 	  || DECL_IGNORED_P (tem)
+	  /* Omit USING_DECL */
+	  || TREE_CODE (tem) == USING_DECL
 	  /* Omit fields whose position or size are variable or too large to
 	     represent.  */
 	  || (TREE_CODE (tem) == FIELD_DECL

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2011-10-11 15:12 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-11 19:44 [Patch] PR c++/26256 Fabien Chêne
2010-05-16 19:20 ` Fabien Chêne
2010-06-08 21:50 ` Jason Merrill
2010-06-09  9:23   ` Fabien Chêne
2010-06-09  9:23     ` Fabien Chêne
2010-06-09 12:17       ` Jason Merrill
2010-06-16 21:21   ` Fabien Chêne
2010-06-17  8:39     ` Fabien Chêne
2010-06-18  8:18     ` Jason Merrill
2010-07-30 13:42       ` Fabien Chêne
2010-08-18 19:29         ` Fabien Chêne
2010-08-20 23:29           ` Jason Merrill
2010-11-15 21:40             ` Fabien Chêne
2010-11-15 21:41               ` Fabien Chêne
2010-11-17 11:25                 ` Fabien Chêne
2010-12-20 16:51                   ` Fabien Chêne
2010-12-22 23:10                     ` Jason Merrill
2011-03-04  8:11                       ` Fabien Chêne
2011-03-05 20:07                         ` Jason Merrill
2011-03-08 21:48                           ` Fabien Chêne
2011-06-15 19:42                             ` Fabien Chêne
2011-06-22 15:56                               ` Jason Merrill
2011-09-17 18:49                                 ` Fabien Chêne
2011-09-20  1:53                                   ` Jason Merrill
2011-09-21 18:33                                     ` Fabien Chêne
2011-09-21 18:52                                       ` Fabien Chêne
2011-09-21 19:01                                       ` Jason Merrill
2011-09-22 10:34                                         ` Fabien Chêne
2011-09-22 16:50                                           ` Jason Merrill
2011-09-22 23:01                                             ` Fabien Chêne
2011-09-22 23:48                                               ` Jason Merrill
2011-09-23  8:57                                                 ` Fabien Chêne
2011-09-25 20:49                                                   ` Fabien Chêne
2011-09-25 21:05                                                     ` Paolo Carlini
2011-09-25 21:48                                                       ` Fabien Chêne
2011-09-25 22:35                                                         ` Paolo Carlini
2011-09-26  1:28                                                           ` Fabien Chêne
2011-09-26 14:28                                                             ` Jason Merrill
2011-10-10 20:35                                                               ` Fabien Chêne
2011-10-11 15:35                                                                 ` 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).