[clang] [clang] implement current direction of CWG2765 for string literal comparisons in constant evaluation (PR #109208)

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 27 13:59:52 PDT 2024


zeroomega wrote:

Hi,

We are seeing build error on fmtlib project after this patch is landed. The error message from the clang is:

```
FAILED: host_x64/obj/third_party/fmtlib/src/src/fmtlib.os.cc.o 
 ../../prebuilt/third_party/clang/custom/bin/clang++ -MD -MF host_x64/obj/third_party/fmtlib/src/src/fmtlib.os.cc.o.d -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS -D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES -I../.. -Ihost_x64/gen -I../../third_party/fmtlib/src/include -fcolor-diagnostics -fcrash-diagnostics-dir=clang-crashreports -fcrash-diagnostics=all -gen-reproducer=error -ffp-contract=off --sysroot=../../prebuilt/third_party/sysroot/linux --target=x86_64-unknown-linux-gnu -ffile-compilation-dir=. -no-canonical-prefixes -fomit-frame-pointer -fdata-sections -ffunction-sections -O0 -Xclang -debug-info-kind=constructor -g3 -grecord-gcc-switches -gdwarf-5 -gz=zstd -Wall -Wextra -Wconversion -Wextra-semi -Wimplicit-fallthrough -Wnewline-eof -Wstrict-prototypes -Wwrite-strings -Wno-sign-conversion -Wno-unused-parameter -Wnonportable-system-include-path -Wno-missing-field-initializers -Wno-extra-qualification -Wno-cast-function-type-strict -Wno-cast-function-type-mismatch -Wno-unknown-warning-option -Wno-missing-template-arg-list-after-template-kw -Wno-deprecated-pragma -fvisibility=hidden -Werror -Wa,--fatal-warnings -Wno-error=deprecated-declarations --sysroot=../../prebuilt/third_party/sysroot/linux --target=x86_64-unknown-linux-gnu -fPIE -fvisibility-inlines-hidden -stdlib=libc++ -stdlib=libc++ -std=c++20 -Wno-deprecated-this-capture -fno-exceptions -fno-rtti -ftemplate-backtrace-limit=0 -stdlib=libc++ -c ../../third_party/fmtlib/src/src/os.cc -o host_x64/obj/third_party/fmtlib/src/src/fmtlib.os.cc.o
 ../../third_party/fmtlib/src/src/os.cc:176:35: error: call to consteval function 'fmt::basic_format_string<char, const char *>::basic_format_string<FMT_COMPILE_STRING, 0>' is not a constant expression
   176 |     FMT_THROW(system_error(errno, FMT_STRING("cannot open file {}"),
       |                                   ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/base.h:779:54: note: subexpression not valid in a constant expression
   779 |     format_str_.remove_prefix(detail::to_unsigned(it - begin()));
       |                                                   ~~~^~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2769:5: note: in call to 'this->context_.advance_to(&"cannot open file {}"[18])'
  2769 |     context_.advance_to(begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2764:5: note: in call to 'this->on_format_specs(0, &"cannot open file {}"[18], &"cannot open file {}"[18])'
  2764 |     on_format_specs(id, begin, begin);  // Call parse() on empty specs.
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2571:5: note: in call to 'handler.on_replacement_field(0, &"cannot open file {}"[18])'
  2571 |     handler.on_replacement_field(handler.on_arg_id(), begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2621:21: note: in call to 'parse_replacement_field<char, fmt::detail::format_string_checker<char, const char *> &>(&"cannot open file {}"[18], &"cannot open file {}"[19], checker(s))'
  2621 |         begin = p = parse_replacement_field(p - 1, end, handler);
       |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2892:7: note: in call to 'parse_format_string<true, char, fmt::detail::format_string_checker<char, const char *>>({&"cannot open file {}"[0], 19}, checker(s))'
  2892 |       detail::parse_format_string<true>(str_, checker(s));
       |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/src/os.cc:176:35: note: in call to 'basic_format_string<FMT_COMPILE_STRING, 0>([] {
     struct __attribute__((visibility("hidden")))  FMT_COMPILE_STRING : fmt::detail::compile_string {
         using char_type [[maybe_unused]] = fmt::remove_cvref_t<decltype("cannot open file {}"[0])>;
         [[maybe_unused]] constexpr operator fmt::basic_string_view<char_type>() const {
             return fmt::detail_exported::compile_string_to_view<char_type>("cannot open file {}");
         }
     };
     return FMT_COMPILE_STRING();
 }())'
   176 |     FMT_THROW(system_error(errno, FMT_STRING("cannot open file {}"),
       |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   177 |                            filename.c_str()));
       |                            ~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/format.h:136:55: note: expanded from macro 'FMT_THROW'
   136 |       ::fmt::detail::assert_fail(__FILE__, __LINE__, (x).what())
       |                                                       ^
 ../../third_party/fmtlib/src/src/os.cc:222:29: error: call to consteval function 'fmt::basic_format_string<char, const char *>::basic_format_string<FMT_COMPILE_STRING, 0>' is not a constant expression
   222 |         system_error(errno, FMT_STRING("cannot open file {}"), path.c_str()));
       |                             ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/base.h:779:54: note: subexpression not valid in a constant expression
   779 |     format_str_.remove_prefix(detail::to_unsigned(it - begin()));
       |                                                   ~~~^~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2769:5: note: in call to 'this->context_.advance_to(&"cannot open file {}"[18])'
  2769 |     context_.advance_to(begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2764:5: note: in call to 'this->on_format_specs(0, &"cannot open file {}"[18], &"cannot open file {}"[18])'
  2764 |     on_format_specs(id, begin, begin);  // Call parse() on empty specs.
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2571:5: note: in call to 'handler.on_replacement_field(0, &"cannot open file {}"[18])'
  2571 |     handler.on_replacement_field(handler.on_arg_id(), begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2621:21: note: in call to 'parse_replacement_field<char, fmt::detail::format_string_checker<char, const char *> &>(&"cannot open file {}"[18], &"cannot open file {}"[19], checker(s))'
  2621 |         begin = p = parse_replacement_field(p - 1, end, handler);
       |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2892:7: note: in call to 'parse_format_string<true, char, fmt::detail::format_string_checker<char, const char *>>({&"cannot open file {}"[0], 19}, checker(s))'
  2892 |       detail::parse_format_string<true>(str_, checker(s));
       |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/src/os.cc:222:29: note: in call to 'basic_format_string<FMT_COMPILE_STRING, 0>([] {
     struct __attribute__((visibility("hidden")))  FMT_COMPILE_STRING : fmt::detail::compile_string {
         using char_type [[maybe_unused]] = fmt::remove_cvref_t<decltype("cannot open file {}"[0])>;
         [[maybe_unused]] constexpr operator fmt::basic_string_view<char_type>() const {
             return fmt::detail_exported::compile_string_to_view<char_type>("cannot open file {}");
         }
     };
     return FMT_COMPILE_STRING();
 }())'
   221 |     FMT_THROW(
       |     ~~~~~~~~~~
   222 |         system_error(errno, FMT_STRING("cannot open file {}"), path.c_str()));
       |         ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/format.h:136:55: note: expanded from macro 'FMT_THROW'
   136 |       ::fmt::detail::assert_fail(__FILE__, __LINE__, (x).what())
       |                                                       ^
 ../../third_party/fmtlib/src/src/os.cc:291:16: error: call to consteval function 'fmt::basic_format_string<char, int &>::basic_format_string<FMT_COMPILE_STRING, 0>' is not a constant expression
   291 |         errno, FMT_STRING("cannot duplicate file descriptor {}"), fd));
       |                ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/base.h:779:54: note: subexpression not valid in a constant expression
   779 |     format_str_.remove_prefix(detail::to_unsigned(it - begin()));
       |                                                   ~~~^~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2769:5: note: in call to 'this->context_.advance_to(&"cannot duplicate file descriptor {}"[34])'
  2769 |     context_.advance_to(begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2764:5: note: in call to 'this->on_format_specs(0, &"cannot duplicate file descriptor {}"[34], &"cannot duplicate file descriptor {}"[34])'
  2764 |     on_format_specs(id, begin, begin);  // Call parse() on empty specs.
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2571:5: note: in call to 'handler.on_replacement_field(0, &"cannot duplicate file descriptor {}"[34])'
  2571 |     handler.on_replacement_field(handler.on_arg_id(), begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2655:13: note: in call to 'parse_replacement_field<char, fmt::detail::format_string_checker<char, int> &>(&"cannot duplicate file descriptor {}"[34], &"cannot duplicate file descriptor {}"[35], checker(s))'
  2655 |     begin = parse_replacement_field(p, end, handler);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2892:7: note: in call to 'parse_format_string<true, char, fmt::detail::format_string_checker<char, int>>({&"cannot duplicate file descriptor {}"[0], 35}, checker(s))'
  2892 |       detail::parse_format_string<true>(str_, checker(s));
       |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/src/os.cc:291:16: note: in call to 'basic_format_string<FMT_COMPILE_STRING, 0>([] {
     struct __attribute__((visibility("hidden")))  FMT_COMPILE_STRING : fmt::detail::compile_string {
         using char_type [[maybe_unused]] = fmt::remove_cvref_t<decltype("cannot duplicate file descriptor {}"[0])>;
         [[maybe_unused]] constexpr operator fmt::basic_string_view<char_type>() const {
             return fmt::detail_exported::compile_string_to_view<char_type>("cannot duplicate file descriptor {}");
         }
     };
     return FMT_COMPILE_STRING();
 }())'
   290 |     FMT_THROW(system_error(
       |     ~~~~~~~~~~~~~~~~~~~~~~~
   291 |         errno, FMT_STRING("cannot duplicate file descriptor {}"), fd));
       |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/format.h:136:55: note: expanded from macro 'FMT_THROW'
   136 |       ::fmt::detail::assert_fail(__FILE__, __LINE__, (x).what())
       |                                                       ^
 ../../third_party/fmtlib/src/src/os.cc:300:16: error: call to consteval function 'fmt::basic_format_string<char, int &, int &>::basic_format_string<FMT_COMPILE_STRING, 0>' is not a constant expression
   300 |         errno, FMT_STRING("cannot duplicate file descriptor {} to {}"), fd_,
       |                ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/base.h:779:54: note: subexpression not valid in a constant expression
   779 |     format_str_.remove_prefix(detail::to_unsigned(it - begin()));
       |                                                   ~~~^~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2769:5: note: in call to 'this->context_.advance_to(&"cannot duplicate file descriptor {} to {}"[34])'
  2769 |     context_.advance_to(begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2764:5: note: in call to 'this->on_format_specs(0, &"cannot duplicate file descriptor {} to {}"[34], &"cannot duplicate file descriptor {} to {}"[34])'
  2764 |     on_format_specs(id, begin, begin);  // Call parse() on empty specs.
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2571:5: note: in call to 'handler.on_replacement_field(0, &"cannot duplicate file descriptor {} to {}"[34])'
  2571 |     handler.on_replacement_field(handler.on_arg_id(), begin);
       |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2655:13: note: in call to 'parse_replacement_field<char, fmt::detail::format_string_checker<char, int, int> &>(&"cannot duplicate file descriptor {} to {}"[34], &"cannot duplicate file descriptor {} to {}"[41], checker(s))'
  2655 |     begin = parse_replacement_field(p, end, handler);
       |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/include/fmt/base.h:2892:7: note: in call to 'parse_format_string<true, char, fmt::detail::format_string_checker<char, int, int>>({&"cannot duplicate file descriptor {} to {}"[0], 41}, checker(s))'
  2892 |       detail::parse_format_string<true>(str_, checker(s));
       |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ../../third_party/fmtlib/src/src/os.cc:300:16: note: in call to 'basic_format_string<FMT_COMPILE_STRING, 0>([] {
     struct __attribute__((visibility("hidden")))  FMT_COMPILE_STRING : fmt::detail::compile_string {
         using char_type [[maybe_unused]] = fmt::remove_cvref_t<decltype("cannot duplicate file descriptor {} to {}"[0])>;
         [[maybe_unused]] constexpr operator fmt::basic_string_view<char_type>() const {
             return fmt::detail_exported::compile_string_to_view<char_type>("cannot duplicate file descriptor {} to {}");
         }
     };
     return FMT_COMPILE_STRING();
 }())'
   299 |     FMT_THROW(system_error(
       |     ~~~~~~~~~~~~~~~~~~~~~~~
   300 |         errno, FMT_STRING("cannot duplicate file descriptor {} to {}"), fd_,
       |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   301 |         fd));
       |         ~~~~
 ../../third_party/fmtlib/src/include/fmt/format.h:1842:23: note: expanded from macro 'FMT_STRING'
  1842 | #define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, )
       |                       ^
 ../../third_party/fmtlib/src/include/fmt/format.h:1821:3: note: expanded from macro 'FMT_STRING_IMPL'
  1821 |   [] {                                                                        \
       |   ^
 ../../third_party/fmtlib/src/include/fmt/format.h:136:55: note: expanded from macro 'FMT_THROW'
   136 |       ::fmt::detail::assert_fail(__FILE__, __LINE__, (x).what())
       |                                                       ^
 4 errors generated.
```

Full build log can be seen from: https://logs.chromium.org/logs/fuchsia/buildbucket/cr-buildbucket/8735688601552461713/+/u/build/ninja/stdout

We are still looking into it to understand if it is a compiler bug or an issue with fmtlib's implementation. 

https://github.com/llvm/llvm-project/pull/109208


More information about the cfe-commits mailing list