From a92d840d5a612188f17e71f3366bc3f9a0f3f39e Mon Sep 17 00:00:00 2001
From: Argyrios Kyrtzidis <akyrtzi@gmail.com>
Date: Thu, 6 Aug 2015 18:46:36 +0000
Subject: [PATCH] [Frontend] Fix crash when serializing diagnostics with really
 long text.

rdar://21896690

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@244245 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Frontend/SerializedDiagnosticPrinter.cpp  |  2 +-
 .../serialized-diags-really-long-text.cpp     | 30 +++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 test/Misc/serialized-diags-really-long-text.cpp

diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index d31b12e87a4..f63f9ef44ca 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -478,7 +478,7 @@ void SDiagsWriter::EmitBlockInfoBlock() {
   AddSourceLocationAbbrev(Abbrev);
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Category.  
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped Diag ID.
-  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size.
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // Text size.
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Diagnostc text.
   Abbrevs.set(RECORD_DIAG, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
   
diff --git a/test/Misc/serialized-diags-really-long-text.cpp b/test/Misc/serialized-diags-really-long-text.cpp
new file mode 100644
index 00000000000..2cdd50994a3
--- /dev/null
+++ b/test/Misc/serialized-diags-really-long-text.cpp
@@ -0,0 +1,30 @@
+// Make sure that diagnostics serialization does not crash with a really long diagnostic text.
+
+// RUN: not %clang_cc1 -std=c++11 %s -serialize-diagnostic-file %t.dia
+// RUN: c-index-test -read-diagnostics %t.dia 2>&1 | FileCheck %s
+
+typedef class AReallyLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooongName {} alias;
+
+template <int N, typename ...T>
+struct MyTS {
+  typedef MyTS<N-1, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias,
+    alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, alias, T...> type;
+  static type callme() {
+    return type::callme();
+  }
+};
+
+template <typename ...T>
+struct MyTS<0, T...> {};
+
+void foo() {
+  // CHECK: [[@LINE+1]]:20: note: in instantiation of member function
+  int e = MyTS<2>::callme();
+}
-- 
GitLab