[libcxx] Reinstate <string.h> and fix overload sets to be const-correct wherever possible

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 29 17:21:57 PDT 2015


Hi,

The attached patch undoes the revert of r249929, and adds an extension to
allow <string.h> (and <wchar.h>) to work properly even in environments such
as iOS where the underlying libc does not provide C++'s const-correct
overloads of strchr and friends.

This works as follows:

 * The macro _LIBCPP_PREFERRED_OVERLOAD is, where possible, defined by
<__config> to an attribute that provides the following semantics:
   - A function declaration with the attribute declares a different
function from a function declaration without the attribute.
   - Overload resolution prefers a function with the attribute over a
function without.
 * For each of the functions that has a "broken" signature in C, if we
don't believe that the C library provided the C++ signatures, and we have a
_LIBCPP_PREFERRED_OVERLOAD, then we add the C++ declarations and mark them
as preferred over the C overloads.
 * The overloads provided in namespace std always exactly match those in ::.


This results in the following changes in cases where the underlying libc
provides the C signature not the C++ one, compared to the status quo:


<string.h>:

      char *strchr(const char*, int) // #1
      char *strchr(char*, int) // #2
      const char *strchr(const char*, int) // #3

We used to provide #1 and #2 in namespace std (in <cstring>) and only #1 in
global namespace (in <string.h>).

For a very old clang or non-clang compiler, we now have only #1 in both
places (note that #2 is essentially useless). This is unlikely to be a
visible change in real code, but it's slightly broken either way and we
can't fix it.

For newer clang (3.6 onwards?), we now have correct signatures (#2 and #3)
in :: and std (depending on header). Taking address of strchr requires
~trunk clang (but it didn't work before either, so this is not really a
regression).


<wchar.h>:

      wchar_t *wcschr(const wchar_t *, wchar_t) // #1
      const wchar_t *wcschr(const wchar_t *, wchar_t) // #2
      wchar_t *wcschr(wchar_t *, wchar_t) // #3

We used to provide #1 in global namespace, and #2 and #3 in namespace std.
This broke code that uses 'using namespace std;'.

For a very old clang or non-clang compiler, we now have #1 in global
namespace and namespace std. This fixes the ambiguity errors, but decreases
const-correctness in this case. On the whole, this seems like an
improvement to me.

For newer clang, we now have correct signatures (#2 and #3) in :: and std
(depending on header). As above, taking address doesn't work unless you're
using very recent Clang (this is not a regression in ::, but is a
regression in namespace std).


To summarize, we previously had ad-hoc, inconsistent, slightly broken rules
for <cstring> and <cwchar>, and with this patch we fix the overload set to
give the exact C++ semantics where possible (for all recent versions of
Clang), and otherwise leave the C signatures alone.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151029/a3bd536e/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: string-wchar-overload-sets.patch
Type: application/octet-stream
Size: 9380 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151029/a3bd536e/attachment-0001.obj>


More information about the cfe-commits mailing list