<commit_before>//=-- GRExprEngineInternalChecks.cpp - Builtin GRExprEngine Checks---*- C++ -*-=
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the BugType classes used by GRExprEngine to report
//  bugs derived from builtin checks in the path-sensitive engine.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "llvm/Support/Compiler.h"
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//

template <typename ITERATOR> inline
ExplodedNode<GRState>* GetNode(ITERATOR I) {
  return *I;
}

template <> inline
ExplodedNode<GRState>* GetNode(GRExprEngine::undef_arg_iterator I) {
  return I->first;
}

//===----------------------------------------------------------------------===//
// Bug Descriptions.
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation {
  const char* name;
  const char* desc;
public:
  BuiltinBug(const char* n, const char* d = 0) : name(n), desc(d) {}  
  virtual const char* getName() const { return name; }
  virtual const char* getDescription() const {
    return desc ? desc : name;
  }
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) = 0;
  virtual void EmitWarnings(BugReporter& BR) {
    EmitBuiltinWarnings(BR, cast<GRBugReporter>(BR).getEngine());
  }
  
  template <typename ITER>
  void Emit(BugReporter& BR, ITER I, ITER E) {
    for (; I != E; ++I) {
      BugReport R(*this, GetNode(I));
      BR.EmitWarning(R);
    }
  }
  
  virtual const char* getCategory() const { return "Logic Errors"; }
};
  
class VISIBILITY_HIDDEN NullDeref : public BuiltinBug {
public:
  NullDeref() : BuiltinBug("null dereference",
                           "Dereference of null pointer.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.null_derefs_begin(), Eng.null_derefs_end());
  }
};
  
class VISIBILITY_HIDDEN UndefinedDeref : public BuiltinBug {
public:
  UndefinedDeref() : BuiltinBug("uninitialized pointer dereference",
                                "Dereference of undefined value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_derefs_begin(), Eng.undef_derefs_end());
  }
};

class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
public:
  DivZero() : BuiltinBug("divide-by-zero",
                         "Division by zero/undefined value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
  }
};
  
class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
public:
  UndefResult() : BuiltinBug("undefined result",
                             "Result of operation is undefined.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
  }
};
  
class VISIBILITY_HIDDEN BadCall : public BuiltinBug {
public:
  BadCall()
  : BuiltinBug("invalid function call",
        "Called function is a NULL or undefined function pointer value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
  }
};

class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
public:
  BadArg() : BuiltinBug("uninitialized argument",  
    "Pass-by-value argument in function is undefined.") {}

  BadArg(const char* d) : BuiltinBug("uninitialized argument", d) {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
         E = Eng.undef_arg_end(); I!=E; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};
  
class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
public:
  BadMsgExprArg() 
    : BadArg("Pass-by-value argument in message expression is undefined.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
         E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
      
      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());
      
      // Emit the warning.
      BR.EmitWarning(report);
    }    
  }
};
  
class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
public:  
  BadReceiver()
  : BuiltinBug("uninitialized receiver",
               "Receiver in message expression is an uninitialized value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
         End = Eng.undef_receivers_end(); I!=End; ++I) {
      
      // Generate a report for this bug.
      RangedBugReport report(*this, *I);
      
      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
      assert (E && "Receiver cannot be NULL");
      report.addRange(E->getSourceRange());
      
      // Emit the warning.
      BR.EmitWarning(report);
    }    
  }
};
  
class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
public:
  RetStack() : BuiltinBug("return of stack address") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(),
         End = Eng.ret_stackaddr_end(); I!=End; ++I) {

      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ReturnStmt>(S)->getRetValue();
      assert (E && "Return expression cannot be NULL");
      
      // Get the value associated with E.
      loc::MemRegionVal V =
        cast<loc::MemRegionVal>(Eng.getStateManager().GetSVal(N->getState(),
                                                               E));
      
      // Generate a report for this bug.
      std::ostringstream os;
      os << "Address of stack memory associated with local variable '"
         << V.getRegion()->getString() << "' returned.";
      
      std::string s = os.str();
      
      RangedBugReport report(*this, N, s.c_str());
      report.addRange(E->getSourceRange());
      
      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};


