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

Compilation fails with g++ #58

Open
osankur opened this issue Aug 8, 2023 · 9 comments
Open

Compilation fails with g++ #58

osankur opened this issue Aug 8, 2023 · 9 comments

Comments

@osankur
Copy link

osankur commented Aug 8, 2023

I wasn't able to compile the release v0.7 with g++ 10.5.0. I get the following error:

[  8%] Building CXX object src/parsing/program_parser/CMakeFiles/program_parsing_static.dir/program.tab.cc.o
In file included from program.yy:25,
                 from /home/osankur/tools/tchecker/build/src/parsing/program_parser/program.tab.cc:42:
/usr/include/c++/10/limits: In instantiation of ‘struct std::numeric_limits<tchecker::statement_t>’:
/usr/local/include/boost/rational.hpp:123:7:   required from ‘const bool boost::rational_detail::is_compatible_integer<tchecker::statement_t, long int, void>::value’
/usr/local/include/boost/rational.hpp:184:21:   required by substitution of ‘template<class T> constexpr boost::rational<long int>::rational(const T&, const typename boost::enable_if_c<boost::rational_detail::is_compatible_integer<T, long int, void>::value, void>::type*) [with T = tchecker::statement_t]’
program.yy:192:29:   required from ‘void tchecker::parsing::program::parser_t::yy_print_(std::ostream&, const tchecker::parsing::program::parser_t::basic_symbol<Base>&) const [with Base = tchecker::parsing::program::parser_t::by_state; std::ostream = std::basic_ostream<char>]’
/home/osankur/tools/tchecker/build/src/parsing/program_parser/program.tab.cc:696:7:   required from here
/usr/include/c++/10/limits:317:7: error: invalid abstract return type ‘tchecker::statement_t’
  317 |       min() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~
In file included from /home/osankur/tools/tchecker/src/../include/tchecker/parsing/parsing.hh:16,
                 from program.yy:31,
                 from /home/osankur/tools/tchecker/build/src/parsing/program_parser/program.tab.cc:42:
