[cfe-commits] [PATCH] [libc++] make errno saving more resilient to types

Saleem Abdulrasool compnerd at compnerd.org
Tue Jan 22 07:43:30 PST 2013


On Tue, Jan 22, 2013 at 7:06 AM, Howard Hinnant <hhinnant at apple.com> wrote:
> I appreciate the problem, but this solution won't work for me:
>
> #include <iostream>
> #include <cerrno>
>
> int main()
> {
>     decltype(errno) save_errno = errno;
>     std::cout << "save_errno = " << save_errno << '\n';
>     std::cout << "errno = " << errno << '\n';
>     errno = 5;
>     std::cout << "save_errno = " << save_errno << '\n';
>     std::cout << "errno = " << errno << '\n';
> }
>
> For me outputs:
>
> save_errno = 0
> errno = 0
> save_errno = 5
> errno = 5
>
> Desired output:
>
> save_errno = 0
> errno = 0
> save_errno = 0
> errno = 5
>
> For me decltype(errno) is int&.

Ah, silly me.  You are correct, but, that is simple enough to fix.  I
should have used typename remove_reference<decltype(errno)>::type.
Ill send out an updated patch momentarily.

#include <iostream>
#include <cerrno>

int main()
{
    typename std::remove_reference<decltype(errno)>::type save_errno = errno;
    std::cout << "save_errno = " << save_errno << '\n';
    std::cout << "errno = " << errno << '\n';
    errno = 5;
    std::cout << "save_errno = " << save_errno << '\n';
    std::cout << "errno = " << errno << '\n';
}

Gives me:

save_errno = 0
errno = 0
save_errno = 0
errno = 5

> Howard
>
> On Jan 21, 2013, at 10:03 PM, Saleem Abdulrasool <compnerd at compnerd.org> wrote:
>
>> If errno is defined as volatile int, the qualifier differences can cause
>> template typename deductions on swap<> (used in string.cpp).  Use
>> decltype(errno) to replicate the type and qualifier information for holding the
>> errno value.  Because errno is expected to be assignable, there is no need to
>> use typename std::remove_const<decltype(errno)>::type to hold the value.
>>
>> http://llvm-reviews.chandlerc.com/D318
>>
>> Files:
>>  include/locale
>>  src/string.cpp
>>
>> Index: include/locale
>> ===================================================================
>> --- include/locale
>> +++ include/locale
>> @@ -830,11 +830,11 @@
>> {
>>     if (__a != __a_end)
>>     {
>> -        int __save_errno = errno;
>> +        decltype(errno) __save_errno = errno;
>>         errno = 0;
>>         char *__p2;
>>         long long __ll = strtoll_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
>> -        int __current_errno = errno;
>> +        decltype(errno) __current_errno = errno;
>>         if (__current_errno == 0)
>>             errno = __save_errno;
>>         if (__p2 != __a_end)
>> @@ -870,11 +870,11 @@
>>             __err = ios_base::failbit;
>>             return 0;
>>         }
>> -        int __save_errno = errno;
>> +        decltype(errno) __save_errno = errno;
>>         errno = 0;
>>         char *__p2;
>>         unsigned long long __ll = strtoull_l(__a, &__p2, __base, _LIBCPP_GET_C_LOCALE);
>> -        int __current_errno = errno;
>> +        decltype(errno) __current_errno = errno;
>>         if (__current_errno == 0)
>>             errno = __save_errno;
>>         if (__p2 != __a_end)
>> Index: src/string.cpp
>> ===================================================================
>> --- src/string.cpp
>> +++ src/string.cpp
>> @@ -31,7 +31,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long r = strtol(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -52,7 +52,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long r = wcstol(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -73,7 +73,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long r = strtol(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -93,7 +93,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long r = wcstol(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -113,7 +113,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     unsigned long r = strtoul(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -133,7 +133,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     unsigned long r = wcstoul(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -153,7 +153,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long long r = strtoll(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -173,7 +173,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long long r = wcstoll(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -193,7 +193,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     unsigned long long r = strtoull(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -213,7 +213,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     unsigned long long r = wcstoull(p, &ptr, base);
>>     swap(errno, errno_save);
>> @@ -233,7 +233,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     float r = strtof(p, &ptr);
>>     swap(errno, errno_save);
>> @@ -253,7 +253,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     float r = wcstof(p, &ptr);
>>     swap(errno, errno_save);
>> @@ -273,7 +273,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     double r = strtod(p, &ptr);
>>     swap(errno, errno_save);
>> @@ -293,7 +293,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     double r = wcstod(p, &ptr);
>>     swap(errno, errno_save);
>> @@ -313,7 +313,7 @@
>> {
>>     char* ptr;
>>     const char* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long double r = strtold(p, &ptr);
>>     swap(errno, errno_save);
>> @@ -333,7 +333,7 @@
>> {
>>     wchar_t* ptr;
>>     const wchar_t* const p = str.c_str();
>> -    int errno_save = errno;
>> +    decltype(errno) errno_save = errno;
>>     errno = 0;
>>     long double r = wcstold(p, &ptr);
>>     swap(errno, errno_save);
>> <D318.1.patch>_______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>



--
Saleem Abdulrasool
compnerd (at) compnerd (dot) org



More information about the cfe-commits mailing list