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 broken in clang++17 #62071

Closed
ar-visions opened this issue Apr 11, 2023 · 5 comments
Closed

C++20 modules broken in clang++17 #62071

ar-visions opened this issue Apr 11, 2023 · 5 comments
Labels
clang:modules C++20 modules and Clang Header Modules duplicate Resolved as duplicate

Comments

@ar-visions
Copy link

ar-visions commented Apr 11, 2023

I cannot use this compiler for experiments. What I'm noticing is you cant implement a simple lambda without having to resort to random hacks to get the compiler to not delete default constructors.

Clang version 17.0.0 (https://github.com/llvm/llvm-project f66b9fe)

Can't use GCC either because it doesnt have AArch64 on Mac. Utterly stuck, and it means write a transpiler or goto Rust (same as many others).

a.cppm:

module;

#include <cstdlib>
#include <cstdio>
#include <cstdarg>
#include <new>
#include <memory>

export module a;

export template<typename T>
class func;

export template<typename R, typename... Args>
class func<R(Args...)> {
public:
    func() { };

    template<typename F>
    func(F&& func) : impl_(new Impl<typename std::decay<F>::type>(std::forward<F>(func))) {}

    R operator()(Args... args) const {
        if (impl_)
            return impl_->call(args...);
        throw std::runtime_error("Empty func object");
    }

    explicit operator bool() const {
        return static_cast<bool>(impl_);
    }

private:
    struct Base {
        virtual ~Base() { };
        virtual R call(Args... args) const = 0;
    };

    template<typename F>
    struct Impl : Base {
        explicit Impl(F&& func) : func_(std::forward<F>(func)) {}

        R call(Args... args) const override {
            return func_(args...);
        }

        F func_;
    };

    std::unique_ptr<Base> impl_ = nullptr;
};

// compiles ONLY when this line is uncommented.  its not even used
// -----------> Broken <------------
// func<void()> abc2 = func<void()>([]() -> void { });

export int foo() {
    return 43;
}

b.cppm:

export module b;
import a;
export int bar() {
    return 43;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.26)
project(two_libraries CXX C ASM)

set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a")

include(../cxx_modules_rules_clang.cmake)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

add_library(a STATIC)
target_sources(a
  PUBLIC
    FILE_SET cxx_modules TYPE CXX_MODULES FILES
    a.cppm
)

add_library(b STATIC)
target_sources(b
  PUBLIC
    FILE_SET cxx_modules TYPE CXX_MODULES FILES
    b.cppm
)

# The compiler won't find module 'a' if we delete the following line.
target_link_libraries(b PUBLIC a)

add_executable(main main.cpp)
target_link_libraries(main PUBLIC a b)

main.cpp:

import a;
import b;

int main() {
    foo();
    bar();

    func<void()> abc3 = func<void()>([]() -> void { });
    abc3();
    
    return 0;
}

build log with abc2 commented out:

kalen@Kalens-Mac-mini build% ninja
[8/10] Building CXX object CMakeFiles/main.dir/main.cpp.o
FAILED: CMakeFiles/main.dir/main.cpp.o 
/Users/kalen/Dropbox/src/llvm-project/build/bin/clang++   -std=c++20 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d @CMakeFiles/main.dir/main.cpp.o.modmap -o CMakeFiles/main.dir/main.cpp.o -c /Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp
In file included from /Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp:2:
/Users/kalen/src/CMake-Modules-Examples/two_static_libraries/a.cppm:20:22: error: no matching constructor for initialization of 'std::unique_ptr<Base>'
    func(F&& func) : impl_(new Impl<typename std::decay<F>::type>(std::forward<F>(func))) {}
                     ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp:9:25: note: in instantiation of function template specialization 'func<void ()>::func<(lambda at /Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp:9:38)>' requested here
    func<void()> abc3 = func<void()>([]() -> void { });
                        ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:121:59: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Impl<typename std::decay<(lambda at /Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp:9:38)>::type> *' (aka 'Impl<(lambda at /Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp:9:38)> *') to 'const unique_ptr<Base>' for 1st argument
class _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS unique_ptr {
                                                          ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:185:21: note: candidate template ignored: requirement 'is_default_constructible<std::default_delete<func<void ()>::Base>>::value' was not satisfied [with _Dummy = true]
  _LIBCPP_CONSTEXPR unique_ptr(nullptr_t) _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
                    ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:190:12: note: candidate template ignored: requirement 'is_default_constructible<std::default_delete<func<void ()>::Base>>::value' was not satisfied [with _Dummy = true]
  explicit unique_ptr(pointer __p) _NOEXCEPT : __ptr_(__p, __default_init_tag()) {}
           ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:222:3: note: candidate template ignored: could not match 'unique_ptr<_Up, _Ep>' against 'Impl<typename std::decay<(lambda at /Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp:9:38)>::type> *' (aka 'Impl<(lambda at /Users/kalen/src/CMake-Modules-Examples/two_static_libraries/main.cpp:9:38)> *')
  unique_ptr(unique_ptr<_Up, _Ep>&& __u) _NOEXCEPT
  ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:180:21: note: candidate constructor template not viable: requires 0 arguments, but 1 was provided
  _LIBCPP_CONSTEXPR unique_ptr() _NOEXCEPT : __ptr_(pointer(), __default_init_tag()) {}
                    ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:195:3: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
  unique_ptr(pointer __p, _LValRefType<_Dummy> __d) _NOEXCEPT
  ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:201:3: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
  unique_ptr(pointer __p, _GoodRValRefType<_Dummy> __d) _NOEXCEPT
  ^
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include/c++/v1/__memory/unique_ptr.h:210:3: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided

when its not commented, it works.

I've been waiting years for Clang to do something with C++ modules and it seems unusable. I can't EXPERIMENT with it at all. It cant DO anything. Its like a laboratory that blows up when you step foot in it. Definitely not experimental as-is.

new T(args) is also broken, it tells you to use include new> but that doesnt fix it, as it still complains. Using ::new doesnt do it either. Its broken.

As is, it seems a waste of time to proceed with Clang. Not a single experiment works for me. So I wouldnt classify this code as 'experimental', I cant experiment with it as-is! Unless I want to experiment with errors doing anything modular in nature?

@EugeneZelenko EugeneZelenko added clang:modules C++20 modules and Clang Header Modules and removed new issue labels Apr 11, 2023
@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2023

@llvm/issue-subscribers-clang-modules

@royjacobson
Copy link
Contributor

Please be mindful of the LLVM community's code of conduct.

@ar-visions
Copy link
Author

ar-visions commented Apr 11, 2023

Please me give an example of this not being followed. I understand that and going to its very letter. My time is valuable and I define my own time as my own, and it has been set back by attempting to experiment with clang. So, clang has wasted my time, as investment into MSVCs working C++23 prototype may be a waste due to a lack of portability. Omitting harm is not some required code of conduct from what I understand? I've used Clang for years but this 2020 draft standard is not even at experimental phase, as you cant experiment with it in Clang++17. Thats 3 years past its draft date, and by compiler history that is unusual and noteworthy.

Using standard include and a templated wrapper case of it would be test #1 in 2020. Its striking that this simple example does not work. I only hope that its a compiler switch I am missing where its shaking away even when using modules: -x c++-module. My small case demonstrates the most important feature of modules and their exports seem broken, and I hadn't even begun experimenting yet. All optimizations done by Clang seem to be with the inclusion of a switch, so unless I am mistaken I don't see how I am doing this wrong.

Experimenting would be including std libraries and checking performance. I can't do step 1, so I can't experiment. At multiple years into a 2020 draft thats worth saying this issue makes it so I can't form generics in any possible way with modules (the point of the language). That means I cannot experiment with C++20 with clang++17 as-is. The laboratory picture makes sense. You can't experiment in a blown up laboratory. At 3 years into expected experimental basis you simply receive these messages describing the error behavior in detail (5k+)

@ar-visions ar-visions changed the title Nonsensical compilation, random errors in C++ modules 20 Compilation woes in C++ modules 20 (3 year old draft) using clang++17 Apr 11, 2023
@ar-visions ar-visions changed the title Compilation woes in C++ modules 20 (3 year old draft) using clang++17 modules broken in clang++17 Apr 11, 2023
@ar-visions ar-visions changed the title modules broken in clang++17 C++20 modules broken in clang++17 Apr 11, 2023
@ar-visions
Copy link
Author

ar-visions commented Apr 11, 2023

I have tried using c++2b as well as c++20. that didnt help.

This is the modmap file which includes both pcms when compiling main.cpp
CMakeFiles/main.dir/main.cpp.o.modmap:

-fmodule-file=a=CMakeFiles/a.dir/a.pcm
-fmodule-file=b=CMakeFiles/b.dir/b.pcm

@ChuanqiXu9
Copy link
Member

This should be a duplication for #59513.

@ChuanqiXu9 ChuanqiXu9 added the duplicate Resolved as duplicate label Apr 13, 2023
@EugeneZelenko EugeneZelenko closed this as not planned Won't fix, can't repro, duplicate, stale Apr 13, 2023
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 duplicate Resolved as duplicate
Projects
None yet
Development

No branches or pull requests

5 participants