Fix bindings for using declarations.

When an identifier is declared in a using declaration, we were
registering the USING_DECL object in the corresponding binding.

This was wrong, and at the time I hacked around it by simply ignoring
USING_DECLs when setting bindings.  That was wrong too.  What we
actually need to do is discover what is the USING_DECL pointing to and
register that.

I traced the regular parser, and I'm mimicking the lookup of the
associated TYPE_DECL by calling do_nonmember_using_decl.

The only issue I have with this is that I'm not sure where to get the
scope from. In the testcase I'm fixing, the USING_DECL's type has the
namespace_decl where the search should be done. 

I'll test in the internal codebase and see if this is always the case.

2012-03-23   Diego Novillo  <>

        * name-lookup.c (pph_set_identifier_binding): If DECL is a USING_DECL,
        register the TYPE_DECL it is referring to.
        (pph_set_namespace_decl_binding): Remove previous hack that skipped

        * g++.dg/pph/x1mbstate_t.h: Mark fixed.

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 1b33ce3..26d4f86 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -6197,15 +6197,27 @@ pph_set_identifier_binding (tree id, tree decl,
                            cp_binding_level *bl, int flags)
   tree old_value;
+  cxx_binding *b;
   /* FIXME pph: This code plagarizes from push_overloaded_decl_1 and
      binding_for_name.  It may be incomplete.  */
-  cxx_binding *b = cp_binding_level_find_binding_for_name (bl, id);
+  b = cp_binding_level_find_binding_for_name (bl, id);
   if (!b)
       b = cxx_binding_make_for_name (bl, id);
-      b->value = decl;
+      if (TREE_CODE (decl) == USING_DECL)
+       {
+         /* USING_DECLs cannot be registered into the binding.  Instead, we
+            look up the TYPE_DECL it is pointing to by calling
+            do_nonmember_using_decl.  */
+         tree new_value, new_type;
+         do_nonmember_using_decl (TREE_TYPE (decl), id, b->value, b->type,
+                                  &new_value, &new_type);
+         b->value = new_value;
+         b->type = new_type;
+       }
+      else
+       b->value = decl;
       pph_debug_binding_action ("new bind", decl);
@@ -6271,11 +6283,7 @@ pph_set_namespace_decl_binding (tree decl, 
cp_binding_level *bl, int flags)
   /* Set the namespace identifier binding for a single decl.  */
   tree id = DECL_NAME (decl);
-  /* FIXME pph.  USING_DECLs do not seem to be used in bindings by
-     the parser. This was causing the SEGV in
-     testsuite/g++.dg/pph/x1mbstate_t.h.  It's unclear whether this is
-     the right fix.  */
-  if (id && TREE_CODE (decl) != USING_DECL)
+  if (id)
     pph_set_identifier_binding (id, decl, bl, flags);
diff --git a/gcc/testsuite/g++.dg/pph/x1mbstate_t.h 
index 69323d1..4d473e4 100644
--- a/gcc/testsuite/g++.dg/pph/x1mbstate_t.h
+++ b/gcc/testsuite/g++.dg/pph/x1mbstate_t.h
@@ -1,10 +1,8 @@
-// { xfail-if "" { "*-*-*" } { "" } }
 #ifndef _X1_MBSTATE_H
 #define _X1_MBSTATE_H
 #include "x0mbstate_t.h"
 // Name lookup for std::mbstate_t was failingfails here.  Instead of returning
 // the global type_decl for mbstate_t, it was returning the
 // "usings ::mbstate_t" declaration.
-typedef std::mbstate_t state_type;  // { dg-bogus "'mbstate_t' in namespace 
'std' does not name a type" "" { xfail *-*-* } }
+typedef std::mbstate_t state_type;

This patch is available for review at

Reply via email to