[PATCH] D78715: [clangd] Fix modernize-loop-convert "multiple diag in flight" crash.

Haojian Wu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 23 07:32:20 PDT 2020


hokein created this revision.
hokein added a reviewer: sammccall.
Herald added subscribers: usaxena95, kadircet, arphaman, jkorous, MaskRay, ilya-biryukov.
Herald added a project: clang.

this maybe not ideal, but it is trivial and does fix the crash.

Fixes https://github.com/clangd/clangd/issues/156.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78715

Files:
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp


Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -272,6 +272,33 @@
                   "use a trailing return type for this function")))));
 }
 
+TEST(DiagnosticTest, NoMultipleDiagnosticInFlight) {
+  Annotations Main(R"cpp(
+    template <typename T> struct Foo {
+      T *begin();
+      T *end();
+    };
+    struct LabelInfo {
+      int a;
+      bool b;
+    };
+
+    void f() {
+      Foo<LabelInfo> label_info_map;
+      [[for]] (auto it = label_info_map.begin(); it != label_info_map.end(); ++it) {
+        auto S = *it;
+      }
+    }
+  )cpp");
+  TestTU TU = TestTU::withCode(Main.code());
+  TU.ClangTidyChecks = "modernize-loop-convert";
+  EXPECT_THAT(
+      TU.build().getDiagnostics(),
+      UnorderedElementsAre(::testing::AllOf(
+          Diag(Main.range(), "use range-based for loop instead"),
+          DiagSource(Diag::ClangTidy), DiagName("modernize-loop-convert"))));
+}
+
 TEST(DiagnosticTest, ClangTidySuppressionComment) {
   Annotations Main(R"cpp(
     int main() {
Index: clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
@@ -525,6 +525,9 @@
     const ValueDecl *MaybeContainer, const UsageResult &Usages,
     const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit,
     const ForStmt *Loop, RangeDescriptor Descriptor) {
+  // getTypeInfo may emit a diagnostic, we have to call it before constructing
+  // the Diag to avoid the "multiple-diagnostic in flight" crash in clangd.
+  auto TypeWidth = Context->getTypeInfo(Descriptor.ElemType).Width;
   auto Diag = diag(Loop->getForLoc(), "use range-based for loop instead");
 
   std::string VarName;
@@ -628,7 +631,7 @@
       !Descriptor.ElemType.isNull() &&
       Descriptor.ElemType.isTriviallyCopyableType(*Context) &&
       // TypeInfo::Width is in bits.
-      Context->getTypeInfo(Descriptor.ElemType).Width <= 8 * MaxCopySize;
+      TypeWidth <= 8 * MaxCopySize;
   bool UseCopy = CanCopy && ((VarNameFromAlias && !AliasVarIsRef) ||
                              (Descriptor.DerefByConstRef && IsCheapToCopy));
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78715.259563.patch
Type: text/x-patch
Size: 2444 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200423/1d0c6447/attachment.bin>


More information about the cfe-commits mailing list