void doStmt(TreeNode *p) { //printf("doStmt\n"); //printf("TreeNode->state:%s\n", p->state); //printf("TreeNode->productionRule: %d\n", p->productionRule); switch (p->productionRule) { case 1:{ TreeNode *p1 = p->firstChild; doExp(p1); break; } case 2:{ TreeNode *p1 = p->firstChild; doCompSt(p1); break; } case 3: {//这块之后要做函数返回类型检查 TreeNode *p2 = p->firstChild->rightBrother; doExp(p2); break; } case 4: { //这块可以判断一下p3代表的exp是不是int。不过实验讲义假设一定是 //后两个同理 TreeNode *p3 = p->firstChild->rightBrother->rightBrother; TreeNode *p5 = p3->rightBrother->rightBrother; doExp(p3); doStmt(p5); break; } case 5:{ TreeNode *p3 = p->firstChild->rightBrother->rightBrother; TreeNode *p5 = p3->rightBrother->rightBrother; TreeNode *p7 = p5->rightBrother->rightBrother; doExp(p3); doStmt(p5); doStmt(p7); break; } case 6:{ TreeNode *p3 = p->firstChild->rightBrother->rightBrother; TreeNode *p5 = p3->rightBrother->rightBrother; doExp(p3); doStmt(p5); break; } } }
void MustUseChecker::registerMatchers(MatchFinder *AstMatcher) { AstMatcher->addMatcher(switchCase().bind("switchcase"), this); AstMatcher->addMatcher(compoundStmt().bind("compound"), this); AstMatcher->addMatcher(ifStmt().bind("if"), this); AstMatcher->addMatcher(whileStmt().bind("while"), this); AstMatcher->addMatcher(doStmt().bind("do"), this); AstMatcher->addMatcher(forStmt().bind("for"), this); AstMatcher->addMatcher(binaryOperator(binaryCommaOperator()).bind("bin"), this); }
void AvoidGotoCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) return; // TODO: This check does not recognize `IndirectGotoStmt` which is a // GNU extension. These must be matched separately and an AST matcher // is currently missing for them. // Check if the 'goto' is used for control flow other than jumping // out of a nested loop. auto Loop = stmt(anyOf(forStmt(), cxxForRangeStmt(), whileStmt(), doStmt())); auto NestedLoop = stmt(anyOf(forStmt(hasAncestor(Loop)), cxxForRangeStmt(hasAncestor(Loop)), whileStmt(hasAncestor(Loop)), doStmt(hasAncestor(Loop)))); Finder->addMatcher(gotoStmt(anyOf(unless(hasAncestor(NestedLoop)), unless(isForwardJumping()))) .bind("goto"), this); }
void FunctionSizeCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( functionDecl( unless(isInstantiated()), forEachDescendant( stmt(unless(compoundStmt()), hasParent(stmt(anyOf(compoundStmt(), ifStmt(), anyOf(whileStmt(), doStmt(), forRangeStmt(), forStmt()))))) .bind("stmt"))).bind("func"), this); }
void doStmtList(TreeNode *p) { //printf("doStmtList\n"); //printf("TreeNode->state:%s\n", p->state); switch (p->productionRule) { case 1:{ TreeNode *p1 = p->firstChild; TreeNode *p2 = p1->rightBrother; doStmt(p1); doStmtList(p2); break; } case 2: break; } }
void doStmt(TreeNode *p) { //printf("doStmt\n"); //printf("TreeNode->state:%s\n", p->state); //printf("TreeNode->productionRule: %d\n", p->productionRule); switch (p->productionRule) { case 1:{ TreeNode *p1 = p->firstChild; doExp(p1); break; } case 2:{ TreeNode *p1 = p->firstChild; doCompSt(p1); break; } case 3: { //printf("in return\n"); TreeNode *p2 = p->firstChild->rightBrother; Type type = doExp(p2); if (!type_equal(type, funcTableHeader->type)) { //直接和函数表中第一项比较,一定是最近的函数 printf("Error 8 at line %d: function return unexpected type\n", p->line); } //printf("out return\n"); break; } case 4: { //这块可以判断一下p3代表的exp是不是int。不过实验讲义假设一定是 //后两个同理 TreeNode *p3 = p->firstChild->rightBrother->rightBrother; TreeNode *p5 = p3->rightBrother->rightBrother; doExp(p3); doStmt(p5); break; } case 5:{ TreeNode *p3 = p->firstChild->rightBrother->rightBrother; TreeNode *p5 = p3->rightBrother->rightBrother; TreeNode *p7 = p5->rightBrother->rightBrother; doExp(p3); doStmt(p5); doStmt(p7); break; } case 6:{ TreeNode *p3 = p->firstChild->rightBrother->rightBrother; TreeNode *p5 = p3->rightBrother->rightBrother; loopNum++; doExp(p3); doStmt(p5); loopNum--; break; } case 7: { if (loopNum == 0) printf("Error 18 at line %d: use 'break' out of a loop\n", p->line); break; } case 8: { if (loopNum == 0) printf("Error 19 at line %d: use 'continue' out of a loop\n", p->line); break; } case 9:{ //the for loop,待完善,应该是中间那个要做个type检查。 TreeNode *p3 = p->firstChild->rightBrother->rightBrother; TreeNode *p5 = p3->rightBrother->rightBrother; TreeNode *p7 = p5->rightBrother->rightBrother; TreeNode *p9 = p7->rightBrother->rightBrother; loopNum++; doOptExp(p3); doExp(p5); doOptExp(p7); doStmt(p9); loopNum--; } } }
void SuspiciousStringCompareCheck::registerMatchers(MatchFinder *Finder) { // Match relational operators. const auto ComparisonUnaryOperator = unaryOperator(hasOperatorName("!")); const auto ComparisonBinaryOperator = binaryOperator(matchers::isComparisonOperator()); const auto ComparisonOperator = expr(anyOf(ComparisonUnaryOperator, ComparisonBinaryOperator)); // Add the list of known string compare-like functions and add user-defined // functions. std::vector<std::string> FunctionNames = utils::options::parseStringList( (llvm::Twine(KnownStringCompareFunctions) + StringCompareLikeFunctions) .str()); // Match a call to a string compare functions. const auto FunctionCompareDecl = functionDecl(hasAnyName(std::vector<StringRef>(FunctionNames.begin(), FunctionNames.end()))) .bind("decl"); const auto DirectStringCompareCallExpr = callExpr(hasDeclaration(FunctionCompareDecl)).bind("call"); const auto MacroStringCompareCallExpr = conditionalOperator(anyOf( hasTrueExpression(ignoringParenImpCasts(DirectStringCompareCallExpr)), hasFalseExpression(ignoringParenImpCasts(DirectStringCompareCallExpr)))); // The implicit cast is not present in C. const auto StringCompareCallExpr = ignoringParenImpCasts( anyOf(DirectStringCompareCallExpr, MacroStringCompareCallExpr)); if (WarnOnImplicitComparison) { // Detect suspicious calls to string compare: // 'if (strcmp())' -> 'if (strcmp() != 0)' Finder->addMatcher( stmt(anyOf(ifStmt(hasCondition(StringCompareCallExpr)), whileStmt(hasCondition(StringCompareCallExpr)), doStmt(hasCondition(StringCompareCallExpr)), forStmt(hasCondition(StringCompareCallExpr)), binaryOperator( anyOf(hasOperatorName("&&"), hasOperatorName("||")), hasEitherOperand(StringCompareCallExpr)))) .bind("missing-comparison"), this); } if (WarnOnLogicalNotComparison) { // Detect suspicious calls to string compared with '!' operator: // 'if (!strcmp())' -> 'if (strcmp() == 0)' Finder->addMatcher(unaryOperator(hasOperatorName("!"), hasUnaryOperand(ignoringParenImpCasts( StringCompareCallExpr))) .bind("logical-not-comparison"), this); } // Detect suspicious cast to an inconsistant type (i.e. not integer type). Finder->addMatcher( implicitCastExpr(unless(hasType(isInteger())), hasSourceExpression(StringCompareCallExpr)) .bind("invalid-conversion"), this); // Detect suspicious operator with string compare function as operand. Finder->addMatcher( binaryOperator( unless(anyOf(matchers::isComparisonOperator(), hasOperatorName("&&"), hasOperatorName("||"), hasOperatorName("="))), hasEitherOperand(StringCompareCallExpr)) .bind("suspicious-operator"), this); // Detect comparison to invalid constant: 'strcmp() == -1'. const auto InvalidLiteral = ignoringParenImpCasts( anyOf(integerLiteral(unless(equals(0))), unaryOperator( hasOperatorName("-"), has(ignoringParenImpCasts(integerLiteral(unless(equals(0)))))), characterLiteral(), cxxBoolLiteral())); Finder->addMatcher(binaryOperator(matchers::isComparisonOperator(), hasEitherOperand(StringCompareCallExpr), hasEitherOperand(InvalidLiteral)) .bind("invalid-comparison"), this); }