2019-01-28 22:01:55 +08:00
|
|
|
//===--- DiagnosticsTests.cpp ------------------------------------*- C++-*-===//
|
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Annotations.h"
|
2019-04-18 23:17:07 +08:00
|
|
|
#include "Diagnostics.h"
|
2019-09-04 17:46:06 +08:00
|
|
|
#include "ParsedAST.h"
|
2019-04-29 18:25:44 +08:00
|
|
|
#include "Path.h"
|
2019-04-18 23:17:07 +08:00
|
|
|
#include "Protocol.h"
|
2019-01-28 22:01:55 +08:00
|
|
|
#include "SourceCode.h"
|
2019-04-18 23:17:07 +08:00
|
|
|
#include "TestFS.h"
|
2019-04-29 18:25:44 +08:00
|
|
|
#include "TestIndex.h"
|
2019-01-28 22:01:55 +08:00
|
|
|
#include "TestTU.h"
|
|
|
|
#include "index/MemIndex.h"
|
2019-04-18 23:17:07 +08:00
|
|
|
#include "clang/Basic/Diagnostic.h"
|
2019-04-17 20:35:16 +08:00
|
|
|
#include "clang/Basic/DiagnosticSema.h"
|
2019-01-28 22:01:55 +08:00
|
|
|
#include "llvm/Support/ScopedPrinter.h"
|
2019-12-09 18:57:23 +08:00
|
|
|
#include "llvm/Support/TargetSelect.h"
|
2019-01-28 22:01:55 +08:00
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include "gtest/gtest.h"
|
2019-04-29 18:25:44 +08:00
|
|
|
#include <algorithm>
|
2019-01-28 22:01:55 +08:00
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
|
|
|
namespace {
|
|
|
|
|
2019-05-06 18:08:47 +08:00
|
|
|
using ::testing::_;
|
|
|
|
using ::testing::ElementsAre;
|
|
|
|
using ::testing::Field;
|
|
|
|
using ::testing::IsEmpty;
|
|
|
|
using ::testing::Pair;
|
|
|
|
using ::testing::UnorderedElementsAre;
|
|
|
|
|
|
|
|
::testing::Matcher<const Diag &> WithFix(::testing::Matcher<Fix> FixMatcher) {
|
2019-01-28 22:01:55 +08:00
|
|
|
return Field(&Diag::Fixes, ElementsAre(FixMatcher));
|
|
|
|
}
|
|
|
|
|
2019-05-06 18:08:47 +08:00
|
|
|
::testing::Matcher<const Diag &> WithFix(::testing::Matcher<Fix> FixMatcher1,
|
|
|
|
::testing::Matcher<Fix> FixMatcher2) {
|
2019-02-07 17:23:22 +08:00
|
|
|
return Field(&Diag::Fixes, UnorderedElementsAre(FixMatcher1, FixMatcher2));
|
|
|
|
}
|
|
|
|
|
2019-05-06 18:08:47 +08:00
|
|
|
::testing::Matcher<const Diag &>
|
|
|
|
WithNote(::testing::Matcher<Note> NoteMatcher) {
|
2019-01-28 22:01:55 +08:00
|
|
|
return Field(&Diag::Notes, ElementsAre(NoteMatcher));
|
|
|
|
}
|
|
|
|
|
|
|
|
MATCHER_P2(Diag, Range, Message,
|
|
|
|
"Diag at " + llvm::to_string(Range) + " = [" + Message + "]") {
|
|
|
|
return arg.Range == Range && arg.Message == Message;
|
|
|
|
}
|
|
|
|
|
|
|
|
MATCHER_P3(Fix, Range, Replacement, Message,
|
|
|
|
"Fix " + llvm::to_string(Range) + " => " +
|
2019-05-06 18:08:47 +08:00
|
|
|
::testing::PrintToString(Replacement) + " = [" + Message + "]") {
|
2019-01-28 22:01:55 +08:00
|
|
|
return arg.Message == Message && arg.Edits.size() == 1 &&
|
|
|
|
arg.Edits[0].range == Range && arg.Edits[0].newText == Replacement;
|
|
|
|
}
|
|
|
|
|
2019-07-01 16:05:53 +08:00
|
|
|
MATCHER_P(FixMessage, Message, "") {
|
|
|
|
return arg.Message == Message;
|
|
|
|
}
|
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
MATCHER_P(EqualToLSPDiag, LSPDiag,
|
|
|
|
"LSP diagnostic " + llvm::to_string(LSPDiag)) {
|
2019-04-18 23:17:07 +08:00
|
|
|
if (toJSON(arg) != toJSON(LSPDiag)) {
|
|
|
|
*result_listener << llvm::formatv("expected:\n{0:2}\ngot\n{1:2}",
|
2019-04-29 18:25:44 +08:00
|
|
|
toJSON(LSPDiag), toJSON(arg))
|
|
|
|
.str();
|
2019-04-18 23:17:07 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2019-01-28 22:01:55 +08:00
|
|
|
}
|
|
|
|
|
2019-04-17 20:35:16 +08:00
|
|
|
MATCHER_P(DiagSource, S, "") { return arg.Source == S; }
|
|
|
|
MATCHER_P(DiagName, N, "") { return arg.Name == N; }
|
2019-05-19 12:19:14 +08:00
|
|
|
MATCHER_P(DiagSeverity, S, "") { return arg.Severity == S; }
|
2019-03-06 18:51:38 +08:00
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
MATCHER_P(EqualToFix, Fix, "LSP fix " + llvm::to_string(Fix)) {
|
|
|
|
if (arg.Message != Fix.Message)
|
|
|
|
return false;
|
|
|
|
if (arg.Edits.size() != Fix.Edits.size())
|
|
|
|
return false;
|
|
|
|
for (std::size_t I = 0; I < arg.Edits.size(); ++I) {
|
|
|
|
if (arg.Edits[I].range != Fix.Edits[I].range ||
|
|
|
|
arg.Edits[I].newText != Fix.Edits[I].newText)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper function to make tests shorter.
|
|
|
|
Position pos(int line, int character) {
|
|
|
|
Position Res;
|
|
|
|
Res.line = line;
|
|
|
|
Res.character = character;
|
|
|
|
return Res;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagnosticsTest, DiagnosticRanges) {
|
|
|
|
// Check we report correct ranges, including various edge-cases.
|
|
|
|
Annotations Test(R"cpp(
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
// error-ok
|
2019-01-28 22:01:55 +08:00
|
|
|
namespace test{};
|
|
|
|
void $decl[[foo]]();
|
2019-06-13 20:31:36 +08:00
|
|
|
class T{$explicit[[]]$constructor[[T]](int a);};
|
2019-01-28 22:01:55 +08:00
|
|
|
int main() {
|
|
|
|
$typo[[go\
|
|
|
|
o]]();
|
|
|
|
foo()$semicolon[[]]//with comments
|
|
|
|
$unk[[unknown]]();
|
|
|
|
double $type[[bar]] = "foo";
|
|
|
|
struct Foo { int x; }; Foo a;
|
|
|
|
a.$nomember[[y]];
|
|
|
|
test::$nomembernamespace[[test]];
|
|
|
|
}
|
|
|
|
)cpp");
|
2019-06-13 20:31:36 +08:00
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
TU.ClangTidyChecks = "-*,google-explicit-constructor";
|
2019-01-28 22:01:55 +08:00
|
|
|
EXPECT_THAT(
|
2019-06-13 20:31:36 +08:00
|
|
|
TU.build().getDiagnostics(),
|
2019-01-28 22:01:55 +08:00
|
|
|
ElementsAre(
|
|
|
|
// This range spans lines.
|
|
|
|
AllOf(Diag(Test.range("typo"),
|
|
|
|
"use of undeclared identifier 'goo'; did you mean 'foo'?"),
|
2019-04-29 18:25:44 +08:00
|
|
|
DiagSource(Diag::Clang), DiagName("undeclared_var_use_suggest"),
|
2019-01-28 22:01:55 +08:00
|
|
|
WithFix(
|
2019-05-24 18:26:23 +08:00
|
|
|
Fix(Test.range("typo"), "foo", "change 'go\\…' to 'foo'")),
|
2019-01-28 22:01:55 +08:00
|
|
|
// This is a pretty normal range.
|
|
|
|
WithNote(Diag(Test.range("decl"), "'foo' declared here"))),
|
|
|
|
// This range is zero-width and insertion. Therefore make sure we are
|
|
|
|
// not expanding it into other tokens. Since we are not going to
|
|
|
|
// replace those.
|
|
|
|
AllOf(Diag(Test.range("semicolon"), "expected ';' after expression"),
|
|
|
|
WithFix(Fix(Test.range("semicolon"), ";", "insert ';'"))),
|
|
|
|
// This range isn't provided by clang, we expand to the token.
|
|
|
|
Diag(Test.range("unk"), "use of undeclared identifier 'unknown'"),
|
|
|
|
Diag(Test.range("type"),
|
|
|
|
"cannot initialize a variable of type 'double' with an lvalue "
|
|
|
|
"of type 'const char [4]'"),
|
|
|
|
Diag(Test.range("nomember"), "no member named 'y' in 'Foo'"),
|
|
|
|
Diag(Test.range("nomembernamespace"),
|
2019-06-13 20:31:36 +08:00
|
|
|
"no member named 'test' in namespace 'test'"),
|
|
|
|
// We make sure here that the entire token is highlighted
|
|
|
|
AllOf(Diag(Test.range("constructor"),
|
|
|
|
"single-argument constructors must be marked explicit to "
|
|
|
|
"avoid unintentional implicit conversions"),
|
|
|
|
WithFix(Fix(Test.range("explicit"), "explicit ",
|
|
|
|
"insert 'explicit '")))));
|
2019-01-28 22:01:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagnosticsTest, FlagsMatter) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test("[[void]] main() {} // error-ok");
|
2019-01-28 22:01:55 +08:00
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"),
|
|
|
|
WithFix(Fix(Test.range(), "int",
|
|
|
|
"change 'void' to 'int'")))));
|
|
|
|
// Same code built as C gets different diagnostics.
|
|
|
|
TU.Filename = "Plain.c";
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
ElementsAre(AllOf(
|
|
|
|
Diag(Test.range(), "return type of 'main' is not 'int'"),
|
|
|
|
WithFix(Fix(Test.range(), "int", "change return type to 'int'")))));
|
|
|
|
}
|
|
|
|
|
2019-03-06 18:51:38 +08:00
|
|
|
TEST(DiagnosticsTest, DiagnosticPreamble) {
|
|
|
|
Annotations Test(R"cpp(
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
#include $[["not-found.h"]] // error-ok
|
2019-03-06 18:51:38 +08:00
|
|
|
)cpp");
|
|
|
|
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
2019-05-06 18:08:47 +08:00
|
|
|
ElementsAre(::testing::AllOf(
|
2019-03-06 18:51:38 +08:00
|
|
|
Diag(Test.range(), "'not-found.h' file not found"),
|
2019-04-18 04:12:03 +08:00
|
|
|
DiagSource(Diag::Clang), DiagName("pp_file_not_found"))));
|
2019-03-06 18:51:38 +08:00
|
|
|
}
|
|
|
|
|
2019-07-05 20:57:56 +08:00
|
|
|
TEST(DiagnosticsTest, DeduplicatedClangTidyDiagnostics) {
|
|
|
|
Annotations Test(R"cpp(
|
|
|
|
float foo = [[0.1f]];
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
// Enable alias clang-tidy checks, these check emits the same diagnostics
|
|
|
|
// (except the check name).
|
|
|
|
TU.ClangTidyChecks = "-*, readability-uppercase-literal-suffix, "
|
|
|
|
"hicpp-uppercase-literal-suffix";
|
|
|
|
// Verify that we filter out the duplicated diagnostic message.
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(::testing::AllOf(
|
|
|
|
Diag(Test.range(),
|
|
|
|
"floating point literal has suffix 'f', which is not uppercase"),
|
|
|
|
DiagSource(Diag::ClangTidy))));
|
|
|
|
|
|
|
|
Test = Annotations(R"cpp(
|
|
|
|
template<typename T>
|
|
|
|
void func(T) {
|
|
|
|
float f = [[0.3f]];
|
|
|
|
}
|
|
|
|
void k() {
|
|
|
|
func(123);
|
|
|
|
func(2.0);
|
|
|
|
}
|
|
|
|
)cpp");
|
2020-01-29 03:23:46 +08:00
|
|
|
TU.Code = std::string(Test.code());
|
2019-07-05 20:57:56 +08:00
|
|
|
// The check doesn't handle template instantiations which ends up emitting
|
|
|
|
// duplicated messages, verify that we deduplicate them.
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(::testing::AllOf(
|
|
|
|
Diag(Test.range(),
|
|
|
|
"floating point literal has suffix 'f', which is not uppercase"),
|
|
|
|
DiagSource(Diag::ClangTidy))));
|
|
|
|
}
|
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
TEST(DiagnosticsTest, ClangTidy) {
|
|
|
|
Annotations Test(R"cpp(
|
|
|
|
#include $deprecated[["assert.h"]]
|
|
|
|
|
|
|
|
#define $macrodef[[SQUARE]](X) (X)*(X)
|
2019-07-01 16:05:53 +08:00
|
|
|
int $main[[main]]() {
|
2019-01-28 22:01:55 +08:00
|
|
|
int y = 4;
|
|
|
|
return SQUARE($macroarg[[++]]y);
|
2019-07-01 16:05:53 +08:00
|
|
|
return $doubled[[sizeof]](sizeof(int));
|
2019-01-28 22:01:55 +08:00
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
TU.HeaderFilename = "assert.h"; // Suppress "not found" error.
|
|
|
|
TU.ClangTidyChecks =
|
|
|
|
"-*, bugprone-sizeof-expression, bugprone-macro-repeated-side-effects, "
|
2019-07-01 16:05:53 +08:00
|
|
|
"modernize-deprecated-headers, modernize-use-trailing-return-type";
|
2019-01-28 22:01:55 +08:00
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
AllOf(Diag(Test.range("deprecated"),
|
|
|
|
"inclusion of deprecated C++ header 'assert.h'; consider "
|
2019-04-18 04:15:08 +08:00
|
|
|
"using 'cassert' instead"),
|
2019-03-06 18:51:38 +08:00
|
|
|
DiagSource(Diag::ClangTidy),
|
2019-04-17 20:35:16 +08:00
|
|
|
DiagName("modernize-deprecated-headers"),
|
2019-01-28 22:01:55 +08:00
|
|
|
WithFix(Fix(Test.range("deprecated"), "<cassert>",
|
|
|
|
"change '\"assert.h\"' to '<cassert>'"))),
|
|
|
|
Diag(Test.range("doubled"),
|
2019-04-18 04:15:08 +08:00
|
|
|
"suspicious usage of 'sizeof(sizeof(...))'"),
|
2019-01-28 22:01:55 +08:00
|
|
|
AllOf(
|
|
|
|
Diag(Test.range("macroarg"),
|
|
|
|
"side effects in the 1st macro argument 'X' are repeated in "
|
2019-04-18 04:15:08 +08:00
|
|
|
"macro expansion"),
|
2019-03-06 18:51:38 +08:00
|
|
|
DiagSource(Diag::ClangTidy),
|
2019-04-17 20:35:16 +08:00
|
|
|
DiagName("bugprone-macro-repeated-side-effects"),
|
2019-04-18 04:15:08 +08:00
|
|
|
WithNote(
|
|
|
|
Diag(Test.range("macrodef"), "macro 'SQUARE' defined here"))),
|
2019-01-28 22:01:55 +08:00
|
|
|
Diag(Test.range("macroarg"),
|
2019-07-01 16:05:53 +08:00
|
|
|
"multiple unsequenced modifications to 'y'"),
|
|
|
|
AllOf(
|
|
|
|
Diag(Test.range("main"),
|
|
|
|
"use a trailing return type for this function"),
|
|
|
|
DiagSource(Diag::ClangTidy),
|
|
|
|
DiagName("modernize-use-trailing-return-type"),
|
|
|
|
// Verify that we don't have "[check-name]" suffix in the message.
|
|
|
|
WithFix(FixMessage("use a trailing return type for this function")))
|
|
|
|
));
|
2019-01-28 22:01:55 +08:00
|
|
|
}
|
|
|
|
|
2019-05-19 12:06:52 +08:00
|
|
|
TEST(DiagnosticTest, ClangTidySuppressionComment) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
int main() {
|
|
|
|
int i = 3;
|
|
|
|
double d = 8 / i; // NOLINT
|
|
|
|
// NOLINTNEXTLINE
|
|
|
|
double e = 8 / i;
|
|
|
|
double f = [[8]] / i;
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
|
|
|
TU.ClangTidyChecks = "bugprone-integer-division";
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(::testing::AllOf(
|
|
|
|
Diag(Main.range(), "result of integer division used in a floating "
|
|
|
|
"point context; possible loss of precision"),
|
|
|
|
DiagSource(Diag::ClangTidy), DiagName("bugprone-integer-division"))));
|
|
|
|
}
|
|
|
|
|
2019-05-19 12:19:14 +08:00
|
|
|
TEST(DiagnosticTest, ClangTidyWarningAsError) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
int main() {
|
|
|
|
int i = 3;
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
double f = [[8]] / i; // error-ok
|
2019-05-19 12:19:14 +08:00
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
|
|
|
TU.ClangTidyChecks = "bugprone-integer-division";
|
|
|
|
TU.ClangTidyWarningsAsErrors = "bugprone-integer-division";
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(::testing::AllOf(
|
|
|
|
Diag(Main.range(), "result of integer division used in a floating "
|
|
|
|
"point context; possible loss of precision"),
|
|
|
|
DiagSource(Diag::ClangTidy), DiagName("bugprone-integer-division"),
|
|
|
|
DiagSeverity(DiagnosticsEngine::Error))));
|
|
|
|
}
|
|
|
|
|
2019-05-24 18:26:23 +08:00
|
|
|
TEST(DiagnosticTest, LongFixMessages) {
|
|
|
|
// We limit the size of printed code.
|
|
|
|
Annotations Source(R"cpp(
|
|
|
|
int main() {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
// error-ok
|
2019-05-24 18:26:23 +08:00
|
|
|
int somereallyreallyreallyreallyreallyreallyreallyreallylongidentifier;
|
|
|
|
[[omereallyreallyreallyreallyreallyreallyreallyreallylongidentifier]]= 10;
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Source.code());
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
ElementsAre(WithFix(Fix(
|
|
|
|
Source.range(),
|
|
|
|
"somereallyreallyreallyreallyreallyreallyreallyreallylongidentifier",
|
|
|
|
"change 'omereallyreallyreallyreallyreallyreallyreallyreall…' to "
|
|
|
|
"'somereallyreallyreallyreallyreallyreallyreallyreal…'"))));
|
|
|
|
// Only show changes up to a first newline.
|
|
|
|
Source = Annotations(R"cpp(
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
// error-ok
|
2019-05-24 18:26:23 +08:00
|
|
|
int main() {
|
|
|
|
int ident;
|
|
|
|
[[ide\
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
n]] = 10; // error-ok
|
2019-05-24 18:26:23 +08:00
|
|
|
}
|
|
|
|
)cpp");
|
2020-01-29 06:30:02 +08:00
|
|
|
TU.Code = std::string(Source.code());
|
2019-05-24 18:26:23 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
ElementsAre(WithFix(
|
|
|
|
Fix(Source.range(), "ident", "change 'ide\\…' to 'ident'"))));
|
|
|
|
}
|
|
|
|
|
2019-05-19 12:19:14 +08:00
|
|
|
TEST(DiagnosticTest, ClangTidyWarningAsErrorTrumpsSuppressionComment) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
int main() {
|
|
|
|
int i = 3;
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
double f = [[8]] / i; // NOLINT // error-ok
|
2019-05-19 12:19:14 +08:00
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
|
|
|
TU.ClangTidyChecks = "bugprone-integer-division";
|
|
|
|
TU.ClangTidyWarningsAsErrors = "bugprone-integer-division";
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(::testing::AllOf(
|
|
|
|
Diag(Main.range(), "result of integer division used in a floating "
|
|
|
|
"point context; possible loss of precision"),
|
|
|
|
DiagSource(Diag::ClangTidy), DiagName("bugprone-integer-division"),
|
|
|
|
DiagSeverity(DiagnosticsEngine::Error))));
|
|
|
|
}
|
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
TEST(DiagnosticsTest, Preprocessor) {
|
|
|
|
// This looks like a preamble, but there's an #else in the middle!
|
|
|
|
// Check that:
|
|
|
|
// - the #else doesn't generate diagnostics (we had this bug)
|
|
|
|
// - we get diagnostics from the taken branch
|
|
|
|
// - we get no diagnostics from the not taken branch
|
|
|
|
Annotations Test(R"cpp(
|
|
|
|
#ifndef FOO
|
|
|
|
#define FOO
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
int a = [[b]]; // error-ok
|
2019-01-28 22:01:55 +08:00
|
|
|
#else
|
|
|
|
int x = y;
|
|
|
|
#endif
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(
|
|
|
|
TestTU::withCode(Test.code()).build().getDiagnostics(),
|
|
|
|
ElementsAre(Diag(Test.range(), "use of undeclared identifier 'b'")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagnosticsTest, InsideMacros) {
|
|
|
|
Annotations Test(R"cpp(
|
|
|
|
#define TEN 10
|
|
|
|
#define RET(x) return x + 10
|
|
|
|
|
|
|
|
int* foo() {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
RET($foo[[0]]); // error-ok
|
2019-01-28 22:01:55 +08:00
|
|
|
}
|
|
|
|
int* bar() {
|
|
|
|
return $bar[[TEN]];
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
EXPECT_THAT(TestTU::withCode(Test.code()).build().getDiagnostics(),
|
|
|
|
ElementsAre(Diag(Test.range("foo"),
|
|
|
|
"cannot initialize return object of type "
|
|
|
|
"'int *' with an rvalue of type 'int'"),
|
|
|
|
Diag(Test.range("bar"),
|
|
|
|
"cannot initialize return object of type "
|
|
|
|
"'int *' with an rvalue of type 'int'")));
|
|
|
|
}
|
|
|
|
|
2019-02-22 17:43:56 +08:00
|
|
|
TEST(DiagnosticsTest, NoFixItInMacro) {
|
|
|
|
Annotations Test(R"cpp(
|
|
|
|
#define Define(name) void name() {}
|
|
|
|
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
[[Define]](main) // error-ok
|
2019-02-22 17:43:56 +08:00
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"),
|
|
|
|
Not(WithFix(_)))));
|
|
|
|
}
|
|
|
|
|
2019-12-09 18:57:23 +08:00
|
|
|
TEST(ClangdTest, MSAsm) {
|
|
|
|
// Parsing MS assembly tries to use the target MCAsmInfo, which we don't link.
|
|
|
|
// We used to crash here. Now clang emits a diagnostic, which we filter out.
|
|
|
|
llvm::InitializeAllTargetInfos(); // As in ClangdMain
|
|
|
|
auto TU = TestTU::withCode("void fn() { __asm { cmp cl,64 } }");
|
|
|
|
TU.ExtraArgs = {"-fms-extensions"};
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(), IsEmpty());
|
|
|
|
}
|
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
TEST(DiagnosticsTest, ToLSP) {
|
2019-04-18 23:17:07 +08:00
|
|
|
URIForFile MainFile =
|
|
|
|
URIForFile::canonicalize(testPath("foo/bar/main.cpp"), "");
|
|
|
|
URIForFile HeaderFile =
|
|
|
|
URIForFile::canonicalize(testPath("foo/bar/header.h"), "");
|
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
clangd::Diag D;
|
2019-04-17 20:35:16 +08:00
|
|
|
D.ID = clang::diag::err_enum_class_reference;
|
2019-04-18 04:12:03 +08:00
|
|
|
D.Name = "enum_class_reference";
|
2019-04-17 20:35:16 +08:00
|
|
|
D.Source = clangd::Diag::Clang;
|
2019-01-28 22:01:55 +08:00
|
|
|
D.Message = "something terrible happened";
|
|
|
|
D.Range = {pos(1, 2), pos(3, 4)};
|
|
|
|
D.InsideMainFile = true;
|
|
|
|
D.Severity = DiagnosticsEngine::Error;
|
|
|
|
D.File = "foo/bar/main.cpp";
|
2020-01-29 03:23:46 +08:00
|
|
|
D.AbsFile = std::string(MainFile.file());
|
2019-01-28 22:01:55 +08:00
|
|
|
|
|
|
|
clangd::Note NoteInMain;
|
|
|
|
NoteInMain.Message = "declared somewhere in the main file";
|
|
|
|
NoteInMain.Range = {pos(5, 6), pos(7, 8)};
|
|
|
|
NoteInMain.Severity = DiagnosticsEngine::Remark;
|
|
|
|
NoteInMain.File = "../foo/bar/main.cpp";
|
|
|
|
NoteInMain.InsideMainFile = true;
|
2020-01-29 03:23:46 +08:00
|
|
|
NoteInMain.AbsFile = std::string(MainFile.file());
|
2019-04-18 23:17:07 +08:00
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
D.Notes.push_back(NoteInMain);
|
|
|
|
|
|
|
|
clangd::Note NoteInHeader;
|
|
|
|
NoteInHeader.Message = "declared somewhere in the header file";
|
|
|
|
NoteInHeader.Range = {pos(9, 10), pos(11, 12)};
|
|
|
|
NoteInHeader.Severity = DiagnosticsEngine::Note;
|
|
|
|
NoteInHeader.File = "../foo/baz/header.h";
|
|
|
|
NoteInHeader.InsideMainFile = false;
|
2020-01-29 03:23:46 +08:00
|
|
|
NoteInHeader.AbsFile = std::string(HeaderFile.file());
|
2019-01-28 22:01:55 +08:00
|
|
|
D.Notes.push_back(NoteInHeader);
|
|
|
|
|
|
|
|
clangd::Fix F;
|
|
|
|
F.Message = "do something";
|
|
|
|
D.Fixes.push_back(F);
|
|
|
|
|
|
|
|
// Diagnostics should turn into these:
|
2019-04-18 23:17:07 +08:00
|
|
|
clangd::Diagnostic MainLSP;
|
|
|
|
MainLSP.range = D.Range;
|
|
|
|
MainLSP.severity = getSeverity(DiagnosticsEngine::Error);
|
|
|
|
MainLSP.code = "enum_class_reference";
|
|
|
|
MainLSP.source = "clang";
|
2019-04-29 18:25:44 +08:00
|
|
|
MainLSP.message =
|
|
|
|
R"(Something terrible happened (fix available)
|
2019-01-28 22:01:55 +08:00
|
|
|
|
|
|
|
main.cpp:6:7: remark: declared somewhere in the main file
|
|
|
|
|
|
|
|
../foo/baz/header.h:10:11:
|
2019-04-18 23:17:07 +08:00
|
|
|
note: declared somewhere in the header file)";
|
2019-01-28 22:01:55 +08:00
|
|
|
|
2019-04-18 23:17:07 +08:00
|
|
|
clangd::Diagnostic NoteInMainLSP;
|
|
|
|
NoteInMainLSP.range = NoteInMain.Range;
|
|
|
|
NoteInMainLSP.severity = getSeverity(DiagnosticsEngine::Remark);
|
|
|
|
NoteInMainLSP.message = R"(Declared somewhere in the main file
|
2019-01-28 22:01:55 +08:00
|
|
|
|
2019-04-18 23:17:07 +08:00
|
|
|
main.cpp:2:3: error: something terrible happened)";
|
2019-01-28 22:01:55 +08:00
|
|
|
|
2019-04-18 23:17:07 +08:00
|
|
|
ClangdDiagnosticOptions Opts;
|
|
|
|
// Transform diagnostics and check the results.
|
2019-01-28 22:01:55 +08:00
|
|
|
std::vector<std::pair<clangd::Diagnostic, std::vector<clangd::Fix>>> LSPDiags;
|
2019-04-18 23:17:07 +08:00
|
|
|
toLSPDiags(D, MainFile, Opts,
|
2019-01-28 22:01:55 +08:00
|
|
|
[&](clangd::Diagnostic LSPDiag, ArrayRef<clangd::Fix> Fixes) {
|
|
|
|
LSPDiags.push_back(
|
|
|
|
{std::move(LSPDiag),
|
|
|
|
std::vector<clangd::Fix>(Fixes.begin(), Fixes.end())});
|
|
|
|
});
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
LSPDiags,
|
|
|
|
ElementsAre(Pair(EqualToLSPDiag(MainLSP), ElementsAre(EqualToFix(F))),
|
|
|
|
Pair(EqualToLSPDiag(NoteInMainLSP), IsEmpty())));
|
2019-04-18 04:12:03 +08:00
|
|
|
EXPECT_EQ(LSPDiags[0].first.code, "enum_class_reference");
|
2019-04-17 20:35:16 +08:00
|
|
|
EXPECT_EQ(LSPDiags[0].first.source, "clang");
|
|
|
|
EXPECT_EQ(LSPDiags[1].first.code, "");
|
|
|
|
EXPECT_EQ(LSPDiags[1].first.source, "");
|
2019-04-18 23:17:07 +08:00
|
|
|
|
|
|
|
// Same thing, but don't flatten notes into the main list.
|
|
|
|
LSPDiags.clear();
|
|
|
|
Opts.EmitRelatedLocations = true;
|
|
|
|
toLSPDiags(D, MainFile, Opts,
|
|
|
|
[&](clangd::Diagnostic LSPDiag, ArrayRef<clangd::Fix> Fixes) {
|
|
|
|
LSPDiags.push_back(
|
|
|
|
{std::move(LSPDiag),
|
|
|
|
std::vector<clangd::Fix>(Fixes.begin(), Fixes.end())});
|
|
|
|
});
|
|
|
|
MainLSP.message = "Something terrible happened (fix available)";
|
|
|
|
DiagnosticRelatedInformation NoteInMainDRI;
|
|
|
|
NoteInMainDRI.message = "Declared somewhere in the main file";
|
|
|
|
NoteInMainDRI.location.range = NoteInMain.Range;
|
|
|
|
NoteInMainDRI.location.uri = MainFile;
|
|
|
|
MainLSP.relatedInformation = {NoteInMainDRI};
|
|
|
|
DiagnosticRelatedInformation NoteInHeaderDRI;
|
|
|
|
NoteInHeaderDRI.message = "Declared somewhere in the header file";
|
|
|
|
NoteInHeaderDRI.location.range = NoteInHeader.Range;
|
|
|
|
NoteInHeaderDRI.location.uri = HeaderFile;
|
|
|
|
MainLSP.relatedInformation = {NoteInMainDRI, NoteInHeaderDRI};
|
2019-04-29 18:25:44 +08:00
|
|
|
EXPECT_THAT(LSPDiags, ElementsAre(Pair(EqualToLSPDiag(MainLSP),
|
|
|
|
ElementsAre(EqualToFix(F)))));
|
2019-01-28 22:01:55 +08:00
|
|
|
}
|
|
|
|
|
2019-02-07 17:23:22 +08:00
|
|
|
struct SymbolWithHeader {
|
|
|
|
std::string QName;
|
|
|
|
std::string DeclaringFile;
|
|
|
|
std::string IncludeHeader;
|
|
|
|
};
|
|
|
|
|
|
|
|
std::unique_ptr<SymbolIndex>
|
|
|
|
buildIndexWithSymbol(llvm::ArrayRef<SymbolWithHeader> Syms) {
|
|
|
|
SymbolSlab::Builder Slab;
|
|
|
|
for (const auto &S : Syms) {
|
|
|
|
Symbol Sym = cls(S.QName);
|
|
|
|
Sym.Flags |= Symbol::IndexedForCodeCompletion;
|
|
|
|
Sym.CanonicalDeclaration.FileURI = S.DeclaringFile.c_str();
|
|
|
|
Sym.Definition.FileURI = S.DeclaringFile.c_str();
|
|
|
|
Sym.IncludeHeaders.emplace_back(S.IncludeHeader, 1);
|
|
|
|
Slab.insert(Sym);
|
|
|
|
}
|
2019-06-15 10:26:47 +08:00
|
|
|
return MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
|
2019-02-07 17:23:22 +08:00
|
|
|
}
|
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
TEST(IncludeFixerTest, IncompleteType) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
2019-01-28 22:01:55 +08:00
|
|
|
$insert[[]]namespace ns {
|
|
|
|
class X;
|
2019-02-21 17:33:49 +08:00
|
|
|
$nested[[X::]]Nested n;
|
2019-01-28 22:01:55 +08:00
|
|
|
}
|
|
|
|
class Y : $base[[public ns::X]] {};
|
|
|
|
int main() {
|
|
|
|
ns::X *x;
|
|
|
|
x$access[[->]]f();
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
2019-02-07 17:23:22 +08:00
|
|
|
auto Index = buildIndexWithSymbol(
|
|
|
|
{SymbolWithHeader{"ns::X", "unittest:///x.h", "\"x.h\""}});
|
2019-01-28 22:01:55 +08:00
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
2019-02-21 17:33:49 +08:00
|
|
|
AllOf(Diag(Test.range("nested"),
|
|
|
|
"incomplete type 'ns::X' named in nested name specifier"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol ns::X"))),
|
2019-01-28 22:01:55 +08:00
|
|
|
AllOf(Diag(Test.range("base"), "base class has incomplete type"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol ns::X"))),
|
|
|
|
AllOf(Diag(Test.range("access"),
|
|
|
|
"member access into incomplete type 'ns::X'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol ns::X")))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IncludeFixerTest, NoSuggestIncludeWhenNoDefinitionInHeader) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
2019-01-28 22:01:55 +08:00
|
|
|
$insert[[]]namespace ns {
|
|
|
|
class X;
|
|
|
|
}
|
|
|
|
class Y : $base[[public ns::X]] {};
|
|
|
|
int main() {
|
|
|
|
ns::X *x;
|
|
|
|
x$access[[->]]f();
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
Symbol Sym = cls("ns::X");
|
|
|
|
Sym.Flags |= Symbol::IndexedForCodeCompletion;
|
|
|
|
Sym.CanonicalDeclaration.FileURI = "unittest:///x.h";
|
|
|
|
Sym.Definition.FileURI = "unittest:///x.cc";
|
|
|
|
Sym.IncludeHeaders.emplace_back("\"x.h\"", 1);
|
|
|
|
|
|
|
|
SymbolSlab::Builder Slab;
|
|
|
|
Slab.insert(Sym);
|
2019-06-15 10:26:47 +08:00
|
|
|
auto Index =
|
|
|
|
MemIndex::build(std::move(Slab).build(), RefSlab(), RelationSlab());
|
2019-01-28 22:01:55 +08:00
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
Diag(Test.range("base"), "base class has incomplete type"),
|
|
|
|
Diag(Test.range("access"),
|
|
|
|
"member access into incomplete type 'ns::X'")));
|
|
|
|
}
|
|
|
|
|
2019-02-07 17:23:22 +08:00
|
|
|
TEST(IncludeFixerTest, Typo) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
2019-02-07 17:23:22 +08:00
|
|
|
$insert[[]]namespace ns {
|
|
|
|
void foo() {
|
2019-02-13 16:58:54 +08:00
|
|
|
$unqualified1[[X]] x;
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
// No fix if the unresolved type is used as specifier. (ns::)X::Nested will be
|
|
|
|
// considered the unresolved type.
|
2019-02-13 16:58:54 +08:00
|
|
|
$unqualified2[[X]]::Nested n;
|
2019-02-07 17:23:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void bar() {
|
2019-02-13 16:58:54 +08:00
|
|
|
ns::$qualified1[[X]] x; // ns:: is valid.
|
|
|
|
ns::$qualified2[[X]](); // Error: no member in namespace
|
|
|
|
|
2019-02-07 17:23:22 +08:00
|
|
|
::$global[[Global]] glob;
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
auto Index = buildIndexWithSymbol(
|
|
|
|
{SymbolWithHeader{"ns::X", "unittest:///x.h", "\"x.h\""},
|
|
|
|
SymbolWithHeader{"Global", "unittest:///global.h", "\"global.h\""}});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
2019-02-13 16:58:54 +08:00
|
|
|
AllOf(Diag(Test.range("unqualified1"), "unknown type name 'X'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol ns::X"))),
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
Diag(Test.range("unqualified2"), "use of undeclared identifier 'X'"),
|
2019-02-13 16:58:54 +08:00
|
|
|
AllOf(Diag(Test.range("qualified1"),
|
2019-02-07 17:23:22 +08:00
|
|
|
"no type named 'X' in namespace 'ns'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol ns::X"))),
|
2019-02-13 16:58:54 +08:00
|
|
|
AllOf(Diag(Test.range("qualified2"),
|
|
|
|
"no member named 'X' in namespace 'ns'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol ns::X"))),
|
2019-02-07 17:23:22 +08:00
|
|
|
AllOf(Diag(Test.range("global"),
|
|
|
|
"no type named 'Global' in the global namespace"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"global.h\"\n",
|
|
|
|
"Add include \"global.h\" for symbol Global")))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IncludeFixerTest, MultipleMatchedSymbols) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
2019-02-07 17:23:22 +08:00
|
|
|
$insert[[]]namespace na {
|
|
|
|
namespace nb {
|
|
|
|
void foo() {
|
|
|
|
$unqualified[[X]] x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
auto Index = buildIndexWithSymbol(
|
|
|
|
{SymbolWithHeader{"na::X", "unittest:///a.h", "\"a.h\""},
|
|
|
|
SymbolWithHeader{"na::nb::X", "unittest:///b.h", "\"b.h\""}});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(AllOf(
|
|
|
|
Diag(Test.range("unqualified"), "unknown type name 'X'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"a.h\"\n",
|
|
|
|
"Add include \"a.h\" for symbol na::X"),
|
|
|
|
Fix(Test.range("insert"), "#include \"b.h\"\n",
|
|
|
|
"Add include \"b.h\" for symbol na::nb::X")))));
|
|
|
|
}
|
|
|
|
|
2019-02-08 21:27:47 +08:00
|
|
|
TEST(IncludeFixerTest, NoCrashMemebrAccess) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
2019-02-08 21:27:47 +08:00
|
|
|
struct X { int xyz; };
|
|
|
|
void g() { X x; x.$[[xy]] }
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
auto Index = buildIndexWithSymbol(
|
|
|
|
SymbolWithHeader{"na::X", "unittest:///a.h", "\"a.h\""});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(Diag(Test.range(), "no member named 'xy' in 'X'")));
|
|
|
|
}
|
|
|
|
|
2019-02-18 21:12:10 +08:00
|
|
|
TEST(IncludeFixerTest, UseCachedIndexResults) {
|
|
|
|
// As index results for the identical request are cached, more than 5 fixes
|
|
|
|
// are generated.
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
2019-02-18 21:12:10 +08:00
|
|
|
$insert[[]]void foo() {
|
|
|
|
$x1[[X]] x;
|
|
|
|
$x2[[X]] x;
|
|
|
|
$x3[[X]] x;
|
|
|
|
$x4[[X]] x;
|
|
|
|
$x5[[X]] x;
|
|
|
|
$x6[[X]] x;
|
|
|
|
$x7[[X]] x;
|
|
|
|
}
|
|
|
|
|
|
|
|
class X;
|
|
|
|
void bar(X *x) {
|
|
|
|
x$a1[[->]]f();
|
|
|
|
x$a2[[->]]f();
|
|
|
|
x$a3[[->]]f();
|
|
|
|
x$a4[[->]]f();
|
|
|
|
x$a5[[->]]f();
|
|
|
|
x$a6[[->]]f();
|
|
|
|
x$a7[[->]]f();
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
auto Index =
|
|
|
|
buildIndexWithSymbol(SymbolWithHeader{"X", "unittest:///a.h", "\"a.h\""});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
auto Parsed = TU.build();
|
|
|
|
for (const auto &D : Parsed.getDiagnostics()) {
|
2019-11-26 20:45:04 +08:00
|
|
|
if (D.Fixes.size() != 1) {
|
|
|
|
ADD_FAILURE() << "D.Fixes.size() != 1";
|
|
|
|
continue;
|
|
|
|
}
|
2019-02-18 21:12:10 +08:00
|
|
|
EXPECT_EQ(D.Fixes[0].Message,
|
|
|
|
std::string("Add include \"a.h\" for symbol X"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
TEST(IncludeFixerTest, UnresolvedNameAsSpecifier) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
$insert[[]]namespace ns {
|
|
|
|
}
|
|
|
|
void g() { ns::$[[scope]]::X_Y(); }
|
|
|
|
)cpp");
|
2019-10-14 01:19:00 +08:00
|
|
|
TestTU TU;
|
2020-01-29 03:23:46 +08:00
|
|
|
TU.Code = std::string(Test.code());
|
2019-10-14 01:19:00 +08:00
|
|
|
// FIXME: Figure out why this is needed and remove it, PR43662.
|
|
|
|
TU.ExtraArgs.push_back("-fno-ms-compatibility");
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
auto Index = buildIndexWithSymbol(
|
|
|
|
SymbolWithHeader{"ns::scope::X_Y", "unittest:///x.h", "\"x.h\""});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(AllOf(
|
|
|
|
Diag(Test.range(), "no member named 'scope' in namespace 'ns'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol ns::scope::X_Y")))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IncludeFixerTest, UnresolvedSpecifierWithSemaCorrection) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
$insert[[]]namespace clang {
|
|
|
|
void f() {
|
|
|
|
// "clangd::" will be corrected to "clang::" by Sema.
|
|
|
|
$q1[[clangd]]::$x[[X]] x;
|
|
|
|
$q2[[clangd]]::$ns[[ns]]::Y y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)cpp");
|
2019-10-14 01:19:00 +08:00
|
|
|
TestTU TU;
|
2020-01-29 03:23:46 +08:00
|
|
|
TU.Code = std::string(Test.code());
|
2019-10-14 01:19:00 +08:00
|
|
|
// FIXME: Figure out why this is needed and remove it, PR43662.
|
|
|
|
TU.ExtraArgs.push_back("-fno-ms-compatibility");
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
auto Index = buildIndexWithSymbol(
|
|
|
|
{SymbolWithHeader{"clang::clangd::X", "unittest:///x.h", "\"x.h\""},
|
|
|
|
SymbolWithHeader{"clang::clangd::ns::Y", "unittest:///y.h", "\"y.h\""}});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(
|
|
|
|
TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
AllOf(
|
|
|
|
Diag(Test.range("q1"), "use of undeclared identifier 'clangd'; "
|
|
|
|
"did you mean 'clang'?"),
|
|
|
|
WithFix(_, // change clangd to clang
|
|
|
|
Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol clang::clangd::X"))),
|
|
|
|
AllOf(
|
|
|
|
Diag(Test.range("x"), "no type named 'X' in namespace 'clang'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol clang::clangd::X"))),
|
|
|
|
AllOf(
|
|
|
|
Diag(Test.range("q2"), "use of undeclared identifier 'clangd'; "
|
|
|
|
"did you mean 'clang'?"),
|
|
|
|
WithFix(
|
|
|
|
_, // change clangd to clangd
|
|
|
|
Fix(Test.range("insert"), "#include \"y.h\"\n",
|
|
|
|
"Add include \"y.h\" for symbol clang::clangd::ns::Y"))),
|
|
|
|
AllOf(Diag(Test.range("ns"),
|
|
|
|
"no member named 'ns' in namespace 'clang'"),
|
|
|
|
WithFix(Fix(
|
|
|
|
Test.range("insert"), "#include \"y.h\"\n",
|
|
|
|
"Add include \"y.h\" for symbol clang::clangd::ns::Y")))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(IncludeFixerTest, SpecifiedScopeIsNamespaceAlias) {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Test(R"cpp(// error-ok
|
[clangd] Handle unresolved scope specifier when fixing includes.
Summary:
In the following examples, "clangd" is unresolved, and the fixer will try to fix
include for `clang::clangd`; however, clang::clangd::X is usually intended. So
when handling a qualifier that is unresolved, we change the unresolved name and
scopes so that the fixer will fix "clang::clangd::X" in the following example.
```
namespace clang {
clangd::X
~~~~~~
}
// or
clang::clangd::X
~~~~~~
```
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58185
llvm-svn: 354330
2019-02-19 22:32:22 +08:00
|
|
|
$insert[[]]namespace a {}
|
|
|
|
namespace b = a;
|
|
|
|
namespace c {
|
|
|
|
b::$[[X]] x;
|
|
|
|
}
|
|
|
|
)cpp");
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
auto Index = buildIndexWithSymbol(
|
|
|
|
SymbolWithHeader{"a::X", "unittest:///x.h", "\"x.h\""});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(AllOf(
|
|
|
|
Diag(Test.range(), "no type named 'X' in namespace 'a'"),
|
|
|
|
WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n",
|
|
|
|
"Add include \"x.h\" for symbol a::X")))));
|
|
|
|
}
|
|
|
|
|
[clangd] Compute scopes eagerly in IncludeFixer
Summary:
Computing lazily leads to crashes. In particular, computing scopes may
produce diagnostics (from inside template instantiations) and we
currently do it when processing another diagnostic, which leads to
crashes.
Moreover, we remember and access 'Scope*' when computing scopes. This
might lead to invalid memory access if the Scope is deleted by the time
we run the delayed computation. We did not actually construct an example
when this happens, though.
From the VCS and review history, it seems the optimization was
introduced in the initial version without a mention of any performance
benchmarks justifying the performance gains. This led me to a
conclusion that the optimization was premature, so removing it to avoid
crashes seems like the right trade-off at that point.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D65796
llvm-svn: 368019
2019-08-06 19:37:50 +08:00
|
|
|
TEST(IncludeFixerTest, NoCrashOnTemplateInstantiations) {
|
|
|
|
Annotations Test(R"cpp(
|
|
|
|
template <typename T> struct Templ {
|
|
|
|
template <typename U>
|
|
|
|
typename U::type operator=(const U &);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct A {
|
|
|
|
Templ<char> s;
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
A() { [[a]]; /*error-ok*/ } // crash if we compute scopes lazily.
|
[clangd] Compute scopes eagerly in IncludeFixer
Summary:
Computing lazily leads to crashes. In particular, computing scopes may
produce diagnostics (from inside template instantiations) and we
currently do it when processing another diagnostic, which leads to
crashes.
Moreover, we remember and access 'Scope*' when computing scopes. This
might lead to invalid memory access if the Scope is deleted by the time
we run the delayed computation. We did not actually construct an example
when this happens, though.
From the VCS and review history, it seems the optimization was
introduced in the initial version without a mention of any performance
benchmarks justifying the performance gains. This led me to a
conclusion that the optimization was premature, so removing it to avoid
crashes seems like the right trade-off at that point.
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D65796
llvm-svn: 368019
2019-08-06 19:37:50 +08:00
|
|
|
};
|
|
|
|
)cpp");
|
|
|
|
|
|
|
|
auto TU = TestTU::withCode(Test.code());
|
|
|
|
auto Index = buildIndexWithSymbol({});
|
|
|
|
TU.ExternalIndex = Index.get();
|
|
|
|
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
ElementsAre(Diag(Test.range(), "use of undeclared identifier 'a'")));
|
|
|
|
}
|
|
|
|
|
2019-04-29 18:25:44 +08:00
|
|
|
TEST(DiagsInHeaders, DiagInsideHeader) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#include [["a.h"]]
|
|
|
|
void foo() {})cpp");
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
Annotations Header("[[no_type_spec]]; // error-ok");
|
2019-04-29 18:25:44 +08:00
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
2020-01-29 06:30:02 +08:00
|
|
|
TU.AdditionalFiles = {{"a.h", std::string(Header.code())}};
|
2019-04-29 18:25:44 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(AllOf(
|
|
|
|
Diag(Main.range(), "in included file: C++ requires a "
|
|
|
|
"type specifier for all declarations"),
|
|
|
|
WithNote(Diag(Header.range(), "error occurred here")))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, DiagInTransitiveInclude) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#include [["a.h"]]
|
|
|
|
void foo() {})cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
TU.AdditionalFiles = {{"a.h", "#include \"b.h\""},
|
|
|
|
{"b.h", "no_type_spec; // error-ok"}};
|
2019-04-29 18:25:44 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
Diag(Main.range(), "in included file: C++ requires a "
|
|
|
|
"type specifier for all declarations")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, DiagInMultipleHeaders) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#include $a[["a.h"]]
|
|
|
|
#include $b[["b.h"]]
|
|
|
|
void foo() {})cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
TU.AdditionalFiles = {{"a.h", "no_type_spec; // error-ok"},
|
|
|
|
{"b.h", "no_type_spec; // error-ok"}};
|
2019-04-29 18:25:44 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
Diag(Main.range("a"), "in included file: C++ requires a type "
|
|
|
|
"specifier for all declarations"),
|
|
|
|
Diag(Main.range("b"), "in included file: C++ requires a type "
|
|
|
|
"specifier for all declarations")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, PreferExpansionLocation) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#include [["a.h"]]
|
|
|
|
#include "b.h"
|
|
|
|
void foo() {})cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
TU.AdditionalFiles = {
|
|
|
|
{"a.h", "#include \"b.h\"\n"},
|
|
|
|
{"b.h", "#ifndef X\n#define X\nno_type_spec; // error-ok\n#endif"}};
|
2019-04-29 18:25:44 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(Diag(Main.range(),
|
|
|
|
"in included file: C++ requires a type "
|
|
|
|
"specifier for all declarations")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, PreferExpansionLocationMacros) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#define X
|
|
|
|
#include "a.h"
|
|
|
|
#undef X
|
|
|
|
#include [["b.h"]]
|
|
|
|
void foo() {})cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
TU.AdditionalFiles = {
|
|
|
|
{"a.h", "#include \"c.h\"\n"},
|
|
|
|
{"b.h", "#include \"c.h\"\n"},
|
|
|
|
{"c.h", "#ifndef X\n#define X\nno_type_spec; // error-ok\n#endif"}};
|
2019-04-29 18:25:44 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
Diag(Main.range(), "in included file: C++ requires a "
|
|
|
|
"type specifier for all declarations")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, LimitDiagsOutsideMainFile) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#include [["a.h"]]
|
|
|
|
#include "b.h"
|
|
|
|
void foo() {})cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
|
|
|
TU.AdditionalFiles = {{"a.h", "#include \"c.h\"\n"},
|
|
|
|
{"b.h", "#include \"c.h\"\n"},
|
|
|
|
{"c.h", R"cpp(
|
|
|
|
#ifndef X
|
|
|
|
#define X
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
no_type_spec_0; // error-ok
|
2019-04-29 18:25:44 +08:00
|
|
|
no_type_spec_1;
|
|
|
|
no_type_spec_2;
|
|
|
|
no_type_spec_3;
|
|
|
|
no_type_spec_4;
|
|
|
|
no_type_spec_5;
|
|
|
|
no_type_spec_6;
|
|
|
|
no_type_spec_7;
|
|
|
|
no_type_spec_8;
|
|
|
|
no_type_spec_9;
|
|
|
|
no_type_spec_10;
|
|
|
|
#endif)cpp"}};
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
Diag(Main.range(), "in included file: C++ requires a "
|
|
|
|
"type specifier for all declarations")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, OnlyErrorOrFatal) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#include [["a.h"]]
|
|
|
|
void foo() {})cpp");
|
|
|
|
Annotations Header(R"cpp(
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
[[no_type_spec]]; // error-ok
|
2019-04-29 18:25:44 +08:00
|
|
|
int x = 5/0;)cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
2020-01-29 06:30:02 +08:00
|
|
|
TU.AdditionalFiles = {{"a.h", std::string(Header.code())}};
|
2019-04-29 18:25:44 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(AllOf(
|
|
|
|
Diag(Main.range(), "in included file: C++ requires "
|
|
|
|
"a type specifier for all declarations"),
|
|
|
|
WithNote(Diag(Header.range(), "error occurred here")))));
|
|
|
|
}
|
2019-05-19 12:06:52 +08:00
|
|
|
|
2019-11-20 23:17:03 +08:00
|
|
|
TEST(DiagsInHeaders, FromNonWrittenSources) {
|
2019-07-30 18:26:51 +08:00
|
|
|
Annotations Main(R"cpp(
|
|
|
|
#include [["a.h"]]
|
|
|
|
void foo() {})cpp");
|
|
|
|
Annotations Header(R"cpp(
|
|
|
|
int x = 5/0;
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
int b = [[FOO]]; // error-ok)cpp");
|
2019-07-30 18:26:51 +08:00
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
2020-01-29 06:30:02 +08:00
|
|
|
TU.AdditionalFiles = {{"a.h", std::string(Header.code())}};
|
2019-07-30 18:26:51 +08:00
|
|
|
TU.ExtraArgs = {"-DFOO=NOOO"};
|
2019-11-20 23:17:03 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(AllOf(
|
|
|
|
Diag(Main.range(),
|
|
|
|
"in included file: use of undeclared identifier 'NOOO'"),
|
|
|
|
WithNote(Diag(Header.range(), "error occurred here")))));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, ErrorFromMacroExpansion) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
void bar() {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
int fo; // error-ok
|
2019-11-20 23:17:03 +08:00
|
|
|
#include [["a.h"]]
|
|
|
|
})cpp");
|
|
|
|
Annotations Header(R"cpp(
|
|
|
|
#define X foo
|
|
|
|
X;)cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
2020-01-29 06:30:02 +08:00
|
|
|
TU.AdditionalFiles = {{"a.h", std::string(Header.code())}};
|
2019-11-20 23:17:03 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
Diag(Main.range(), "in included file: use of undeclared "
|
|
|
|
"identifier 'foo'; did you mean 'fo'?")));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(DiagsInHeaders, ErrorFromMacroArgument) {
|
|
|
|
Annotations Main(R"cpp(
|
|
|
|
void bar() {
|
[clangd] Errors in TestTU cause test failures unless suppressed with error-ok.
Summary:
The historic behavior of TestTU is to gather diagnostics and otherwise ignore
them. So if a test has a syntax error, and doesn't assert diagnostics, it
silently misbehaves.
This can be annoying when developing tests, as evidenced by various tests
gaining "assert no diagnostics" where that's not really the point of the test.
This patch aims to make that default behavior. For the first error
(not warning), TestTU will call ADD_FAILURE().
This can be suppressed with a comment containing "error-ok". For now that will
suppress any errors in the TU. We can make this stricter later -verify style.
(-verify itself is hard to reuse because of DiagnosticConsumer interfaces...)
A magic-comment was chosen over a TestTU option because of table-driven tests.
In addition to the behavior change, this patch:
- adds //error-ok where we're knowingly testing invalid code
(e.g. for diagnostics, crash-resilience, or token-level tests)
- fixes a bunch of errors in the checked-in tests, mostly trivial (missing ;)
- removes a bunch of now-redundant instances of "assert no diagnostics"
Reviewers: kadircet
Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73199
2020-01-22 23:38:41 +08:00
|
|
|
int fo; // error-ok
|
2019-11-20 23:17:03 +08:00
|
|
|
#include [["a.h"]]
|
|
|
|
})cpp");
|
|
|
|
Annotations Header(R"cpp(
|
|
|
|
#define X(arg) arg
|
|
|
|
X(foo);)cpp");
|
|
|
|
TestTU TU = TestTU::withCode(Main.code());
|
2020-01-29 06:30:02 +08:00
|
|
|
TU.AdditionalFiles = {{"a.h", std::string(Header.code())}};
|
2019-11-20 23:17:03 +08:00
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(),
|
|
|
|
UnorderedElementsAre(
|
|
|
|
Diag(Main.range(), "in included file: use of undeclared "
|
|
|
|
"identifier 'foo'; did you mean 'fo'?")));
|
2019-07-30 18:26:51 +08:00
|
|
|
}
|
|
|
|
|
2019-08-12 17:35:04 +08:00
|
|
|
TEST(IgnoreDiags, FromNonWrittenInclude) {
|
2019-11-20 23:17:03 +08:00
|
|
|
TestTU TU;
|
2019-08-12 17:35:04 +08:00
|
|
|
TU.ExtraArgs.push_back("--include=a.h");
|
|
|
|
TU.AdditionalFiles = {{"a.h", "void main();"}};
|
|
|
|
// The diagnostic "main must return int" is from the header, we don't attempt
|
|
|
|
// to render it in the main file as there is no written location there.
|
|
|
|
EXPECT_THAT(TU.build().getDiagnostics(), UnorderedElementsAre());
|
|
|
|
}
|
|
|
|
|
2020-01-09 23:54:22 +08:00
|
|
|
TEST(ToLSPDiag, RangeIsInMain) {
|
|
|
|
ClangdDiagnosticOptions Opts;
|
|
|
|
clangd::Diag D;
|
|
|
|
D.Range = {pos(1, 2), pos(3, 4)};
|
|
|
|
D.Notes.emplace_back();
|
|
|
|
Note &N = D.Notes.back();
|
|
|
|
N.Range = {pos(2, 3), pos(3, 4)};
|
|
|
|
|
|
|
|
D.InsideMainFile = true;
|
|
|
|
N.InsideMainFile = false;
|
|
|
|
toLSPDiags(D, {}, Opts,
|
|
|
|
[&](clangd::Diagnostic LSPDiag, ArrayRef<clangd::Fix>) {
|
|
|
|
EXPECT_EQ(LSPDiag.range, D.Range);
|
|
|
|
});
|
|
|
|
|
|
|
|
D.InsideMainFile = false;
|
|
|
|
N.InsideMainFile = true;
|
|
|
|
toLSPDiags(D, {}, Opts,
|
|
|
|
[&](clangd::Diagnostic LSPDiag, ArrayRef<clangd::Fix>) {
|
|
|
|
EXPECT_EQ(LSPDiag.range, N.Range);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-01-28 22:01:55 +08:00
|
|
|
} // namespace
|
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|