Skip to content

Conversation

@ajneu
Copy link
Contributor

@ajneu ajneu commented Mar 5, 2016

Hi Alex,

here is some initial work on getting embxx to compile with clang-3.7 and clang++-3.7.
Errors are removed, but there are still some warnings left, that one should investigate.

So no need, for this to be merged just yet. You can just leave this pull-request open, as a base, for people to base their further work on, regarding issue #7

Edit: I should mention, that many of the errors removed, actually seem to be just working around limitations of clang. So g++ really does feel much more mature, at least for the time being.

@ajneu ajneu mentioned this pull request Apr 21, 2016
…etails::StaticQueueBaseOptimised<T>), since we pass &array_[0] to Base's constructor

This removes the following clang warning: warning: field 'array_' is uninitialized when used here
@ajneu
Copy link
Contributor Author

ajneu commented Feb 25, 2017

The compilation (non-cross, i.e. desktop-target) on clang is working very well, when using libstdc++.
To try it:

sudo apt-get install clang                     # clang

git clone https://github.com/ajneu/embxx.git
cd embxx/
git checkout clang  # special branch for clang (equivalent with this pull-request)

mkdir build
cd    build

export CC=clang; export CXX=clang++

cmake ..
make -j4
make test

But when using clang with libc++ (see below), there are errors which I don't know how to remove.
Try:

sudo apt-get install clang                     # clang
sudo apt-get install libc++-dev libc++abi-dev  # libc++ (https://libcxx.llvm.org/)

git clone https://github.com/ajneu/embxx.git
cd embxx/
git checkout clang  # special branch for clang (equivalent with this pull-request)

mkdir build
cd    build

export CC=clang; export CXX=clang++

cmake -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ -lc++abi" ..
make -j4

The errors are static_asserts here, and the output is the following:

In file included from /tmp/embxx/build/module/driver/test/GenericTestRunner.cpp:23:
In file included from /tmp/embxx/module/driver/test/Generic.th:19:
/tmp/embxx/embxx/util/StaticFunction.h:421:5: error: static_assert failed "Wrong function invocation"
    static_assert(!std::is_same<ThisType, DecayedFuncType>::value,
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/embxx/embxx/util/StaticFunction.h:196:5: note: in instantiation of function template specialization 'embxx::util::StaticFunction<void (),
      24>::assignHandler<embxx::util::StaticFunction<void (), 24> &>' requested here
    assignHandler(std::forward<TFunc>(func));
    ^
/usr/include/c++/v1/functional:2078:11: note: in instantiation of function template specialization 'embxx::util::StaticFunction<void (),
      24>::StaticFunction<embxx::util::StaticFunction<void (), 24> &>' requested here
        : __f_(_VSTD::forward<_Gp>(__f)),
          ^
/usr/include/c++/v1/functional:2187:12: note: in instantiation of function template specialization 'std::__1::__bind<embxx::util::StaticFunction<void (), 24>
      &>::__bind<embxx::util::StaticFunction<void (), 24> &, void>' requested here
    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
           ^
/tmp/embxx/embxx/driver/Generic.h:199:26: note: in instantiation of function template specialization 'std::__1::bind<embxx::util::StaticFunction<void (), 24> &>' requested here
                    std::bind(handler_, args...));
                         ^
