[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 27 09:56:40 PST 2024
https://github.com/Sirraide updated https://github.com/llvm/llvm-project/pull/83103
>From 071b6287e89e4601d9e441978f0b4bd53e757c26 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 27 Feb 2024 06:19:05 +0100
Subject: [PATCH 1/3] [Clang] [Sema] Handle placeholders in '.*' expressions
---
clang/lib/Sema/SemaOverload.cpp | 22 +++++++++++++++++-----
clang/test/SemaCXX/gh53815.cpp | 21 +++++++++++++++++++++
2 files changed, 38 insertions(+), 5 deletions(-)
create mode 100644 clang/test/SemaCXX/gh53815.cpp
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index c46f6338a5a125..f4b67e7b469418 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -14474,6 +14474,23 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
CurFPFeatureOverrides());
}
+ // If this is the .* operator, which is not overloadable, just
+ // create a built-in binary operator.
+ if (Opc == BO_PtrMemD) {
+ auto CheckPlaceholder = [&](Expr *&Arg) {
+ ExprResult Res = CheckPlaceholderExpr(Arg);
+ if (!Res.isInvalid())
+ Arg = Res.get();
+ return Res.isInvalid();
+ };
+
+ // CreateBuiltinBinOp() doesn't like it if we tell it to create a '.*'
+ // expression that contains placeholders (in either the LHS or RHS).
+ if (CheckPlaceholder(Args[0]) || CheckPlaceholder(Args[1]))
+ return ExprError();
+ return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
+ }
+
// Always do placeholder-like conversions on the RHS.
if (checkPlaceholderForOverload(*this, Args[1]))
return ExprError();
@@ -14493,11 +14510,6 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType())
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
- // If this is the .* operator, which is not overloadable, just
- // create a built-in binary operator.
- if (Opc == BO_PtrMemD)
- return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
-
// Build the overload set.
OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator,
OverloadCandidateSet::OperatorRewriteInfo(
diff --git a/clang/test/SemaCXX/gh53815.cpp b/clang/test/SemaCXX/gh53815.cpp
new file mode 100644
index 00000000000000..326c911c7bfaf5
--- /dev/null
+++ b/clang/test/SemaCXX/gh53815.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
+// expected-no-diagnostics
+
+// Check that we don't crash due to forgetting to check for placeholders
+// in the RHS of '.*'.
+
+template <typename Fn>
+static bool has_explicitly_named_overload() {
+ return requires { Fn().*&Fn::operator(); };
+}
+
+int main() {
+ has_explicitly_named_overload<decltype([](auto){})>();
+}
+
+template <typename Fn>
+constexpr bool has_explicitly_named_overload_2() {
+ return requires { Fn().*&Fn::operator(); };
+}
+
+static_assert(!has_explicitly_named_overload_2<decltype([](auto){})>());
>From b39abdb1a5d083a59ce818748c0d130501467706 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 27 Feb 2024 18:35:22 +0100
Subject: [PATCH 2/3] [Clang] Update release notes
---
clang/docs/ReleaseNotes.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c60c5682dbd826..7e16b9f0c67dbd 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -288,6 +288,8 @@ Bug Fixes to C++ Support
templates when determining the primary template of an explicit specialization.
- Fixed a crash in Microsoft compatibility mode where unqualified dependent base class
lookup searches the bases of an incomplete class.
+- Fix a crash when an unresolved overload set is encountered on the RHS of a ``.*`` operator.
+ (`#53815 <https://github.com/llvm/llvm-project/issues/53815>`_)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
>From c52a0e91b9949c8ee4a13df11309b230d37ca933 Mon Sep 17 00:00:00 2001
From: Sirraide <aeternalmail at gmail.com>
Date: Tue, 27 Feb 2024 18:56:23 +0100
Subject: [PATCH 3/3] [NFC] Use isUsable() instead of isInvalid()
---
clang/lib/Sema/SemaOverload.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 1b1252ba90e560..7d38043890ca20 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -14576,9 +14576,9 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Opc == BO_PtrMemD) {
auto CheckPlaceholder = [&](Expr *&Arg) {
ExprResult Res = CheckPlaceholderExpr(Arg);
- if (!Res.isInvalid())
+ if (Res.isUsable())
Arg = Res.get();
- return Res.isInvalid();
+ return !Res.isUsable();
};
// CreateBuiltinBinOp() doesn't like it if we tell it to create a '.*'
More information about the cfe-commits
mailing list