void MisplacedOperatorInStrlenInAllocCheck::registerMatchers(
    MatchFinder *Finder) {
  const auto StrLenFunc = functionDecl(anyOf(
      hasName("::strlen"), hasName("::std::strlen"), hasName("::strnlen"),
      hasName("::std::strnlen"), hasName("::strnlen_s"),
      hasName("::std::strnlen_s"), hasName("::wcslen"),
      hasName("::std::wcslen"), hasName("::wcsnlen"), hasName("::std::wcsnlen"),
      hasName("::wcsnlen_s"), hasName("std::wcsnlen_s")));

  const auto BadUse =
      callExpr(callee(StrLenFunc),
               hasAnyArgument(ignoringImpCasts(
                   binaryOperator(
                       hasOperatorName("+"),
                       hasRHS(ignoringParenImpCasts(integerLiteral(equals(1)))))
                       .bind("BinOp"))))
          .bind("StrLen");

  const auto BadArg = anyOf(
      allOf(unless(binaryOperator(
                hasOperatorName("+"), hasLHS(BadUse),
                hasRHS(ignoringParenImpCasts(integerLiteral(equals(1)))))),
            hasDescendant(BadUse)),
      BadUse);

  const auto Alloc0Func =
      functionDecl(anyOf(hasName("::malloc"), hasName("std::malloc"),
                         hasName("::alloca"), hasName("std::alloca")));
  const auto Alloc1Func =
      functionDecl(anyOf(hasName("::calloc"), hasName("std::calloc"),
                         hasName("::realloc"), hasName("std::realloc")));

  const auto Alloc0FuncPtr =
      varDecl(hasType(isConstQualified()),
              hasInitializer(ignoringParenImpCasts(
                  declRefExpr(hasDeclaration(Alloc0Func)))));
  const auto Alloc1FuncPtr =
      varDecl(hasType(isConstQualified()),
              hasInitializer(ignoringParenImpCasts(
                  declRefExpr(hasDeclaration(Alloc1Func)))));

  Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc0Func, Alloc0FuncPtr))),
                              hasArgument(0, BadArg))
                         .bind("Alloc"),
                     this);
  Finder->addMatcher(callExpr(callee(decl(anyOf(Alloc1Func, Alloc1FuncPtr))),
                              hasArgument(1, BadArg))
                         .bind("Alloc"),
                     this);
  Finder->addMatcher(
      cxxNewExpr(isArray(), hasArraySize(BadArg)).bind("Alloc"), this);
}
void DefinitionsInHeadersCheck::registerMatchers(MatchFinder *Finder) {
  if (UseHeaderFileExtension) {
    Finder->addMatcher(
        namedDecl(anyOf(functionDecl(isDefinition()), varDecl(isDefinition())),
                  isHeaderFileExtension()).bind("name-decl"),
        this);
  } else {
    Finder->addMatcher(
        namedDecl(anyOf(functionDecl(isDefinition()), varDecl(isDefinition())),
                  anyOf(isHeaderFileExtension(),
                        unless(isExpansionInMainFile()))).bind("name-decl"),
        this);
  }
}
Exemplo n.º 3
0
// compoundStmt ::= '{' varDecl* stmt* '}'
std::unique_ptr<Stmt> FlowParser::compoundStmt()
{
	FNTRACE();
	FlowLocation sloc(location());
	nextToken(); // '{'

	std::unique_ptr<CompoundStmt> cs = std::make_unique<CompoundStmt>(sloc);

	while (token() == FlowToken::Var) {
		if (std::unique_ptr<Variable> var = varDecl())
			scope()->appendSymbol(std::move(var));
		else
			return nullptr;
	}

	for (;;) {
		if (consumeIf(FlowToken::End)) {
			cs->location().update(end());
			return std::unique_ptr<Stmt>(cs.release());
		}

		if (std::unique_ptr<Stmt> s = stmt())
			cs->push_back(std::move(s));
		else
			return nullptr;
	}
}
Exemplo n.º 4
0
void block(int pIndex)		/* pIndex はこのブロックの関数名のインデックス */
{
	int backP;
	backP = genCodeV(jmp, 0);		/* 内部関数を飛び越す命令、後でバックパッチ */
	while (1) {				/* 宣言部のコンパイルを繰り返す */
		switch (token.kind){
		case Const:			/* 定数宣言部のコンパイル */
			token = nextToken();
			constDecl(); continue;
		case Var:				/* 変数宣言部のコンパイル */
			token = nextToken();
			varDecl(); continue;
		case Func:				/* 関数宣言部のコンパイル */
			token = nextToken();
			funcDecl(); continue;
		default:				/* それ以外なら宣言部は終わり */
			break;
		}
		break;
	}			
	backPatch(backP);			/* 内部関数を飛び越す命令にパッチ */
	changeV(pIndex, nextCode());	/* この関数の開始番地を修正 */
	genCodeV(ict, frameL());		/* このブロックの実行時の必要記憶域をとる命令 */
	statement();				/* このブロックの主文 */		
	genCodeR();				/* リターン命令 */
	blockEnd();				/* ブロックが終ったことをtableに連絡 */
}	
Exemplo n.º 5
0
vector<string> CodeGenerator::block(vector<Node>::iterator& it)
{
    vector<string> blockCode;

    ++it;

    ++it;
    while (it->symbol == "VarDeclList") {
        ++it;
        if (it->symbol == "VarDecl") {
            appendVectors(blockCode, varDecl(it));
            ++it;
        }
    }

    ++it;
    while (it->symbol == "StmtList") {
        ++it;
        appendVectors(blockCode, statement(it));
        it += 2;
    }
    ++it;
    // cout << "block " << it->symbol << endl;

    return blockCode;
}
Exemplo n.º 6
0
void CodeGenerator::codeGeneration(vector<Node> parseTree)
{
    // set up print function
    llvmCode.push_back("@istr = private constant[4 x i8] c\"%d\\0A\\00\"\n");
    llvmCode.push_back("@fstr = private constant[4 x i8] c\"%f\\0A\\00\"\n");
    llvmCode.push_back("declare i32 @printf(i8*, ...)\n\n");

    // scan the tree to generate the code
    for (vector<Node>::iterator it = parseTree.begin(); it != parseTree.end();
         it++) {
        // Start analyzing the tree
        if (it->symbol == "DeclList'")  // declaration of variable or function
            appendVectors(llvmCode, declaration(it));
        else if (it->symbol == "VarDecl")  // declaration of variable (could be array)
            appendVectors(llvmCode,varDecl(it));
        else if (it->symbol == "Stmt")  // statement is appeared
            appendVectors(llvmCode, statement(it));
        else if (it->symbol == "{") {
            llvmCode.push_back("{\n");
            instruction = 0;
        }
        else if (it->symbol == "}")
            llvmCode.push_back("}\n");
    }
    exportLlvmCode();
}
Exemplo n.º 7
0
int compile(char *fname) /* コンパイル */
{
  initChTyp();                                                    /* 文字種表 */
  gencode2(CALL, -1);                         /* main関数呼出。番地-1は仮設定 */
  gencode1(STOP);                                           /* プログラム終了 */

  fileOpen(fname);
  token = nextTkn();
  while (token.kind != EofTkn) {
    switch (token.kind) {
    case Int: case Void:                                        /* 変数か関数 */
      set_type(); set_name();                             /* 型名と名前を格納 */
      if (token.kind == '(') fncDecl(); else varDecl();      /* 関数,変数宣言 */
      break;
    case Semicolon:
      token = nextTkn();                                      /* 何もせず次へ */
      break;
    default:
      err_ss("構文エラー", token.text);
      token = nextTkn();
    }
  }
  if (err_ct == 0) backPatch_callAdrs();            /* 関数呼出未定番地を後埋 */
  *INT_P(mem_adrs(0)) = mallocG(0);            /* 静的領域サイズを0番地に格納 */

  if (err_ct > 0) fprintf(stderr, "%d個のエラーが発生しました。\n", err_ct);
  return err_ct == 0;                                     /* エラーなしなら真 */
}
void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(functionDecl(parameterCountIs(0), unless(isImplicit()),
                                  unless(isExternC()))
                         .bind(FunctionId),
                     this);
  Finder->addMatcher(typedefNameDecl().bind(TypedefId), this);
  auto ParenFunctionType = parenType(innerType(functionType()));
  auto PointerToFunctionType = pointee(ParenFunctionType);
  auto FunctionOrMemberPointer =
      anyOf(hasType(pointerType(PointerToFunctionType)),
            hasType(memberPointerType(PointerToFunctionType)));
  Finder->addMatcher(fieldDecl(FunctionOrMemberPointer).bind(FieldId), this);
  Finder->addMatcher(varDecl(FunctionOrMemberPointer).bind(VarId), this);
  auto CastDestinationIsFunction =
      hasDestinationType(pointsTo(ParenFunctionType));
  Finder->addMatcher(
      cStyleCastExpr(CastDestinationIsFunction).bind(CStyleCastId), this);
  Finder->addMatcher(
      cxxStaticCastExpr(CastDestinationIsFunction).bind(NamedCastId), this);
  Finder->addMatcher(
      cxxReinterpretCastExpr(CastDestinationIsFunction).bind(NamedCastId),
      this);
  Finder->addMatcher(
      cxxConstCastExpr(CastDestinationIsFunction).bind(NamedCastId), this);
  Finder->addMatcher(lambdaExpr().bind(LambdaId), this);
}
void InterfacesGlobalInitCheck::registerMatchers(MatchFinder *Finder) {
  const auto IsGlobal =
      allOf(hasGlobalStorage(),
            hasDeclContext(anyOf(translationUnitDecl(), // Global scope.
                                 namespaceDecl(),       // Namespace scope.
                                 recordDecl())),        // Class scope.
            unless(isConstexpr()));

  const auto ReferencesUndefinedGlobalVar = declRefExpr(hasDeclaration(
      varDecl(IsGlobal, unless(isDefinition())).bind("referencee")));

  Finder->addMatcher(
      varDecl(IsGlobal, isDefinition(),
              hasInitializer(expr(hasDescendant(ReferencesUndefinedGlobalVar))))
          .bind("var"),
      this);
}
void StaticAccessedThroughInstanceCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(
      memberExpr(hasDeclaration(anyOf(cxxMethodDecl(isStaticStorageClass()),
                                      varDecl(hasStaticStorageDuration()))),
                 unless(isInTemplateInstantiation()))
          .bind("memberExpression"),
      this);
}
Exemplo n.º 11
0
void ScopeChecker::registerMatchers(MatchFinder *AstMatcher) {
  AstMatcher->addMatcher(varDecl().bind("node"), this);
  AstMatcher->addMatcher(cxxNewExpr().bind("node"), this);
  AstMatcher->addMatcher(materializeTemporaryExpr().bind("node"), this);
  AstMatcher->addMatcher(
      callExpr(callee(functionDecl(heapAllocator()))).bind("node"), this);
  AstMatcher->addMatcher(parmVarDecl().bind("parm_vardecl"), this);
}
Exemplo n.º 12
0
void petabricks::CodeGenerator::addMember(const std::string& type, const std::string& name, const std::string& initializer){
  if(_curClass.size()>0){
    //TODO
    for(ClassMembers::iterator i = _curMembers.begin(); i != _curMembers.end(); ++i) {
      JASSERT(i->type != type || i->name != name || i->initializer != initializer)(type)(name)(initializer);
    }
    ClassMember tmp;
    tmp.type=type;
    tmp.name=name;
    tmp.initializer=initializer;
    _curMembers.push_back(tmp);
  }else{
    if(initializer.size()>0)
      varDecl(type+" "+name+" = "+initializer);
    else
      varDecl(type+" "+name);
  }
}
Exemplo n.º 13
0
IntrusiveRefCntPtr<VarDecl> Parser::declVar(string const& name, TypePtr type)
{
	IntrusiveRefCntPtr<VarDecl> varDecl(new VarDecl(name, type));
	varDecl->isParameter = false;

	currentScope->slots.push_back(varDecl);
	currentFunction->locals.push_back(varDecl);
	return varDecl;
}
Exemplo n.º 14
0
void Rule_18_7_1::registerMatchers(ast_matchers::MatchFinder *Finder) {
  Finder->addMatcher(callExpr(callee(functionDecl(anyOf(hasName("::signal"),
                                                        hasName("::raise")))))
                         .bind("CallExpr"),
                     this);

  Finder->addMatcher(
      varDecl(hasType(namedDecl(hasName("::sig_atomic_t")))).bind("VarDecl"),
      this);
}
Exemplo n.º 15
0
void Parser::statement(SeqExpr& seqExpr)
{
	if(token == TLet)
	{
		varDecl(seqExpr, true);
	}
	else if(firstExpression[token])
	{
		seqExpr.expressions.push_back(expression(true));
	}
}
Exemplo n.º 16
0
std::unique_ptr<Symbol> FlowParser::decl()
{
	FNTRACE();

	switch (token()) {
		case FlowToken::Var:
			return varDecl();
		case FlowToken::Handler:
			return handlerDecl();
		default:
			return nullptr;
	}
}
Exemplo n.º 17
0
void block(int is_func) /* {}内の処理 */
{
  TknKind kd = Others;

  token = nextTkn();
  ++blkNest;
  if (is_func) {                              /* 関数ブロックなら変数宣言処理 */
    while (token.kind == Int) { set_type(); set_name(); varDecl(); }
  }

  while (token.kind != '}') {                                     /* 文を処理 */
    kd = token.kind; statement();
  }
  last_statement = kd;                    /* 関数末尾のreturn有無確認に用いる */

  --blkNest;
  token = nextTkn();
}
void StaticObjectExceptionCheck::registerMatchers(MatchFinder *Finder) {
  if ((!getLangOpts().CPlusPlus) || (!getLangOpts().CXXExceptions))
    return;

  // Match any static or thread_local variable declaration that has an
  // initializer that can throw.
  Finder->addMatcher(
      varDecl(anyOf(hasThreadStorageDuration(), hasStaticStorageDuration()),
              unless(anyOf(isConstexpr(), hasType(cxxRecordDecl(isLambda())),
                           hasAncestor(functionDecl()))),
              anyOf(hasDescendant(cxxConstructExpr(hasDeclaration(
                        cxxConstructorDecl(unless(isNoThrow())).bind("func")))),
                    hasDescendant(cxxNewExpr(hasDeclaration(
                        functionDecl(unless(isNoThrow())).bind("func")))),
                    hasDescendant(callExpr(hasDeclaration(
                        functionDecl(unless(isNoThrow())).bind("func"))))))
          .bind("var"),
      this);
}
void NonConstParameterCheck::registerMatchers(MatchFinder *Finder) {
  // Add parameters to Parameters.
  Finder->addMatcher(parmVarDecl(unless(isInstantiated())).bind("Parm"), this);

  // C++ constructor.
  Finder->addMatcher(cxxConstructorDecl().bind("Ctor"), this);

  // Track unused parameters, there is Wunused-parameter about unused
  // parameters.
  Finder->addMatcher(declRefExpr().bind("Ref"), this);

  // Analyse parameter usage in function.
  Finder->addMatcher(stmt(anyOf(unaryOperator(anyOf(hasOperatorName("++"),
                                                    hasOperatorName("--"))),
                                binaryOperator(), callExpr(), returnStmt(),
                                cxxConstructExpr()))
                         .bind("Mark"),
                     this);
  Finder->addMatcher(varDecl(hasInitializer(anything())).bind("Mark"), this);
}
void DefinitionsInHeadersCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;
  auto DefinitionMatcher =
      anyOf(functionDecl(isDefinition(), unless(isDeleted())),
            varDecl(isDefinition()));
  if (UseHeaderFileExtension) {
    Finder->addMatcher(namedDecl(DefinitionMatcher,
                                 usesHeaderFileExtension(HeaderFileExtensions))
                           .bind("name-decl"),
                       this);
  } else {
    Finder->addMatcher(
        namedDecl(DefinitionMatcher,
                  anyOf(usesHeaderFileExtension(HeaderFileExtensions),
                        unless(isExpansionInMainFile())))
            .bind("name-decl"),
        this);
  }
}
void StaticallyConstructedObjectsCheck::registerMatchers(MatchFinder *Finder) {
  // Constructing global, non-trivial objects with static storage is
  // disallowed, unless the object is statically initialized with a constexpr 
  // constructor or has no explicit constructor.

  // Constexpr requires C++11 or later.
  if (!getLangOpts().CPlusPlus11)
    return;

  Finder->addMatcher(varDecl(
                         // Match global, statically stored objects...
                         isGlobalStatic(),
                         // ... that have C++ constructors...
                         hasDescendant(cxxConstructExpr(unless(allOf(
                             // ... unless it is constexpr ...
                             hasDeclaration(cxxConstructorDecl(isConstexpr())),
                             // ... and is statically initialized.
                             isConstantInitializer())))))
                         .bind("decl"),
                     this);
}
void MisplacedWideningCastCheck::registerMatchers(MatchFinder *Finder) {
  const auto Calc =
      expr(anyOf(binaryOperator(
                     anyOf(hasOperatorName("+"), hasOperatorName("-"),
                           hasOperatorName("*"), hasOperatorName("<<"))),
                 unaryOperator(hasOperatorName("~"))),
           hasType(isInteger()))
          .bind("Calc");

  const auto ExplicitCast = explicitCastExpr(hasDestinationType(isInteger()),
                                             has(ignoringParenImpCasts(Calc)));
  const auto ImplicitCast =
      implicitCastExpr(hasImplicitDestinationType(isInteger()),
                       has(ignoringParenImpCasts(Calc)));
  const auto Cast = expr(anyOf(ExplicitCast, ImplicitCast)).bind("Cast");

  Finder->addMatcher(varDecl(hasInitializer(Cast)), this);
  Finder->addMatcher(returnStmt(hasReturnValue(Cast)), this);
  Finder->addMatcher(callExpr(hasAnyArgument(Cast)), this);
  Finder->addMatcher(binaryOperator(hasOperatorName("="), hasRHS(Cast)), this);
  Finder->addMatcher(
      binaryOperator(matchers::isComparisonOperator(), hasEitherOperand(Cast)),
      this);
}
Exemplo n.º 23
0
void NonCopyableObjectsCheck::registerMatchers(MatchFinder *Finder) {
  // There are two ways to get into trouble with objects like FILE *:
  // dereferencing the pointer type to be a non-pointer type, and declaring
  // the type as a non-pointer type in the first place. While the declaration
  // itself could technically be well-formed in the case where the type is not
  // an opaque type, it's highly suspicious behavior.
  //
  // POSIX types are a bit different in that it's reasonable to declare a
  // non-pointer variable or data member of the type, but it is not reasonable
  // to dereference a pointer to the type, or declare a parameter of non-pointer
  // type.
  auto BadFILEType = hasType(namedDecl(isFILEType()).bind("type_decl"));
  auto BadPOSIXType = hasType(namedDecl(isPOSIXType()).bind("type_decl"));
  auto BadEitherType = anyOf(BadFILEType, BadPOSIXType);

  Finder->addMatcher(
      namedDecl(anyOf(varDecl(BadFILEType), fieldDecl(BadFILEType)))
          .bind("decl"),
      this);
  Finder->addMatcher(parmVarDecl(BadPOSIXType).bind("decl"), this);
  Finder->addMatcher(
      expr(unaryOperator(hasOperatorName("*"), BadEitherType)).bind("expr"),
      this);
}
Exemplo n.º 24
0
StatementMatcher LoopMatcher = 
  forStmt(			// Node
    hasLoopInit(		// Traversal
      declStmt(			// Node
	hasSingleDecl(		// Traversal
	  varDecl(		// Node
            hasInitializer(	// Traversal
	      integerLiteral(	// Node
		equals(		// Narrowing
		  0)))))))).bind("forLoop")
