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

clang 13 C++20 consteval error #2455

Closed
englercj opened this issue Aug 15, 2021 · 24 comments
Closed

clang 13 C++20 consteval error #2455

englercj opened this issue Aug 15, 2021 · 24 comments

Comments

@englercj
Copy link

I'm getting a compilation error with 8.0.1 using clang 13:

In file included from dependencies/fmtlib.fmt/fmt-8.0.1/src/format.cc:8:
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/format-inl.h:92:54: error: call to consteval function 'fmt::basic_format_string<char>::basic_format_string<char [21], 0>' is not a constant expression
  if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
                                                     ^
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/core.h:463:15: note: non-constexpr function 'strlen' cannot be used in a constant expression
      size_ = std::strlen(reinterpret_cast<const char*>(s));
              ^
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/core.h:2835:51: note: in call to 'basic_string_view(&"cannot write to file"[0])'
  FMT_CONSTEVAL basic_format_string(const S& s) : str_(s) {
                                                  ^
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/format-inl.h:92:54: note: in call to 'basic_format_string("cannot write to file")'
  if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
                                                     ^

Here is the full invocation:

clang++ -Idependencies/fmtlib.fmt/fmt-8.0.1/include -MMD -MP -m64 -Werror -ffast-math -O0 -g -mavx -Wall -Wextra -std=c++20 -fno-exceptions -fno-rtti -mcx16 -fvisibility=hidden -fvisibility-inlines-hidden -Wundef -o $(OBJDIR)/format.o -c dependencies/fmtlib.fmt/fmt-8.0.1/src/format.cc

And my full clang version if it helps:

$ clang --version
Debian clang version 13.0.0-++20210811062604+6789c4564a4b-1~exp1~20210811163414.34
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
@vitaut
Copy link
Contributor

vitaut commented Aug 15, 2021

clang 13 hasn't been released yet. Do you mean the current development version of clang? Also do you have a godbolt repro?

@englercj
Copy link
Author

englercj commented Aug 15, 2021

I'm using the Debian apt nightly packages from llvm: https://apt.llvm.org/. I've also tried with 12 and get the same error. I haven't been able to get a reproduction in godbolt yet.

@englercj
Copy link
Author

englercj commented Aug 15, 2021

Just downgraded and confirmed I'm seeing the same thing with clang 12:

$ make
==== Building fmt (debug_x64) ====
format.cc
clang++   -MMD -MP -DHE_PLATFORM_LINUX -DHE_PLATFORM_API_POSIX -D_DEBUG -DDEBUG -DHE_CFG_DEBUG -DHE_CFG_MODULE_NAME=\"fmt\" -DHE_CFG_MODULE_STATIC=1 -Idependencies/fmtlib.fmt/fmt-8.0.1/include -m64 -Werror -ffast-math -O0 -g -mavx -Wall -Wextra -std=c++20 -fno-exceptions -fno-rtti -mcx16 -fvisibility=hidden -fvisibility-inlines-hidden -Wundef  -o "obj/linux-debug_x64/fmt/format.o" -MF "obj/linux-debug_x64/fmt/format.d" -c "dependencies/fmtlib.fmt/fmt-8.0.1/src/format.cc"
In file included from dependencies/fmtlib.fmt/fmt-8.0.1/src/format.cc:8:
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/format-inl.h:92:54: error: call to consteval function 'fmt::basic_format_string<char>::basic_format_string<char [21], 0>' is not a constant expression
  if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
                                                     ^
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/core.h:463:15: note: non-constexpr function 'strlen' cannot be used in a constant expression
      size_ = std::strlen(reinterpret_cast<const char*>(s));
              ^
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/core.h:2835:51: note: in call to 'basic_string_view(&"cannot write to file"[0])'
  FMT_CONSTEVAL basic_format_string(const S& s) : str_(s) {
                                                  ^
dependencies/fmtlib.fmt/fmt-8.0.1/include/fmt/format-inl.h:92:54: note: in call to 'basic_format_string("cannot write to file")'
  if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
                                                     ^
1 error generated.
make[1]: *** [fmt.make:180: obj/linux-debug_x64/fmt/format.o] Error 1
make: *** [Makefile:57: fmt] Error 2

$ clang++ --version
Debian clang version 12.0.1-++20210804103842+fed41342a82f-1~exp1~20210804084624.136
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

@phprus
Copy link
Contributor

phprus commented Aug 15, 2021

libstdc++ from Debian 9 does not support constexpr std::char_traits.
libstdc++ from Debian 10 does not support is_constant_evaluated.
https://distrowatch.com/table.php?distribution=debian and https://en.cppreference.com/w/cpp/compiler_support

-std=c++20 is not fully compatible with libstdc++ 6.3.0, 8.3.0.

Please check code with libc++.

@englercj
Copy link
Author

Upgrading libc++ did in-fact fix the issue, great catch there. Thanks for your help.

@ndevenish
Copy link

I also ran into this, and solved by downgrading my set(CMAKE_CXX_STANDARD 20) to set(CMAKE_CXX_STANDARD 17) (wasn't otherwise using C++20 features).

@timblechmann
Copy link
Contributor

i'm seeing a slightly related error: appleclang (from xcode 12.5 and xcode 13) both ICE when compiling in c++20 mode. the ICE goes away when disabling the FMT_CONSTEVAL selection.

the code enables the consteval codepath when clang v11.1 is detected, though

@kotori2
Copy link

kotori2 commented Sep 24, 2021

i'm seeing a slightly related error: appleclang (from xcode 12.5 and xcode 13) both ICE when compiling in c++20 mode. the ICE goes away when disabling the FMT_CONSTEVAL selection.

the code enables the consteval codepath when clang v11.1 is detected, though

@timblechmann
Similar issue here. It seems this bug was introduced somewhere between fmtlib 70103 and 80001.
I got the same error: call to consteval function 'fmt::basic_format_string<char, char *&>::basic_format_string<std::basic_string_view<char>, 0>' is not a constant expression error.
Currently using Apple clang version 13.0.0 (clang-1300.0.29.3) on macOS 12.0 beta.

@mwinterb
Copy link
Contributor

i'm seeing a slightly related error: appleclang (from xcode 12.5 and xcode 13) both ICE when compiling in c++20 mode. the ICE goes away when disabling the FMT_CONSTEVAL selection.
the code enables the consteval codepath when clang v11.1 is detected, though

@timblechmann
Similar issue here. It seems this bug was introduced somewhere between fmtlib 70103 and 80001.
I got the same error: call to consteval function 'fmt::basic_format_string<char, char *&>::basic_format_string<std::basic_string_view<char>, 0>' is not a constant expression error.
Currently using Apple clang version 13.0.0 (clang-1300.0.29.3) on macOS 12.0 beta.

Your issue sounds more like #2438.

@kotori2
Copy link

kotori2 commented Sep 24, 2021

@mwinterb I just realized the error was followed by a compiler crash.
There is an example to reproduce:

#include <fmt/format.h>

template<typename ... Args>
static void output_logs() {
    fmt::format("");
}

int main() {
    output_logs();
}
[ 50%] Building CXX object CMakeFiles/untitled.dir/main.cpp.o
clang: error: unable to execute command: Segmentation fault: 11
clang: error: clang frontend command failed due to signal (use -v to see invocation)
Apple clang version 13.0.0 (clang-1300.0.29.3)
Target: x86_64-apple-darwin21.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /var/folders/cj/z4mkrrn51rlfcqvwq7_9pmfw0000gn/T/main-b1386c.cpp
clang: note: diagnostic msg: /var/folders/cj/z4mkrrn51rlfcqvwq7_9pmfw0000gn/T/main-b1386c.sh
clang: note: diagnostic msg: Crash backtrace is located in
clang: note: diagnostic msg: /Users/kotori0/Library/Logs/DiagnosticReports/clang_<YYYY-MM-DD-HHMMSS>_<hostname>.crash
clang: note: diagnostic msg: (choose the .crash file that corresponds to your crash)
clang: note: diagnostic msg: 

********************
make[3]: *** [CMakeFiles/untitled.dir/main.cpp.o] Error 254
make[2]: *** [CMakeFiles/untitled.dir/all] Error 2
make[1]: *** [CMakeFiles/untitled.dir/rule] Error 2
make: *** [untitled] Error 2

@vitaut
Copy link
Contributor

vitaut commented Sep 24, 2021

@kotori2, please open a new issue since it's unrelated to the current one.

@timblechmann
Copy link
Contributor

@kotori2's issue reduces to:

struct basic_format_string {
  template <typename S> consteval basic_format_string(S);
};
template <typename...> using format_string = basic_format_string;
auto format(format_string<>) -> int;
template <typename...> void output_logs() { format(""); }
int main() { output_logs(); }

@vitaut
Copy link
Contributor

vitaut commented Sep 25, 2021

consteval is now disabled in Apple clang because of https://bugs.llvm.org/show_bug.cgi?id=51938.

@ndevenish
Copy link

I'm also seeing this on linux, and now want to use some C++20 features. Is it worth adding a configuration check for (presumably) partially missing standard library support for this?

@vitaut
Copy link
Contributor

vitaut commented Sep 30, 2021

@ndevenish, there have been several unrelated issue reported here. What error do you get?

@ndevenish
Copy link

Roughly equivalent to the original issue:

fmt/include/fmt/os.h:495:49: error: call to consteval function 'fmt::basic_format_string<char>::basic_format_string<char [21], 0>' is not a constant expression
    if (!locale_) FMT_THROW(system_error(errno, "cannot create locale"));
                                                ^
/home/user101/miniapp/dependencies/fmt/include/fmt/core.h:463:15: note: non-constexpr function 'strlen' cannot be used in a constant expression
      size_ = std::strlen(reinterpret_cast<const char*>(s));

Hmm, did some further digging, and maybe I jumped a bit too soon on the suggestion of feature checks. Although it works fine in compiler C++17 mode, and the clang-based compiler (dpcpp) i'm using is supposed to have up-to-date (if not full) C++20 support, it looks like the setup I am given has GCC 7.4's libstdc++ underneath, which would probably imply very little C++20 existing on the library side.

I suppose fixing this in features would require supporting C++20 the language changes without any C++20 The Standard Library changes, which probably isn't a reasonable.

@vitaut
Copy link
Contributor

vitaut commented Sep 30, 2021

I think it's just a matter of refining the check here:

fmt/include/fmt/core.h

Lines 461 to 462 in d141cdb

if (detail::const_check(std::is_same<Char, char>::value &&
!detail::is_constant_evaluated()))

to account for unimplemented is_constant_evaluated in the standard library. A PR is welcome.

@vitaut vitaut reopened this Sep 30, 2021
@phprus
Copy link
Contributor

phprus commented Sep 30, 2021

@vitaut, Why is this if statement needed?

std::char_traits<Char>::length(s) uses strlen if possible.

@ndevenish
Copy link

It seems to specifically be using std::strlen in cases where it detects that the standard library is not constant evaluated here. Is this a bug or I am misunderstanding the check?

fmt/include/fmt/core.h

Lines 352 to 358 in d141cdb

constexpr FMT_INLINE auto is_constant_evaluated() FMT_NOEXCEPT -> bool {
#ifdef __cpp_lib_is_constant_evaluated
return std::is_constant_evaluated();
#else
return false;
#endif
}

@vitaut
Copy link
Contributor

vitaut commented Sep 30, 2021

Why is this if statement needed?

To get sensible code in debug mode: https://godbolt.org/z/56W3YG5xe.

@vitaut
Copy link
Contributor

vitaut commented Sep 30, 2021

Is this a bug or I am misunderstanding the check?

It just doesn't play well with the fallback which is why it needs to be refined.

mwinterb added a commit to mwinterb/fmt that referenced this issue Sep 30, 2021
Also added commentary for why std::strlen is directly called in certain situations.
Addresses fmtlib#2455 (comment).
@vitaut
Copy link
Contributor

vitaut commented Oct 2, 2021

@ndevenish do you have a godbolt repro for the issue?

@vitaut
Copy link
Contributor

vitaut commented Oct 9, 2021

This should be fixed now.

@timblechmann
Copy link
Contributor

haven't been able to test, yet, but apparently fixed it in xcode13.3

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

7 participants