class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
  struct VISIBILITY_HIDDEN FindUndefExpr {
    GRStateManager& VM;
    const GRState* St;
    
    FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
    
    Expr* FindExpr(Expr* Ex) {      
      if (!MatchesCriteria(Ex))
        return 0;
      
      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
          Expr* E2 = FindExpr(ExI);
          if (E2) return E2;
        }
      
      return Ex;
    }
    <commit_msg>Enhance path-sensitive return-of-stack-address check to print out the line number of a compound literal (whose address is being returned) instead of printing out the hex representation of the pointer address of the CompoundLiteralExpr.<commit_after>//=-- GRExprEngineInternalChecks.cpp - Builtin GRExprEngine Checks---*- C++ -*-=
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines the BugType classes used by GRExprEngine to report
//  bugs derived from builtin checks in the path-sensitive engine.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/PathSensitive/BugReporter.h"
#include "clang/Analysis/PathSensitive/GRExprEngine.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/Compiler.h"
#include <sstream>

using namespace clang;

//===----------------------------------------------------------------------===//
// Utility functions.
//===----------------------------------------------------------------------===//

template <typename ITERATOR> inline
ExplodedNode<GRState>* GetNode(ITERATOR I) {
  return *I;
}

template <> inline
ExplodedNode<GRState>* GetNode(GRExprEngine::undef_arg_iterator I) {
  return I->first;
}

//===----------------------------------------------------------------------===//
// Bug Descriptions.
//===----------------------------------------------------------------------===//

namespace {
class VISIBILITY_HIDDEN BuiltinBug : public BugTypeCacheLocation {
  const char* name;
  const char* desc;
public:
  BuiltinBug(const char* n, const char* d = 0) : name(n), desc(d) {}  
  virtual const char* getName() const { return name; }
  virtual const char* getDescription() const {
    return desc ? desc : name;
  }
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) = 0;
  virtual void EmitWarnings(BugReporter& BR) {
    EmitBuiltinWarnings(BR, cast<GRBugReporter>(BR).getEngine());
  }
  
  template <typename ITER>
  void Emit(BugReporter& BR, ITER I, ITER E) {
    for (; I != E; ++I) {
      BugReport R(*this, GetNode(I));
      BR.EmitWarning(R);
    }
  }
  
  virtual const char* getCategory() const { return "Logic Errors"; }
};
  
class VISIBILITY_HIDDEN NullDeref : public BuiltinBug {
public:
  NullDeref() : BuiltinBug("null dereference",
                           "Dereference of null pointer.") {}

  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.null_derefs_begin(), Eng.null_derefs_end());
  }
};
  
class VISIBILITY_HIDDEN UndefinedDeref : public BuiltinBug {
public:
  UndefinedDeref() : BuiltinBug("uninitialized pointer dereference",
                                "Dereference of undefined value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_derefs_begin(), Eng.undef_derefs_end());
  }
};

class VISIBILITY_HIDDEN DivZero : public BuiltinBug {
public:
  DivZero() : BuiltinBug("divide-by-zero",
                         "Division by zero/undefined value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.explicit_bad_divides_begin(), Eng.explicit_bad_divides_end());
  }
};
  
class VISIBILITY_HIDDEN UndefResult : public BuiltinBug {
public:
  UndefResult() : BuiltinBug("undefined result",
                             "Result of operation is undefined.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.undef_results_begin(), Eng.undef_results_end());
  }
};
  
class VISIBILITY_HIDDEN BadCall : public BuiltinBug {
public:
  BadCall()
  : BuiltinBug("invalid function call",
        "Called function is a NULL or undefined function pointer value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    Emit(BR, Eng.bad_calls_begin(), Eng.bad_calls_end());
  }
};

class VISIBILITY_HIDDEN BadArg : public BuiltinBug {
public:
  BadArg() : BuiltinBug("uninitialized argument",  
    "Pass-by-value argument in function is undefined.") {}

  BadArg(const char* d) : BuiltinBug("uninitialized argument", d) {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I = Eng.undef_arg_begin(),
         E = Eng.undef_arg_end(); I!=E; ++I) {

      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());

      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};
  
