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


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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to