8

Consider this minimal example:

#include <filesystem>
#include <iostream>

int main()
{
    std::cout << std::filesystem::current_path() << '\n';
}

It works as expected in GCC 9.2, but Clang 8.0.1 refuses to compile the <filesystem> header (from GCC 9.2's libstdc++):

# clang++ 1.cpp -std=c++17
In file included from 1.cpp:1:
In file included from Z:\Lander\msys2\mingw64\include\c++\9.2.0\filesystem:37:
Z:\Lander\msys2\mingw64\include\c++\9.2.0\bits/fs_path.h:636:31: error: invalid use of incomplete
      type 'std::filesystem::__cxx11::filesystem_error'
      _GLIBCXX_THROW_OR_ABORT(filesystem_error(
                              ^~~~~~~~~~~~~~~~~
Z:\Lander\msys2\mingw64\include\c++\9.2.0\x86_64-w64-mingw32\bits/c++config.h:177:49: note: expanded
      from macro '_GLIBCXX_THROW_OR_ABORT'
#  define _GLIBCXX_THROW_OR_ABORT(_EXC) (throw (_EXC))
                                                ^~~~
Z:\Lander\msys2\mingw64\include\c++\9.2.0\bits/fs_fwd.h:61:9: note: forward declaration of
      'std::filesystem::__cxx11::filesystem_error'
  class filesystem_error;
        ^
1 error generated.

Is it a Clang bug, or a libstdc++ bug?

I found this bug report on MSYS2 bug tracker, but there is no useful information in there.

Is there a way to patch <filesystem> header to get rid of this error, while we're waiting for an official fix?


I'm on Windows. I'm using latest GCC & Clang available in MSYS2 packages.

GCC identifies as:

# g++ --version
g++.exe (Rev2, Built by MSYS2 project) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Clang identifies as:

# clang++ --version
clang version 8.0.1 (tags/RELEASE_801/final)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: Z:\Lander\msys2\mingw64\bin

Clang uses libstdc++ that comes with this GCC.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
  • 1
    I wouldn't say it's a bug of either. Standard Library is considered to be a be a part of the implementation, and gcc is under no obligation to make their library implementation conforming for other (non-gcc) compiler. – SergeyA Sep 16 '19 at 19:55
  • As to practical solution, why don't you use LLVM's standard library? – SergeyA Sep 16 '19 at 19:56
  • @SergeyA *"Standard Library is considered to be a be a part of the implementation"* True, but Clang is normally compatible with libstdc++ (and even with MSVC's standard library). Even if it's technically not a bug, I think it's going to be fixed on either side. *"why don't you use LLVM's standard library"* I'm not sure if libc++ works on Windows. Last time I tried it (a few months ago), it was unusable. – HolyBlackCat Sep 16 '19 at 20:00
  • sorry, maybe it is silly, did you try with -lstdc++fs on your compilation command? – Boki Sep 16 '19 at 20:06
  • @Boki I don't think it's going to work. `-lstdc++fs` affects linking, but I'm getting a compilation error (the linking doesn't even start). – HolyBlackCat Sep 16 '19 at 20:11
  • @HolyBlackCat it might be fixed on either side. You can submit bugreport and see what will happen. I would be curious to know too. – SergeyA Sep 16 '19 at 20:15

1 Answers1

12

The issue can be fixed by patching <msys2_path>/mingw64/include/c++/9.2.0/bits/fs_path.h.

At lines 666-692, there is a definition of class filesystem_error. It has to be moved up to line 614, to be right above the definition of u8path().


I think it's a libstdc++ bug. I've reported it here.

class filesystem_error is used several times in bits/fs_path.h, and every use of it is below the definition, except for the problematic line 636.

That line is wrapped in #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS, so I guess the Clang developers don't run libstdc++ compatibility tests on Windows.


UPD: This is fixed in GCC 9.3.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207