11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 21 void SignedBitwiseCheck::registerMatchers(MatchFinder *Finder) {
22 const auto SignedIntegerOperand =
23 expr(ignoringImpCasts(hasType(isSignedInteger()))).bind(
"signed-operand");
29 const auto BitmaskType = namedDecl(anyOf(
30 hasName(
"::std::locale::category"), hasName(
"::std::ctype_base::mask"),
31 hasName(
"::std::ios_base::fmtflags"), hasName(
"::std::ios_base::iostate"),
32 hasName(
"::std::ios_base::openmode")));
33 const auto IsStdBitmask = ignoringImpCasts(declRefExpr(hasType(BitmaskType)));
38 allOf(anyOf(hasOperatorName(
"^"), hasOperatorName(
"|"),
39 hasOperatorName(
"&"), hasOperatorName(
"^="),
40 hasOperatorName(
"|="), hasOperatorName(
"&=")),
42 unless(allOf(hasLHS(IsStdBitmask), hasRHS(IsStdBitmask))),
44 hasEitherOperand(SignedIntegerOperand),
45 hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger()))))
46 .bind(
"binary-no-sign-interference"),
53 allOf(anyOf(hasOperatorName(
"<<"), hasOperatorName(
">>"),
54 hasOperatorName(
"<<="), hasOperatorName(
">>=")),
55 hasEitherOperand(SignedIntegerOperand),
56 hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger()))))
57 .bind(
"binary-sign-interference"),
61 Finder->addMatcher(unaryOperator(allOf(hasOperatorName(
"~"),
62 hasUnaryOperand(SignedIntegerOperand)))
63 .bind(
"unary-signed"),
67 void SignedBitwiseCheck::check(
const MatchFinder::MatchResult &Result) {
68 const ast_matchers::BoundNodes &N = Result.Nodes;
69 const auto *SignedOperand = N.getNodeAs<Expr>(
"signed-operand");
70 assert(SignedOperand &&
71 "No signed operand found in problematic bitwise operations");
76 if (
const auto *UnaryOp = N.getNodeAs<UnaryOperator>(
"unary-signed")) {
78 Location = UnaryOp->getLocStart();
80 if (
const auto *BinaryOp =
81 N.getNodeAs<BinaryOperator>(
"binary-no-sign-interference"))
82 Location = BinaryOp->getLocStart();
83 else if (
const auto *BinaryOp =
84 N.getNodeAs<BinaryOperator>(
"binary-sign-interference"))
85 Location = BinaryOp->getLocStart();
87 llvm_unreachable(
"unexpected matcher result");
89 diag(Location,
"use of a signed integer operand with a " 90 "%select{binary|unary}0 bitwise operator")
91 << IsUnary << SignedOperand->getSourceRange();
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//