Author: Corentin Jabot Date: 2026-07-10T11:05:29+02:00 New Revision: ef1b46f29293db7b16dee598fb1e8f2a62555c33
URL: https://github.com/llvm/llvm-project/commit/ef1b46f29293db7b16dee598fb1e8f2a62555c33 DIFF: https://github.com/llvm/llvm-project/commit/ef1b46f29293db7b16dee598fb1e8f2a62555c33.diff LOG: [Clang] Fix a crash when checking the constraints of a self-referential concept (#208465) Mark self-referencial concepts as invalid to prevent them from being evaluated (which would crash). Fixes #206336 Added: Modified: clang/lib/Sema/SemaTemplate.cpp clang/test/CXX/drs/cwg25xx.cpp clang/test/SemaTemplate/concepts.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 43bcd0bfb9e17..a7f252be1cb39 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -9321,6 +9321,7 @@ bool Sema::CheckConceptUseInDefinition(NamedDecl *Concept, SourceLocation Loc) { CE && !CE->isInvalidDecl() && !CE->hasDefinition()) { Diag(Loc, diag::err_recursive_concept) << CE; Diag(CE->getLocation(), diag::note_declared_at); + CE->setInvalidDecl(); return true; } // Concept template parameters don't have a definition and can't diff --git a/clang/test/CXX/drs/cwg25xx.cpp b/clang/test/CXX/drs/cwg25xx.cpp index d5219bcd74756..6b4b167d8f07f 100644 --- a/clang/test/CXX/drs/cwg25xx.cpp +++ b/clang/test/CXX/drs/cwg25xx.cpp @@ -247,9 +247,6 @@ namespace cwg2565 { // cwg2565: 16 open 2023-06-07 x; }; static_assert(ErrorRequires<int>); - // since-cxx20-error@-1 {{static assertion failed}} \ - // since-cxx20-note@-1 {{because 'int' does not satisfy 'ErrorRequires'}} \ - // since-cxx20-note@#cwg2565-expr {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}} template<typename T> concept NestedErrorInRequires = requires (T x) { // #cwg2565-NEIR @@ -261,9 +258,6 @@ namespace cwg2565 { // cwg2565: 16 open 2023-06-07 }; }; static_assert(NestedErrorInRequires<int>); - // since-cxx20-error@-1 {{static assertion failed}} \ - // since-cxx20-note@-1 {{because 'int' does not satisfy 'NestedErrorInRequires'}} \ - // since-cxx20-note-re@#cwg2565-NEIR-inner {{because {{.*}} would be invalid: constraint depends on a previously diagnosed expression}} #endif } // namespace cwg2565 diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp index 6f7f00bf12e61..f2478e1a22a6a 100644 --- a/clang/test/SemaTemplate/concepts.cpp +++ b/clang/test/SemaTemplate/concepts.cpp @@ -997,7 +997,7 @@ template<class> concept True = true; template<class> -concept False = false; // expected-note 9 {{'false' evaluated to false}} +concept False = false; // expected-note 8 {{'false' evaluated to false}} template<class> concept Irrelevant = false; @@ -1009,8 +1009,8 @@ concept ErrorRequires = requires(ErrorRequires auto x) { x; }; //#GH54678-ill-fo // expected-note@-1 {{declared here}} template<typename T> concept C1 = C1<T> && []<C1>(C1 auto) -> C1 auto {}; -//expected-error@-1 4{{a concept definition cannot refer to itself}} \ -//expected-note@-1 4{{declared here}} +//expected-error@-1 {{a concept definition cannot refer to itself}} \ +//expected-note@-1 {{declared here}} template<class T> void aaa(T t) // expected-note {{candidate template ignored: constraints not satisfied}} requires (False<T> || False<T>) || False<T> {} // expected-note 3 {{'int' does not satisfy 'False'}} @@ -1023,15 +1023,15 @@ requires (Irrelevant<T> || True<T>) && False<T> {} // expected-note {{'int' does template<class T> void eee(T t) // expected-note {{candidate template ignored: constraints not satisfied}} requires (Irrelevant<T> || Irrelevant<T> || True<T>) && False<T> {} // expected-note {{'long' does not satisfy 'False'}} -template<class T> void fff(T t) // expected-note {{candidate template ignored: constraints not satisfied}} -requires((ErrorRequires<T> || False<T> || True<T>) && False<T>) {} // expected-note {{because 'unsigned long' does not satisfy 'False'}} +template<class T> void fff(T t) +requires((ErrorRequires<T> || False<T> || True<T>) && False<T>) {} void test() { aaa(42); // expected-error {{no matching function}} bbb(42L); // expected-error{{no matching function}} ccc(42UL); // expected-error {{no matching function}} ddd(42); // expected-error {{no matching function}} eee(42L); // expected-error {{no matching function}} - fff(42UL); // expected-error {{no matching function}} + fff(42UL); } } @@ -2064,3 +2064,19 @@ auto x = quantity<reference<int>{}, int>{}; } // namespace CannotResolve1 } // namespace GH175831 + + +namespace GH206336 { +class Dim; +struct S; +template <class T> concept foo = true; +template <class T> concept SS = false; // expected-note {{because 'false' evaluated to false}} +template <class X> concept _Dim = _Dim<X>; // expected-error {{a concept definition cannot refer to itself}} \ + // expected-note {{declared here}} +template <SS, _Dim Dim, foo<> E> auto bar(Dim, E) {}; // expected-note {{candidate template ignored: constraints not satisfied}} \ + // expected-note {{because 'GH206336::S' does not satisfy 'SS'}} + +void baz() { + auto qux = bar<S>(true, [] {}); // expected-error {{no matching function for call to 'bar'}} +} +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
