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

[C++20][Modules] Can't import <complex> and <iostream> at the same time with libc++ #60358

Open
Arthapz opened this issue Jan 28, 2023 · 6 comments
Labels
clang:modules C++20 modules and Clang Header Modules

Comments

@Arthapz
Copy link

Arthapz commented Jan 28, 2023

This snippet fails to build on df34581 with https://reviews.llvm.org/D142704 applied

import <iostream>;
import <complex>;

using namespace std;

int main(int argc, char** argv)
{
    cout << "hello world!" << endl;
    return 0;
}
/usr/bin/clang -Qunused-arguments -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -std=c++20 -fmodules -fno-implicit-module-maps -stdlib=libc++ -DNDEBUG -fmodules-cache-path=build/stlmodules/cache -c -Wno-everything -o build/stlmodules/cache/iostream.pcm -x c++-system-header iostream

/usr/bin/clang -Qunused-arguments -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -std=c++20 -fmodules -fno-implicit-module-maps -stdlib=libc++ -DNDEBUG -fmodules-cache-path=build/stlmodules/cache -c -Wno-everything -o build/stlmodules/cache/complex.pcm -x c++-system-header complex

/usr/bin/clang -c -Qunused-arguments -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -std=c++20 -fmodules -fno-implicit-module-maps -stdlib=libc++ -DNDEBUG -fmodule-file=build/stlmodules/cache/iostream.pcm -fmodule-file=build/stlmodules/cache/complex.pcm -o build/.objs/stl_headerunit_cpp_only/linux/x86_64/release/src/main.cpp.o src/main.cpp
error: /usr/bin/../include/c++/v1/ostream:254:20: error: 'std::basic_ostream<char>::operator<<' from module '/usr/bin/../include/c++/v1/complex' is not present in definition of 'std::ostream' in module '/usr/bin/../include/c++/v1/iostream'
    basic_ostream& operator<<(basic_streambuf<char_type, traits_type>* __sb);
                   ^
/usr/bin/../include/c++/v1/ostream:221:20: note: declaration of 'operator<<' does not match
    basic_ostream& operator<<(basic_ostream& (*__pf)(basic_ostream&))
                   ^
