Esempio n. 1
0
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;
			   }
	}
}
Esempio n. 2
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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;
	}
}
Esempio n. 6
0
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);
}