[PATCH 3/3] [LLVM] [sanitizer] add conditionals for libc
Konstantin Serebryany
konstantin.s.serebryany at gmail.com
Thu Apr 17 07:06:42 PDT 2014
Hi,
If you are trying to modify the libsanitizer files, please read here:
https://code.google.com/p/address-sanitizer/wiki/HowToContribute
--kcc
On Thu, Apr 17, 2014 at 5:49 PM, Bernhard Reutner-Fischer <
rep.dot.nop at gmail.com> wrote:
> Conditionalize usage of dlvsym(), nanosleep(), usleep();
> Conditionalize layout of struct sigaction and type of it's member
> sa_flags.
> Conditionalize glob_t members gl_closedir, gl_readdir, gl_opendir,
> gl_flags, gl_lstat, gl_stat.
> Check for availability of glob.h for use with above members.
> Check for availability of netrom/netrom.h, sys/ustat.h (for obsolete
> ustat() function), utime.h (for obsolete utime() function), wordexp.h.
> Determine size of sigset_t instead of hardcoding it.
> Determine size of struct statfs64, if available.
>
> Leave defaults to match what glibc expects but probe them for uClibc.
>
> Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop at gmail.com>
> ---
> CMakeLists.txt | 58 +++++++
> cmake/Modules/CompilerRTUtils.cmake | 15 ++
> cmake/Modules/FunctionExistsNotStub.cmake | 56 +++++++
> lib/interception/interception_linux.cc | 2 +
> lib/interception/interception_linux.h | 9 ++
> .../sanitizer_common_interceptors.inc | 101 +++++++++++-
> .../sanitizer_platform_limits_posix.cc | 44 ++++-
> .../sanitizer_platform_limits_posix.h | 27 +++-
> lib/sanitizer_common/sanitizer_posix_libcdep.cc | 9 ++
> make/platform/clang_linux.mk | 180
> +++++++++++++++++++++
> make/platform/clang_linux_test_libc.c | 68 ++++++++
> 11 files changed, 561 insertions(+), 8 deletions(-)
> create mode 100644 cmake/Modules/FunctionExistsNotStub.cmake
> create mode 100644 make/platform/clang_linux_test_libc.c
>
> diff --git a/CMakeLists.txt b/CMakeLists.txt
> index e1a7a1f..af8073e 100644
> --- a/CMakeLists.txt
> +++ b/CMakeLists.txt
> @@ -330,6 +330,64 @@ if(APPLE)
> -isysroot ${IOSSIM_SDK_DIR})
> endif()
>
> +set(ct_c ${COMPILER_RT_SOURCE_DIR}/make/platform/clang_linux_test_libc.c)
> +check_include_file(sys/ustat.h HAVE_SYS_USTAT_H)
> +check_include_file(utime.h HAVE_UTIME_H)
> +check_include_file(wordexp.h HAVE_WORDEXP_H)
> +check_include_file(glob.h HAVE_GLOB_H)
> +include(FunctionExistsNotStub)
> +check_function_exists_not_stub(${ct_c} nanosleep HAVE_NANOSLEEP)
> +check_function_exists_not_stub(${ct_c} usleep HAVE_USLEEP)
> +include(CheckTypeSize)
> +# check for sizeof sigset_t
> +set(oCMAKE_EXTRA_INCLUDE_FILES "${CMAKE_EXTRA_INCLUDE_FILES}")
> +set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} signal.h)
> +check_type_size("sigset_t" SIZEOF_SIGSET_T BUILTIN_TYPES_ONLY)
> +if(EXISTS HAVE_SIZEOF_SIGSET_T)
> + set(SIZEOF_SIGSET_T ${HAVE_SIZEOF_SIGSET_T})
> +endif()
> +set(CMAKE_EXTRA_INCLUDE_FILES "${oCMAKE_EXTRA_INCLUDE_FILES}")
> +# check for sizeof struct statfs64
> +set(oCMAKE_EXTRA_INCLUDE_FILES "${CMAKE_EXTRA_INCLUDE_FILES}")
> +check_include_file(sys/statfs.h HAVE_SYS_STATFS_H)
> +check_include_file(sys/vfs.h HAVE_SYS_VFS_H)
> +if(HAVE_SYS_STATFS_H)
> + set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} sys/statfs.h)
> +endif()
> +if(HAVE_SYS_VFS_H)
> + set(CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_EXTRA_INCLUDE_FILES} sys/vfs.h)
> +endif()
> +# Have to pass _LARGEFILE64_SOURCE otherwise there is no struct statfs64.
> +# We forcefully enable LFS to retain glibc legacy behaviour herein.
> +set(oCMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS})
> +set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
> -D_LARGEFILE64_SOURCE)
> +check_type_size("struct statfs64" SIZEOF_STRUCT_STATFS64)
> +if(EXISTS HAVE_SIZEOF_STRUCT_STATFS64)
> + set(SIZEOF_STRUCT_STATFS64 ${HAVE_SIZEOF_STRUCT_STATFS64})
> +else()
> + set(CMAKE_REQUIRED_DEFINITIONS ${oCMAKE_REQUIRED_DEFINITIONS})
> +endif()
> +set(CMAKE_EXTRA_INCLUDE_FILES "${oCMAKE_EXTRA_INCLUDE_FILES}")
> +# do not set(CMAKE_REQUIRED_DEFINITIONS ${oCMAKE_REQUIRED_DEFINITIONS})
> +# it back here either way.
> +include(CheckStructHasMember)
> +check_struct_has_member(glob_t gl_flags glob.h HAVE_GLOB_T_GL_FLAGS)
> +check_struct_has_member(glob_t gl_closedir glob.h HAVE_GLOB_T_GL_CLOSEDIR)
> +check_struct_has_member(glob_t gl_readdir glob.h HAVE_GLOB_T_GL_READDIR)
> +check_struct_has_member(glob_t gl_opendir glob.h HAVE_GLOB_T_GL_OPENDIR)
> +check_struct_has_member(glob_t gl_lstat glob.h HAVE_GLOB_T_GL_LSTAT)
> +check_struct_has_member(glob_t gl_stat glob.h HAVE_GLOB_T_GL_STAT)
> +
> +# folks seem to have an aversion to configure_file? So be it..
> +foreach(x HAVE_SYS_USTAT_H HAVE_UTIME_H HAVE_WORDEXP_H HAVE_GLOB_H
> +HAVE_NANOSLEEP HAVE_USLEEP SIZEOF_SIGSET_T SIZEOF_STRUCT_STATFS64
> +HAVE_GLOB_T_GL_FLAGS HAVE_GLOB_T_GL_CLOSEDIR
> +HAVE_GLOB_T_GL_READDIR HAVE_GLOB_T_GL_OPENDIR
> +HAVE_GLOB_T_GL_LSTAT HAVE_GLOB_T_GL_STAT)
> +def_undef_string(${x} SANITIZER_COMMON_CFLAGS)
> +endforeach()
> +
> +
> # Architectures supported by Sanitizer runtimes. Specific sanitizers may
> # support only subset of these (e.g. TSan works on x86_64 only).
> filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
> diff --git a/cmake/Modules/CompilerRTUtils.cmake
> b/cmake/Modules/CompilerRTUtils.cmake
> index e22e775..3a0beec 100644
> --- a/cmake/Modules/CompilerRTUtils.cmake
> +++ b/cmake/Modules/CompilerRTUtils.cmake
> @@ -59,3 +59,18 @@ macro(append_no_rtti_flag list)
> append_if(COMPILER_RT_HAS_FNO_RTTI_FLAG -fno-rtti ${list})
> append_if(COMPILER_RT_HAS_GR_FLAG /GR- ${list})
> endmacro()
> +
> +# Appends -Dvalue=${value}/-Uvalue to all strings in ARGN
> +macro(def_undef_string condition)
> + if("${${condition}}" STREQUAL "")
> + foreach(str ${ARGN})
> + set(${str} "${${str}} -U${condition}")
> + endforeach()
> + else()
> + foreach(str ${ARGN})
> + set(${str} "${${str}} '-D${condition}=${${condition}}'")
> + endforeach()
> + endif()
> +endmacro()
> +
> +
> diff --git a/cmake/Modules/FunctionExistsNotStub.cmake
> b/cmake/Modules/FunctionExistsNotStub.cmake
> new file mode 100644
> index 0000000..9f944dd
> --- /dev/null
> +++ b/cmake/Modules/FunctionExistsNotStub.cmake
> @@ -0,0 +1,56 @@
> +INCLUDE(CheckFunctionExists)
> +
> +# The following variables may be set before calling this macro to
> +# modify the way the check is run:
> +#
> +# CMAKE_REQUIRED_FLAGS = string of compile command line flags
> +# CMAKE_REQUIRED_DEFINITIONS = list of macros to define (-DFOO=bar)
> +# CMAKE_REQUIRED_INCLUDES = list of include directories
> +
> +macro(CHECK_FUNCTION_EXISTS_NOT_STUB CSRC FUNCTION VARIABLE)
> + if(NOT DEFINED CHECKED_STUB_${VARIABLE})
> + set(CHECKED_STUB_${VARIABLE} "done" CACHE INTERNAL "checked stub of
> ${FUNCTION}")
> + CHECK_FUNCTION_EXISTS("${FUNCTION}" "${VARIABLE}")
> + if(DEFINED ${VARIABLE})
> + if(NOT CMAKE_REQUIRED_QUIET)
> + message(STATUS "Looking for stubbed out ${FUNCTION}")
> + endif()
> + if(CMAKE_REQUIRED_INCLUDES)
> + set(MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_INCLUDES
> + "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
> + else()
> + set(MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_INCLUDES)
> + endif()
> + set(MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_FLAGS
> ${CMAKE_REQUIRED_FLAGS})
> + try_compile(${VARIABLE}
> + ${CMAKE_BINARY_DIR}
> + "${CSRC}"
> + COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
> + CMAKE_FLAGS
> + "-DCOMPILE_DEFINITIONS:STRING=-DL_features_h
> -DL_AC_CHECK_FUNC=${FUNCTION} -DL_AC_CHECK_FUNC_stub='defined
> __stub_${FUNCTION} || defined __stub___${FUNCTION}'"
> + "${MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_FLAGS}"
> + "${MACRO_CHECK_FUNCTION_EXISTS_NOT_STUB_INCLUDES}"
> + OUTPUT_VARIABLE OUTPUT
> + )
> + endif()
> + if(${VARIABLE})
> + set(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
> + file(APPEND
> ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
> + "Determining if function ${FUNCTION} is a stub "
> + "passed with the following output:\n"
> + "${OUTPUT}\n\n")
> + if(NOT CMAKE_REQUIRED_QUIET)
> + message(STATUS "Looking for stubbed out ${FUNCTION} - no stub")
> + endif()
> + else()
> + set(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}")
> + file(APPEND
> ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
> + "Determining if function ${FUNCTION} is a stub "
> + "failed with the following output:\n"
> + "${OUTPUT}\n\n")
> + if(NOT CMAKE_REQUIRED_QUIET)
> + message(STATUS "Looking for stubbed out ${FUNCTION} - stub found")
> + endif()
> + endif()
> + endif()
> +endmacro()
> diff --git a/lib/interception/interception_linux.cc
> b/lib/interception/interception_linux.cc
> index 6e908ac..c9b4a6e 100644
> --- a/lib/interception/interception_linux.cc
> +++ b/lib/interception/interception_linux.cc
> @@ -24,11 +24,13 @@ bool GetRealFunctionAddress(const char *func_name,
> uptr *func_addr,
> return real == wrapper;
> }
>
> +#ifdef HAVE_DLVSYM
> #if !defined(__ANDROID__) // android does not have dlvsym
> void *GetFuncAddrVer(const char *func_name, const char *ver) {
> return dlvsym(RTLD_NEXT, func_name, ver);
> }
> #endif // !defined(__ANDROID__)
> +#endif // HAVE_DLVSYM
>
> } // namespace __interception
>
> diff --git a/lib/interception/interception_linux.h
> b/lib/interception/interception_linux.h
> index d3f774b..4802fe5 100644
> --- a/lib/interception/interception_linux.h
> +++ b/lib/interception/interception_linux.h
> @@ -25,7 +25,9 @@ namespace __interception {
> // returns true if a function with the given name was found.
> bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
> uptr real, uptr wrapper);
> +# ifdef HAVE_DLVSYM
> void *GetFuncAddrVer(const char *func_name, const char *ver);
> +# endif /* HAVE_DLVSYM */
> } // namespace __interception
>
> #define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
> \
> @@ -43,5 +45,12 @@ void *GetFuncAddrVer(const char *func_name, const char
> *ver);
> INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
> #endif // !defined(__ANDROID__)
>
> +#ifndef HAVE_DLVSYM
> +/* Undo marketing crap above. Probe functionality, use result to decide.
> */
> +# undef INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD
> +# define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
> + INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
> +#endif
> +
> #endif // INTERCEPTION_LINUX_H
> #endif // __linux__ || __FreeBSD__
> diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc
> b/lib/sanitizer_common/sanitizer_common_interceptors.inc
> index 0d076a0..0a767d4 100644
> --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
> +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
> @@ -1273,33 +1273,43 @@ static void unpoison_glob_t(void *ctx,
> __sanitizer_glob_t *pglob) {
>
> static THREADLOCAL __sanitizer_glob_t *pglob_copy;
>
> +#ifdef HAVE_GLOB_T_GL_CLOSEDIR
> static void wrapped_gl_closedir(void *dir) {
> COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
> IndirectExternCall(pglob_copy->gl_closedir)(dir);
> }
> +#endif
>
> +#ifdef HAVE_GLOB_T_GL_READDIR
> static void *wrapped_gl_readdir(void *dir) {
> COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
> return IndirectExternCall(pglob_copy->gl_readdir)(dir);
> }
> +#endif
>
> +#ifdef HAVE_GLOB_T_GL_OPENDIR
> static void *wrapped_gl_opendir(const char *s) {
> COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
> COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
> return IndirectExternCall(pglob_copy->gl_opendir)(s);
> }
> +#endif
>
> +#ifdef HAVE_GLOB_T_GL_LSTAT
> static int wrapped_gl_lstat(const char *s, void *st) {
> COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
> COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
> return IndirectExternCall(pglob_copy->gl_lstat)(s, st);
> }
> +#endif
>
> +#ifdef HAVE_GLOB_T_GL_STAT
> static int wrapped_gl_stat(const char *s, void *st) {
> COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
> COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
> return IndirectExternCall(pglob_copy->gl_stat)(s, st);
> }
> +#endif
>
> INTERCEPTOR(int, glob, const char *pattern, int flags,
> int (*errfunc)(const char *epath, int eerrno),
> @@ -1307,24 +1317,64 @@ INTERCEPTOR(int, glob, const char *pattern, int
> flags,
> void *ctx;
> COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
> __sanitizer_glob_t glob_copy = {
> - 0, 0, 0,
> - 0, wrapped_gl_closedir, wrapped_gl_readdir,
> - wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat};
> + 0,
> + 0,
> + 0
> +#ifdef HAVE_GLOB_T_GL_FLAGS
> + ,0
> +#endif
> +#ifdef HAVE_GLOB_T_GL_CLOSEDIR
> + ,wrapped_gl_closedir
> +#endif
> +#ifdef HAVE_GLOB_T_GL_READDIR
> + ,wrapped_gl_readdir
> +#endif
> +#ifdef HAVE_GLOB_T_GL_OPENDIR
> + ,wrapped_gl_opendir
> +#endif
> +#ifdef HAVE_GLOB_T_GL_LSTAT
> + ,wrapped_gl_lstat
> +#endif
> +#ifdef HAVE_GLOB_T_GL_STAT
> + ,wrapped_gl_stat
> +#endif
> + };
> +
> if (flags & glob_altdirfunc) {
> +#ifdef HAVE_GLOB_T_GL_CLOSEDIR
> Swap(pglob->gl_closedir, glob_copy.gl_closedir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_READDIR
> Swap(pglob->gl_readdir, glob_copy.gl_readdir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_OPENDIR
> Swap(pglob->gl_opendir, glob_copy.gl_opendir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_LSTAT
> Swap(pglob->gl_lstat, glob_copy.gl_lstat);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_STAT
> Swap(pglob->gl_stat, glob_copy.gl_stat);
> +#endif
> pglob_copy = &glob_copy;
> }
> int res = REAL(glob)(pattern, flags, errfunc, pglob);
> if (flags & glob_altdirfunc) {
> +#ifdef HAVE_GLOB_T_GL_CLOSEDIR
> Swap(pglob->gl_closedir, glob_copy.gl_closedir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_READDIR
> Swap(pglob->gl_readdir, glob_copy.gl_readdir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_OPENDIR
> Swap(pglob->gl_opendir, glob_copy.gl_opendir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_LSTAT
> Swap(pglob->gl_lstat, glob_copy.gl_lstat);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_STAT
> Swap(pglob->gl_stat, glob_copy.gl_stat);
> +#endif
> }
> pglob_copy = 0;
> if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
> @@ -1337,24 +1387,63 @@ INTERCEPTOR(int, glob64, const char *pattern, int
> flags,
> void *ctx;
> COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
> __sanitizer_glob_t glob_copy = {
> - 0, 0, 0,
> - 0, wrapped_gl_closedir, wrapped_gl_readdir,
> - wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat};
> + 0,
> + 0,
> + 0
> +#ifdef HAVE_GLOB_T_GL_FLAGS
> + ,0
> +#endif
> +#ifdef HAVE_GLOB_T_GL_CLOSEDIR
> + ,wrapped_gl_closedir
> +#endif
> +#ifdef HAVE_GLOB_T_GL_READDIR
> + ,wrapped_gl_readdir
> +#endif
> +#ifdef HAVE_GLOB_T_GL_OPENDIR
> + ,wrapped_gl_opendir
> +#endif
> +#ifdef HAVE_GLOB_T_GL_LSTAT
> + ,wrapped_gl_lstat
> +#endif
> +#ifdef HAVE_GLOB_T_GL_STAT
> + ,wrapped_gl_stat
> +#endif
> + };
> if (flags & glob_altdirfunc) {
> +#ifdef HAVE_GLOB_T_GL_CLOSEDIR
> Swap(pglob->gl_closedir, glob_copy.gl_closedir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_READDIR
> Swap(pglob->gl_readdir, glob_copy.gl_readdir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_OPENDIR
> Swap(pglob->gl_opendir, glob_copy.gl_opendir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_LSTAT
> Swap(pglob->gl_lstat, glob_copy.gl_lstat);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_STAT
> Swap(pglob->gl_stat, glob_copy.gl_stat);
> +#endif
> pglob_copy = &glob_copy;
> }
> int res = REAL(glob64)(pattern, flags, errfunc, pglob);
> if (flags & glob_altdirfunc) {
> +#ifdef HAVE_GLOB_T_GL_CLOSEDIR
> Swap(pglob->gl_closedir, glob_copy.gl_closedir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_READDIR
> Swap(pglob->gl_readdir, glob_copy.gl_readdir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_OPENDIR
> Swap(pglob->gl_opendir, glob_copy.gl_opendir);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_LSTAT
> Swap(pglob->gl_lstat, glob_copy.gl_lstat);
> +#endif
> +#ifdef HAVE_GLOB_T_GL_STAT
> Swap(pglob->gl_stat, glob_copy.gl_stat);
> +#endif
> }
> pglob_copy = 0;
> if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
> diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
> b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
> index 9ae4870..645777f 100644
> --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
> +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
> @@ -103,14 +103,18 @@
> #endif
>
> #if SANITIZER_LINUX || SANITIZER_FREEBSD
> +# ifdef HAVE_UTIME_H
> # include <utime.h>
> +# endif
> # include <sys/ptrace.h>
> #endif
>
> #if !SANITIZER_ANDROID
> #include <ifaddrs.h>
> #include <sys/ucontext.h>
> +# ifdef HAVE_WORDEXP_H
> #include <wordexp.h>
> +# endif
> #endif
>
> #if SANITIZER_LINUX && !SANITIZER_ANDROID
> @@ -119,7 +123,9 @@
> #include <net/if_ppp.h>
> #include <netax25/ax25.h>
> #include <netipx/ipx.h>
> +# ifdef HAVE_NETROM_NETROM_H
> #include <netrom/netrom.h>
> +# endif
> #include <rpc/xdr.h>
> #include <scsi/scsi.h>
> #include <sys/mtio.h>
> @@ -128,7 +134,9 @@
> #include <sys/statvfs.h>
> #include <sys/timex.h>
> #include <sys/user.h>
> +# ifdef HAVE_SYS_USTAT_H
> #include <sys/ustat.h>
> +# endif
> #include <linux/cyclades.h>
> #include <linux/if_eql.h>
> #include <linux/if_plip.h>
> @@ -215,12 +223,16 @@ namespace __sanitizer {
> #if SANITIZER_LINUX || SANITIZER_FREEBSD
> unsigned struct_rlimit_sz = sizeof(struct rlimit);
> unsigned struct_timespec_sz = sizeof(struct timespec);
> +# ifdef HAVE_UTIME_H
> unsigned struct_utimbuf_sz = sizeof(struct utimbuf);
> +# endif
> unsigned struct_itimerspec_sz = sizeof(struct itimerspec);
> #endif // SANITIZER_LINUX || SANITIZER_FREEBSD
>
> #if SANITIZER_LINUX && !SANITIZER_ANDROID
> +# ifdef HAVE_SYS_USTAT_H
> unsigned struct_ustat_sz = sizeof(struct ustat);
> +# endif
> unsigned struct_rlimit64_sz = sizeof(struct rlimit64);
> unsigned struct_statvfs64_sz = sizeof(struct statvfs64);
> #endif // SANITIZER_LINUX && !SANITIZER_ANDROID
> @@ -266,7 +278,9 @@ namespace __sanitizer {
>
> #if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
> int glob_nomatch = GLOB_NOMATCH;
> +# ifdef GLOB_ALTDIRFUNC
> int glob_altdirfunc = GLOB_ALTDIRFUNC;
> +# endif
> #endif
>
> #if SANITIZER_LINUX && !SANITIZER_ANDROID && \
> @@ -370,7 +384,9 @@ namespace __sanitizer {
> unsigned struct_kbkeycode_sz = sizeof(struct kbkeycode);
> unsigned struct_kbsentry_sz = sizeof(struct kbsentry);
> unsigned struct_mtconfiginfo_sz = sizeof(struct mtconfiginfo);
> +# ifdef HAVE_NETROM_NETROM_H
> unsigned struct_nr_parms_struct_sz = sizeof(struct nr_parms_struct);
> +# endif
> unsigned struct_scc_modem_sz = sizeof(struct scc_modem);
> unsigned struct_scc_stat_sz = sizeof(struct scc_stat);
> unsigned struct_serial_multiport_struct_sz
> @@ -805,10 +821,18 @@ namespace __sanitizer {
> unsigned IOCTL_SIOCAX25SETPARMS = SIOCAX25SETPARMS;
> unsigned IOCTL_SIOCDEVPLIP = SIOCDEVPLIP;
> unsigned IOCTL_SIOCIPXCFGDATA = SIOCIPXCFGDATA;
> +# ifdef SIOCNRDECOBS
> unsigned IOCTL_SIOCNRDECOBS = SIOCNRDECOBS;
> +# endif
> +# ifdef SIOCNRGETPARMS
> unsigned IOCTL_SIOCNRGETPARMS = SIOCNRGETPARMS;
> +# endif
> +# ifdef SIOCNRRTCTL
> unsigned IOCTL_SIOCNRRTCTL = SIOCNRRTCTL;
> +# endif
> +# ifdef SIOCNRSETPARMS
> unsigned IOCTL_SIOCNRSETPARMS = SIOCNRSETPARMS;
> +# endif
> unsigned IOCTL_TIOCGSERIAL = TIOCGSERIAL;
> unsigned IOCTL_TIOCSERGETMULTI = TIOCSERGETMULTI;
> unsigned IOCTL_TIOCSERSETMULTI = TIOCSERSETMULTI;
> @@ -890,12 +914,24 @@ CHECK_TYPE_SIZE(glob_t);
> CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);
> CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);
> CHECK_SIZE_AND_OFFSET(glob_t, gl_offs);
> +# ifdef HAVE_GLOB_T_GL_FLAGS
> CHECK_SIZE_AND_OFFSET(glob_t, gl_flags);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_CLOSEDIR
> CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_READDIR
> CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_OPENDIR
> CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_LSTAT
> CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_STAT
> CHECK_SIZE_AND_OFFSET(glob_t, gl_stat);
> +# endif
> #endif
>
> CHECK_TYPE_SIZE(addrinfo);
> @@ -967,11 +1003,17 @@ CHECK_TYPE_SIZE(sigset_t);
> COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction));
> // Can't write checks for sa_handler and sa_sigaction due to them being
> // preprocessor macros.
> +#if HAVE_STRUCT_SIGACTION_SA_MASK_LAST
> +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags);
> +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer);
> +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask);
> +#else // HAVE_STRUCT_SIGACTION_SA_MASK_LAST
> CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask);
> CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags);
> #if SANITIZER_LINUX
> CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_restorer);
> #endif
> +#endif // HAVE_STRUCT_SIGACTION_SA_MASK_LAST
>
> #if SANITIZER_LINUX
> CHECK_TYPE_SIZE(__sysctl_args);
> @@ -991,7 +1033,7 @@ CHECK_TYPE_SIZE(__kernel_loff_t);
> CHECK_TYPE_SIZE(__kernel_fd_set);
> #endif
>
> -#if !SANITIZER_ANDROID
> +#ifdef HAVE_WORDEXP_H
> CHECK_TYPE_SIZE(wordexp_t);
> CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);
> CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);
> diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
> b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
> index a780ee2..04c6a96 100644
> --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
> +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
> @@ -478,7 +478,8 @@ namespace __sanitizer {
> #elif SANITIZER_LINUX
> struct __sanitizer_sigset_t {
> // The size is determined by looking at sizeof of real sigset_t on
> linux.
> - uptr val[128 / sizeof(uptr)];
> + /* .. except this should be * sizeof(uptr), not '/', no? */
> + uptr val[SIZEOF_SIGSET_T / sizeof(uptr)];
> };
> #elif SANITIZER_FREEBSD
> struct __sanitizer_sigset_t {
> @@ -487,6 +488,17 @@ namespace __sanitizer {
> };
> #endif
>
> +#if HAVE_STRUCT_SIGACTION_SA_MASK_LAST
> + struct __sanitizer_sigaction {
> + union {
> + void (*sigaction)(int sig, void *siginfo, void *uctx);
> + void (*handler)(int sig);
> + };
> + STRUCT_SIGACTION_SA_FLAGS_TYPE sa_flags;
> + void (*sa_restorer)();
> + __sanitizer_sigset_t sa_mask;
> + };
> +#else // HAVE_STRUCT_SIGACTION_SA_MASK_LAST
> // Linux system headers define the 'sa_handler' and 'sa_sigaction'
> macros.
> struct __sanitizer_sigaction {
> union {
> @@ -504,6 +516,7 @@ namespace __sanitizer {
> void (*sa_restorer)();
> #endif
> };
> +#endif // HAVE_STRUCT_SIGACTION_SA_MASK_LAST
>
> #if SANITIZER_FREEBSD
> typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
> @@ -588,13 +601,25 @@ namespace __sanitizer {
> uptr gl_pathc;
> char **gl_pathv;
> uptr gl_offs;
> +# ifdef HAVE_GLOB_T_GL_FLAGS
> int gl_flags;
> +# endif
>
> +# ifdef HAVE_GLOB_T_GL_CLOSEDIR
> void (*gl_closedir)(void *dirp);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_READDIR
> void *(*gl_readdir)(void *dirp);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_OPENDIR
> void *(*gl_opendir)(const char *);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_LSTAT
> int (*gl_lstat)(const char *, void *);
> +# endif
> +# ifdef HAVE_GLOB_T_GL_STAT
> int (*gl_stat)(const char *, void *);
> +# endif
> };
> # elif SANITIZER_FREEBSD
> struct __sanitizer_glob_t {
> diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
> b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
> index bb6e587..973f698 100644
> --- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc
> +++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc
> @@ -73,7 +73,16 @@ void SleepForSeconds(int seconds) {
> }
>
> void SleepForMillis(int millis) {
> +#ifdef HAVE_NANOSLEEP
> + struct timespec ts;
> + ts.tv_sec = millis / 1000;
> + ts.tv_nsec = (millis % 1000) * 1000000;
> + nanosleep(&ts, NULL); /* could as well loop here */
> +#elif defined HAVE_USLEEP
> usleep(millis * 1000);
> +# else
> + dunno how to SleepForMillis
> +#endif
> }
>
> void Abort() {
> diff --git a/make/platform/clang_linux.mk b/make/platform/clang_linux.mk
> index c6921ea..5ce1567 100644
> --- a/make/platform/clang_linux.mk
> +++ b/make/platform/clang_linux.mk
> @@ -74,6 +74,185 @@ Arch.dfsan-x86_64 := x86_64
> Arch.lsan-x86_64 := x86_64
> endif
>
> +# TryCompile2 compiler source flags
> +# Returns exit code of running a compiler invocation.
> +# Same as TryCompile but in outer scope, don't want to touch the other one
> +TryCompile2 = \
> + $(shell \
> + cflags=""; \
> + for flag in $(3); do \
> + cflags="$$cflags $$flag"; \
> + done; \
> + $(1) $$cflags $(2) -o /dev/null > /dev/null 2> /dev/null ; \
> + echo $$?)
> +
> +# our conftest.c
> +ct_c = $(ProjSrcRoot)/make/platform/clang_linux_test_libc.c
> +
> +HAVE_DLVSYM := 1
> +HAVE_NETROM_NETROM_H := 1
> +HAVE_GLOB_H := 1
> +HAVE_NANOSLEEP := 1
> +HAVE_GLOB_T_GL_CLOSEDIR := 1
> +HAVE_GLOB_T_GL_FLAGS := 1
> +HAVE_GLOB_T_GL_LSTAT := 1
> +HAVE_GLOB_T_GL_OPENDIR := 1
> +HAVE_GLOB_T_GL_READDIR := 1
> +HAVE_GLOB_T_GL_STAT := 1
> +HAVE_STRUCT_SIGACTION_SA_MASK_LAST := 0
> +HAVE_SYS_USTAT_H := 1
> +HAVE_USLEEP := 1
> +HAVE_UTIME_H := 1
> +HAVE_WORDEXP_H := 1
> +SIZEOF_STRUCT_STATFS64 := 120
> +SIZEOF_SIGSET_T := 128
> +STRUCT_SIGACTION_SA_FLAGS_TYPE := int
> +
> +#ifneq ($(findstring -uclibc,$(CompilerTargetTriple)),)
> +# does not work, cross-compilation seems to be non-working?
> +ifeq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN -DL_AC_CHECK_UCLIBC
> -DL_AC_CHECK_HEADER="<stdio.h>",),0)
> + HAVE_DLVSYM :=
> + HAVE_NETROM_NETROM_H :=
> + STRUCT_SIGACTION_SA_FLAGS_TYPE := unsigned long
> +ifneq ($(filter alpha%,$(CompilerTargetTriple)),)
> + STRUCT_SIGACTION_SA_FLAGS_TYPE := unsigned
> +endif
> +ifneq ($(filter mips%,$(CompilerTargetTriple)),)
> + STRUCT_SIGACTION_SA_FLAGS_TYPE := unsigned
> +endif
> + HAVE_STRUCT_SIGACTION_SA_MASK_LAST := 1
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN
> -DL_AC_CHECK_HEADER="<sys/ustat.h>",),0)
> + HAVE_SYS_USTAT_H :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN
> -DL_AC_CHECK_HEADER="<utime.h>",),0)
> + HAVE_UTIME_H :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN
> -DL_AC_CHECK_HEADER="<wordexp.h>",),0)
> + HAVE_WORDEXP_H :=
> +endif
> +glob_h := -DL_AC_CHECK_HEADER="<glob.h>"
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN $(glob_h),),0)
> + HAVE_GLOB_H :=
> +endif
> +# check for struct glob members (check for GNU extensions)
> +glob_h += -DL_AC_STRUCT="glob_t"
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h)
> -DL_AC_CHECK_STRUCT_MEMBER=gl_flags,),0)
> + HAVE_GLOB_T_GL_FLAGS :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h)
> -DL_AC_CHECK_STRUCT_MEMBER=gl_closedir,),0)
> + HAVE_GLOB_T_GL_CLOSEDIR :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h)
> -DL_AC_CHECK_STRUCT_MEMBER=gl_readdir,),0)
> + HAVE_GLOB_T_GL_READDIR :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h)
> -DL_AC_CHECK_STRUCT_MEMBER=gl_opendir,),0)
> + HAVE_GLOB_T_GL_OPENDIR :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h)
> -DL_AC_CHECK_STRUCT_MEMBER=gl_lstat,),0)
> + HAVE_GLOB_T_GL_LSTAT :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) $(glob_h)
> -DL_AC_CHECK_STRUCT_MEMBER=gl_stat,),0)
> + HAVE_GLOB_T_GL_STAT :=
> +endif
> +# check misc functions
> +# for __stub_* on glibc and uClibc including features.h is enough
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_features_h
> -DL_AC_CHECK_FUNC=nanosleep -DL_AC_CHECK_FUNC_stub="defined
> __stub_nanosleep || defined __stub___nanosleep",),0)
> + HAVE_NANOSLEEP :=
> +endif
> +ifneq ($(call TryCompile2,$(CC),$(ct_c) -DL_features_h
> -DL_AC_CHECK_FUNC=usleep -DL_AC_CHECK_FUNC_stub="defined __stub_usleep ||
> defined __stub___usleep",),0)
> + HAVE_USLEEP :=
> +endif
> +
> +# AC_CHECK_SIZEOF, in make
> +define ac_check_sizeof
> +$(shell \
> +if test $$($(CC) $(1) -DL_AC_SIZEOF_GE=0 -o /dev/null > /dev/null 2>
> /dev/null; echo $$?) -eq 0; \
> +then \
> + ac_lo=0 ac_mid=0; \
> + while :; \
> + do \
> + if test $$($(CC) $(1) -DL_AC_SIZEOF_LE=$$ac_mid -o /dev/null >
> /dev/null 2> /dev/null; echo $$?) -eq 0; then \
> + ac_hi=$$ac_mid; \
> + break; \
> + else \
> + ac_lo=$$(( $$ac_mid + 1 )); \
> + if test $$ac_lo -le $$ac_mid; then ac_lo= ac_hi=; break; fi; \
> + ac_mid=$$(( 2 * $$ac_mid + 1 )); \
> + fi; \
> + done; \
> +else \
> + if test $$($(CC) $(1) -DL_AC_SIZEOF_LT=0 -o /dev/null > /dev/null 2>
> /dev/null; echo $$?) -eq 0; then \
> + ac_hi=-1 ac_mid=-1; \
> + while :; \
> + do \
> + if test $$($(CC) $(1) -DL_AC_SIZEOF_GE=$$ac_mid -o /dev/null >
> /dev/null 2> /dev/null; echo $$?) -eq 0; then \
> + ac_lo=$$ac_mid; \
> + break; \
> + else \
> + ac_hi=$$(( ($$ac_mid) - 1 )); \
> + if test $$ac_mid -le $$ac_hi; then ac_lo= ac_hi=; break; fi; \
> + ac_mid=$$(( 2 * $$ac_mid )); \
> + fi; \
> + done; \
> + else \
> + ac_lo= ac_hi=; \
> + fi; \
> +fi; \
> +while test "x$$ac_lo" != "x$$ac_hi"; \
> +do \
> + ac_mid=$$(( ($$ac_hi - $$ac_lo) / 2 + $$ac_lo )); \
> + if test $$($(CC) $(1) -DL_AC_SIZEOF_LE=$$ac_mid -o /dev/null >
> /dev/null 2> /dev/null; echo $$?) -eq 0; then \
> + ac_hi=$$ac_mid; \
> + else \
> + ac_lo=$$(( ($$ac_mid) + 1 )); \
> + fi; \
> +done; \
> +echo $$(( $$ac_lo + 0 )); \
> +)
> +endef
> +
> +# determine sizeof sigset_t
> +SIZEOF_SIGSET_T := $(call ac_check_sizeof,$(ct_c)
> -DL_AC_CHECK_HEADER="<signal.h>" -DL_AC_SIZEOF="sigset_t")
> +
> +# determine sizeof struct statfs64
> +SIZEOF_STRUCT_STATFS64 := 0
> +ifeq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN
> -DL_AC_CHECK_HEADER="<sys/statfs.h>",),0)
> +SIZEOF_STRUCT_STATFS64 := $(call ac_check_sizeof,$(ct_c)
> -DL_AC_CHECK_HEADER="<sys/statfs.h>" -DL_AC_SIZEOF="struct statfs64")
> +else
> + ifeq ($(call TryCompile2,$(CC),$(ct_c) -DL_MAIN
> -DL_AC_CHECK_HEADER="<sys/vfs.h>",),0)
> + SIZEOF_STRUCT_STATFS64 := $(call ac_check_sizeof,$(ct_c)
> -DL_AC_CHECK_HEADER="<sys/vfs.h>" -DL_AC_SIZEOF="struct statfs64")
> + endif
> +endif
> +# end of -uclibc handling
> +endif
> +
> +define add_config_h_cppflag
> +ifeq ($($(1)),)
> +CONFIG_H_CPPFLAGS += -U$(1)
> +else
> +CONFIG_H_CPPFLAGS += '-D$(1)=$($(1))'
> +endif
> +endef
> +
> +CONFIG_H_CPPFLAGS :=
> +$(eval $(call add_config_h_cppflag,HAVE_DLVSYM))
> +$(eval $(call add_config_h_cppflag,HAVE_GLOB_H))
> +$(eval $(call add_config_h_cppflag,HAVE_NANOSLEEP))
> +$(eval $(call add_config_h_cppflag,HAVE_NETROM_NETROM_H))
> +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_CLOSEDIR))
> +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_FLAGS))
> +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_LSTAT))
> +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_OPENDIR))
> +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_READDIR))
> +$(eval $(call add_config_h_cppflag,HAVE_GLOB_T_GL_STAT))
> +$(eval $(call add_config_h_cppflag,HAVE_STRUCT_SIGACTION_SA_MASK_LAST))
> +$(eval $(call add_config_h_cppflag,HAVE_SYS_USTAT_H))
> +$(eval $(call add_config_h_cppflag,HAVE_USLEEP))
> +$(eval $(call add_config_h_cppflag,HAVE_UTIME_H))
> +$(eval $(call add_config_h_cppflag,HAVE_WORDEXP_H))
> +$(eval $(call add_config_h_cppflag,SIZEOF_STRUCT_STATFS64))
> +$(eval $(call add_config_h_cppflag,SIZEOF_SIGSET_T))
> +$(eval $(call add_config_h_cppflag,STRUCT_SIGACTION_SA_FLAGS_TYPE))
> endif
>
> ifneq ($(LLVM_ANDROID_TOOLCHAIN_DIR),)
> @@ -87,6 +266,7 @@ endif
>
> CFLAGS := -Wall -Werror -O3 -fomit-frame-pointer
> SANITIZER_CFLAGS := -fPIE -fno-builtin -gline-tables-only
> +CFLAGS += $(CONFIG_H_CPPFLAGS)
>
> CFLAGS.full-i386 := $(CFLAGS) -m32
> CFLAGS.full-x86_64 := $(CFLAGS) -m64
> diff --git a/make/platform/clang_linux_test_libc.c
> b/make/platform/clang_linux_test_libc.c
> new file mode 100644
> index 0000000..2f9bba8
> --- /dev/null
> +++ b/make/platform/clang_linux_test_libc.c
> @@ -0,0 +1,68 @@
> +/* This file is used to check for libc characteristics and features */
> +#ifdef L_features_h
> +# include <features.h>
> +#endif
> +
> +#ifdef L_AC_CHECK_HEADER
> +/* compile-time check for availability of a header */
> +# include L_AC_CHECK_HEADER
> +#endif
> +
> +#ifdef L_AC_CHECK_UCLIBC
> +# ifndef __UCLIBC__
> +choke me /* not uClibc */
> +# endif
> +#endif
> +
> +#ifdef L_MAIN
> +/* provide a dummy main for the linker */
> +int main()
> +{
> + return 0;
> +}
> +#endif
> +
> +#ifdef L_AC_CHECK_STRUCT_MEMBER
> +/* compile-time check for presence of struct member */
> +int main()
> +{
> + static L_AC_STRUCT ac_aggr;
> + if (ac_aggr.L_AC_CHECK_STRUCT_MEMBER)
> + return 0;
> + return 0;
> +}
> +#endif
> +
> +#ifdef L_AC_CHECK_FUNC
> +/* check if function (or macro) is available */
> +# ifdef __cplusplus
> +extern "C"
> +# endif
> +# if L_AC_CHECK_FUNC_stub
> +choke me /* function 'L_AC_CHECK_FUNC' stubbed out! */
> +# endif
> +char L_AC_CHECK_FUNC ();
> +int main ()
> +{
> + return L_AC_CHECK_FUNC ();
> +}
> +#endif
> +
> +#ifdef L_AC_SIZEOF
> +/* Determine sizeof expression */
> +int main ()
> +{
> +# define s (long int) (sizeof (L_AC_SIZEOF))
> +# if defined L_AC_SIZEOF_GE
> + static int test_array [1 - 2 * !((s) >= L_AC_SIZEOF_GE)];
> +# elif defined L_AC_SIZEOF_LE
> + static int test_array [1 - 2 * !((s) <= L_AC_SIZEOF_LE)];
> +# elif defined L_AC_SIZEOF_LT
> + static int test_array [1 - 2 * !((s) < L_AC_SIZEOF_LT)];
> +# else
> +# error no such comparison operator
> +# endif
> + test_array [0] = 0;
> + return 0;
> +}
> +#endif
> --
> 1.9.1
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140417/128e4dde/attachment.html>
More information about the llvm-commits
mailing list