/usr/bin/../include/c++/v1/ostream:225:20: note: declaration of 'operator<<' does not match
    basic_ostream& operator<<(basic_ios<char_type, traits_type>&
                   ^
/usr/bin/../include/c++/v1/ostream:230:20: note: declaration of 'operator<<' does not match
    basic_ostream& operator<<(ios_base& (*__pf)(ios_base&))
                   ^
/usr/bin/../include/c++/v1/ostream:233:20: note: declaration of 'operator<<' does not match
    basic_ostream& operator<<(bool __n);
                   ^
/usr/bin/../include/c++/v1/ostream:234:20: note: declaration of 'operator<<' does not match
    basic_ostream& operator<<(short __n);
@Arthapz Arthapz changed the title [C++20][Modules] Can't import <complex> and <iostream> at the same time [C++20][Modules] Can't import <complex> and <iostream> at the same time with libc++ Jan 28, 2023
@EugeneZelenko EugeneZelenko added clang:modules C++20 modules and Clang Header Modules and removed new issue labels Jan 29, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 29, 2023

@llvm/issue-subscribers-clang-modules

@Arthapz
Copy link
Author

Arthapz commented Jan 31, 2023

May be the same as #58540

@koplas
Copy link

koplas commented Oct 27, 2023

The diagnostic message is misleading. All member functions clang complains about are in both header units and even the AST matches. The preprocessor output also reveals no big differences. There seems to be a problem with the merging.

Update: While checking the PendingOdrMergeChecks it does not find the declarations.

@koplas
Copy link

koplas commented Jan 2, 2024

Here is a still big repro for this issue: headerunits_repro.zip

Update:
Here is a reproducer with an interesting test: https://github.com/koplas/clang-headerunits
cvise seems only to be able to remove comments.

@koplas
Copy link

koplas commented Jan 4, 2024

@Arthapz Can you check if this issue occurs with a clang build with this flag: -DLIBCXX_ENABLE_WIDE_CHARACTERS=OFF?

@koplas
Copy link

koplas commented Jan 5, 2024

Here is a big reproducer:

// ostream.hpp
namespace std {
inline namespace __1 {
template <class _CharT> struct char_traits;
}
} // namespace std

namespace std {
inline namespace __1 {
class ios_base;

template <class _CharT, class _Traits = char_traits<_CharT>> class basic_ios;

template <class _CharT, class _Traits = char_traits<_CharT>>
class basic_ostream;

typedef basic_ios<char> ios;
typedef basic_ios<wchar_t> wios;

typedef basic_ostream<char> ostream;

typedef basic_ostream<wchar_t> wostream;

template <class _CharT, class _Traits>
class __attribute__((__preferred_name__(ios)))
__attribute__((__preferred_name__(wios))) basic_ios;
} // namespace __1
} // namespace std

namespace std {
inline namespace __1 {

class ios_base {
public:
  class failure;

  virtual ~ios_base();

protected:
  ios_base() {}

  void init(void *__sb);
};

template <class _CharT, class _Traits> class basic_ios : public ios_base {
public:
  typedef _Traits traits_type;

  explicit basic_ios(void *__sb);
  ~basic_ios() override;

protected:
  basic_ios() {}
  void init(void *__sb);
};

template <class _CharT, class _Traits>
inline basic_ios<_CharT, _Traits>::basic_ios(void *__sb) {
  init(__sb);
}

template <class _CharT, class _Traits>
basic_ios<_CharT, _Traits>::~basic_ios() {}

template <class _CharT, class _Traits>
inline void basic_ios<_CharT, _Traits>::init(void *__sb) {}
} // namespace __1
} // namespace std

namespace std {
inline namespace __1 {
extern template class basic_ios<char>;
}
} // namespace std

namespace std {
inline namespace __1 {

template <class _CharT, class _Traits>
class __attribute__((__type_visibility__("default"))) basic_ostream
    : virtual public basic_ios<_CharT, _Traits> {
public:
  inline explicit basic_ostream(void *__sb) { this->init(__sb); }
  ~basic_ostream() override;

protected:
  inline basic_ostream(basic_ostream &&__rhs);

protected:
  basic_ostream() {}
};
} // namespace __1
} // namespace std
// a.hpp
#include "ostream.hpp"
// b.hpp
#include "ostream.hpp"
// main.cpp
import "a.hpp";
import "b.hpp";


std::basic_ostream<char> test()
{
    return std::basic_ostream<char>(nullptr);
}
clang++ -stdlib=libc++ -std=c++20 -xc++-user-header --precompile a.hpp -o a.pcm
clang++ -stdlib=libc++ -std=c++20 -xc++-user-header --precompile b.hpp -o b.pcm
clang++ -stdlib=libc++ -std=c++20 -fmodule-file=a.pcm -fmodule-file=b.pcm -c main.cpp

Output:

In module '/home/xxx/Documents/clang_header_units_repro/a.hpp':
/home/xxx/Documents/clang_header_units_repro/ostream.hpp:49:3: error: 'std::basic_ios<char>::~basic_ios' from module '/home/xxx/Documents/clang_header_units_repro/a.hpp' is not present in definition of 'std::ios' in module '/home/xxx/Documents/clang_header_units_repro/b.hpp'
  ~basic_ios() override;
  ^
/home/xxx/Documents/clang_header_units_repro/ostream.hpp:71:23: note: definition has no member '~basic_ios'
extern template class basic_ios<char>;
                      ^
In module '/home/xxx/Documents/clang_header_units_repro/a.hpp':
/home/xxx/Documents/clang_header_units_repro/ostream.hpp:48:12: error: 'std::basic_ios<char>::basic_ios' from module '/home/xxx/Documents/clang_header_units_repro/a.hpp' is not present in definition of 'std::ios' in module '/home/xxx/Documents/clang_header_units_repro/b.hpp'
  explicit basic_ios(void *__sb);
           ^
/home/xxx/Documents/clang_header_units_repro/ostream.hpp:71:23: note: definition has no member 'basic_ios'
extern template class basic_ios<char>;
                      ^
In module '/home/xxx/Documents/clang_header_units_repro/a.hpp':
/home/xxx/Documents/clang_header_units_repro/ostream.hpp:52:3: error: 'std::basic_ios<char>::basic_ios' from module '/home/xxx/Documents/clang_header_units_repro/a.hpp' is not present in definition of 'std::ios' in module '/home/xxx/Documents/clang_header_units_repro/b.hpp'
  basic_ios() {}
  ^
/home/xxx/Documents/clang_header_units_repro/ostream.hpp:71:23: note: definition has no member 'basic_ios'
extern template class basic_ios<char>;
                      ^
3 errors generated.

Note: For brevity, this reproducer highlights the issue only with the constructor and no other functions, like the streaming operators. But the root cause should be the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:modules C++20 modules and Clang Header Modules
Projects
None yet
Development

No branches or pull requests

4 participants