class VISIBILITY_HIDDEN BadMsgExprArg : public BadArg {
public:
  BadMsgExprArg() 
    : BadArg("Pass-by-value argument in message expression is undefined.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefArgsTy::iterator I=Eng.msg_expr_undef_arg_begin(),
         E = Eng.msg_expr_undef_arg_end(); I!=E; ++I) {
      
      // Generate a report for this bug.
      RangedBugReport report(*this, I->first);
      report.addRange(I->second->getSourceRange());
      
      // Emit the warning.
      BR.EmitWarning(report);
    }    
  }
};
  
class VISIBILITY_HIDDEN BadReceiver : public BuiltinBug {
public:  
  BadReceiver()
  : BuiltinBug("uninitialized receiver",
               "Receiver in message expression is an uninitialized value.") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::UndefReceiversTy::iterator I=Eng.undef_receivers_begin(),
         End = Eng.undef_receivers_end(); I!=End; ++I) {
      
      // Generate a report for this bug.
      RangedBugReport report(*this, *I);
      
      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ObjCMessageExpr>(S)->getReceiver();
      assert (E && "Receiver cannot be NULL");
      report.addRange(E->getSourceRange());
      
      // Emit the warning.
      BR.EmitWarning(report);
    }    
  }
};
  
class VISIBILITY_HIDDEN RetStack : public BuiltinBug {
public:
  RetStack() : BuiltinBug("return of stack address") {}
  
  virtual void EmitBuiltinWarnings(BugReporter& BR, GRExprEngine& Eng) {
    for (GRExprEngine::ret_stackaddr_iterator I=Eng.ret_stackaddr_begin(),
         End = Eng.ret_stackaddr_end(); I!=End; ++I) {

      ExplodedNode<GRState>* N = *I;
      Stmt *S = cast<PostStmt>(N->getLocation()).getStmt();
      Expr* E = cast<ReturnStmt>(S)->getRetValue();
      assert (E && "Return expression cannot be NULL");
      
      // Get the value associated with E.
      loc::MemRegionVal V =
        cast<loc::MemRegionVal>(Eng.getStateManager().GetSVal(N->getState(),
                                                               E));
      
      // Generate a report for this bug.
      std::ostringstream os;
      SourceRange R;
      
      // Check if the region is a compound literal.
      if (const CompoundLiteralRegion* CR = 
            dyn_cast<CompoundLiteralRegion>(V.getRegion())) {
        
        const CompoundLiteralExpr* CL = CR->getLiteralExpr();
        os << "Address of stack memory associated with a compound literal "
              "declared on line "
            << BR.getSourceManager().getLogicalLineNumber(CL->getLocStart())
            << " returned.";
        
        R = CL->getSourceRange();
      }
      else {        
        os << "Address of stack memory associated with local variable '"
           << V.getRegion()->getString() << "' returned.";
      }
      
      std::string s = os.str();      
      RangedBugReport report(*this, N, s.c_str());
      report.addRange(E->getSourceRange());
      if (R.isValid()) report.addRange(R);
      
      // Emit the warning.
      BR.EmitWarning(report);
    }
  }
};


class VISIBILITY_HIDDEN UndefBranch : public BuiltinBug {
  struct VISIBILITY_HIDDEN FindUndefExpr {
    GRStateManager& VM;
    const GRState* St;
    
    FindUndefExpr(GRStateManager& V, const GRState* S) : VM(V), St(S) {}
    
    Expr* FindExpr(Expr* Ex) {      
      if (!MatchesCriteria(Ex))
        return 0;
      
      for (Stmt::child_iterator I=Ex->child_begin(), E=Ex->child_end();I!=E;++I)
        if (Expr* ExI = dyn_cast_or_null<Expr>(*I)) {
          Expr* E2 = FindExpr(ExI);
          if (E2) return E2;
        }
      
      return Ex;
    }
    
{'fraction_non_alphanumeric': 0.1739398802543053, 'fraction_numerical': 0.0007406950188259984, 'mean_word_length': 2.4399150743099787, 'pattern_counts': {'":': 0, '<': 52, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5440348', 'n_tokens_mistral': 5101, 'n_tokens_neox': 4891, 'n_words': 1170}