liblzma: Use __has_attribute(__symver__) to fix Clang detection.

If someone sets up Clang to define __GNUC__ to 10 or greater
then symvers broke. __has_attribute is supported by such GCC
and Clang versions that don't support __symver__ so this should
be much better and simpler way to detect if __symver__ is
actually supported.

Thanks to Tomasz Gajc for the bug report.
This commit is contained in:
Lasse Collin 2022-12-01 20:04:17 +02:00
parent 7e86a7632c
commit ef315163ef
1 changed files with 14 additions and 1 deletions

View File

@ -34,6 +34,14 @@
#include "lzma.h" #include "lzma.h"
// This is for detecting modern GCC and Clang attributes
// like __symver__ in GCC >= 10.
#ifdef __has_attribute
# define lzma_has_attribute(attr) __has_attribute(attr)
#else
# define lzma_has_attribute(attr) 0
#endif
// The extra symbol versioning in the C files may only be used when // The extra symbol versioning in the C files may only be used when
// building a shared library. If HAVE_SYMBOL_VERSIONS_LINUX is defined // building a shared library. If HAVE_SYMBOL_VERSIONS_LINUX is defined
// to 2 then symbol versioning is done only if also PIC is defined. // to 2 then symbol versioning is done only if also PIC is defined.
@ -63,7 +71,12 @@
// since 2000). When using @@ instead of @@@, the internal name must not be // since 2000). When using @@ instead of @@@, the internal name must not be
// the same as the external name to avoid problems in some situations. This // the same as the external name to avoid problems in some situations. This
// is why "#define foo_52 foo" is needed for the default symbol versions. // is why "#define foo_52 foo" is needed for the default symbol versions.
# if TUKLIB_GNUC_REQ(10, 0) && !defined(__INTEL_COMPILER) //
// __has_attribute is supported before GCC 10 and it is supported in Clang 14
// too (which doesn't support __symver__) so use it to detect if __symver__
// is available. This should be far more reliable than looking at compiler
// version macros as nowadays especially __GNUC__ is defined by many compilers.
# if lzma_has_attribute(__symver__)
# define LZMA_SYMVER_API(extnamever, type, intname) \ # define LZMA_SYMVER_API(extnamever, type, intname) \
extern __attribute__((__symver__(extnamever))) \ extern __attribute__((__symver__(extnamever))) \
LZMA_API(type) intname LZMA_API(type) intname