[cfe-dev] Keyword warnings in libc++'s type_traits and other headers

Alp Toker alp at nuanti.com
Mon Dec 23 13:30:09 PST 2013

On 23/12/2013 20:16, Marshall Clow wrote:
> On Dec 22, 2013, at 6:37 PM, Alp Toker <alp at nuanti.com 
> <mailto:alp at nuanti.com>> wrote:
>> On 23/12/2013 00:46, Marshall Clow wrote:
>>> On Dec 22, 2013, at 1:58 PM, Alp Toker <alp at nuanti.com 
>>> <mailto:alp at nuanti.com> <mailto:alp at nuanti.com>> wrote:
>>>> On 22/12/2013 21:27, Dimitry Andric wrote:
>>>>> Hi,
>>>>> I ran into a situation where a C++ program was compiled with 
>>>>> -Wsystem-headers.  When I did this with clang 3.4 or trunk, I got 
>>>>> the following keyword warnings:
>>>> [snipped]
>>>>> include/type_traits:668:8: warning: keyword '__is_unsigned' will 
>>>>> be made available as an identifier for the remainder of the 
>>>>> translation unit [-Wkeyword-compat]
>>>>> struct __is_unsigned : public ___is_unsigned<_Tp> {};
>>>>>      ^
>>>>> 9 warnings generated.
>>>>> This seems to have been introduced with r196212 in clang by Alp 
>>>>> Toker, but it is unfortunate the warning hits libc++. :-)  The 
>>>>> cause is a bunch of Embarcadero keywords defined in clang's 
>>>>> lib/Parse/ParseExpr.cpp, which are exactly the same as these 
>>>>> libc++-internal identifers.
>>>>> Is the attached patch acceptable as a workaround?
> I’m still confused.
> I tried the following tests using today’s clang (and libc++):

Hi Marshall,

I'll step you through each of the cases you posted.

In your first example:

|trait.cpp:1:39: error: expected '('||
||        int main () { const int i = __is_void<int>::value; }||
||                                             ^|

__is_void is handled as an intrinsic keyword which the parser expects to 
be written as a functional call. Try the following to get it to compile:

|    int main () { const int i = __is_void(int); }||

In your second example:

|trait.cpp:1:34: error: expected unqualified-id||
||int main () { const int i = std::__is_void<int>::value; }||
||                                 ^|

std:: is parsed as the beginning of a nested name specifier. When the 
__is_void keyword is encountered, the scope specifier is no longer valid 
and the error diagnostic is emitted.

The error message in your third example is changed after inclusion of 
headers because <type_traits> header activated the fallback mode and 
downgraded __is_void to an identifier. You can get it to compile as in 
your final example if you prefix __is_void with std::

In the last two examples you've activated the GNU header compatibility 
mode by attempting to introduce keywords as a type name in system 
headers. The appropriate extension warning will have been issued:

|include/c++/v1/type_traits:288:29: warning: keyword '__is_void' will be 
made available as an identifier for the remainder of the translation unit||
||template <class _Tp> struct __is_void       : public false_type {};|

There are any number of __is_* compiler built-ins in clang and other 
compilers, and there will be more added in the new year so it's a good 
plan to move away from using these intrinsic names as type names while 
we still have the keyword hack in the parser.


the browser experts

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131223/4871a2e1/attachment.html>

More information about the cfe-dev mailing list