bool Nullptr::VisitBinaryOperator(BinaryOperator const * expr) { if (ignoreLocation(expr)) { returntrue;
}
Expr const * e; switch (expr->getOpcode()) { case BO_EQ: case BO_NE: if (isAnyKindOfPointerType(expr->getRHS()->getType())) {
e = expr->getLHS(); break;
} // fall through case BO_Assign: if (isAnyKindOfPointerType(expr->getLHS()->getType())) {
e = expr->getRHS(); break;
} // fall through default: returntrue;
}
handleZero(e); returntrue;
}
bool Nullptr::VisitCXXOperatorCallExpr(CXXOperatorCallExpr const * expr) { if (ignoreLocation(expr)) { returntrue;
}
Expr const * e; switch (expr->getOperator()) { case OO_EqualEqual: case OO_ExclaimEqual: if (isAnyKindOfPointerType(expr->getArg(1)->getType())) {
e = expr->getArg(0); break;
} // fall through case OO_Equal: if (isAnyKindOfPointerType(expr->getArg(0)->getType())) {
e = expr->getArg(1); break;
} // fall through default: returntrue;
}
handleZero(e); returntrue;
}
bool Nullptr::VisitParmVarDecl(ParmVarDecl const * decl) { if (ignoreLocation(decl)) { returntrue;
} if (!isAnyKindOfPointerType(decl->getType())) { returntrue;
} if (decl->hasUninstantiatedDefaultArg()) { returntrue; //TODO
} auto e = decl->getDefaultArg(); if (e == nullptr) { returntrue;
}
handleZero(e); returntrue;
}
bool Nullptr::isSharedCAndCppCode(SourceLocation location) const { // Assume that code is intended to be shared between C and C++ if it comes // from an include file ending in .h, and is either in an extern "C" context // or the body of a macro definition: return
isFromCIncludeFile(compiler.getSourceManager().getSpellingLoc(location))
&& (externCContexts_ != 0
|| compiler.getSourceManager().isMacroBodyExpansion(location));
}
void Nullptr::visitCXXCtorInitializer(CXXCtorInitializer const * init) { if (!init->isWritten()) { return;
} auto e = init->getInit(); if (ignoreLocation(e)) { return;
} auto d = init->getAnyMember(); if (d == nullptr || !isAnyKindOfPointerType(d->getType())) { return;
} if (auto e2 = dyn_cast<ParenListExpr>(e)) { if (e2->getNumExprs() != 1) { return;
}
e = e2->getExpr(0);
} elseif (auto e2 = dyn_cast<InitListExpr>(e)) { if (e2->getNumInits() != 1) { return;
}
e = e2->getInit(0);
}
handleZero(e);
}
void Nullptr::handleZero(Expr const * expr) { //TODO: detect NPCK_ZeroExpression where appropriate // Filter out ImplicitCastExpr that will be handled by // VisitImplicitCastExpr: if (auto ice = dyn_cast<ImplicitCastExpr>(expr)) { if (isNullPointerCast(ice)) { return;
}
} autoconst lit = dyn_cast<IntegerLiteral>(expr->IgnoreParenImpCasts()); if (lit != nullptr && !lit->getValue().getBoolValue()) {
handleNull(expr, nullptr, Expr::NPCK_ZeroLiteral);
}
}
void Nullptr::handleNull(
Expr const * expr, charconst * castKind,
Expr::NullPointerConstantKind nullPointerKind)
{ auto e = expr;
SourceLocation loc; for (;;) {
e = e->IgnoreImpCasts();
loc = e->getBeginLoc(); while (compiler.getSourceManager().isMacroArgExpansion(loc)) {
loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc);
} if (compiler.getSourceManager().isMacroBodyExpansion(loc)) { if (Lexer::getImmediateMacroName(
loc, compiler.getSourceManager(), compiler.getLangOpts())
== "NULL")
{ if (!compiler.getLangOpts().CPlusPlus) { //TODO: if !castKind, warn if NULL is passed into fn call // ellipsis, cast to void* return;
}
loc = compat::getImmediateExpansionRange(compiler.getSourceManager(), loc).first; if (ignoreLocation(
compiler.getSourceManager().getSpellingLoc(loc)))
{ return;
} if (isInUnoIncludeFile(
compiler.getSourceManager().getSpellingLoc(loc))
|| isInLokIncludeFile(
compiler.getSourceManager().getSpellingLoc(loc))
|| isSharedCAndCppCode(loc))
{ //TODO: if !castKind, warn if NULL is passed into fn call // ellipsis, cast to void* return;
}
} elseif (ignoreLocation(
compiler.getSourceManager().getSpellingLoc(loc)))
{ return;
}
}
ParenExpr const * pe = dyn_cast<ParenExpr>(e); if (pe == nullptr) { break;
}
e = pe->getSubExpr();
} if (nullPointerKind == Expr::NPCK_GNUNull) { if (castKind == nullptr) { if (gnuNulls_.erase(expr) == 1) { return;
}
} else { autoconst ok = gnuNulls_.insert(expr).second;
assert(ok); (void) ok;
}
} autoconst asMacro = !compiler.getLangOpts().CPlusPlus
|| isInUnoIncludeFile(compiler.getSourceManager().getSpellingLoc(loc))
|| isInLokIncludeFile(compiler.getSourceManager().getSpellingLoc(loc))
|| isSharedCAndCppCode(loc);
assert(!asMacro || nullPointerKind != Expr::NPCK_GNUNull);
rewriteOrWarn(e, castKind, nullPointerKind, asMacro ? "NULL" : "nullptr");
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.