https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124444

            Bug ID: 124444
           Summary: debug _M_invalidate_if  incompatible with C++20 since
                    r16-5845
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jakub at gcc dot gnu.org
  Target Milestone: ---

#include <functional>
#include <iostream>

int main()
{
}

clang++ t.cc -g -std=c++20 -D_GLIBCXX_DEBUG
fails with:
In file included from t.cc:1:
In file included from
/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/functional:81:
In file included from
/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/vector:78:
In file included from
/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/debug/vector:42:
In file included from
/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/debug/safe_sequence.h:177:
/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/debug/safe_sequence.tcc:46:27:
error: variable of non-literal
      type '__gnu_cxx::__scoped_lock' cannot be defined in a constexpr function
before C++23
   46 |         __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
      |                                  ^
/usr/bin/../lib/gcc/x86_64-redhat-linux/16/../../../../include/c++/16/ext/concurrence.h:233:9:
note: '__scoped_lock' is not literal
      because it is not an aggregate and has no constexpr constructors other
than copy or move constructors
  233 |   class __scoped_lock
      |         ^

Wonder if for C++20 the body doesn't have to be moved to a non-constexpr
function template.

I think this is a bug in g++ that it accepts it.
struct S { S () : s (42) {} ~S () {} int s; };
#ifdef TMPL
template <int N>
#endif
constexpr bool
foo ()
{
  if (__builtin_is_constant_evaluated ()) { return true; }
  S s;
  return true;
}
#ifdef TMPL
auto a = foo <42> ();
#else
auto a = foo ();
#endif
Both g++ and clang++ reject this with -std=c++20 if TMPL is not defined
g++ -S -std=c++20 -o /tmp/0.s /tmp/0.C
/tmp/0.C: In function ‘constexpr bool foo()’:
/tmp/0.C:9:5: error: variable ‘s’ of non-literal type ‘S’ in ‘constexpr’
function only available with ‘-std=c++23’ or ‘-std=gnu++23’
    9 |   S s;
      |     ^
/tmp/0.C:1:8: note: ‘S’ is not literal because:
    1 | struct S { S () : s (42) {} ~S () {} int s; };
      |        ^
/tmp/0.C:1:8: note:   ‘S’ does not have ‘constexpr’ destructor
clang++ -S -std=c++20 -o /tmp/0.s /tmp/0.C
/tmp/0.C:9:5: error: variable of non-literal type 'S' cannot be defined in a
constexpr function before C++23
    9 |   S s;
      |     ^
/tmp/0.C:1:8: note: 'S' is not literal because it is not an aggregate and has
no constexpr constructors other than copy or move constructors
    1 | struct S { S () : s (42) {} ~S () {} int s; };
      |        ^
1 error generated.
but 
g++ -S -DTMPL -std=c++20 -o /tmp/0.s /tmp/0.C
is quiet and
clang++ -S -DTMPL -std=c++20 -o /tmp/0.s /tmp/0.C
/tmp/0.C:9:5: error: variable of non-literal type 'S' cannot be defined in a
constexpr function before C++23
    9 |   S s;
      |     ^
/tmp/0.C:1:8: note: 'S' is not literal because it is not an aggregate and has
no constexpr constructors other than copy or move constructors
    1 | struct S { S () : s (42) {} ~S () {} int s; };
      |        ^
/tmp/0.C:13:10: error: no matching function for call to 'foo'
   13 | auto a = foo <42> ();
      |          ^~~~~~~~
/tmp/0.C:6:1: note: candidate template ignored: substitution failure [with N =
42]
    6 | foo ()
      | ^
2 errors generated.

Reply via email to