Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QNX compilation failure of .WillOnce() #3947

Open
mnil opened this issue Jul 15, 2022 · 8 comments
Open

QNX compilation failure of .WillOnce() #3947

mnil opened this issue Jul 15, 2022 · 8 comments

Comments

@mnil
Copy link

mnil commented Jul 15, 2022

Describe the bug

During an uplift of our gtest version we got compilation failures for our QNX compiler but not for gcc or clang.
I bisected it to this commit: 0498660 by @jacobsa.

Steps to reproduce the bug

The following works on gcc and clang but not on QNX 7:

#include <gmock/gmock.h>
#include <gtest/gtest.h>

class Turtle
{
 public:
    Turtle() {}
    virtual ~Turtle() {}
    virtual int age() const = 0;
};

class MockTurtle : public Turtle
{
 public:
    MOCK_METHOD(int, age, (), (const, override));
};

TEST(Turtle, TurtleAgeTest)
{
    MockTurtle turtle;
    EXPECT_CALL(turtle, age()).WillOnce(::testing::Return(1));
    turtle.age();
}

Changing .WillOnce() to .WillRepeatedly() makes it compile on all our platforms.

Does the bug persist in the most recent commit?

Verified that it fails on: bea621c

What operating system and version are you using?

Ubuntu 18.04.

What compiler and version are you using?

QNX 7.

What build system are you using?

Bazel 5.1.1.

Additional context

BUILD.bazel

cc_test(
    name = "foo",
    srcs = [
        "foo.cpp",
    ],
    deps = [
        "@googletest//:gtest_main",
    ],
)

Error message:

$ bazel build --config=aarch64_qnx_qcc //:foo
INFO: Invocation ID: c62e4d54-c742-4b31-8bd8-5892fc173d93
INFO: Analyzed target //:foo (<redacted>).
INFO: Found 1 target...
ERROR: /<redacted>/BUILD.bazel:8:10: Compiling foo.cpp failed: (Exit 1): qcc failed: error executing command external/qnx/qcc -V5.4.0,gcc_ntoaarch64le -Wc,-fstack-protector-strong -Wc,-fno-omit-frame-pointer -Wc,-fno-var-tracking '-Wc,-fmessage-length=0' -fno-math-errno -Wc,-fasynchronous-unwind-tables ... (remaining 50 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox
In file included from external/googletest/googlemock/include/gmock/gmock.h:56:0,
                 from foo.cpp:1:
external/googletest/googlemock/include/gmock/gmock-actions.h: In instantiation of 'struct testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >':
external/googletest/googlemock/include/gmock/gmock-actions.h:284:8:   required from 'struct testing::internal::conjunction<testing::internal::negation<std::__1::is_same<testing::OnceAction<int()>, std::__1::tuple<testing::OnceAction<int()>&&> > >, testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >, testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >'
external/googletest/googlemock/include/gmock/gmock-actions.h:476:30:   required by substitution of 'template<class Callable, typename std::__1::enable_if<testing::internal::conjunction<testing::internal::negation<std::__1::is_same<testing::OnceAction<int()>, typename std::__1::decay<_Tp>::type> >, testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >, testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >::value, int>::type <anonymous> > testing::OnceAction<Result(Args ...)>::OnceAction(Callable&&) [with Callable = std::__1::tuple<testing::OnceAction<int()>&&>; typename std::__1::enable_if<testing::internal::conjunction<testing::internal::negation<std::__1::is_same<testing::OnceAction<int()>, typename std::__1::decay<_Tp>::type> >, testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >, testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >::value, int>::type <anonymous> = <missing>]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/type_traits:2384:43:   required by substitution of 'template<class _Tp, class ... _Args> typename std::__1::__select_2nd<decltype (std::__1::move((_Tp)((declval<_Args>)()...))), std::__1::integral_constant<bool, true> >::type std::__1::__is_constructible_test(_Tp&&, _Args&& ...) [with _Tp = std::__1::tuple<testing::OnceAction<int()>&&>; _Args = {std::__1::tuple<testing::OnceAction<int()>&&>}]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/type_traits:2395:50:   required from 'struct std::__1::__libcpp_is_constructible<false, std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/type_traits:2443:8:   [ skipping 11 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/__tuple:290:8:   required from 'struct std::__1::__tuple_convertible<std::__1::tuple<std::__1::tuple<testing::OnceAction<int()>&&> >, std::__1::__tuple_types<testing::OnceAction<int()>&&>, true, true>'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/tuple:542:59:   required by substitution of 'template<class ... _Up, typename std::__1::enable_if<(((sizeof... (_Up) <= 1ul) && std::__1::__tuple_convertible<std::__1::tuple<_Tp ...>, typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type, std::__1::__tuple_like<typename std::__1::remove_reference<std::__1::tuple<_Tp ...> >::type>::value, std::__1::__tuple_like<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type>::value>::value) && std::__1::__all_default_constructible<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, 1ul, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul)>::type>::value), bool>::type <anonymous> > constexpr std::__1::tuple<_Tp>::tuple(_Up&& ...) [with _Up = {std::__1::tuple<testing::OnceAction<int()>&&>}; typename std::__1::enable_if<(((sizeof... (_Up) <= 1ul) && std::__1::__tuple_convertible<std::__1::tuple<_Tp ...>, typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type, std::__1::__tuple_like<typename std::__1::remove_reference<std::__1::tuple<_Tp ...> >::type>::value, std::__1::__tuple_like<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type>::value>::value) && std::__1::__all_default_constructible<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, 1ul, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul)>::type>::value), bool>::type <anonymous> = <missing>]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/tuple:878:55:   required from 'constexpr std::__1::tuple<_Tp&& ...> std::__1::forward_as_tuple(_Tp&& ...) [with _Tp = {testing::OnceAction<int()>}]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/memory:3801:43:   required from 'std::__1::__shared_ptr_emplace<_Tp, _Alloc>::__shared_ptr_emplace(_Alloc, _Args&& ...) [with _Args = {testing::OnceAction<int()>}; _Tp = testing::OnceAction<int()>; _Alloc = std::__1::allocator<testing::OnceAction<int()> >]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/memory:4394:5:   required from 'static std::__1::shared_ptr<_Tp> std::__1::shared_ptr<_Tp>::make_shared(_Args&& ...) [with _Args = {testing::OnceAction<int()>}; _Tp = testing::OnceAction<int()>]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/memory:4758:40:   required from 'typename std::__1::enable_if<(! std::__1::is_array<_Tp>::value), std::__1::shared_ptr<_Tp> >::type std::__1::make_shared(_Args&& ...) [with _Tp = testing::OnceAction<int()>; _Args = {testing::OnceAction<int()>}; typename std::__1::enable_if<(! std::__1::is_array<_Tp>::value), std::__1::shared_ptr<_Tp> >::type = std::__1::shared_ptr<testing::OnceAction<int()> >]'
external/googletest/googlemock/include/gmock/gmock-spec-builders.h:986:40:   required from 'testing::internal::TypedExpectation<R(Args ...)>& testing::internal::TypedExpectation<R(Args ...)>::WillOnce(testing::OnceAction<Result(Args ...)>) [with R = int; Args = {}]'
foo.cpp:21:61:   required from here
external/googletest/googlemock/include/gmock/gmock-actions.h:271:41: error: incomplete type 'testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > >' used in nested name specifier
     : std::integral_constant<bool, bool(!P::value)> {};
                                         ^
