Possible bug with __has_cpp_attribute

Hi,
The following seems like a clang bug.

You can't use __has_cpp_attribute with namespaces in a header that is included from C. For example:
#if __has_cpp_attribute(clang::fallthrough)
    ...
#endif

Yields:
error: builtin feature check macro requires a parenthesized identifier.

Shouldn't __has_cpp_attribute() evaluate to 0 for C programs?

I worked around the issue with something like:

#ifndef __has_cpp_attribute
#define __has_cpp_attribute(x) 0
#elif defined(__clang__) && !defined(__cplusplus)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wbuiltin-macro-redefined"
#define __has_cpp_attribute(x) 0
#pragma clang diagnostic pop
#endif

Is there a better way?

-Kal

Hi,
The following seems like a clang bug.

You can't use __has_cpp_attribute with namespaces in a header that is
included from C. For example:
#if __has_cpp_attribute(clang::fallthrough)
   ...
#endif

Yields:
error: builtin feature check macro requires a parenthesized identifier.

Shouldn't __has_cpp_attribute() evaluate to 0 for C programs?

That's debatable. I would say it should be an error for C programs to
refer to __has_cpp_attribute because it should not be a predefined
macro there. I think the bug is that __has_cpp_attribute isn't flag as
being available only for C++. Then you could use the canonical
#if/#elif block for C++ attribute feature testing, without needing the
__cplusplus bit in yours.

~Aaron

From claim documentation for __has_cpp_attribute: " No C++ attributes are supported when compiling for C, so shouldn’t they just all return 0? If __has_cpp_attribute wasn’t defined at all for C programs that would also be good. Either way, what clang does now seems broken.

Hi,
The following seems like a clang bug.

You can't use __has_cpp_attribute with namespaces in a header that is
included from C. For example:
#if __has_cpp_attribute(clang::fallthrough)
   ...
#endif

Yields:
error: builtin feature check macro requires a parenthesized identifier.

Shouldn't __has_cpp_attribute() evaluate to 0 for C programs?

That's debatable. I would say it should be an error for C programs to
refer to __has_cpp_attribute because it should not be a predefined
macro there. I think the bug is that __has_cpp_attribute isn't flag as
being available only for C++. Then you could use the canonical
#if/#elif block for C++ attribute feature testing, without needing the
__cplusplus bit in yours.

~Aaron

From claim documentation for __has_cpp_attribute: " If the attribute is not
supported by the current compliation target, this macro evaluates to 0." No
C++ attributes are supported when compiling for C, so shouldn't they just
all return 0? If __has_cpp_attribute wasn't defined at all for C programs
that would also be good. Either way, what clang does now seems broken.

Agreed that what Clang is doing now is not correct. I've filed a bug for it:

https://llvm.org/bugs/show_bug.cgi?id=23435

Thank you!

~Aaron

I've fixed this in r236996; the built-in macro is now only added when
compiling with C++ enabled.

~Aaron