/home/osankur/tools/tchecker/src/../include/tchecker/statement/statement.hh:31:7: note:   because the following virtual functions are pure within ‘tchecker::statement_t’:
   31 | class statement_t : private boost::noncopyable {
      |       ^~~~~~~~~~~
/home/osankur/tools/tchecker/src/../include/tchecker/statement/statement.hh:76:26: note:     ‘virtual std::ostream& tchecker::statement_t::do_output(std::ostream&) const’
   76 |   virtual std::ostream & do_output(std::ostream & os) const = 0;
      |                          ^~~~~~~~~
/home/osankur/tools/tchecker/src/../include/tchecker/statement/statement.hh:81:35: note:     ‘virtual tchecker::statement_t* tchecker::statement_t::do_clone() const’
   81 |   virtual tchecker::statement_t * do_clone() const = 0;
      |                                   ^~~~~~~~
/home/osankur/tools/tchecker/src/../include/tchecker/statement/statement.hh:87:16: note:     ‘virtual void tchecker::statement_t::do_visit(tchecker::statement_visitor_t&) const’
   87 |   virtual void do_visit(tchecker::statement_visitor_t & v) const = 0;
      |                ^~~~~~~~
In file included from program.yy:25,
                 from /home/osankur/tools/tchecker/build/src/parsing/program_parser/program.tab.cc:42:
/usr/include/c++/10/limits:321:7: error: invalid abstract return type ‘tchecker::statement_t’
  321 |       max() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~
/usr/include/c++/10/limits:327:7: error: invalid abstract return type ‘tchecker::statement_t’
  327 |       lowest() noexcept { return _Tp(); }
      |       ^~~~~~
/usr/include/c++/10/limits:333:7: error: invalid abstract return type ‘tchecker::statement_t’
  333 |       epsilon() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~~~~~
/usr/include/c++/10/limits:337:7: error: invalid abstract return type ‘tchecker::statement_t’
  337 |       round_error() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~~~~~~~~~
/usr/include/c++/10/limits:341:7: error: invalid abstract return type ‘tchecker::statement_t’
  341 |       infinity() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~~~~~~
/usr/include/c++/10/limits:346:7: error: invalid abstract return type ‘tchecker::statement_t’
  346 |       quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~~~~~~~
/usr/include/c++/10/limits:351:7: error: invalid abstract return type ‘tchecker::statement_t’
  351 |       signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~~~~~~~~~~~
/usr/include/c++/10/limits:357:7: error: invalid abstract return type ‘tchecker::statement_t’
  357 |       denorm_min() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
      |       ^~~~~~~~~~
[...]

This compiles without any issue with clang-10.0.0.

@alzeha
Copy link

alzeha commented Nov 13, 2023

+1

EDIT: The problem is solved for me. It was sitting in front of the computer and could not read the installation instructions properly.

@pictavien
Copy link
Collaborator

Hi @alzeha,

How did you fix the problem ? With g++10 the only way I have found to fix it, is to comment the declaration of

std::ostream & operator<<(std::ostream & os, tchecker::clock_rational_value_t v);

in tchecker/basicypes.hh. Up to now I failed to understand why the g++ 10 tries to instantiate struct std::numeric_limits with a non scalar type when this operator<< is declared.

@alzeha
Copy link

alzeha commented Nov 22, 2023

The first time I tried it, I set the build directory as a subdirectory of tchecker and the installation directory as well. But they have to be next to each other, then it suddenly works.

I have also made the action live on my fork (https://github.com/Echtzeitsysteme/tchecker). So you can take a look inside to see how you have to call the various commands.

@pictavien
Copy link
Collaborator

Thanks. Your docker image use Boost 1.81 and GCC 12.
I'm trying to solve the problem for the default packages for Ubuntu 22.04 (Boost 1.74 and GCC 10).

@alzeha
Copy link

alzeha commented Nov 22, 2023

Sure. Locally, I use g++ 11, but also with boost 1.81. I'm sorry I can't help you further.

@pictavien
Copy link
Collaborator

Hi,

I've reduced the problem to the following lines. Operator << for clock_rational_value_t is used instead of the one declared for statement_t. I don't have a clue why this happens ! If the declarations of operators are reversed the problem disappears.

#include <boost/rational.hpp>

using clock_rational_value_t = boost::rational<int64_t>;

std::ostream & operator<<(std::ostream & os, clock_rational_value_t v);

class statement_t {
public:
  virtual void func() = 0;
};

std::ostream & operator<<(std::ostream & os, statement_t const & stmt);


void f(std::ostream & os, statement_t *s)
{
  os  << *s;
}

@fredher
Copy link
Collaborator

fredher commented Mar 3, 2024

Thanks @pictavien , here is a similar example, without boost:

#include <iostream>
#include <limits>
#include <type_traits>

template <class IntType> class rational {
public:
    template <class T>
    rational(const T& n,
             typename std::enable_if_t<std::numeric_limits<T>::is_specialized>::type const * = 0) {}
};

using clock_rational_value_t = rational<int64_t>;

std::ostream & operator<<(std::ostream & os, clock_rational_value_t b);

class statement_t {
public:
    virtual void func() = 0;
};

std::ostream & operator<<(std::ostream & os, statement_t const & s);

void f(std::ostream & os, statement_t * s)
{
    os << *s;
}

I get the same error messages as mentionned in @osankur post above. However, I get no error if the initializer = 0 on the second paramater of constructor rational::rational is removed, or if the first parameter of the constructor is removed.

@fredher
Copy link
Collaborator

fredher commented Mar 3, 2024

I finally wrote a simpler, standalone, example:

#include <cstdint>
#include <ostream>

template <class T> class A {
public:
    typedef T type;
    T f() {}
};

template <class IntType> class rational {
public:
    template <class T>
    rational(const T & n, typename A<T>::type const * = nullptr) {}
};

using clock_rational_value_t = rational<int64_t>;

std::ostream & operator<<(std::ostream & os, clock_rational_value_t b);

class statement_t {
public:
    virtual ~statement_t() {}
    virtual void func() = 0;
};

std::ostream & operator<<(std::ostream & os, statement_t const & s);

void f(std::ostream & os, statement_t * s)
{
    os << *s;
}

The compiler message is clearer now:

bar.cc: In instantiation of ‘class A<statement_t>’:
bar.cc:13:5:   required by substitution of ‘template<class T> rational<long int>::rational(const T&, const typename A<T>::type*) [with T = statement_t]’
bar.cc:30:12:   required from here
bar.cc:7:7: error: invalid abstract return type ‘statement_t’
    7 |     T f() {}
      |       ^
bar.cc:20:7: note:   because the following virtual functions are pure within ‘statement_t’:
   20 | class statement_t {
      |       ^~~~~~~~~~~
bar.cc:23:18: note:     ‘virtual void statement_t::func()’
   23 |     virtual void func() = 0;
      |                  ^~~~

What happens is that instruction os << *s in function f calls operator<< on clock_rational_value_t instead of on statement_t const &. Due to = nullptr initializer to the second argument of rational::rational, it looks like implicit conversion constructor clock_rational_value_t::rational<statement_t>(const statement_t &) has higher priority than statement_t const & to chose the variant of operator<< for g++-10. If the constructor of class rational is maked explicit then the error disappears. This is strange.

@pictavien
Copy link
Collaborator

Finally I have reduced the problem to the following example. g++10 fails to compile it while it works with g++ 12.

#include <limits>

class statement_t {
public:
  virtual void func() = 0;
};

static_assert(! std::numeric_limits<statement_t>::is_specialized);

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

No branches or pull requests

4 participants