forked from mirrors/gecko-dev
		
	 0d4a611a04
			
		
	
	
		0d4a611a04
		
	
	
	
	
		
			
			MozReview-Commit-ID: AXrQEjWzxvg --HG-- extra : rebase_source : bf972fbb22648af2edbb756eb899ebddf8444dbc
		
			
				
	
	
		
			64 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "MustUseChecker.h"
 | |
| #include "CustomMatchers.h"
 | |
| #include "CustomTypeAnnotation.h"
 | |
| 
 | |
| CustomTypeAnnotation MustUse =
 | |
|     CustomTypeAnnotation("moz_must_use_type", "must-use");
 | |
| 
 | |
| void MustUseChecker::registerMatchers(MatchFinder *AstMatcher) {
 | |
|   AstMatcher->addMatcher(switchCase().bind("switchcase"), this);
 | |
|   AstMatcher->addMatcher(compoundStmt().bind("compound"), this);
 | |
|   AstMatcher->addMatcher(ifStmt().bind("if"), this);
 | |
|   AstMatcher->addMatcher(whileStmt().bind("while"), this);
 | |
|   AstMatcher->addMatcher(doStmt().bind("do"), this);
 | |
|   AstMatcher->addMatcher(forStmt().bind("for"), this);
 | |
|   AstMatcher->addMatcher(binaryOperator(binaryCommaOperator()).bind("bin"),
 | |
|                          this);
 | |
| }
 | |
| 
 | |
| void MustUseChecker::check(const MatchFinder::MatchResult &Result) {
 | |
|   if (auto SC = Result.Nodes.getNodeAs<SwitchCase>("switchcase")) {
 | |
|     handleUnusedExprResult(SC->getSubStmt());
 | |
|   }
 | |
|   if (auto C = Result.Nodes.getNodeAs<CompoundStmt>("compound")) {
 | |
|     for (const auto &S : C->body()) {
 | |
|       handleUnusedExprResult(S);
 | |
|     }
 | |
|   }
 | |
|   if (auto IF = Result.Nodes.getNodeAs<IfStmt>("if")) {
 | |
|     handleUnusedExprResult(IF->getThen());
 | |
|     handleUnusedExprResult(IF->getElse());
 | |
|   }
 | |
|   if (auto W = Result.Nodes.getNodeAs<WhileStmt>("while")) {
 | |
|     handleUnusedExprResult(W->getBody());
 | |
|   }
 | |
|   if (auto D = Result.Nodes.getNodeAs<DoStmt>("do")) {
 | |
|     handleUnusedExprResult(D->getBody());
 | |
|   }
 | |
|   if (auto F = Result.Nodes.getNodeAs<ForStmt>("for")) {
 | |
|     handleUnusedExprResult(F->getBody());
 | |
|     handleUnusedExprResult(F->getInit());
 | |
|     handleUnusedExprResult(F->getInc());
 | |
|   }
 | |
|   if (auto C = Result.Nodes.getNodeAs<BinaryOperator>("bin")) {
 | |
|     handleUnusedExprResult(C->getLHS());
 | |
|   }
 | |
| }
 | |
| 
 | |
| void MustUseChecker::handleUnusedExprResult(const Stmt *Statement) {
 | |
|   const Expr *E = dyn_cast_or_null<Expr>(Statement);
 | |
|   if (E) {
 | |
|     E = E->IgnoreImplicit(); // Ignore ExprWithCleanup etc. implicit wrappers
 | |
|     QualType T = E->getType();
 | |
|     if (MustUse.hasEffectiveAnnotation(T) && !isIgnoredExprForMustUse(E)) {
 | |
|       diag(E->getLocStart(), "Unused value of must-use type %0",
 | |
|            DiagnosticIDs::Error)
 | |
|           << T;
 | |
|       MustUse.dumpAnnotationReason(*this, T, E->getLocStart());
 | |
|     }
 | |
|   }
 | |
| }
 |