diff --git a/clang/test/Misc/serialized-diags.c b/clang/test/Misc/serialized-diags.c index 9cbb72e2b0a6..7cdac53b84dd 100644 --- a/clang/test/Misc/serialized-diags.c +++ b/clang/test/Misc/serialized-diags.c @@ -8,6 +8,13 @@ void bar() { dragon = dragon + 1 } +// Test handling of FixIts that only remove text. +int baz(); +void qux(int x) { + if ((x == baz())) + return; +} + // RUN: rm -f %t // RUN: %clang -Wall -fsyntax-only %s --serialize-diagnostics %t 2>&1 /dev/null || true // RUN: c-index-test -read-diagnostics %t 2>&1 | FileCheck %s @@ -21,3 +28,12 @@ void bar() { // CHECK: +-FIXIT: ({{.*[/\\]}}serialized-diags.c:2:13 - {{.*[/\\]}}serialized-diags.c:2:13): " = 0" // CHECK: {{.*[/\\]}}serialized-diags.c:8:22: error: expected ';' after expression [] // CHECK: FIXIT: ({{.*[/\\]}}serialized-diags.c:8:22 - {{.*[/\\]}}serialized-diags.c:8:22): ";" +// CHECK: {{.*[/\\]}}serialized-diags.c:14:10: warning: equality comparison with extraneous parentheses [-Wparentheses-equality] +// CHECK: Range: {{.*[/\\]}}serialized-diags.c:14:8 {{.*[/\\]}}serialized-diags.c:14:18 +// CHECK: +-{{.*[/\\]}}serialized-diags.c:14:10: note: remove extraneous parentheses around the comparison to silence this warning [] +// CHECK: +-FIXIT: ({{.*[/\\]}}serialized-diags.c:14:7 - {{.*[/\\]}}serialized-diags.c:14:8): "" +// CHECK: +-FIXIT: ({{.*[/\\]}}serialized-diags.c:14:18 - {{.*[/\\]}}serialized-diags.c:14:19): "" +// CHECK: +-{{.*[/\\]}}serialized-diags.c:14:10: note: use '=' to turn this equality comparison into an assignment [] +// CHECK: +-FIXIT: ({{.*[/\\]}}serialized-diags.c:14:10 - {{.*[/\\]}}serialized-diags.c:14:12): "=" +// CHECK: Number of diagnostics: 3 + diff --git a/clang/tools/libclang/CXLoadedDiagnostic.cpp b/clang/tools/libclang/CXLoadedDiagnostic.cpp index 510f617c5899..61b9e33c2da3 100644 --- a/clang/tools/libclang/CXLoadedDiagnostic.cpp +++ b/clang/tools/libclang/CXLoadedDiagnostic.cpp @@ -220,14 +220,16 @@ class DiagLoader { Strings &strings, llvm::StringRef errorContext, RecordData &Record, const char *BlobStart, - unsigned BlobLen); + unsigned BlobLen, + bool allowEmptyString = false); LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags, llvm::StringRef &RetStr, llvm::StringRef errorContext, RecordData &Record, const char *BlobStart, - unsigned BlobLen); + unsigned BlobLen, + bool allowEmptyString = false); LoadResult readRange(CXLoadedDiagnosticSetImpl &TopDiags, RecordData &Record, unsigned RecStartIdx, @@ -445,7 +447,8 @@ LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags, llvm::StringRef errorContext, RecordData &Record, const char *BlobStart, - unsigned BlobLen) { + unsigned BlobLen, + bool allowEmptyString) { // Basic buffer overflow check. if (BlobLen > 65536) { @@ -453,6 +456,11 @@ LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags, std::string(errorContext)); return Failure; } + + if (allowEmptyString && Record.size() >= 1 && BlobLen == 0) { + RetStr = ""; + return Success; + } if (Record.size() < 1 || BlobLen == 0) { reportInvalidFile(std::string("Corrupted ") + std::string(errorContext) @@ -469,9 +477,11 @@ LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags, llvm::StringRef errorContext, RecordData &Record, const char *BlobStart, - unsigned BlobLen) { + unsigned BlobLen, + bool allowEmptyString) { llvm::StringRef RetStr; - if (readString(TopDiags, RetStr, errorContext, Record, BlobStart, BlobLen)) + if (readString(TopDiags, RetStr, errorContext, Record, BlobStart, BlobLen, + allowEmptyString)) return Failure; strings[Record[0]] = RetStr; return Success; @@ -627,7 +637,8 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream, if (readRange(TopDiags, Record, 0, SR)) return Failure; llvm::StringRef RetStr; - if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen)) + if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen, + /* allowEmptyString */ true)) return Failure; D->FixIts.push_back(std::make_pair(SR, createCXString(RetStr, false))); continue;