Kaydet (Commit) 4d7b194d authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Improved loplugin:literaltoboolconversion looking into cond. exprs.

Change-Id: If54ab99fc82c7895da6bb88ebf18a11570f597ed
üst 22401181
...@@ -29,6 +29,9 @@ public: ...@@ -29,6 +29,9 @@ public:
private: private:
bool isFromCIncludeFile(SourceLocation spellingLocation) const; bool isFromCIncludeFile(SourceLocation spellingLocation) const;
void handleImplicitCastSubExpr(
ImplicitCastExpr const * castExpr, Expr const * subExpr);
}; };
bool LiteralToBoolConversion::VisitImplicitCastExpr( bool LiteralToBoolConversion::VisitImplicitCastExpr(
...@@ -40,25 +43,53 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr( ...@@ -40,25 +43,53 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr(
if (!expr->getType()->isBooleanType()) { if (!expr->getType()->isBooleanType()) {
return true; return true;
} }
Expr const * sub = expr->getSubExpr()->IgnoreParenCasts(); handleImplicitCastSubExpr(expr, expr->getSubExpr());
Expr const * expr2 = expr; return true;
}
bool LiteralToBoolConversion::isFromCIncludeFile(
SourceLocation spellingLocation) const
{
return !compat::isInMainFile(compiler.getSourceManager(), spellingLocation)
&& (StringRef(
compiler.getSourceManager().getPresumedLoc(spellingLocation)
.getFilename())
.endswith(".h"));
}
void LiteralToBoolConversion::handleImplicitCastSubExpr(
ImplicitCastExpr const * castExpr, Expr const * subExpr)
{
Expr const * expr2 = subExpr;
// track sub-expr with potential parens, to e.g. rewrite all of expanded
//
// #define sal_False ((sal_Bool)0)
//
// including the parens
subExpr = expr2->IgnoreParenCasts();
for (;;) { for (;;) {
BinaryOperator const * op = dyn_cast<BinaryOperator>(sub); BinaryOperator const * op = dyn_cast<BinaryOperator>(subExpr);
if (op == nullptr || op->getOpcode() != BO_Comma) { if (op == nullptr || op->getOpcode() != BO_Comma) {
break; break;
} }
expr2 = op->getRHS()->IgnoreParenCasts(); expr2 = op->getRHS();
sub = expr2; subExpr = expr2->IgnoreParenCasts();
} }
if (sub->getType()->isBooleanType()) { if (subExpr->getType()->isBooleanType()) {
return true; return;
}
ConditionalOperator const * op = dyn_cast<ConditionalOperator>(subExpr);
if (op != nullptr) {
handleImplicitCastSubExpr(castExpr, op->getTrueExpr());
handleImplicitCastSubExpr(castExpr, op->getFalseExpr());
return;
} }
APSInt res; APSInt res;
if (!sub->isValueDependent() if (!subExpr->isValueDependent()
&& sub->isIntegerConstantExpr(res, compiler.getASTContext()) && subExpr->isIntegerConstantExpr(res, compiler.getASTContext())
&& res.getLimitedValue() <= 1) && res.getLimitedValue() <= 1)
{ {
SourceLocation loc { sub->getLocStart() }; SourceLocation loc { subExpr->getLocStart() };
while (compiler.getSourceManager().isMacroArgExpansion(loc)) { while (compiler.getSourceManager().isMacroArgExpansion(loc)) {
loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc); loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc);
} }
...@@ -72,46 +103,46 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr( ...@@ -72,46 +103,46 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr(
if (isFromCIncludeFile( if (isFromCIncludeFile(
compiler.getSourceManager().getSpellingLoc(loc))) compiler.getSourceManager().getSpellingLoc(loc)))
{ {
return true; return;
} }
} }
} }
if (isa<StringLiteral>(sub)) { if (isa<StringLiteral>(subExpr)) {
SourceLocation loc { sub->getLocStart() }; SourceLocation loc { subExpr->getLocStart() };
if (compiler.getSourceManager().isMacroArgExpansion(loc) if (compiler.getSourceManager().isMacroArgExpansion(loc)
&& (Lexer::getImmediateMacroName( && (Lexer::getImmediateMacroName(
loc, compiler.getSourceManager(), compiler.getLangOpts()) loc, compiler.getSourceManager(), compiler.getLangOpts())
== "assert")) == "assert"))
{ {
return true; return;
} }
} }
if (isa<IntegerLiteral>(sub) || isa<CharacterLiteral>(sub) if (isa<IntegerLiteral>(subExpr) || isa<CharacterLiteral>(subExpr)
|| isa<FloatingLiteral>(sub) || isa<ImaginaryLiteral>(sub) || isa<FloatingLiteral>(subExpr) || isa<ImaginaryLiteral>(subExpr)
|| isa<StringLiteral>(sub)) || isa<StringLiteral>(subExpr))
{ {
bool rewritten = false; bool rewritten = false;
if (rewriter != nullptr) { if (rewriter != nullptr) {
SourceLocation loc { compiler.getSourceManager().getExpansionLoc( SourceLocation loc { compiler.getSourceManager().getExpansionLoc(
expr->getLocStart()) }; expr2->getLocStart()) };
if (compiler.getSourceManager().getExpansionLoc(expr->getLocEnd()) if (compiler.getSourceManager().getExpansionLoc(expr2->getLocEnd())
== loc) == loc)
{ {
char const * s = compiler.getSourceManager().getCharacterData( char const * s = compiler.getSourceManager().getCharacterData(
loc); loc);
unsigned n = Lexer::MeasureTokenLength( unsigned n = Lexer::MeasureTokenLength(
expr->getLocEnd(), compiler.getSourceManager(), expr2->getLocEnd(), compiler.getSourceManager(),
compiler.getLangOpts()); compiler.getLangOpts());
std::string tok { s, n }; std::string tok { s, n };
if (tok == "sal_False" || tok == "0") { if (tok == "sal_False" || tok == "0") {
rewritten = replaceText( rewritten = replaceText(
compiler.getSourceManager().getExpansionLoc( compiler.getSourceManager().getExpansionLoc(
expr->getLocStart()), expr2->getLocStart()),
n, "false"); n, "false");
} else if (tok == "sal_True" || tok == "1") { } else if (tok == "sal_True" || tok == "1") {
rewritten = replaceText( rewritten = replaceText(
compiler.getSourceManager().getExpansionLoc( compiler.getSourceManager().getExpansionLoc(
expr->getLocStart()), expr2->getLocStart()),
n, "true"); n, "true");
} }
} }
...@@ -121,10 +152,10 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr( ...@@ -121,10 +152,10 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr(
DiagnosticsEngine::Warning, DiagnosticsEngine::Warning,
"implicit conversion (%0) of literal of type %1 to %2", "implicit conversion (%0) of literal of type %1 to %2",
expr2->getLocStart()) expr2->getLocStart())
<< expr->getCastKindName() << expr->getSubExpr()->getType() << castExpr->getCastKindName() << subExpr->getType()
<< expr->getType() << expr2->getSourceRange(); << castExpr->getType() << expr2->getSourceRange();
} }
} else if (sub->isNullPointerConstant( } else if (subExpr->isNullPointerConstant(
compiler.getASTContext(), Expr::NPC_ValueDependentIsNull) compiler.getASTContext(), Expr::NPC_ValueDependentIsNull)
> Expr::NPCK_ZeroExpression) > Expr::NPCK_ZeroExpression)
{ {
...@@ -138,30 +169,20 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr( ...@@ -138,30 +169,20 @@ bool LiteralToBoolConversion::VisitImplicitCastExpr(
("implicit conversion (%0) of null pointer constant of type %1 to" ("implicit conversion (%0) of null pointer constant of type %1 to"
" %2"), " %2"),
expr2->getLocStart()) expr2->getLocStart())
<< expr->getCastKindName() << expr->getSubExpr()->getType() << castExpr->getCastKindName() << subExpr->getType()
<< expr->getType() << expr2->getSourceRange(); << castExpr->getType() << expr2->getSourceRange();
} else if (!sub->isValueDependent() } else if (!subExpr->isValueDependent()
&& sub->isIntegerConstantExpr(res, compiler.getASTContext())) && subExpr->isIntegerConstantExpr(res, compiler.getASTContext()))
{ {
report( report(
DiagnosticsEngine::Warning, DiagnosticsEngine::Warning,
("implicit conversion (%0) of integer constant expression of type" ("implicit conversion (%0) of integer constant expression of type"
" %1 with value %2 to %3"), " %1 with value %2 to %3"),
expr2->getLocStart()) expr2->getLocStart())
<< expr->getCastKindName() << expr->getSubExpr()->getType() << castExpr->getCastKindName() << subExpr->getType()
<< res.toString(10) << expr->getType() << expr2->getSourceRange(); << res.toString(10) << castExpr->getType()
<< expr2->getSourceRange();
} }
return true;
}
bool LiteralToBoolConversion::isFromCIncludeFile(
SourceLocation spellingLocation) const
{
return !compat::isInMainFile(compiler.getSourceManager(), spellingLocation)
&& (StringRef(
compiler.getSourceManager().getPresumedLoc(spellingLocation)
.getFilename())
.endswith(".h"));
} }
loplugin::Plugin::Registration<LiteralToBoolConversion> X( loplugin::Plugin::Registration<LiteralToBoolConversion> X(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment