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: [email protected]
ReportedBy: [email protected]
CC: [email protected]
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