[C++ PATCH] Using declarations should not conflict (fix PR/2294)

Giovanni Bajo giovannibajo@libero.it
Wed Oct 29 20:21:00 GMT 2003


Hello,

Two using declarations importing two identical declarations into the current
scope should not cause a conflict, but just build an ambiguous overload set
(§7.3.3/12 in the draft). The problem is that the C++ frontend does not have a
way to see if a DECL in the current scope comes from an using declaration is not
unless it's an OVERLOAD (for which we have a handy OVL_USED flag). Since the
code was trying to lazily construct an OVERLOAD only when needed, we were losing
this information along the way. Fixed by always constructing an OVERLOAD if the
declaration is pushed into the current scope due to an using declaration.

Bootstrapped (c, c++) and tested (check-g++) on i686-pc-linux-gnu with no
regressions. OK for mainline?

Giovanni Bajo


2003-10-29  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/2294
        * name-lookup.c (push_overloaded_decl): always construct an OVERLOAD
        if the declaration comes from an using declaration (flags & PUSH_USING).


2003-10-29  Giovanni Bajo  <giovannibajo@libero.it>

        PR c++/2294
        * g++.dg/lookup/using9.c: New test.


Index: gcc/cp/name-lookup.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.16
diff -c -p -r1.16 name-lookup.c
*************** push_overloaded_decl (tree decl, int fla
*** 1994,2000 ****
        }
      }

!   if (old || TREE_CODE (decl) == TEMPLATE_DECL)
      {
        if (old && TREE_CODE (old) != OVERLOAD)
        new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
--- 1997,2007 ----
        }
      }

!   if (old || TREE_CODE (decl) == TEMPLATE_DECL
!       /* If it's a using declaration, we always need to build an OVERLOAD,
!        because it's the only way to remember that the declaration comes
!        from 'using', and have the lookup behave correctly.  */
!       || (flags & PUSH_USING))
      {
        if (old && TREE_CODE (old) != OVERLOAD)
        new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));



// { dg-do compile }
// Origin: C++ Standard Draft (7.3.3/12)
// PR c++/2294: using declarations should not conflict, but only cause
//  an ambiguous overload set to be created.

namespace B {
  void f(int);     // { dg-error "note" }
  void f(double);  // { dg-error "note" }
}

namespace C {
  void f(int);     // { dg-error "note" }
  void f(double);  // { dg-error "note" }
  void f(char);    // { dg-error "note" }
}

void h()
{
  using B::f;
  using C::f;
  f('h');
  f(1);         // { dg-error "ambiguous" }
  void f(int);  // { dg-error "previous using declaration" }
}

void m()
{
  void f(int);
  using B::f;   // { dg-error "already declared" }
}





More information about the Gcc-patches mailing list