The previous code would never use __is_identifier and __is_builtin for a compiler that defines __GNU_C__ >= 7. A hypothetical compiler that supports __is_identifier and __is_builtin might define __GNUC__ to 8 and therefore the macros for BUILTIN_IS_CONSTANT_EVALUATED and BUILTIN_IS_SAME would not get defined, and we would not check for those intrinsics using __is_identifier or __is_builtin either.
This change means that after the conditions using __GNUC__ we then check __is_identifier or __is_builtin for any features not yet defined. This probably doesn't achieve anything in practice, because Clang defines __GNUC__ to 4, and Intel defines it to match whatever GCC defines, so it will claim to be GCC 11 if using the libstdc++ headers from GCC 11. But it still seems more correct to do it this way. libstdc++-v3/ChangeLog: * include/bits/c++config: Do checks using __is_identifier and __is_builtin independent of checks for __GNUC__. Does this seem worth doing, despite the caveat above?
commit 358069de33f305d753c64c7e8e4819bf4638ed14 Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Nov 18 16:15:15 2020 libstdc++: Fix detection of intrinsics for __GNUC__ < 11 The previous code would never use __is_identifier and __is_builtin for a compiler that defines __GNU_C__ >= 7. A hypothetical compiler that supports __is_identifier and __is_builtin might define __GNUC__ to 8 and therefore the macros for BUILTIN_IS_CONSTANT_EVALUATED and BUILTIN_IS_SAME would not get defined, and we would not check for those intrinsics using __is_identifier or __is_builtin either. This change means that after the conditions using __GNUC__ we then check __is_identifier or __is_builtin for any features not yet defined. This probably doesn't achieve anything in practice, because Clang defines __GNUC__ to 4, and Intel defines it to match whatever GCC defines, so it will claim to be GCC 11 if using the libstdc++ headers from GCC 11. But it still seems more correct to do it this way. libstdc++-v3/ChangeLog: * include/bits/c++config: Do checks using __is_identifier and __is_builtin independent of checks for __GNUC__. diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index 2e6c880ad95a..abf6320082c0 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -664,21 +664,28 @@ namespace std # if __GNUC__ >= 11 # define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1 # endif -#elif defined(__is_identifier) && defined(__has_builtin) +#endif + +#if defined(__is_identifier) && defined(__has_builtin) // For non-GNU compilers: -# if ! __is_identifier(__has_unique_object_representations) +# if ! defined _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP \ + && ! __is_identifier(__has_unique_object_representations) # define _GLIBCXX_HAVE_BUILTIN_HAS_UNIQ_OBJ_REP 1 # endif -# if ! __is_identifier(__is_aggregate) +# if ! defined _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE \ + && ! __is_identifier(__is_aggregate) # define _GLIBCXX_HAVE_BUILTIN_IS_AGGREGATE 1 # endif -# if __has_builtin(__builtin_launder) +# if ! defined _GLIBCXX_HAVE_BUILTIN_LAUNDER \ + && __has_builtin(__builtin_launder) # define _GLIBCXX_HAVE_BUILTIN_LAUNDER 1 # endif -# if __has_builtin(__builtin_is_constant_evaluated) +# if ! defined _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED \ + && __has_builtin(__builtin_is_constant_evaluated) # define _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 1 # endif -# if ! __is_identifier(__is_same) +# if ! defined _GLIBCXX_HAVE_BUILTIN_IS_SAME \ + && ! __is_identifier(__is_same) # define _GLIBCXX_HAVE_BUILTIN_IS_SAME 1 # endif #endif // GCC