Source code

Revision control

Other Tools

1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "MustUseChecker.h"
6
#include "CustomMatchers.h"
7
#include "CustomTypeAnnotation.h"
8
9
CustomTypeAnnotation MustUse =
10
CustomTypeAnnotation(moz_must_use_type, "must-use");
11
12
void MustUseChecker::registerMatchers(MatchFinder *AstMatcher) {
13
AstMatcher->addMatcher(switchCase().bind("switchcase"), this);
14
AstMatcher->addMatcher(compoundStmt().bind("compound"), this);
15
AstMatcher->addMatcher(ifStmt().bind("if"), this);
16
AstMatcher->addMatcher(whileStmt().bind("while"), this);
17
AstMatcher->addMatcher(doStmt().bind("do"), this);
18
AstMatcher->addMatcher(forStmt().bind("for"), this);
19
AstMatcher->addMatcher(binaryOperator(binaryCommaOperator()).bind("bin"),
20
this);
21
}
22
23
void MustUseChecker::check(const MatchFinder::MatchResult &Result) {
24
if (auto SC = Result.Nodes.getNodeAs<SwitchCase>("switchcase")) {
25
handleUnusedExprResult(SC->getSubStmt());
26
}
27
if (auto C = Result.Nodes.getNodeAs<CompoundStmt>("compound")) {
28
for (const auto &S : C->body()) {
29
handleUnusedExprResult(S);
30
}
31
}
32
if (auto IF = Result.Nodes.getNodeAs<IfStmt>("if")) {
33
handleUnusedExprResult(IF->getThen());
34
handleUnusedExprResult(IF->getElse());
35
}
36
if (auto W = Result.Nodes.getNodeAs<WhileStmt>("while")) {
37
handleUnusedExprResult(W->getBody());
38
}
39
if (auto D = Result.Nodes.getNodeAs<DoStmt>("do")) {
40
handleUnusedExprResult(D->getBody());
41
}
42
if (auto F = Result.Nodes.getNodeAs<ForStmt>("for")) {
43
handleUnusedExprResult(F->getBody());
44
handleUnusedExprResult(F->getInit());
45
handleUnusedExprResult(F->getInc());
46
}
47
if (auto C = Result.Nodes.getNodeAs<BinaryOperator>("bin")) {
48
handleUnusedExprResult(C->getLHS());
49
}
50
}
51
52
void MustUseChecker::handleUnusedExprResult(const Stmt *Statement) {
53
const Expr *E = dyn_cast_or_null<Expr>(Statement);
54
if (E) {
55
E = E->IgnoreImplicit(); // Ignore ExprWithCleanup etc. implicit wrappers
56
QualType T = E->getType();
57
if (MustUse.hasEffectiveAnnotation(T) && !isIgnoredExprForMustUse(E)) {
58
diag(E->getBeginLoc(), "Unused value of must-use type %0",
59
DiagnosticIDs::Error)
60
<< T;
61
MustUse.dumpAnnotationReason(*this, T, E->getBeginLoc());
62
}
63
}
64
}