[clang] [Clang] Fix an assertion in expression recovery (PR #112888)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 18 04:54:36 PDT 2024


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

Explicit object member function calls are not modelled as member calls

Fixes #112559

>From bbb39f2941e38c07ea6902486276528fc10db367 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Fri, 18 Oct 2024 13:52:27 +0200
Subject: [PATCH] [Clang] Fix an assertion in expression recovery

Explicit object member function calls are not modelled as
member calls

Fixes #112559
---
 clang/docs/ReleaseNotes.rst                |  3 ++-
 clang/lib/AST/Expr.cpp                     |  2 +-
 clang/test/SemaCXX/cxx2b-deducing-this.cpp | 17 +++++++++++++++++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a65bd6f382901b..e86d6200fae800 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -418,7 +418,7 @@ Improvements to Clang's diagnostics
 - The warning for an unsupported type for a named register variable is now phrased ``unsupported type for named register variable``,
   instead of ``bad type for named register variable``. This makes it clear that the type is not supported at all, rather than being
   suboptimal in some way the error fails to mention (#GH111550).
-  
+
 - Clang now emits a ``-Wdepredcated-literal-operator`` diagnostic, even if the
   name was a reserved name, which we improperly allowed to suppress the
   diagnostic.
@@ -537,6 +537,7 @@ Bug Fixes to C++ Support
   certain situations. (#GH47400), (#GH90896)
 - Fix erroneous templated array size calculation leading to crashes in generated code. (#GH41441)
 - During the lookup for a base class name, non-type names are ignored. (#GH16855)
+- Fix a crash when recovering an invalid expression involving an explicit object member conversion operator. (#GH112559)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 9ecbf121e3fc0d..66db6263cb1bd2 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1989,7 +1989,7 @@ Expr *CastExpr::getSubExprAsWritten() {
       SubExpr = IgnoreExprNodes(cast<CXXConstructExpr>(SubExpr)->getArg(0),
                                 ignoreImplicitSemaNodes);
     } else if (E->getCastKind() == CK_UserDefinedConversion) {
-      assert((isa<CXXMemberCallExpr>(SubExpr) || isa<BlockExpr>(SubExpr)) &&
+      assert((isa<CallExpr, BlockExpr>(SubExpr)) &&
              "Unexpected SubExpr for CK_UserDefinedConversion.");
       if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SubExpr))
         SubExpr = MCE->getImplicitObjectArgument();
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
index 2a984a75f37d21..520052a89d1840 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
@@ -1097,3 +1097,20 @@ struct C4 {
                                   // expected-warning {{volatile-qualified parameter type 'const volatile C4' is deprecated}}
 };
 }
+
+
+namespace GH112559 {
+struct Wrap  {};
+struct S {
+    constexpr operator Wrap (this const S& self) {
+        return Wrap{};
+    };
+    constexpr int operator <<(this Wrap self, int i) {
+        return 0;
+    }
+};
+// Purposefully invalid expression to check an assertion in the
+// expression recovery machinery.
+static_assert((S{} << 11) == a);
+// expected-error at -1 {{use of undeclared identifier 'a'}}
+}



More information about the cfe-commits mailing list