http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48698

           Summary: gnu-versioned-namespace problems
           Product: gcc
           Version: 4.6.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: r...@gcc.gnu.org
                CC: b...@gcc.gnu.org


Bootstrap fails with errors like:

/tmp/b/x86_64-unknown-linux-gnu/libstdc++-v3/include/cwchar: In function
'wchar_t* std::_6::wcschr(wchar_t*, wchar_t)':
/tmp/b/x86_64-unknown-linux-gnu/libstdc++-v3/include/cwchar:215:55: error:
invalid conversion from 'const wchar_t*' to 'wchar_t*' [-fpermissive]
/tmp/b/x86_64-unknown-linux-gnu/libstdc++-v3/include/cwchar:214:3: error:  
initializing argument 1 of 'wchar_t* std::_6::wcschr(wchar_t*, wchar_t)'
[-fpermissive]

This is because the using declaration for ::wcschr is not in the versioned
namespace, so name lookup inside the versioned namespace finds the declaration
there and doesn't look in the enclosing namespace.

Fixed by:

--- include/c_global/cwchar     2011-04-20 10:09:58.580607848 +0000
+++ include/c_global/cwchar     2011-04-20 10:11:39.348231280 +0000
@@ -136,6 +136,8 @@

 namespace std _GLIBCXX_VISIBILITY(default)
 {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
   using ::wint_t;

   using ::btowc;
@@ -207,8 +209,6 @@
   using ::wcsstr;
   using ::wmemchr;

-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
 #ifndef __CORRECT_ISO_CPP_WCHAR_H_PROTO
   inline wchar_t*
   wcschr(wchar_t* __p, wchar_t __c)



That allows the bootstrap to finish, but the choice of "_6" as the inline
namespace means we cannot compile this valid program or it's C++0x equivalent:

#include <tr1/functional>

int f(int i);

int g()
{
    std::tr1::bind(f, std::tr1::placeholders::_6);
}

b.cc: In function 'int g()':
b.cc:7:49: error: expected primary-expression before ')' token


The problem is that "std::tr1::placeholders::_6" is a namespace not a bind
placeholder

// Inline namespace for symbol versioning.
#if _GLIBCXX_INLINE_VERSION
namespace std
{
...
  namespace tr1
  {
    ...
    namespace placeholders { inline namespace _6 { } }
    ...
  }
  ...
  namespace placeholders { inline namespace _6 { } }


This won't work, placeholders::_6 is required to be a bind placeholder so can't
be a namespace.

It might be better to use _v6 although that would fail if users say
#define _v6 bleurgh
which is allowed.
The inline namespaces should really use a name resperved for the impl, such as
__6 or __v6

Reply via email to