hazohelet created this revision. hazohelet added reviewers: aaron.ballman, erichkeane, tbaeder, shafik. Herald added a project: All. hazohelet requested review of this revision. Herald added a project: clang.
BEFORE this patch, when clang handles constraints like `C1 || C2` where `C1` evaluates to false and `C2` evaluates to true, it emitted irrelevant diagnostics about the falsity of `C1`. This patch removes the irrelevant diagnostic information generated during the evaluation of `C1` if `C2` evaluates to true. Fixes https://github.com/llvm/llvm-project/issues/54678 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D157526 Files: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaConcept.cpp clang/test/SemaTemplate/concepts.cpp Index: clang/test/SemaTemplate/concepts.cpp =================================================================== --- clang/test/SemaTemplate/concepts.cpp +++ clang/test/SemaTemplate/concepts.cpp @@ -994,3 +994,40 @@ } } + +namespace GH54678 { +template<class> +concept True = true; + +template<class> +concept False = false; // expected-note 9 {{'false' evaluated to false}} + +template<class> +concept Irrelevant = false; + +template <typename T> +concept ErrorRequires = requires(ErrorRequires auto x) { x; }; // expected-error {{unknown type name 'ErrorRequires'}} + +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'}} +template<class T> void bbb(T t) // expected-note {{candidate template ignored: constraints not satisfied}} +requires (False<T> || False<T>) && True<T> {} // expected-note 2 {{'long' does not satisfy 'False'}} +template<class T> void ccc(T t) // expected-note {{candidate template ignored: constraints not satisfied}} +requires (True<T> || Irrelevant<T>) && False<T> {} // expected-note {{'unsigned long' does not satisfy 'False'}} +template<class T> void ddd(T t) // expected-note {{candidate template ignored: constraints not satisfied}} +requires (Irrelevant<T> || True<T>) && False<T> {} // expected-note {{'int' does not satisfy 'False'}} +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 {{'unsigned long' does not satisfy 'False'}} + +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}} +} +} Index: clang/lib/Sema/SemaConcept.cpp =================================================================== --- clang/lib/Sema/SemaConcept.cpp +++ clang/lib/Sema/SemaConcept.cpp @@ -183,6 +183,7 @@ ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts(); if (LogicalBinOp BO = ConstraintExpr) { + auto EffectiveDetailEnd = Satisfaction.Details.end(); ExprResult LHSRes = calculateConstraintSatisfaction( S, BO.getLHS(), Satisfaction, Evaluator); @@ -216,6 +217,11 @@ if (RHSRes.isInvalid()) return ExprError(); + bool IsRHSSatisfied = Satisfaction.IsSatisfied; + if (BO.isOr() && IsRHSSatisfied) + Satisfaction.Details.erase(EffectiveDetailEnd, + Satisfaction.Details.end()); + return BO.recreateBinOp(S, LHSRes, RHSRes); } Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -125,6 +125,8 @@ of a base class is not called in the constructor of its derived class. - Clang no longer emits ``-Wmissing-variable-declarations`` for variables declared with the ``register`` storage class. +- Clang no longer emits irrelevant notes about unsatisfied constraint expressions + on the left-hand side of ``||`` when the right-hand side constraint is satisfied. Bug Fixes in This Version -------------------------
Index: clang/test/SemaTemplate/concepts.cpp =================================================================== --- clang/test/SemaTemplate/concepts.cpp +++ clang/test/SemaTemplate/concepts.cpp @@ -994,3 +994,40 @@ } } + +namespace GH54678 { +template<class> +concept True = true; + +template<class> +concept False = false; // expected-note 9 {{'false' evaluated to false}} + +template<class> +concept Irrelevant = false; + +template <typename T> +concept ErrorRequires = requires(ErrorRequires auto x) { x; }; // expected-error {{unknown type name 'ErrorRequires'}} + +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'}} +template<class T> void bbb(T t) // expected-note {{candidate template ignored: constraints not satisfied}} +requires (False<T> || False<T>) && True<T> {} // expected-note 2 {{'long' does not satisfy 'False'}} +template<class T> void ccc(T t) // expected-note {{candidate template ignored: constraints not satisfied}} +requires (True<T> || Irrelevant<T>) && False<T> {} // expected-note {{'unsigned long' does not satisfy 'False'}} +template<class T> void ddd(T t) // expected-note {{candidate template ignored: constraints not satisfied}} +requires (Irrelevant<T> || True<T>) && False<T> {} // expected-note {{'int' does not satisfy 'False'}} +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 {{'unsigned long' does not satisfy 'False'}} + +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}} +} +} Index: clang/lib/Sema/SemaConcept.cpp =================================================================== --- clang/lib/Sema/SemaConcept.cpp +++ clang/lib/Sema/SemaConcept.cpp @@ -183,6 +183,7 @@ ConstraintExpr = ConstraintExpr->IgnoreParenImpCasts(); if (LogicalBinOp BO = ConstraintExpr) { + auto EffectiveDetailEnd = Satisfaction.Details.end(); ExprResult LHSRes = calculateConstraintSatisfaction( S, BO.getLHS(), Satisfaction, Evaluator); @@ -216,6 +217,11 @@ if (RHSRes.isInvalid()) return ExprError(); + bool IsRHSSatisfied = Satisfaction.IsSatisfied; + if (BO.isOr() && IsRHSSatisfied) + Satisfaction.Details.erase(EffectiveDetailEnd, + Satisfaction.Details.end()); + return BO.recreateBinOp(S, LHSRes, RHSRes); } Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -125,6 +125,8 @@ of a base class is not called in the constructor of its derived class. - Clang no longer emits ``-Wmissing-variable-declarations`` for variables declared with the ``register`` storage class. +- Clang no longer emits irrelevant notes about unsatisfied constraint expressions + on the left-hand side of ``||`` when the right-hand side constraint is satisfied. Bug Fixes in This Version -------------------------
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits