[libcxx-commits] [libcxx] [libc++] Enable availability based on the compiler instead of __has_extension (PR #84065)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 6 10:46:22 PST 2024


philnik777 wrote:

> I can see arguments either way. The argument for making `__has_extension` neutral from diagnostic flags is that it's answering the question "does this implementation support this extension" not "can I use this extension without getting diagnostics" which is how `__has_cpp_attribute` works. e.g., https://godbolt.org/z/zMd5W64Ye

>From a standards library perspective getting answers to the first question is much more interesting, since most diagnostics won't be issued to users anyways.

> I think changing the behavior of `__has_extension` could break code: https://sourcegraph.com/github.com/ziglang/zig@1e67f5021159ed1d9888cf2d0b9f04ef73222f7d/-/blob/lib/include/sgxintrin.h?L17 (would currently return `false` with `-pedantic-errors` and thus not issue any diagnostics, but would issue pedantic error diagnostics if `__has_extension` began to return true in that case).

Breaking code is definitely not great, especially changing documented behaviour. OTOH: What do users expect? In my experience people tend to not read the documentation of their compilers and standard libraries very closely (I'm very much guilty of that myself).

> On balance, I think `__has_extension` should be influenced by pedantic errors, however we spell it. I also think `__has_feature`, `__has_cpp_attribute`, et al should be made consistent with `__has_extension` in terms of how we treat pedantic errors. WDYT?

Extending the question to `__has_feature` and `__has_cpp_attribute` is interesting. If we want to make that consistent, we have to break some code no matter what we do.

All in all, I think answers to both questions can be interesting. I'm just not sure how to answer the second without having a million special cases. Here are a few cases where I'm not sure what the correct answer should be:
- `__has_extension(datasizeof)`, but using `__datasizeof` doesn't generate any diagnostic (which might be a bug?)
- ```c++
  #pragma clang diagnostic ignored "-Wc11-extensions"
  _Atomic(int) v; // doesn't generate a diagnostic
  auto v = __has_extension(c_atomic); // Should this be 0 or 1?
  ```
- ```c++
  // with -std=c++11 -Wno-error=-c++17-attribute-extensions
  [[nodiscard]] int func(); // Will issue a diagnostic, but not an error
  auto v = __has_cpp_attribute(nodiscard); // Should this be 0 or 1?
  ```
- ```c++
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wc++17-attribute-extensions"
  #if __has_cpp_attribute(nodiscard)
  #  define NODISCARD [[nodiscard]]
  #else
  #  define NODISCARD
  #endif
  #pragma clang diagnostic pop

  NODISCARD int func();
  ```
They are quite related (other than the first) and it seems to me like we may want to produce different results based on how they're used.

I'm also not sure how one would test things properly if `-Werror` changes the behaviour of the code.


https://github.com/llvm/llvm-project/pull/84065


More information about the libcxx-commits mailing list