Skip to content

[clang] Function call without comparisons reported as non-constant expression after CWG2765 implementation #117409

Open
@ormris

Description

@ormris

We're seeing a new diagnostic trigger in an internal test. The diagnostic is implemented in...

commit d8a281590311010955c323806fb24fa484376f4d
Author: Richard Smith <[email protected]>
Date:   Thu Sep 26 15:56:33 2024 -0700

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

    Track the identity of each string literal object produced by evaluation
    with a global version number. Accept comparisons between literals of the
    same version, and between literals of different versions that cannot
    possibly be placed in overlapping storage. Treat the remaining
    comparisons as non-constant.

    ---------

    Co-authored-by: Timm Baeder <[email protected]>
    Co-authored-by: Aaron Ballman <[email protected]>

Reduced test case below. The test case and CWG document seem to indicate that comparison is the expected use case, but I don't see any comparison operations in the code below. The values returned by the function indicated in the diagnostic are constant as well.

template <class> struct g;
template <class b> struct g<const b> { using e = b; };
template <class> struct l;
template <class b> struct l<b &> { using e = b; };
template <typename aa> struct ab {
  const aa *ac;
  ab();
  constexpr ab(const aa *k, long) : ac(k) {}
  constexpr auto af() { return ac; }
};
constexpr void al(const char *am, ab<char> aj) {
  am - aj.af();
}
struct L {
  ab<char> bp;
  template <typename o> consteval L(o k) : bp(k) {
    al(bp.af(), k);
  }
};
template <typename br> void q(br, L);
template <typename aa, int s> constexpr auto t(const aa (&k)[s]) -> ab<aa> {
  return {k, s};
}
void e() {
  q(0, [] {
    struct bx {
      constexpr operator ab<g<l<decltype(""[0])>::e>::e>() { return t(""); }
    };
    return bx();
  }());
} 

To reproduce:

$ clang -std=c++20 test.cpp
test.cpp:12:6: warning: expression result unused [-Wunused-value]
   12 |   am - aj.af();
      |   ~~ ^ ~~~~~~~
test.cpp:25:8: error: call to consteval function 'L::L<bx>' is not a constant expression
   25 |   q(0, [] {
      |        ^
test.cpp:12:6: note: subexpression not valid in a constant expression
   12 |   am - aj.af();
      |   ~~~^~~~~~~~~
test.cpp:17:5: note: in call to 'al(&""[0], {&""[0]})'
   17 |     al(bp.af(), k);
      |     ^~~~~~~~~~~~~~
test.cpp:25:8: note: in call to 'L<bx>({})'
   25 |   q(0, [] {
      |        ^~~~
   26 |     struct bx {
      |     ~~~~~~~~~~~
   27 |       constexpr operator ab<g<l<decltype(""[0])>::e>::e>() { return t(""); }
      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   28 |     };
      |     ~~
   29 |     return bx();
      |     ~~~~~~~~~~~~
   30 |   }());
      |   ~~~
1 warning and 1 error generated.
$

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++20clang:analysisclang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions