Skip to content

Commit afe0696

Browse files
committed
Test for the range
1 parent 4cb0960 commit afe0696

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "clang/Basic/SourceLocation.h"
1515
#include "clang/Frontend/TextDiagnostic.h"
1616
#include "clang/Tooling/Tooling.h"
17+
#include "llvm/ADT/DenseMap.h"
1718
#include "llvm/ADT/DenseSet.h"
1819
#include "llvm/ADT/STLExtras.h"
1920
#include "llvm/Support/Error.h"
@@ -1282,6 +1283,14 @@ static raw_ostream &operator<<(raw_ostream &OS,
12821283
class UncheckedOptionalAccessTest
12831284
: public ::testing::TestWithParam<OptionalTypeIdentifier> {
12841285
protected:
1286+
// Check that after running the analysis on SourceCode, it produces the
1287+
// expected diagnostics according to [[unsafe]] annotations.
1288+
// - No annotations => no diagnostics.
1289+
// - Given "// [[unsafe]]" annotations on a line, we expect a diagnostic on
1290+
// that line.
1291+
// - Given "// [[unsafe:range_text]]" annotations on a line, we expect a
1292+
// diagnostic on that line, and we expect the diagnostic Range (printed as
1293+
// a string) to match the "range_text".
12851294
void ExpectDiagnosticsFor(std::string SourceCode,
12861295
bool IgnoreSmartPointerDereference = true) {
12871296
ExpectDiagnosticsFor(SourceCode, ast_matchers::hasName("target"),
@@ -1364,8 +1373,14 @@ class UncheckedOptionalAccessTest
13641373
&Annotations,
13651374
const AnalysisOutputs &AO) {
13661375
llvm::DenseSet<unsigned> AnnotationLines;
1367-
for (const auto &[Line, _] : Annotations) {
1376+
llvm::DenseMap<unsigned, std::string> AnnotationRangesInLines;
1377+
for (const auto &[Line, AnnotationWithMaybeRange] : Annotations) {
13681378
AnnotationLines.insert(Line);
1379+
auto it = AnnotationWithMaybeRange.find(':');
1380+
if (it != std::string::npos) {
1381+
AnnotationRangesInLines[Line] =
1382+
AnnotationWithMaybeRange.substr(it + 1);
1383+
}
13691384
}
13701385
auto &SrcMgr = AO.ASTCtx.getSourceManager();
13711386
llvm::DenseSet<unsigned> DiagnosticLines;
@@ -1380,6 +1395,12 @@ class UncheckedOptionalAccessTest
13801395
TD.emitDiagnostic(FullSourceLoc(Diag.Range.getBegin(), SrcMgr),
13811396
DiagnosticsEngine::Error,
13821397
"unexpected diagnostic", {Diag.Range}, {});
1398+
} else {
1399+
auto it = AnnotationRangesInLines.find(Line);
1400+
if (it != AnnotationRangesInLines.end()) {
1401+
EXPECT_EQ(Diag.Range.getAsRange().printToString(SrcMgr),
1402+
it->second);
1403+
}
13831404
}
13841405
}
13851406

@@ -4085,6 +4106,31 @@ TEST_P(UncheckedOptionalAccessTest, ConstPointerRefAccessor) {
40854106
/*IgnoreSmartPointerDereference=*/false);
40864107
}
40874108

4109+
TEST_P(UncheckedOptionalAccessTest, DiagnosticsHaveRanges) {
4110+
ExpectDiagnosticsFor(R"cc(
4111+
#include "unchecked_optional_access_test.h"
4112+
4113+
struct A {
4114+
$ns::$optional<int> fi;
4115+
};
4116+
struct B {
4117+
$ns::$optional<A> fa;
4118+
};
4119+
4120+
void target($ns::$optional<B> opt) {
4121+
opt.value(); // [[unsafe:<input.cc:12:7>]]
4122+
if (opt) {
4123+
opt // [[unsafe:<input.cc:14:9, line:16:13>]]
4124+
->
4125+
fa.value();
4126+
if (opt->fa) {
4127+
opt->fa->fi.value(); // [[unsafe:<input.cc:18:11, col:20>]]
4128+
}
4129+
}
4130+
}
4131+
)cc");
4132+
}
4133+
40884134
// FIXME: Add support for:
40894135
// - constructors (copy, move)
40904136
// - assignment operators (default, copy, move)

0 commit comments

Comments
 (0)