[cfe-dev] FW: Newlib v2.5.0 and LibC++ locale support BROKEN

Martin J. O'Riordan via cfe-dev cfe-dev at lists.llvm.org
Sat Jan 14 05:25:29 PST 2017


Following up on my message yesterday, I tried building with ‘_GNU_SOURCE’ defined, and this fixes the ‘vasprintf’ issue.  But it threw up a different problem.

 

When compiling ‘llvm/projects/libcxx/src/system_error.cpp’ I got the following error message:

 

/home/martino/llvm/projects/libcxx/src/system_error.cpp:79:14: error: assigning to 'int' from incompatible type 'char *'

    if ((ret = ::strerror_r(ev, buffer, strerror_buff_size)) != 0) {

             ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

and this is because Newlib’s implementation of ‘<string.h>’ is as follows (this is unchanged in v2.5.0 from v2.2.0):

 

/* There are two common strerror_r variants.  If you request

   _GNU_SOURCE, you get the GNU version; otherwise you get the POSIX

   version.  POSIX requires that #undef strerror_r will still let you

   invoke the underlying function, but that requires gcc support.  */

#if __GNU_VISIBLE

char *_EXFUN(strerror_r,(int, char *, size_t));

#else

# ifdef __GNUC__

int  _EXFUN(strerror_r,(int, char *, size_t))

#ifdef __ASMNAME

             __asm__ (__ASMNAME ("__xpg_strerror_r"))

#endif

  ;

# else

int  _EXFUN(__xpg_strerror_r,(int, char *, size_t));

#  define strerror_r __xpg_strerror_r

# endif

#endif

 

So I edited ‘system_error.cpp’ and this with the other changes I mentioned appears to make it all compile perfectly :)  Of course, now I have to run the test-suite to see if it breaks anything.  My edit to ‘system_error.cpp’ is as follows:

 

#if defined(__linux__) && !defined(_LIBCPP_HAS_MUSL_LIBC) \

    && (!defined(__ANDROID__) || __ANDROID_API__ >= 23) \

    || (defined(_NEWLIB_VERSION) && defined(_GNU_SOURCE))

// GNU Extended version

string do_strerror_r(int ev) {

    char buffer[strerror_buff_size];

    char* ret = ::strerror_r(ev, buffer, strerror_buff_size);

    return string(ret);

}

#else

// POSIX version

string do_strerror_r(int ev) {

 

Because my target is for an embedded system, ‘__linux__’ is not defined.

 

All the best,

 

            MartinO

 

On Fri, Jan 13, 2017 at 9:06 AM, Martin J. O'Riordan via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org> > wrote:

Thanks James, I will try that.

            MartinO

From: James Y Knight [mailto:jyknight at google.com <mailto:jyknight at google.com> ] 
Sent: 13 January 2017 15:50
To: Martin J. O'Riordan <martin.oriordan at movidius.com <mailto:martin.oriordan at movidius.com> >
Cc: cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org> >
Subject: Re: [cfe-dev] Newlib v2.5.0 and LibC++ locale support BROKEN

You should define _GNU_SOURCE, in order to get the vasprintf definition (newlib will set __GNU_VISIBLE based on it)

While _GNU_SOURCE is "theoretically" supposed to be for end-users to define, to request extra nonstandard functions from standard headers, in practice, it's set effectively always for C++ code, because the C++ standard libraries need it. (see how clang sets it by default for a number of targets in clang/lib/Basic/Targets.cpp).

On Fri, Jan 13, 2017 at 10:17 AM, Martin J. O'Riordan via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org> > wrote:

I have a partial fix for these issues.

The first is a group of errors that are due to Newlib v2.5.0 providing a richer Locale support than previous releases (Newlib’s ‘locale.h’), and this is turn results in conflicts for all the definitions contained in LibC++’s source ‘include/support/newlib/xlocale.h’ I have changed:

#include <support/xlocale/__nop_locale_mgmt.h>

to:

#if defined(__NEWLIB__) && (__NEWLIB__ == 2) \

     && defined(__NEWLIB_MINOR__) && (__NEWLIB_MINOR__ >= 5) \

     && (!defined(__POSIX_VISIBLE) || (__POSIX_VISIBLE < 200809))

#include <support/xlocale/__nop_locale_mgmt.h>

#endif

I think that  this is a reasonably portable resolution, though I will have to examine intermediate versions of Newlib after v2.2.0-20150423 and before v2.5.0 to see when the relevant changes occurred, so the exclusion check may need to be refined.

However, I am not sure what to do about ‘vasprintf’.  I tried excluding the function ‘__libcpp_asprintf_l’ if ‘__STRICT_ANSI__’ is defined, but this had knock-on consequences because this function is used elsewhere in the C++ headers, so it is a more complex issue to resolve.

Thanks,

            MartinO

From: Martin J. O'Riordan [mailto:martin.oriordan at movidius.com <mailto:martin.oriordan at movidius.com> ] 
Sent: 12 January 2017 15:58
To: 'cfe-dev' <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org> >
Subject: Newlib v2.5.0 and LibC++ locale support

I am in the process of updating from using Newlib v2.2.0-20150423 for our common C library with LLVM to v2.5.0 and this is breaking LibC++.  Both LibC++ v3.9 and what is currently at head are affected.

There are some general problems with Locales, and in particular the definition of the type ‘locale_t’ which is defined in Newlib’s ‘sys/_locale.h’ as:

typedef struct __locale_t *locale_t;

and in LibC++’s ‘support/xlocale/__nop_locale_mgmt.h’ as:

typedef void *locale_t;

But it is also running into another problem with ‘vasprintf’.  In LibC++ this is referenced in ‘__bsd_locale_fallbacks.h’, but ‘vasprintf’ is not an ISO C function, and the newer version of Newlib has the declaration in ‘<stdio.h>’ guarded with ‘__GNU_VISIBLE’ to keep it out of the global namespace, thus:

#if __GNU_VISIBLE

int  _EXFUN(asprintf, (char **__restrict, const char *__restrict, ...)

               _ATTRIBUTE ((__format__ (__printf__, 2, 3))));

int  _EXFUN(vasprintf, (char **, const char *, __VALIST)

               _ATTRIBUTE ((__format__ (__printf__, 2, 0))));

#endif

I don’t know which version of Newlib changed the declaration of ‘vasprintf’, but the current LibC++ does not seem to handle the change.  Should I be building LibC++ with ‘__GNU_VISIBLE’ defined?  Any recommendations for how I should resolve the multiple definition of ‘locale_t’?

Thanks,

            MartinO

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170114/13e3fce4/attachment.html>


More information about the cfe-dev mailing list