Exemplo n.º 25
0
#include "ASTUtility.h"

//match function here
StatementMatcher callExprMatcher = callExpr(callee(functionDecl().bind("funcDecl"))).bind("callExpr");
//match var declarations here
DeclarationMatcher varMatcher = varDecl().bind("var");

class StdPrinter : public MatchFinder::MatchCallback {
public:
    virtual void run(const MatchFinder::MatchResult &Result)
    {
        //get the node
        clang::ASTContext *Context = Result.Context;
        const clang::CallExpr *call = Result.Nodes.getNodeAs<clang::CallExpr>("callExpr");
        const clang::FunctionDecl *fun = Result.Nodes.getNodeAs<clang::FunctionDecl>("funcDecl");
        const clang::VarDecl *var = Result.Nodes.getNodeAs<clang::VarDecl>("var");

        if(call && !ASTUtility::IsStmtInSTDFile(call, Context))
        {
            if (ASTUtility::IsDeclInSTDFile(fun, Context))
                ASTUtility::Print(fun, Context, "Rule029.stmt.std");
            else
                ASTUtility::Print(fun, Context, "Rule029.stmt.usr");
        }

        if (var && !ASTUtility::IsDeclInSTDFile(var, Context))
        {
            if (var -> getType().getAsString().find("std::") != std::string::npos)
                ASTUtility::Print(var, Context, "Rule029.decl.std");
            else
                ASTUtility::Print(var, Context, "Rule029.decl.usr");
Exemplo n.º 26
0
TEST(ParmVarDecl, KNRRange) {
  RangeVerifier<ParmVarDecl> Verifier;
  Verifier.expectRange(1, 8, 1, 8);
  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
}
Exemplo n.º 27
0
TEST(ParmVarDecl, KNRLocation) {
  LocationVerifier<ParmVarDecl> Verifier;
  Verifier.expectLocation(1, 8);
  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
}
Exemplo n.º 28
0
TEST(RangeVerifier, WrongRange) {
  RangeVerifier<VarDecl> Verifier;
  Verifier.expectRange(1, 1, 1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}
Exemplo n.º 29
0
TEST(LocationVerifier, WrongLocation) {
  LocationVerifier<VarDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}
Exemplo n.º 30
0
TEST(MatchVerifier, WrongType) {
  LocationVerifier<RecordDecl> Verifier;
  Verifier.expectLocation(1, 1);
  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
}