Thread

Commits

  1. Fix 8a934d677 for libc++ and make more include order resistant.

  1. BUG #15270: __builtin_isinf conflict when building using clang

    The Post Office <noreply@postgresql.org> — 2018-07-09T19:00:31Z

    The following bug has been logged on the website:
    
    Bug reference:      15270
    Logged by:          Steven Winfield
    Email address:      steven.winfield@cantabcapital.com
    PostgreSQL version: 11beta2
    Operating system:   RHEL 7.4
    Description:        
    
    Hi,
    
    I've been experimenting with getting the whole of PG 11beta2 (not just the
    JIT) compiling with the most recent stable version of llvm/clang: 6.0.1.
    
    TL;DR: In src/include/port.h, inside the #else branch of #ifndef HAVE_ISINF,
    there probably need to be some glibc version checks within the #ifdef
    __clang__ block.
    
    
    
    Full version:
    
    I'm running on RHEL 7.4, with gcc 4.8.5 installed. The glibc version is 2.17
    (as reported by ldd --version).
    I used gcc to bootstrap llvm/clang 6.0.1, and then used that to rebuild
    everything (and by "everything" I mean llvm, cfe (clang), clang-tools-extra,
    lld, polly, compiler-rt, libcxx, and libcxxabi).
    
    I configured postgres 11beta2 like this:
    
    Environment variables:
    CC = "clang"
    CFLAGS = "-O3 -flto=thin -I<my clang install>/include/c++/v1"
    CXX = "clang"
    CXXFLAGS = "-O3 -flto=thin -stdlib=libc++ -I<my clang
    install>/include/c++/v1"
    LDFLAGS = "-fuse-ld=lld -flto=thin -L<my clang install>/lib"
    CPP = "clang -E"
    CLANG = "clang"
    
    Configure options:
    --disable-rpath
    --with-includes=<my clang install>/include
    --with-libraries=<my clang install>/lib
    --with-python
    --with-libxslt
    --with-gssapi
    --with-pam
    --with-ldap
    --with-openssl
    --with-llvm
    
    Configure performed the isinf check:
    
    configure:15250: checking for isinf
    configure:15269: clang -o conftest -Wall -Wmissing-prototypes
    -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels
    -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv
    -Wno-unused-command-line-argument -O3 -flto=thin ...
    configure:15269: $? = 0
    configure:15277: result: yes
    
    ...and set HAVE_ISINF in pg_config.h:
    
    /* Define to 1 if you have isinf(). */
    #define HAVE_ISINF 1
    
    
    However, compilation failed in llvmjit_error.cpp like this:
    
    In file included from llvmjit_error.cpp:24:
    In file included from ../../../../src/include/jit/llvmjit.h:18:
    In file included from <my clang install>/include/llvm-c/Types.h:17:
    In file included from <my clang
    install>/include/llvm/Support/DataTypes.h:33:
    In file included from <my clang install>/include/c++/v1/cmath:305:
    In file included from <my clang install>/include/c++/v1/math.h:301:
    In file included from /usr/include/math.h:70:
    /usr/include/bits/mathcalls.h:202:19: error: conflicting types for
    '__builtin_isinf'
    __MATHDECL_1 (int,isinf,, (_Mdouble_ __value)) __attribute__
    ((__const__));
                      ^
    ../../../../src/include/port.h:356:15: note: expanded from macro 'isinf'
    #define isinf __builtin_isinf
                  ^
    /usr/include/bits/mathcalls.h:202:19: note: '__builtin_isinf' is a builtin
    with type 'int (...) noexcept'
    ../../../../src/include/port.h:356:15: note: expanded from macro 'isinf'
    #define isinf __builtin_isinf
    
    
    Looking in src/include/port.h I found this:
    
    #ifndef HAVE_ISINF
    extern int      isinf(double x);
    #else
    /*
     * Glibc doesn't use the builtin for clang due to a *gcc* bug in a version
     * newer than the gcc compatibility clang claims to have. This would cause
    a
     * *lot* of superfluous function calls, therefore revert when using clang.
     */
    #ifdef __clang__
    /* needs to be separate to not confuse other compilers */
    #if __has_builtin(__builtin_isinf)
    #undef isinf
    #define isinf __builtin_isinf
    #endif                                                  /*
    __has_builtin(isinf) */
    #endif                                                  /* __clang__ */
    #endif                                                  /* !HAVE_ISINF */
    
    I started afresh, and removed the whole of the #else branch above after
    running configure, then continued the build. Everything successfully
    compiled and I have confirmed the JIT works correctly. 
    
    (In case this is useful...
    In some unsuccessful attempts, when playing around with the environment
    variables listed above, I ran into runtime errors even after a successful
    compilation... I guess because the JIT provider is dynamically loaded. 
    The complaint was about a missing symbol in libLLVM, which I undecorated
    to:
    
    llvm::IRMover::move(std::__1::unique_ptr<llvm::Module,
    std::__1::default_delete<llvm::Module> >,
    llvm::ArrayRef<llvm::GlobalValue*>, std::__1::function<void
    (llvm::GlobalValue&, std::__1::function<void (llvm::GlobalValue&)>)>,
    bool)
    
    I think this was due to a mixture of c++ standard libraries being in use.)
    
    Best wishes,
    Steve.
    
    
  2. Re: BUG #15270: __builtin_isinf conflict when building using clang

    Andres Freund <andres@anarazel.de> — 2018-09-01T00:12:00Z

    On 2018-07-09 19:00:31 +0000, PG Bug reporting form wrote:
    > The following bug has been logged on the website:
    > 
    > Bug reference:      15270
    > Logged by:          Steven Winfield
    > Email address:      steven.winfield@cantabcapital.com
    > PostgreSQL version: 11beta2
    > Operating system:   RHEL 7.4
    > Description:        
    > 
    > Hi,
    > 
    > I've been experimenting with getting the whole of PG 11beta2 (not just the
    > JIT) compiling with the most recent stable version of llvm/clang: 6.0.1.
    > 
    > TL;DR: In src/include/port.h, inside the #else branch of #ifndef HAVE_ISINF,
    > there probably need to be some glibc version checks within the #ifdef
    > __clang__ block.
    
    The actual problem appears to be issues within libc++ (rather than
    libstdc++).  I nevertheless have restricted it to C for now, as there's
    no performance issue with the tiny amount of C++ in postgres.
    
    We probably need to find a better solution.
    
    Sorry for the late response!
    
    Greetings,
    
    Andres Freund