[clang] [Clang] Ensure compound requirements do not contain placeholder expressions (PR #162618)

Corentin Jabot via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 9 02:11:40 PDT 2025


https://github.com/cor3ntin created https://github.com/llvm/llvm-project/pull/162618

The name of an overload set is not a valid id expression.

Fixes #51246

>From fd65f0c8fac920562c5a4a5fb238e50f293c160d Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 9 Oct 2025 11:06:10 +0200
Subject: [PATCH] [Clang] Ensure compound requirements do not contain
 placeholder expressions

The name of an overloasd set is not a valid id expression.

Fixes #51246
---
 clang/docs/ReleaseNotes.rst                   |  1 +
 clang/lib/Parse/ParseExprCXX.cpp              |  2 ++
 .../AST/ByteCode/libcxx/deref-to-array.cpp    |  2 +-
 clang/test/SemaTemplate/concepts.cpp          | 21 ++++++++++++++++++-
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9a0d69c6c1b0e..2c194c50d85b6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -455,6 +455,7 @@ Bug Fixes to C++ Support
 - Fix a crash when attempting to deduce a deduction guide from a non deducible template template parameter. (#130604)
 - Fix for clang incorrectly rejecting the default construction of a union with
   nontrivial member when another member has an initializer. (#GH81774)
+- Diagnose unresolved overload sets in non-dependent compound requirements. (#51246)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index a2c69578d5087..0147ce5ba085c 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -3369,6 +3369,8 @@ ExprResult Parser::ParseRequiresExpression() {
         //         expression ';'
         SourceLocation StartLoc = Tok.getLocation();
         ExprResult Expression = ParseExpression();
+        if (Expression.isUsable())
+          Expression = Actions.CheckPlaceholderExpr(Expression.get());
         if (!Expression.isUsable()) {
           SkipUntil(tok::semi, tok::r_brace, SkipUntilFlags::StopBeforeMatch);
           break;
diff --git a/clang/test/AST/ByteCode/libcxx/deref-to-array.cpp b/clang/test/AST/ByteCode/libcxx/deref-to-array.cpp
index 2a527ab336a0d..7cfcd76b3965a 100644
--- a/clang/test/AST/ByteCode/libcxx/deref-to-array.cpp
+++ b/clang/test/AST/ByteCode/libcxx/deref-to-array.cpp
@@ -270,7 +270,7 @@ template <class _Op, class _Yp>
 void __is_derived_from_view_interface();
 template <class _Tp>
 bool enable_view = derived_from<_Tp, int> ||
-                   requires { ranges::__is_derived_from_view_interface; };
+                   requires { ranges::__is_derived_from_view_interface<_Tp, int>(); };
 template <class>
 concept range = requires { ranges::end; };
 template <class _Tp>
diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index 3b7c138f83364..5f7fc63d321cf 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1407,7 +1407,6 @@ static_assert(!std::is_constructible_v<span<4>, array<int, 3>>);
 
 }
 
-
 namespace GH162125 {
 template<typename, int size>
 concept true_int = (size, true);
@@ -1444,3 +1443,23 @@ struct s {
 
 void(*test)(int) = &s<bool>::f<int>;
 }
+namespace GH51246 {
+void f(); // expected-note {{possible target for call}}
+void f(int); // expected-note {{possible target for call}}
+void g();
+static_assert(requires { f; }); // expected-error {{reference to overloaded function could not be resolved}}
+static_assert(requires { g; });
+struct S {
+    void mf() {
+        static_assert(requires { mf(); });
+        static_assert(requires { mf; });    // expected-error {{reference to non-static member function must be called}}
+        static_assert(requires { S::mf; }); // expected-error {{reference to non-static member function must be called}}
+    }
+    void mf2(int); // expected-note 2{{possible target for call}}
+    void mf2() { // expected-note 2{{possible target for call}}
+        static_assert(requires { mf2; });    // expected-error {{reference to non-static member function must be called}}
+        static_assert(requires { S::mf2; }); // expected-error {{reference to non-static member function must be called}}
+    }
+};
+
+} // namespace GH51246



More information about the cfe-commits mailing list