Search code examples
c++11gcccross-compilingqnx

libstdc++ QNX cross-compilation fails on mutex class compilation


I try to compile a cross-compiler for Linux-host and QNX-target.

Got the 5.1 version from foundry27 site.

So now I stall on compilation of target libstdc++ by intermediate xgcc just compiled. Error happen when it try to compile libstdc++/src/c++11/conditional_variable.cc Error message is:

In file included from                 /home/kovtyukhrd/toolchain/builds/gcc_5_1_branch/linux-x86-o-ntox86/i486-pc-nto-qnx8.0.0/libstdc++-v3/include/condition_variable:39:0,
             from ../../../../../libstdc++-v3/src/c++11/condition_variable.cc:25:
/home/kovtyukhrd/toolchain/builds/gcc_5_1_branch/linux-x86-o-ntox86/i486-pc-nto-qnx8.0.0/libstdc++-v3/include/mutex:126:5: error: explicitly defaulted function 'constexpr std::mutex::mutex()' cannot be declared as constexpr because the implicit declaration is not constexpr:
 mutex() noexcept = default;
 ^
/home/kovtyukhrd/toolchain/builds/gcc_5_1_branch/linux-x86-o-ntox86/i486-pc-nto-qnx8.0.0/libstdc++-v3/include/mutex:118:9: error: use of deleted function 'constexpr std::__mutex_base::__mutex_base()'
   class mutex : private __mutex_base
     ^
/home/kovtyukhrd/toolchain/builds/gcc_5_1_branch/linux-x86-o-ntox86/i486-pc-nto-qnx8.0.0/libstdc++-v3/include/mutex:65:15: note: 'constexpr std::__mutex_base::__mutex_base() noexcept' is implicitly deleted because its exception-specification does not match the implicit exception-specification 'noexcept (false)'
 constexpr __mutex_base() noexcept = default;
           ^

So now I can see, that compiler is try to implicitly delete __mutex_base constructor and then the compilation is fails when we try to use it in inherited class (mutex). Here we can read about implicit deletion of functions with explicit exception-specification, that is not compatible with implicit exception-specification (got this link here).

Now we should think about the "implicit exception-specification 'noexcept (false)'" of __mutex_base(). It can be implicitly specified to 'noexcept (false)' if it should to call a function, that has 'noexcept (false)' specification. But after preprocessor we has this code:

...
typedef struct _sync { int __count; unsigned __owner; } sync_t;
...
typedef struct _sync pthread_mutex_t;
...
typedef pthread_mutex_t __gthread_mutex_t;
...

    class __mutex_base
  {
  protected:
    typedef __gthread_mutex_t __native_type;


    __native_type _M_mutex = { 0x80000000, 0xffffffff };

    constexpr __mutex_base() noexcept = default;
# 78 "/home/kovtyukhrd/toolchain/builds/gcc_5_1_branch/linux-x86-o-ntox86/i486-pc-nto-qnx8.0.0/libstdc++-v3/include/mutex" 3
    __mutex_base(const __mutex_base&) = delete;
    __mutex_base& operator=(const __mutex_base&) = delete;
  };

And now -- the question: "Why the __mutex_base() has the implicit exception-specification 'noexcept (false)'?"

And another question is how should I correctly compile this library without any modifications in source code?


Solution

  • This is a problem in GCC 5.1, which has already been fixed in GCC 5.2. The issue is that 0x80000000 is not a valid initializer for the int member of the _sync struct, because it is out of range for an int and so is a value of type unsigned. Converting it to int requires a narrowing conversion, which is not permitted in constant expressions. This makes the constructor non-constexpr (the mention of noexcept(false) seems to be a red herring).