/tmp/embxx/module/driver/test/Generic.th:76:12: note: in instantiation of function template specialization
      'embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (), 24> >, embxx::util::EventLoop<132, embxx::device::test::EventLoopLock,
      embxx::device::test::EventLoopCond>, void (), embxx::util::StaticFunction<void (), 24> >::setHandler<(lambda at /tmp/embxx/module/driver/test/Generic.th:77:9)>' requested here
    driver.setHandler(
           ^
In file included from /tmp/embxx/build/module/driver/test/GenericTestRunner.cpp:23:
In file included from /tmp/embxx/module/driver/test/Generic.th:19:
/tmp/embxx/embxx/util/StaticFunction.h:424:5: error: static_assert failed "Increase the TSize template argument of the StaticFucntion"
    static_assert(sizeof(InvokerBoundType) <= StorageAreaSize,
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/embxx/embxx/util/StaticFunction.h:421:5: error: static_assert failed "Wrong function invocation"
    static_assert(!std::is_same<ThisType, DecayedFuncType>::value,
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/embxx/embxx/util/StaticFunction.h:196:5: note: in instantiation of function template specialization 'embxx::util::StaticFunction<void (char),
      24>::assignHandler<embxx::util::StaticFunction<void (char), 24> &>' requested here
    assignHandler(std::forward<TFunc>(func));
    ^
/usr/include/c++/v1/functional:2078:11: note: in instantiation of function template specialization 'embxx::util::StaticFunction<void (char),
      24>::StaticFunction<embxx::util::StaticFunction<void (char), 24> &>' requested here
        : __f_(_VSTD::forward<_Gp>(__f)),
          ^
/usr/include/c++/v1/functional:2187:12: note: in instantiation of function template specialization 'std::__1::__bind<embxx::util::StaticFunction<void (char), 24> &, char
      &>::__bind<embxx::util::StaticFunction<void (char), 24> &, char &, void>' requested here
    return type(_VSTD::forward<_Fp>(__f), _VSTD::forward<_BoundArgs>(__bound_args)...);
           ^
/tmp/embxx/embxx/driver/Generic.h:199:26: note: in instantiation of function template specialization 'std::__1::bind<embxx::util::StaticFunction<void (char), 24> &, char &>' requested
      here
                    std::bind(handler_, args...));
                         ^
/tmp/embxx/module/driver/test/Generic.th:104:12: note: in instantiation of function template specialization
      'embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (char), 24> >, embxx::util::EventLoop<132, embxx::device::test::EventLoopLock,
      embxx::device::test::EventLoopCond>, void (char), embxx::util::StaticFunction<void (char), 24> >::setHandler<(lambda at /tmp/embxx/module/driver/test/Generic.th:105:9)>' requested
      here
    driver.setHandler(
           ^
In file included from /tmp/embxx/build/module/driver/test/GenericTestRunner.cpp:23:
In file included from /tmp/embxx/module/driver/test/Generic.th:19:
/tmp/embxx/embxx/util/StaticFunction.h:424:5: error: static_assert failed "Increase the TSize template argument of the StaticFucntion"
    static_assert(sizeof(InvokerBoundType) <= StorageAreaSize,
    ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 errors generated.

It's rather strange... these static asserts.
They only pop up when using a different standard c++ library...

@ajneu
Copy link
Contributor Author

ajneu commented Feb 25, 2017

It's rather strange... these static asserts.
They only pop up when using a different standard c++ library...

I've tried increasing TSize in this line, but it does not help

@ajneu
Copy link
Contributor Author

ajneu commented Feb 25, 2017

Some investigation regarding the static_asserts here

If you change the following lines, to this:

    std::cout << "\n"
	         "ThisType        : " << typeid(ThisType).name()        << "\n"
	         "DecayedFuncType : " << typeid(DecayedFuncType).name() << '\n';

    std::cout << "InvokerBoundType: " << typeid(InvokerBoundType).name()  << "\n"
                 "sizeof(InvokerBoundType): " << sizeof(InvokerBoundType) << "\n"
	         "StorageAreaSize         : " << StorageAreaSize          << std::endl;

    // static_assert(!std::is_same<ThisType, DecayedFuncType>::value,
    //     "Wrong function invocation");

    // static_assert(sizeof(InvokerBoundType) <= StorageAreaSize,
    //     "Increase the TSize template argument of the StaticFucntion");

then one can compare using libstdc++ with libc++.

Using libstdc++

export CC=clang; export CXX=clang++
cmake ..
reset          # clear shell
make -j4
./module/driver/test/driver.GenericTest | c++filt -t

The output is:

Running cxxtest tests (2 tests)
ThisType        : embxx::util::StaticFunction<void (), 24ul>
DecayedFuncType : GenericDriverTestSuite::test1()::$_0
InvokerBoundType: embxx::util::StaticFunction<void (), 24ul>::InvokerBound<GenericDriverTestSuite::test1()::$_0>
sizeof(InvokerBoundType): 24
StorageAreaSize         : 32

ThisType        : embxx::util::StaticFunction<void (), 24ul>
DecayedFuncType : void embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (), 24ul> >, embxx::util::EventLoop<132ul, embxx::device::test::EventLoopLock, embxx::device::test::EventLoopCond>, void (), embxx::util::StaticFunction<void (), 24ul> >::setHandler<GenericDriverTestSuite::test1()::$_0>(GenericDriverTestSuite::test1()::$_0&&)::{lambda()#1}
InvokerBoundType: embxx::util::StaticFunction<void (), 24ul>::InvokerBound<void embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (), 24ul> >, embxx::util::EventLoop<132ul, embxx::device::test::EventLoopLock, embxx::device::test::EventLoopCond>, void (), embxx::util::StaticFunction<void (), 24ul> >::setHandler<GenericDriverTestSuite::test1()::$_0>(GenericDriverTestSuite::test1()::$_0&&)::{lambda()#1}>
sizeof(InvokerBoundType): 16
StorageAreaSize         : 32
.
ThisType        : embxx::util::StaticFunction<void (char), 24ul>
DecayedFuncType : GenericDriverTestSuite::test2()::$_1
InvokerBoundType: embxx::util::StaticFunction<void (char), 24ul>::InvokerBound<GenericDriverTestSuite::test2()::$_1>
sizeof(InvokerBoundType): 32
StorageAreaSize         : 32

ThisType        : embxx::util::StaticFunction<void (char), 24ul>
DecayedFuncType : void embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (char), 24ul> >, embxx::util::EventLoop<132ul, embxx::device::test::EventLoopLock, embxx::device::test::EventLoopCond>, void (char), embxx::util::StaticFunction<void (char), 24ul> >::setHandler<GenericDriverTestSuite::test2()::$_1>(GenericDriverTestSuite::test2()::$_1&&)::{lambda(char)#1}
InvokerBoundType: embxx::util::StaticFunction<void (char), 24ul>::InvokerBound<void embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (char), 24ul> >, embxx::util::EventLoop<132ul, embxx::device::test::EventLoopLock, embxx::device::test::EventLoopCond>, void (char), embxx::util::StaticFunction<void (char), 24ul> >::setHandler<GenericDriverTestSuite::test2()::$_1>(GenericDriverTestSuite::test2()::$_1&&)::{lambda(char)#1}>
sizeof(InvokerBoundType): 16
StorageAreaSize         : 32
.OK!

Using libc++

# clear build directory, then...

export CC=clang; export CXX=clang++
cmake -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++ -lc++abi" ..
reset          # clear shell
make -j4
./module/driver/test/driver.GenericTest | c++filt -t

The output is:

Running cxxtest tests (2 tests)
ThisType        : embxx::util::StaticFunction<void (), 24ul>
DecayedFuncType : GenericDriverTestSuite::test1()::$_0
InvokerBoundType: embxx::util::StaticFunction<void (), 24ul>::InvokerBound<GenericDriverTestSuite::test1()::$_0>
sizeof(InvokerBoundType): 24
StorageAreaSize         : 32

ThisType        : embxx::util::StaticFunction<void (), 24ul>
DecayedFuncType : void embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (), 24ul> >, embxx::util::EventLoop<132ul, embxx::device::test::EventLoopLock, embxx::device::test::EventLoopCond>, void (), embxx::util::StaticFunction<void (), 24ul> >::setHandler<GenericDriverTestSuite::test1()::$_0>(GenericDriverTestSuite::test1()::$_0&&)::{lambda()#1}
InvokerBoundType: embxx::util::StaticFunction<void (), 24ul>::InvokerBound<void embxx::driver::Generic<GenericDriverTestSuite::Device<embxx::util::StaticFunction<void (), 24ul> >, embxx::util::EventLoop<132ul, embxx::device::test::EventLoopLock, embxx::device::test::EventLoopCond>, void (), embxx::util::StaticFunction<void (), 24ul> >::setHandler<GenericDriverTestSuite::test1()::$_0>(GenericDriverTestSuite::test1()::$_0&&)::{lambda()#1}>
sizeof(InvokerBoundType): 16
StorageAreaSize         : 32

ThisType        : embxx::util::StaticFunction<void (), 24ul>
DecayedFuncType : embxx::util::StaticFunction<void (), 24ul>
InvokerBoundType: embxx::util::StaticFunction<void (), 24ul>::InvokerBound<embxx::util::StaticFunction<void (), 24ul> >
sizeof(InvokerBoundType): 48
StorageAreaSize         : 32

ThisType        : embxx::util::StaticFunction<void (), 24ul>
DecayedFuncType : embxx::util::StaticFunction<void (), 24ul>
InvokerBoundType: embxx::util::StaticFunction<void (), 24ul>::InvokerBound<embxx::util::StaticFunction<void (), 24ul> >
sizeof(InvokerBoundType): 48
StorageAreaSize         : 32

.... etc...........

It also segfaults as can be seen with gdb

gdb -ex run ./module/driver/test/driver.GenericTest

outputs

    ... etc ...
Program received signal SIGSEGV, Segmentation fault.
0x000000000042a5e4 in embxx::util::StaticFunction<void (), 24ul>::StaticFunction<embxx::util::StaticFunction<void (), 24ul>&>(embxx::util::StaticFunction<void (), 24ul>&) ()

or with clang's debugger lldb (sudo apt-get install lldb)

lldb -o run ./module/driver/test/driver.GenericTest

outputs

    ... etc ...
(lldb) Process 11002 stopped
* thread #1: tid = 11002, 0x000000000042a5e4 driver.GenericTest`embxx::util::StaticFunction<void (), 24ul>::StaticFunction<embxx::util::StaticFunction<void (), 24ul>&>(embxx::util::StaticFunction<void (), 24ul>&) + 20, name = 'driver.GenericT', stop reason = signal SIGSEGV: invalid address (fault address: 0x7ffffffff000)
    frame #0: 0x000000000042a5e4 driver.GenericTest`embxx::util::StaticFunction<void (), 24ul>::StaticFunction<embxx::util::StaticFunction<void (), 24ul>&>(embxx::util::StaticFunction<void (), 24ul>&) + 20
driver.GenericTest` 24ul>::StaticFunction<embxx::util::Static::StaticFunction<embxx::util::StaticFunction<void (), 24ul>&>:
->  0x42a5e4 <+20>: movb   $0x1, 0x20(%rsi)
    0x42a5e8 <+24>: movq   -0x18(%rbp), %rdi
    0x42a5ec <+28>: movq   %rdi, -0x8(%rbp)
    0x42a5f0 <+32>: movq   -0x8(%rbp), %rdi

@ajneu
Copy link
Contributor Author

ajneu commented Feb 25, 2017

The segfault happens before test2 is even run.
So there's a weird endless loop happening... (It's happening because in the investigation above, I've commented out the following line)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant