Home | History | Annotate | Line # | Download | only in Analyses
      1 //===---------- ExprMutationAnalyzer.h ------------------------------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
      9 #define LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
     10 
     11 #include <type_traits>
     12 
     13 #include "clang/AST/AST.h"
     14 #include "clang/ASTMatchers/ASTMatchers.h"
     15 #include "llvm/ADT/DenseMap.h"
     16 
     17 namespace clang {
     18 
     19 class FunctionParmMutationAnalyzer;
     20 
     21 /// Analyzes whether any mutative operations are applied to an expression within
     22 /// a given statement.
     23 class ExprMutationAnalyzer {
     24 public:
     25   ExprMutationAnalyzer(const Stmt &Stm, ASTContext &Context)
     26       : Stm(Stm), Context(Context) {}
     27 
     28   bool isMutated(const Expr *Exp) { return findMutation(Exp) != nullptr; }
     29   bool isMutated(const Decl *Dec) { return findMutation(Dec) != nullptr; }
     30   const Stmt *findMutation(const Expr *Exp);
     31   const Stmt *findMutation(const Decl *Dec);
     32 
     33   bool isPointeeMutated(const Expr *Exp) {
     34     return findPointeeMutation(Exp) != nullptr;
     35   }
     36   bool isPointeeMutated(const Decl *Dec) {
     37     return findPointeeMutation(Dec) != nullptr;
     38   }
     39   const Stmt *findPointeeMutation(const Expr *Exp);
     40   const Stmt *findPointeeMutation(const Decl *Dec);
     41 
     42 private:
     43   using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *);
     44   using ResultMap = llvm::DenseMap<const Expr *, const Stmt *>;
     45 
     46   const Stmt *findMutationMemoized(const Expr *Exp,
     47                                    llvm::ArrayRef<MutationFinder> Finders,
     48                                    ResultMap &MemoizedResults);
     49   const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder);
     50 
     51   bool isUnevaluated(const Expr *Exp);
     52 
     53   const Stmt *findExprMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
     54   const Stmt *findDeclMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
     55   const Stmt *
     56   findExprPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
     57   const Stmt *
     58   findDeclPointeeMutation(ArrayRef<ast_matchers::BoundNodes> Matches);
     59 
     60   const Stmt *findDirectMutation(const Expr *Exp);
     61   const Stmt *findMemberMutation(const Expr *Exp);
     62   const Stmt *findArrayElementMutation(const Expr *Exp);
     63   const Stmt *findCastMutation(const Expr *Exp);
     64   const Stmt *findRangeLoopMutation(const Expr *Exp);
     65   const Stmt *findReferenceMutation(const Expr *Exp);
     66   const Stmt *findFunctionArgMutation(const Expr *Exp);
     67 
     68   const Stmt &Stm;
     69   ASTContext &Context;
     70   llvm::DenseMap<const FunctionDecl *,
     71                  std::unique_ptr<FunctionParmMutationAnalyzer>>
     72       FuncParmAnalyzer;
     73   ResultMap Results;
     74   ResultMap PointeeResults;
     75 };
     76 
     77 // A convenient wrapper around ExprMutationAnalyzer for analyzing function
     78 // params.
     79 class FunctionParmMutationAnalyzer {
     80 public:
     81   FunctionParmMutationAnalyzer(const FunctionDecl &Func, ASTContext &Context);
     82 
     83   bool isMutated(const ParmVarDecl *Parm) {
     84     return findMutation(Parm) != nullptr;
     85   }
     86   const Stmt *findMutation(const ParmVarDecl *Parm);
     87 
     88 private:
     89   ExprMutationAnalyzer BodyAnalyzer;
     90   llvm::DenseMap<const ParmVarDecl *, const Stmt *> Results;
     91 };
     92 
     93 } // namespace clang
     94 
     95 #endif // LLVM_CLANG_ANALYSIS_ANALYSES_EXPRMUTATIONANALYZER_H
     96