bool LiteralToBoolConversion::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 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 (;;) {
BinaryOperator const * op = dyn_cast<BinaryOperator>(subExpr); if (op == nullptr || op->getOpcode() != BO_Comma) { break;
}
expr2 = op->getRHS();
subExpr = expr2->IgnoreParenCasts();
} if (subExpr->getType()->isBooleanType()) { return;
}
ConditionalOperator const * op = dyn_cast<ConditionalOperator>(subExpr); if (op != nullptr) {
handleImplicitCastSubExpr(castExpr, op->getTrueExpr());
handleImplicitCastSubExpr(castExpr, op->getFalseExpr()); return;
} if (!subExpr->isValueDependent()) { if (autoconst res = subExpr->getIntegerConstantExpr(compiler.getASTContext())) { if (res->getLimitedValue() <= 1)
{
SourceLocation loc { subExpr->getBeginLoc() }; while (compiler.getSourceManager().isMacroArgExpansion(loc)) {
loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc);
} if (compiler.getSourceManager().isMacroBodyExpansion(loc)) {
StringRef name { Lexer::getImmediateMacroName(
loc, compiler.getSourceManager(), compiler.getLangOpts()) }; if (name == "sal_False" || name == "sal_True") {
loc = compat::getImmediateExpansionRange(compiler.getSourceManager(), loc)
.first;
} if (isSharedCAndCppCode(loc)) { return;
}
}
}
}
} if (isa<clang::StringLiteral>(subExpr)) {
SourceLocation loc { subExpr->getBeginLoc() }; if (compiler.getSourceManager().isMacroArgExpansion(loc)
&& (Lexer::getImmediateMacroName(
loc, compiler.getSourceManager(), compiler.getLangOpts())
== "assert"))
{ return;
}
} if (isa<IntegerLiteral>(subExpr) || isa<CharacterLiteral>(subExpr)
|| isa<FloatingLiteral>(subExpr) || isa<ImaginaryLiteral>(subExpr)
|| isa<clang::StringLiteral>(subExpr))
{ bool bRewritten = false; if (rewriter != nullptr) {
SourceLocation loc { compiler.getSourceManager().getExpansionLoc(
expr2->getBeginLoc()) }; if (compiler.getSourceManager().getExpansionLoc(expr2->getEndLoc())
== loc)
{ charconst * s = compiler.getSourceManager().getCharacterData(
loc); unsigned n = Lexer::MeasureTokenLength(
expr2->getEndLoc(), compiler.getSourceManager(),
compiler.getLangOpts());
std::string tok { s, n }; if (tok == "sal_False" || tok == "0") {
bRewritten = replaceText(
compiler.getSourceManager().getExpansionLoc(
expr2->getBeginLoc()),
n, "false");
} elseif (tok == "sal_True" || tok == "1") {
bRewritten = replaceText(
compiler.getSourceManager().getExpansionLoc(
expr2->getBeginLoc()),
n, "true");
}
}
} if (!bRewritten) {
report(
DiagnosticsEngine::Warning, "implicit conversion (%0) of literal of type %1 to %2",
expr2->getBeginLoc())
<< castExpr->getCastKindName() << subExpr->getType()
<< castExpr->getType() << expr2->getSourceRange();
}
} elseif (subExpr->isNullPointerConstant(
compiler.getASTContext(), Expr::NPC_ValueDependentIsNull)
> Expr::NPCK_ZeroExpression)
{ // The test above originally checked for != Expr::NPCK_NotNull, but in non-C++11 // mode we can get also Expr::NPCK_ZeroExpression inside templates, even though // the expression is actually not a null pointer. Clang bug or C++98 misfeature? // See Clang's NPCK_ZeroExpression declaration and beginning of isNullPointerConstant().
static_assert( Expr::NPCK_NotNull == 0 && Expr::NPCK_ZeroExpression == 1, "Clang API change");
report(
DiagnosticsEngine::Warning,
("implicit conversion (%0) of null pointer constant of type %1 to" " %2"),
expr2->getBeginLoc())
<< castExpr->getCastKindName() << subExpr->getType()
<< castExpr->getType() << expr2->getSourceRange();
} elseif (!subExpr->isValueDependent()) { if (autoconst res = subExpr->getIntegerConstantExpr(compiler.getASTContext())) {
report(
DiagnosticsEngine::Warning,
("implicit conversion (%0) of integer constant expression of type" " %1 with value %2 to %3"),
expr2->getBeginLoc())
<< castExpr->getCastKindName() << subExpr->getType()
<< compat::toString(*res, 10) << castExpr->getType()
<< expr2->getSourceRange();
}
}
}
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.