mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Backed out changeset b4a4d8144010 (bug 1374024)
This commit is contained in:
parent
b41e12901b
commit
67bab57920
@ -51,8 +51,9 @@ AST_MATCHER(CXXMethodDecl, noDanglingOnTemporaries) {
|
||||
/// The first inner matcher matches the statement where the escape happens, and
|
||||
/// the second inner matcher corresponds to the declaration through which it
|
||||
/// happens.
|
||||
AST_MATCHER_P2(Expr, escapesParentFunctionCall, internal::Matcher<Stmt>,
|
||||
EscapeStmtMatcher, internal::Matcher<Decl>, EscapeDeclMatcher) {
|
||||
AST_MATCHER_P2(Expr, escapesParentFunctionCall, \
|
||||
internal::Matcher<Stmt>, EscapeStmtMatcher, \
|
||||
internal::Matcher<Decl>, EscapeDeclMatcher) {
|
||||
auto Call =
|
||||
IgnoreParentTrivials(Node, &Finder->getASTContext()).get<CallExpr>();
|
||||
if (!Call) {
|
||||
@ -63,13 +64,13 @@ AST_MATCHER_P2(Expr, escapesParentFunctionCall, internal::Matcher<Stmt>,
|
||||
assert(FunctionEscapeData && "escapesFunction() returned NoneType: there is a"
|
||||
" logic bug in the matcher");
|
||||
|
||||
const Stmt *EscapeStmt;
|
||||
const Decl *EscapeDecl;
|
||||
const Stmt* EscapeStmt;
|
||||
const Decl* EscapeDecl;
|
||||
std::tie(EscapeStmt, EscapeDecl) = *FunctionEscapeData;
|
||||
|
||||
return EscapeStmt && EscapeDecl &&
|
||||
EscapeStmtMatcher.matches(*EscapeStmt, Finder, Builder) &&
|
||||
EscapeDeclMatcher.matches(*EscapeDecl, Finder, Builder);
|
||||
return EscapeStmt && EscapeDecl
|
||||
&& EscapeStmtMatcher.matches(*EscapeStmt, Finder, Builder)
|
||||
&& EscapeDeclMatcher.matches(*EscapeDecl, Finder, Builder);
|
||||
}
|
||||
|
||||
/// This is the custom matcher class corresponding to hasNonTrivialParent.
|
||||
@ -104,7 +105,8 @@ const internal::ArgumentAdaptingMatcherFunc<
|
||||
/// This matcher will match any function declaration that is marked to prohibit
|
||||
/// calling AddRef or Release on its return value.
|
||||
AST_MATCHER(FunctionDecl, hasNoAddRefReleaseOnReturnAttr) {
|
||||
return hasCustomAnnotation(&Node, "moz_no_addref_release_on_return");
|
||||
return hasCustomAnnotation(&Node,
|
||||
"moz_no_addref_release_on_return");
|
||||
}
|
||||
|
||||
/// This matcher will match all arithmetic binary operators.
|
||||
@ -153,7 +155,11 @@ AST_MATCHER(BinaryOperator, isInSystemHeader) {
|
||||
/// This matcher will match a list of files. These files contain
|
||||
/// known NaN-testing expressions which we would like to whitelist.
|
||||
AST_MATCHER(BinaryOperator, isInWhitelistForNaNExpr) {
|
||||
const char *whitelist[] = {"SkScalar.h", "json_writer.cpp", "State.cpp"};
|
||||
const char* whitelist[] = {
|
||||
"SkScalar.h",
|
||||
"json_writer.cpp",
|
||||
"State.cpp"
|
||||
};
|
||||
|
||||
SourceLocation Loc = Node.getOperatorLoc();
|
||||
auto &SourceManager = Finder->getASTContext().getSourceManager();
|
||||
@ -251,8 +257,9 @@ AST_MATCHER(CallExpr, isAssertAssignmentTestFunc) {
|
||||
static const std::string AssertName = "MOZ_AssertAssignmentTest";
|
||||
const FunctionDecl *Method = Node.getDirectCallee();
|
||||
|
||||
return Method && Method->getDeclName().isIdentifier() &&
|
||||
Method->getName() == AssertName;
|
||||
return Method
|
||||
&& Method->getDeclName().isIdentifier()
|
||||
&& Method->getName() == AssertName;
|
||||
}
|
||||
|
||||
AST_MATCHER(CallExpr, isSnprintfLikeFunc) {
|
||||
@ -269,13 +276,16 @@ AST_MATCHER(CallExpr, isSnprintfLikeFunc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !isIgnoredPathForSprintfLiteral(
|
||||
&Node, Finder->getASTContext().getSourceManager());
|
||||
return !isIgnoredPathForSprintfLiteral(&Node, Finder->getASTContext().getSourceManager());
|
||||
}
|
||||
|
||||
AST_MATCHER(CXXRecordDecl, isLambdaDecl) { return Node.isLambda(); }
|
||||
AST_MATCHER(CXXRecordDecl, isLambdaDecl) {
|
||||
return Node.isLambda();
|
||||
}
|
||||
|
||||
AST_MATCHER(QualType, isRefPtr) { return typeIsRefPtr(Node); }
|
||||
AST_MATCHER(QualType, isRefPtr) {
|
||||
return typeIsRefPtr(Node);
|
||||
}
|
||||
|
||||
AST_MATCHER(CXXRecordDecl, hasBaseClasses) {
|
||||
const CXXRecordDecl *Decl = Node.getCanonicalDecl();
|
||||
@ -286,7 +296,8 @@ AST_MATCHER(CXXRecordDecl, hasBaseClasses) {
|
||||
|
||||
AST_MATCHER(CXXMethodDecl, isRequiredBaseMethod) {
|
||||
const CXXMethodDecl *Decl = Node.getCanonicalDecl();
|
||||
return Decl && hasCustomAnnotation(Decl, "moz_required_base_method");
|
||||
return Decl
|
||||
&& hasCustomAnnotation(Decl, "moz_required_base_method");
|
||||
}
|
||||
|
||||
AST_MATCHER(CXXMethodDecl, isNonVirtual) {
|
||||
|
@ -55,8 +55,9 @@ void DanglingOnTemporaryChecker::registerMatchers(MatchFinder *AstMatcher) {
|
||||
unless(hasNonTrivialParent(callExpr())),
|
||||
// Unless the argument somehow escapes the function scope through
|
||||
// globals/statics/black magic.
|
||||
escapesParentFunctionCall(stmt().bind("escapeStatement"),
|
||||
decl().bind("escapeDeclaration"))),
|
||||
escapesParentFunctionCall(
|
||||
stmt().bind("escapeStatement"),
|
||||
decl().bind("escapeDeclaration"))),
|
||||
|
||||
expr().bind("memberCallExpr")),
|
||||
this);
|
||||
@ -75,15 +76,15 @@ void DanglingOnTemporaryChecker::check(const MatchFinder::MatchResult &Result) {
|
||||
"MOZ_NO_DANGLING_ON_TEMPORARIES must "
|
||||
"return a pointer";
|
||||
|
||||
if (auto InvalidRefQualified =
|
||||
Result.Nodes.getNodeAs<CXXMethodDecl>("invalidMethodRefQualified")) {
|
||||
if (auto InvalidRefQualified
|
||||
= Result.Nodes.getNodeAs<CXXMethodDecl>("invalidMethodRefQualified")) {
|
||||
diag(InvalidRefQualified->getLocation(), ErrorInvalidRefQualified,
|
||||
DiagnosticIDs::Error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto InvalidPointer =
|
||||
Result.Nodes.getNodeAs<CXXMethodDecl>("invalidMethodPointer")) {
|
||||
if (auto InvalidPointer
|
||||
= Result.Nodes.getNodeAs<CXXMethodDecl>("invalidMethodPointer")) {
|
||||
diag(InvalidPointer->getLocation(), ErrorInvalidPointer,
|
||||
DiagnosticIDs::Error);
|
||||
return;
|
||||
@ -96,16 +97,18 @@ void DanglingOnTemporaryChecker::check(const MatchFinder::MatchResult &Result) {
|
||||
const char *Error = "calling `%0` on a temporary, potentially allowing use "
|
||||
"after free of the raw pointer";
|
||||
|
||||
const char *EscapeStmtNote =
|
||||
"the raw pointer escapes the function scope here";
|
||||
const char *EscapeStmtNote
|
||||
= "the raw pointer escapes the function scope here";
|
||||
|
||||
const CXXMemberCallExpr *MemberCall =
|
||||
Result.Nodes.getNodeAs<CXXMemberCallExpr>("memberCallExpr");
|
||||
|
||||
// If we escaped the a parent function call, we get the statement and the
|
||||
// associated declaration.
|
||||
const Stmt *EscapeStmt = Result.Nodes.getNodeAs<Stmt>("escapeStatement");
|
||||
const Decl *EscapeDecl = Result.Nodes.getNodeAs<Decl>("escapeDeclaration");
|
||||
const Stmt *EscapeStmt =
|
||||
Result.Nodes.getNodeAs<Stmt>("escapeStatement");
|
||||
const Decl *EscapeDecl =
|
||||
Result.Nodes.getNodeAs<Decl>("escapeDeclaration");
|
||||
|
||||
// Just in case.
|
||||
if (!MemberCall) {
|
||||
@ -115,7 +118,8 @@ void DanglingOnTemporaryChecker::check(const MatchFinder::MatchResult &Result) {
|
||||
// We emit the error diagnostic indicating that we are calling the method
|
||||
// temporary.
|
||||
diag(MemberCall->getExprLoc(), Error, DiagnosticIDs::Error)
|
||||
<< MemberCall->getMethodDecl()->getName() << MemberCall->getSourceRange();
|
||||
<< MemberCall->getMethodDecl()->getName()
|
||||
<< MemberCall->getSourceRange();
|
||||
|
||||
// If we didn't escape a parent function, we're done.
|
||||
if (!EscapeStmt || !EscapeDecl) {
|
||||
|
@ -5,8 +5,8 @@
|
||||
#ifndef Utils_h__
|
||||
#define Utils_h__
|
||||
|
||||
#include "ThirdPartyPaths.h"
|
||||
#include "plugin.h"
|
||||
#include "ThirdPartyPaths.h"
|
||||
|
||||
// Check if the given expression contains an assignment expression.
|
||||
// This can either take the form of a Binary Operator or a
|
||||
@ -34,8 +34,7 @@ inline bool hasSideEffectAssignment(const Expr *Expression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool ASTIsInSystemHeader(const ASTContext &AC, const T &D) {
|
||||
template <class T> inline bool ASTIsInSystemHeader(const ASTContext &AC, const T &D) {
|
||||
auto &SourceManager = AC.getSourceManager();
|
||||
auto ExpansionLoc = SourceManager.getExpansionLoc(D.getLocStart());
|
||||
if (ExpansionLoc.isInvalid()) {
|
||||
@ -44,7 +43,8 @@ inline bool ASTIsInSystemHeader(const ASTContext &AC, const T &D) {
|
||||
return SourceManager.isInSystemHeader(ExpansionLoc);
|
||||
}
|
||||
|
||||
template <typename T> inline StringRef getNameChecked(const T &D) {
|
||||
template<typename T>
|
||||
inline StringRef getNameChecked(const T& D) {
|
||||
return D->getIdentifier() ? D->getName() : "";
|
||||
}
|
||||
|
||||
@ -229,8 +229,7 @@ inline bool isIgnoredPathForImplicitConversion(const Decl *Declaration) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isIgnoredPathForSprintfLiteral(const CallExpr *Call,
|
||||
const SourceManager &SM) {
|
||||
inline bool isIgnoredPathForSprintfLiteral(const CallExpr *Call, const SourceManager &SM) {
|
||||
SourceLocation Loc = Call->getLocStart();
|
||||
SmallString<1024> FileName = SM.getFilename(Loc);
|
||||
llvm::sys::fs::make_absolute(FileName);
|
||||
@ -412,7 +411,8 @@ inline bool isPlacementNew(const CXXNewExpr *Expression) {
|
||||
if (Expression->getNumPlacementArgs() == 0)
|
||||
return false;
|
||||
const FunctionDecl *Declaration = Expression->getOperatorNew();
|
||||
if (Declaration && hasCustomAnnotation(Declaration, "moz_heap_allocator")) {
|
||||
if (Declaration && hasCustomAnnotation(Declaration,
|
||||
"moz_heap_allocator")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user