Skip to content

QNX compilation failure of .WillOnce() #3947

@mnil

Description

@mnil

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions