[PATCH] D133948: [clang][C++20] Fix clang/clangd assert/crash after compilation errors

Dmitry Polukhin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 15 08:41:35 PDT 2022


DmitryPolukhin created this revision.
DmitryPolukhin added reviewers: Tyker, rsmith, aaron.ballman.
DmitryPolukhin added a project: clang.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
DmitryPolukhin requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.

After compilation errors, expression a transformation result may not be usable.
It triggers an assert in RemoveNestedImmediateInvocation and SIGSEGV in case of
builds without asserts. This issue significantly affects clangd because source
may not be valid during typing. Tests cases that I attached was reduce from huge
C++ translation unit.

Test Plan: check-clang


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133948

Files:
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/remove-nested-immediate-invocation-crash.cpp


Index: clang/test/SemaCXX/remove-nested-immediate-invocation-crash.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/remove-nested-immediate-invocation-crash.cpp
@@ -0,0 +1,11 @@
+// RUN: not %clang_cc1 -fsyntax-only -verify -std=gnu++20 -ferror-limit 19 %s
+// Creduced test case for the crash in RemoveNestedImmediateInvocation after compliation errros.
+
+a, class b {                               template < typename c>                 consteval b(c
+} template <typename...> using d = b;
+auto e(d<>) -> int:;
+}
+f
+}
+g() {
+                    auto h = "":(::i(e(h))
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -17624,9 +17624,13 @@
     Transformer.AllowSkippingFirstCXXConstructExpr = false;
 
   ExprResult Res = Transformer.TransformExpr(It->getPointer()->getSubExpr());
-  assert(Res.isUsable());
-  Res = SemaRef.MaybeCreateExprWithCleanups(Res);
-  It->getPointer()->setSubExpr(Res.get());
+  // The result may not be usable in case of previous compilation errors.
+  // In this case evaluation of the expression may result in crash so just
+  // don't do anything further with the result.
+  if(Res.isUsable()) {
+    Res = SemaRef.MaybeCreateExprWithCleanups(Res);
+    It->getPointer()->setSubExpr(Res.get());
+  }
 }
 
 static void


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D133948.460428.patch
Type: text/x-patch
Size: 1437 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220915/83ccf8ef/attachment.bin>


More information about the llvm-commits mailing list