external/googletest/googlemock/include/gmock/gmock-actions.h: In instantiation of 'struct testing::internal::conjunction<testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >, testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >':
external/googletest/googlemock/include/gmock/gmock-actions.h:284:8:   required from 'struct testing::internal::conjunction<testing::internal::negation<std::__1::is_same<testing::OnceAction<int()>, std::__1::tuple<testing::OnceAction<int()>&&> > >, testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >, testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >'
external/googletest/googlemock/include/gmock/gmock-actions.h:476:30:   required by substitution of 'template<class Callable, typename std::__1::enable_if<testing::internal::conjunction<testing::internal::negation<std::__1::is_same<testing::OnceAction<int()>, typename std::__1::decay<_Tp>::type> >, testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >, testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >::value, int>::type <anonymous> > testing::OnceAction<Result(Args ...)>::OnceAction(Callable&&) [with Callable = std::__1::tuple<testing::OnceAction<int()>&&>; typename std::__1::enable_if<testing::internal::conjunction<testing::internal::negation<std::__1::is_same<testing::OnceAction<int()>, typename std::__1::decay<_Tp>::type> >, testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >, testing::internal::conjunction<std::__1::is_constructible<typename std::__1::decay<_Tp>::type, Callable>, testing::internal::is_callable_r_impl<void, int, typename std::__1::decay<_Tp>::type> > >::value, int>::type <anonymous> = <missing>]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/type_traits:2384:43:   required by substitution of 'template<class _Tp, class ... _Args> typename std::__1::__select_2nd<decltype (std::__1::move((_Tp)((declval<_Args>)()...))), std::__1::integral_constant<bool, true> >::type std::__1::__is_constructible_test(_Tp&&, _Args&& ...) [with _Tp = std::__1::tuple<testing::OnceAction<int()>&&>; _Args = {std::__1::tuple<testing::OnceAction<int()>&&>}]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/type_traits:2395:50:   required from 'struct std::__1::__libcpp_is_constructible<false, std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/type_traits:2443:8:   required from 'struct std::__1::__is_constructible_void_check<false, std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/type_traits:2469:30:   [ skipping 11 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/tuple:542:59:   required by substitution of 'template<class ... _Up, typename std::__1::enable_if<(((sizeof... (_Up) <= 1ul) && std::__1::__tuple_convertible<std::__1::tuple<_Tp ...>, typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type, std::__1::__tuple_like<typename std::__1::remove_reference<std::__1::tuple<_Tp ...> >::type>::value, std::__1::__tuple_like<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type>::value>::value) && std::__1::__all_default_constructible<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, 1ul, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul)>::type>::value), bool>::type <anonymous> > constexpr std::__1::tuple<_Tp>::tuple(_Up&& ...) [with _Up = {std::__1::tuple<testing::OnceAction<int()>&&>}; typename std::__1::enable_if<(((sizeof... (_Up) <= 1ul) && std::__1::__tuple_convertible<std::__1::tuple<_Tp ...>, typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type, std::__1::__tuple_like<typename std::__1::remove_reference<std::__1::tuple<_Tp ...> >::type>::value, std::__1::__tuple_like<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul), 0ul>::type>::value>::value) && std::__1::__all_default_constructible<typename std::__1::__make_tuple_types<std::__1::tuple<testing::OnceAction<int()>&&>, 1ul, ((sizeof... (_Up) < 1ul) ? sizeof... (_Up) : 1ul)>::type>::value), bool>::type <anonymous> = <missing>]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/tuple:878:55:   required from 'constexpr std::__1::tuple<_Tp&& ...> std::__1::forward_as_tuple(_Tp&& ...) [with _Tp = {testing::OnceAction<int()>}]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/memory:3801:43:   required from 'std::__1::__shared_ptr_emplace<_Tp, _Alloc>::__shared_ptr_emplace(_Alloc, _Args&& ...) [with _Args = {testing::OnceAction<int()>}; _Tp = testing::OnceAction<int()>; _Alloc = std::__1::allocator<testing::OnceAction<int()> >]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/memory:4394:5:   required from 'static std::__1::shared_ptr<_Tp> std::__1::shared_ptr<_Tp>::make_shared(_Args&& ...) [with _Args = {testing::OnceAction<int()>}; _Tp = testing::OnceAction<int()>]'
/<redacted>/external/qnx/target/qnx7/usr/include/c++/v1/memory:4758:40:   required from 'typename std::__1::enable_if<(! std::__1::is_array<_Tp>::value), std::__1::shared_ptr<_Tp> >::type std::__1::make_shared(_Args&& ...) [with _Tp = testing::OnceAction<int()>; _Args = {testing::OnceAction<int()>}; typename std::__1::enable_if<(! std::__1::is_array<_Tp>::value), std::__1::shared_ptr<_Tp> >::type = std::__1::shared_ptr<testing::OnceAction<int()> >]'
external/googletest/googlemock/include/gmock/gmock-spec-builders.h:986:40:   required from 'testing::internal::TypedExpectation<R(Args ...)>& testing::internal::TypedExpectation<R(Args ...)>::WillOnce(testing::OnceAction<Result(Args ...)>) [with R = int; Args = {}]'
foo.cpp:21:61:   required from here
external/googletest/googlemock/include/gmock/gmock-actions.h:284:8: error: 'value' is not a member of 'testing::internal::negation<testing::internal::conjunction<std::__1::is_constructible<std::__1::tuple<testing::OnceAction<int()>&&>, std::__1::tuple<testing::OnceAction<int()>&&> >, testing::internal::is_callable_r_impl<void, int, std::__1::tuple<testing::OnceAction<int()>&&> > > >'
 struct conjunction<P1, Ps...>
        ^
cc: /<redacted>/external/qnx/host/linux/x86_64/usr/lib/gcc/aarch64-unknown-nto-qnx7.0.0/5.4.0/cc1plus error 1
Target //:foo failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 2.591s, Critical Path: 1.25s
INFO: 5 processes: 5 internal.
FAILED: Build did NOT complete successfully
@mnil mnil added the bug label Jul 15, 2022
@mjvankampen
Copy link
Contributor

mjvankampen commented Jul 19, 2022

Same issue here with latest QNX (gcc 8.3.0 based) under Windows with CMake

@derekmauro
Copy link
Member

QNX isn't officially supported. We would like a patch from the community to fix this issue.

@tntljc
Copy link

tntljc commented Aug 31, 2023

Same issue here with latest QNX (gcc 8.3.0 based) under Linux with CMake

@Primer81
Copy link

Primer81 commented May 29, 2024

Same issue using latest google-test V1.14.0 with QNX 7.1 qcc 8.3.0 under Windows 10 with CMake.
Downgrading to google-test V1.11.0 seems to fix the issue for me.

@malgorzatagora
Copy link

malgorzatagora commented Aug 16, 2024

Hi, does anyone know if a patch fixing that issue is available?

@clanghans
Copy link

Debugged into this but couldn't find the issue.

In case anybody is interested, boiled down the code to reproduce the issue below.

#include <gmock/gmock.h>
#include <gtest/gtest.h>

int main (int argc, char *argv[]) {
  auto fn = [](){return 0;};

  testing::OnceAction<int()> once(fn); 
  testing::OnceAction<int()> second(std::move(once));
  
  std::tuple<testing::OnceAction<int()>> t1(fn);
  std::tuple<testing::OnceAction<int()>> t2(std::move(t1));
  
  return 0;
}
#include <gmock/gmock.h>
#include <gtest/gtest.h> 

int main (int argc, char *argv[]){ 
  using k = std::__1::is_constructible<
      std::__1::tuple<testing::OnceAction<int()>>, 
      std::__1::tuple<testing::OnceAction<int()>> 
    >; 
  return sizeof(k);
}

@dacolj
Copy link

dacolj commented Nov 26, 2024

Hi, if it can help, on my side I was able to fix the issue by applying this change from QNX googletest fork :
qnx/googletest@ceebbad#diff-91a00bafe0b6186545af81d16fdc9a5fd0afccfc336bdbbcab5deb7de63a57f6R473

(I'm using googletest v1.15.2)

@clanghans
Copy link

clanghans commented Dec 4, 2024

works, thanks @dacolj

are you sure the ___QNX__ has three underscores, it shows an -Wundef warning for me and this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants