r231266 - [analyzer] Individual configuration options can be specified for checkers.

Gabor Horvath xazax.hun at gmail.com
Wed Mar 4 09:59:34 PST 2015


Author: xazax
Date: Wed Mar  4 11:59:34 2015
New Revision: 231266

URL: http://llvm.org/viewvc/llvm-project?rev=231266&view=rev
Log:
[analyzer] Individual configuration options can be specified for checkers.

Reviewed by: Anna Zaks

Original patch by: Aleksei Sidorin

Differential Revision: http://reviews.llvm.org/D7905

Added:
    cfe/trunk/unittests/StaticAnalyzer/
    cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp
    cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt
    cfe/trunk/unittests/StaticAnalyzer/Makefile
Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td
    cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
    cfe/trunk/test/Analysis/free.c
    cfe/trunk/test/Analysis/malloc-annotations.c
    cfe/trunk/test/Analysis/outofbound.c
    cfe/trunk/test/Analysis/undef-buffers.c
    cfe/trunk/unittests/CMakeLists.txt
    cfe/trunk/unittests/Makefile

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Wed Mar  4 11:59:34 2015
@@ -28,6 +28,10 @@ class DiagnosticsEngine;
 class Preprocessor;
 class LangOptions;
 
+namespace ento {
+class CheckerBase;
+}
+
 /// Analysis - Set of available source code analyses.
 enum Analyses {
 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
@@ -252,18 +256,102 @@ private:
   /// \sa getMaxNodesPerTopLevelFunction
   Optional<unsigned> MaxNodesPerTopLevelFunction;
 
+  /// A helper function that retrieves option for a given full-qualified
+  /// checker name.
+  /// Options for checkers can be specified via 'analyzer-config' command-line
+  /// option.
+  /// Example:
+  /// @code-analyzer-config unix.Malloc:OptionName=CheckerOptionValue @endcode
+  /// or @code-analyzer-config unix:OptionName=GroupOptionValue @endcode
+  /// for groups of checkers.
+  /// @param [in] CheckerName  Full-qualified checker name, like
+  /// alpha.unix.StreamChecker.
+  /// @param [in] OptionName  Name of the option to get.
+  /// @param [in] Default  Default value if no option is specified.
+  /// @param [in] SearchInParents If set to true and the searched option was not
+  /// specified for the given checker the options for the parent packages will
+  /// be searched as well. The inner packages take precedence over the outer
+  /// ones.
+  /// @retval CheckerOptionValue  An option for a checker if it was specified.
+  /// @retval GroupOptionValue  An option for group if it was specified and no
+  /// checker-specific options were found. The closer group to checker,
+  /// the more priority it has. For example, @c coregroup.subgroup has more
+  /// priority than @c coregroup for @c coregroup.subgroup.CheckerName checker.
+  /// @retval Default  If nor checker option, nor group option was found.
+  StringRef getCheckerOption(StringRef CheckerName, StringRef OptionName,
+                             StringRef Default,
+                             bool SearchInParents = false);
+
 public:
-  /// Interprets an option's string value as a boolean.
+  /// Interprets an option's string value as a boolean. The "true" string is
+  /// interpreted as true and the "false" string is interpreted as false.
   ///
-  /// Accepts the strings "true" and "false".
   /// If an option value is not provided, returns the given \p DefaultVal.
-  bool getBooleanOption(StringRef Name, bool DefaultVal);
+  /// @param [in] Name Name for option to retrieve.
+  /// @param [in] DefaultVal Default value returned if no such option was
+  /// specified.
+  /// @param [in] C The optional checker parameter that can be used to restrict
+  /// the search to the options of this particular checker (and its parents
+  /// dependening on search mode).
+  /// @param [in] SearchInParents If set to true and the searched option was not
+  /// specified for the given checker the options for the parent packages will
+  /// be searched as well. The inner packages take precedence over the outer
+  /// ones.
+  bool getBooleanOption(StringRef Name, bool DefaultVal,
+                        const ento::CheckerBase *C = nullptr,
+                        bool SearchInParents = false);
 
   /// Variant that accepts a Optional value to cache the result.
-  bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal);
+  ///
+  /// @param [in,out] V Return value storage, returned if parameter contains
+  /// an existing valid option, else it is used to store a return value
+  /// @param [in] Name Name for option to retrieve.
+  /// @param [in] DefaultVal Default value returned if no such option was
+  /// specified.
+  /// @param [in] C The optional checker parameter that can be used to restrict
+  /// the search to the options of this particular checker (and its parents
+  /// dependening on search mode).
+  /// @param [in] SearchInParents If set to true and the searched option was not
+  /// specified for the given checker the options for the parent packages will
+  /// be searched as well. The inner packages take precedence over the outer
+  /// ones.
+  bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal,
+                        const ento::CheckerBase *C  = nullptr,
+                        bool SearchInParents = false);
 
   /// Interprets an option's string value as an integer value.
-  int getOptionAsInteger(StringRef Name, int DefaultVal);
+  ///
+  /// If an option value is not provided, returns the given \p DefaultVal.
+  /// @param [in] Name Name for option to retrieve.
+  /// @param [in] DefaultVal Default value returned if no such option was
+  /// specified.
+  /// @param [in] C The optional checker parameter that can be used to restrict
+  /// the search to the options of this particular checker (and its parents
+  /// dependening on search mode).
+  /// @param [in] SearchInParents If set to true and the searched option was not
+  /// specified for the given checker the options for the parent packages will
+  /// be searched as well. The inner packages take precedence over the outer
+  /// ones.
+  int getOptionAsInteger(StringRef Name, int DefaultVal,
+                         const ento::CheckerBase *C = nullptr,
+                         bool SearchInParents = false);
+
+  /// Query an option's string value.
+  ///
+  /// If an option value is not provided, returns the given \p DefaultVal.
+  /// @param [in] Name Name for option to retrieve.
+  /// @param [in] DefaultVal Default value returned if no such option was
+  /// specified.
+  /// @param [in] C The optional checker parameter that can be used to restrict
+  /// the search to the options of this particular checker (and its parents
+  /// dependening on search mode).
+  /// @param [in] SearchInParents If set to true and the searched option was not
+  /// specified for the given checker the options for the parent packages will
+  /// be searched as well. The inner packages take precedence over the outer
+  /// ones.
+  StringRef getOptionAsString(StringRef Name, StringRef DefaultVal,
+                              const ento::CheckerBase *C = nullptr,
+                              bool SearchInParents = false);
 
   /// \brief Retrieves and sets the UserMode. This is a high-level option,
   /// which is used to set other low-level options. It is not accessible

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/Checkers.td Wed Mar  4 11:59:34 2015
@@ -295,7 +295,7 @@ def UnixAPIChecker : Checker<"API">,
   HelpText<"Check calls to various UNIX/Posix functions">,
   DescFile<"UnixAPIChecker.cpp">;
 
-def MallocPessimistic : Checker<"Malloc">,
+def MallocChecker: Checker<"Malloc">,
   HelpText<"Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().">,
   DescFile<"MallocChecker.cpp">;
   
@@ -315,10 +315,6 @@ def ChrootChecker : Checker<"Chroot">,
   HelpText<"Check improper use of chroot">,
   DescFile<"ChrootChecker.cpp">;
 
-def MallocOptimistic : Checker<"MallocWithAnnotations">,
-  HelpText<"Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free(). Assumes that all user-defined functions which might free a pointer are annotated.">,
-  DescFile<"MallocChecker.cpp">;
-
 def PthreadLockChecker : Checker<"PthreadLock">,
   HelpText<"Simple lock -> unlock checker">,
   DescFile<"PthreadLockChecker.cpp">;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Wed Mar  4 11:59:34 2015
@@ -170,8 +170,7 @@ public:
   /// In pessimistic mode, the checker assumes that it does not know which
   /// functions might free the memory.
   enum CheckKind {
-    CK_MallocPessimistic,
-    CK_MallocOptimistic,
+    CK_MallocChecker,
     CK_NewDeleteChecker,
     CK_NewDeleteLeaksChecker,
     CK_MismatchedDeallocatorChecker,
@@ -184,6 +183,8 @@ public:
     MOK_Any
   };
 
+  DefaultBool IsOptimistic;
+
   DefaultBool ChecksEnabled[CK_NumCheckKinds];
   CheckName CheckNames[CK_NumCheckKinds];
   typedef llvm::SmallVector<CheckKind, CK_NumCheckKinds> CKVecTy;
@@ -584,7 +585,7 @@ bool MallocChecker::isCMemFunction(const
   if (Family != AF_Malloc)
     return false;
 
-  if (ChecksEnabled[CK_MallocOptimistic] && FD->hasAttrs()) {
+  if (IsOptimistic && FD->hasAttrs()) {
     for (const auto *I : FD->specific_attrs<OwnershipAttr>()) {
       OwnershipAttr::OwnershipKind OwnKind = I->getOwnKind();
       if(OwnKind == OwnershipAttr::Takes || OwnKind == OwnershipAttr::Holds) {
@@ -791,8 +792,7 @@ void MallocChecker::checkPostStmt(const
     }
   }
 
-  if (ChecksEnabled[CK_MallocOptimistic] ||
-      ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
+  if (IsOptimistic || ChecksEnabled[CK_MismatchedDeallocatorChecker]) {
     // Check all the attributes, if there are any.
     // There can be multiple of these attributes.
     if (FD->hasAttrs())
@@ -1362,8 +1362,7 @@ MallocChecker::getCheckIfTracked(MallocC
   case AF_IfNameIndex:
   case AF_Alloca: {
     // C checkers.
-    if (CK == CK_MallocOptimistic ||
-        CK == CK_MallocPessimistic) {
+    if (CK == CK_MallocChecker) {
       return CK;
     }
     return Optional<MallocChecker::CheckKind>();
@@ -1516,8 +1515,7 @@ void MallocChecker::ReportBadFree(Checke
                                   SourceRange Range, 
                                   const Expr *DeallocExpr) const {
 
-  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocOptimistic,
-                                                   CK_MallocPessimistic,
+  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocChecker,
                                                    CK_NewDeleteChecker),
                                      C, DeallocExpr);
   if (!CheckKind.hasValue())
@@ -1559,8 +1557,7 @@ void MallocChecker::ReportBadFree(Checke
 void MallocChecker::ReportFreeAlloca(CheckerContext &C, SVal ArgVal, 
                                      SourceRange Range) const {
 
-  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocOptimistic,
-                                               CK_MallocPessimistic,
+  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocChecker,
                                                CK_MismatchedDeallocatorChecker),
                                      AF_Alloca);
   if (!CheckKind.hasValue())
@@ -1639,8 +1636,7 @@ void MallocChecker::ReportOffsetFree(Che
                                      const Expr *AllocExpr) const {
 
 
-  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocOptimistic,
-                                                   CK_MallocPessimistic,
+  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocChecker,
                                                    CK_NewDeleteChecker),
                                      C, AllocExpr);
   if (!CheckKind.hasValue())
@@ -1692,8 +1688,7 @@ void MallocChecker::ReportOffsetFree(Che
 void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
                                        SymbolRef Sym) const {
 
-  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocOptimistic,
-                                                   CK_MallocPessimistic,
+  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocChecker,
                                                    CK_NewDeleteChecker),
                                      C, Sym);
   if (!CheckKind.hasValue())
@@ -1718,8 +1713,7 @@ void MallocChecker::ReportDoubleFree(Che
                                      bool Released, SymbolRef Sym, 
                                      SymbolRef PrevSym) const {
 
-  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocOptimistic,
-                                                   CK_MallocPessimistic,
+  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocChecker,
                                                    CK_NewDeleteChecker),
                                      C, Sym);
   if (!CheckKind.hasValue())
@@ -1934,8 +1928,7 @@ MallocChecker::getAllocationSite(const E
 void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
                                CheckerContext &C) const {
 
-  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocOptimistic,
-                                                   CK_MallocPessimistic,
+  auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocChecker,
                                                    CK_NewDeleteLeaksChecker),
                                      C, Sym);
   if (!CheckKind.hasValue())
@@ -2058,8 +2051,7 @@ void MallocChecker::checkPreCall(const C
       return;
 
     ASTContext &Ctx = C.getASTContext();
-    if ((ChecksEnabled[CK_MallocOptimistic] ||
-         ChecksEnabled[CK_MallocPessimistic]) &&
+    if (ChecksEnabled[CK_MallocChecker] &&
         (isCMemFunction(FD, Ctx, AF_Malloc, MemoryOperationKind::MOK_Free) ||
          isCMemFunction(FD, Ctx, AF_IfNameIndex,
                         MemoryOperationKind::MOK_Free)))
@@ -2551,8 +2543,7 @@ void MallocChecker::printState(raw_ostre
     for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
       const RefState *RefS = State->get<RegionState>(I.getKey());
       AllocationFamily Family = RefS->getAllocationFamily();
-      auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocOptimistic,
-                                                       CK_MallocPessimistic,
+      auto CheckKind = getCheckIfTracked(MakeVecFromCK(CK_MallocChecker,
                                                        CK_NewDeleteChecker),
                                          Family);
       I.getKey()->dumpToStream(Out);
@@ -2568,6 +2559,8 @@ void MallocChecker::printState(raw_ostre
 void ento::registerNewDeleteLeaksChecker(CheckerManager &mgr) {
   registerCStringCheckerBasic(mgr);
   MallocChecker *checker = mgr.registerChecker<MallocChecker>();
+  checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(
+      "Optimistic", false, checker);
   checker->ChecksEnabled[MallocChecker::CK_NewDeleteLeaksChecker] = true;
   checker->CheckNames[MallocChecker::CK_NewDeleteLeaksChecker] =
       mgr.getCurrentCheckName();
@@ -2581,11 +2574,12 @@ void ento::registerNewDeleteLeaksChecker
   void ento::register##name(CheckerManager &mgr) {                             \
     registerCStringCheckerBasic(mgr);                                          \
     MallocChecker *checker = mgr.registerChecker<MallocChecker>();             \
+    checker->IsOptimistic = mgr.getAnalyzerOptions().getBooleanOption(         \
+        "Optimistic", false, checker);                                         \
     checker->ChecksEnabled[MallocChecker::CK_##name] = true;                   \
     checker->CheckNames[MallocChecker::CK_##name] = mgr.getCurrentCheckName(); \
   }
 
-REGISTER_CHECKER(MallocPessimistic)
-REGISTER_CHECKER(MallocOptimistic)
+REGISTER_CHECKER(MallocChecker)
 REGISTER_CHECKER(NewDeleteChecker)
 REGISTER_CHECKER(MismatchedDeallocatorChecker)

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Wed Mar  4 11:59:34 2015
@@ -13,12 +13,14 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
+using namespace ento;
 using namespace llvm;
 
 AnalyzerOptions::UserModeKind AnalyzerOptions::getUserMode() {
@@ -100,12 +102,37 @@ AnalyzerOptions::mayInlineCXXMemberFunct
 
 static StringRef toString(bool b) { return b ? "true" : "false"; }
 
-bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal) {
+StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName,
+                                            StringRef OptionName,
+                                            StringRef Default,
+                                            bool SearchInParents) {
+  // Search for a package option if the option for the checker is not specified
+  // and search in parents is enabled.
+  ConfigTable::const_iterator E = Config.end();
+  do {
+    ConfigTable::const_iterator I =
+        Config.find((Twine(CheckerName) + ":" + OptionName).str());
+    if (I != E)
+      return StringRef(I->getValue());
+    size_t Pos = CheckerName.rfind('.');
+    if (Pos == StringRef::npos)
+      return Default;
+    CheckerName = CheckerName.substr(0, Pos);
+  } while (!CheckerName.empty() && SearchInParents);
+  return Default;
+}
+
+bool AnalyzerOptions::getBooleanOption(StringRef Name, bool DefaultVal,
+                                       const CheckerBase *C,
+                                       bool SearchInParents) {
   // FIXME: We should emit a warning here if the value is something other than
   // "true", "false", or the empty string (meaning the default value),
   // but the AnalyzerOptions doesn't have access to a diagnostic engine.
+  StringRef Default = toString(DefaultVal);
   StringRef V =
-      Config.insert(std::make_pair(Name, toString(DefaultVal))).first->second;
+      C ? getCheckerOption(C->getTagDescription(), Name, Default,
+                           SearchInParents)
+        : StringRef(Config.insert(std::make_pair(Name, Default)).first->second);
   return llvm::StringSwitch<bool>(V)
       .Case("true", true)
       .Case("false", false)
@@ -113,9 +140,10 @@ bool AnalyzerOptions::getBooleanOption(S
 }
 
 bool AnalyzerOptions::getBooleanOption(Optional<bool> &V, StringRef Name,
-                                       bool DefaultVal) {
+                                       bool DefaultVal, const CheckerBase *C,
+                                       bool SearchInParents) {
   if (!V.hasValue())
-    V = getBooleanOption(Name, DefaultVal);
+    V = getBooleanOption(Name, DefaultVal, C, SearchInParents);
   return V.getValue();
 }
 
@@ -199,19 +227,35 @@ bool AnalyzerOptions::shouldWriteStableR
                           /* Default = */ false);
 }
 
-int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal) {
+int AnalyzerOptions::getOptionAsInteger(StringRef Name, int DefaultVal,
+                                        const CheckerBase *C,
+                                        bool SearchInParents) {
   SmallString<10> StrBuf;
   llvm::raw_svector_ostream OS(StrBuf);
   OS << DefaultVal;
 
-  StringRef V = Config.insert(std::make_pair(Name, OS.str())).first->second;
+  StringRef V = C ? getCheckerOption(C->getTagDescription(), Name, OS.str(),
+                                     SearchInParents)
+                  : StringRef(Config.insert(std::make_pair(Name, OS.str()))
+                                  .first->second);
+
   int Res = DefaultVal;
   bool b = V.getAsInteger(10, Res);
   assert(!b && "analyzer-config option should be numeric");
-  (void) b;
+  (void)b;
   return Res;
 }
 
+StringRef AnalyzerOptions::getOptionAsString(StringRef Name,
+                                             StringRef DefaultVal,
+                                             const CheckerBase *C,
+                                             bool SearchInParents) {
+  return C ? getCheckerOption(C->getTagDescription(), Name, DefaultVal,
+                              SearchInParents)
+           : StringRef(
+                 Config.insert(std::make_pair(Name, DefaultVal)).first->second);
+}
+
 unsigned AnalyzerOptions::getAlwaysInlineSize() {
   if (!AlwaysInlineSize.hasValue())
     AlwaysInlineSize = getOptionAsInteger("ipa-always-inline-size", 3);
@@ -281,4 +325,3 @@ bool AnalyzerOptions::shouldPrunePaths()
 bool AnalyzerOptions::shouldConditionalizeStaticInitializers() {
   return getBooleanOption("cfg-conditional-static-initializers", true);
 }
-

Modified: cfe/trunk/test/Analysis/free.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/free.c?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/free.c (original)
+++ cfe/trunk/test/Analysis/free.c Wed Mar  4 11:59:34 2015
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,alpha.unix.MallocWithAnnotations -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void free(void *);
 void *alloca(size_t);

Modified: cfe/trunk/test/Analysis/malloc-annotations.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/malloc-annotations.c?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/malloc-annotations.c (original)
+++ cfe/trunk/test/Analysis/malloc-annotations.c Wed Mar  4 11:59:34 2015
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,alpha.unix.MallocWithAnnotations -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify -analyzer-config unix.Malloc:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);

Modified: cfe/trunk/test/Analysis/outofbound.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/outofbound.c?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/outofbound.c (original)
+++ cfe/trunk/test/Analysis/outofbound.c Wed Mar  4 11:59:34 2015
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.unix,alpha.security.ArrayBound -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,unix,alpha.security.ArrayBound -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);

Modified: cfe/trunk/test/Analysis/undef-buffers.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/undef-buffers.c?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/undef-buffers.c (original)
+++ cfe/trunk/test/Analysis/undef-buffers.c Wed Mar  4 11:59:34 2015
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.unix,core.uninitialized -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,core.uninitialized -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);

Modified: cfe/trunk/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/CMakeLists.txt?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/unittests/CMakeLists.txt (original)
+++ cfe/trunk/unittests/CMakeLists.txt Wed Mar  4 11:59:34 2015
@@ -13,6 +13,7 @@ add_subdirectory(Basic)
 add_subdirectory(Lex)
 add_subdirectory(Driver)
 if(CLANG_ENABLE_STATIC_ANALYZER)
+  add_subdirectory(StaticAnalyzer)
   add_subdirectory(Frontend)
 endif()
 add_subdirectory(ASTMatchers)

Modified: cfe/trunk/unittests/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Makefile?rev=231266&r1=231265&r2=231266&view=diff
==============================================================================
--- cfe/trunk/unittests/Makefile (original)
+++ cfe/trunk/unittests/Makefile Wed Mar  4 11:59:34 2015
@@ -20,7 +20,7 @@ PARALLEL_DIRS = CodeGen Basic Lex Driver
 include $(CLANG_LEVEL)/../..//Makefile.config
 
 ifeq ($(ENABLE_CLANG_ARCMT),1)
-PARALLEL_DIRS += Frontend libclang
+PARALLEL_DIRS += Frontend libclang StaticAnalyzer
 endif
 
 endif  # CLANG_LEVEL

Added: cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp?rev=231266&view=auto
==============================================================================
--- cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp (added)
+++ cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp Wed Mar  4 11:59:34 2015
@@ -0,0 +1,74 @@
+//===- unittest/Analysis/AnalyzerOptionsTest.cpp - SA Options test --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace ento {
+
+TEST(StaticAnalyzerOptions, SearchInParentPackageTests) {
+  AnalyzerOptions Opts;
+  Opts.Config["Outer.Inner.CheckerOne:Option"] = "true";
+  Opts.Config["Outer.Inner:Option"] = "false";
+  Opts.Config["Outer.Inner:Option2"] = "true";
+  Opts.Config["Outer:Option2"] = "false";
+
+  struct CheckerOneMock : CheckerBase {
+    StringRef getTagDescription() const override {
+      return "Outer.Inner.CheckerOne";
+    }
+  };
+  struct CheckerTwoMock : CheckerBase {
+    StringRef getTagDescription() const override {
+      return "Outer.Inner.CheckerTwo";
+    }
+  };
+
+  // Checker one has Option specified as true. It should read true regardless of
+  // search mode.
+  CheckerOneMock CheckerOne;
+  EXPECT_TRUE(Opts.getBooleanOption("Option", false, &CheckerOne));
+  // The package option is overriden with a checker option.
+  EXPECT_TRUE(Opts.getBooleanOption("Option", false, &CheckerOne, true));
+  // The Outer package option is overriden by the Inner package option. No
+  // package option is specified.
+  EXPECT_TRUE(Opts.getBooleanOption("Option2", false, &CheckerOne, true));
+  // No package option is specified and search in packages is turned off. The
+  // default value should be returned.
+  EXPECT_FALSE(Opts.getBooleanOption("Option2", false, &CheckerOne));
+  EXPECT_TRUE(Opts.getBooleanOption("Option2", true, &CheckerOne));
+
+  // Checker true has no option specified. It should get the default value when
+  // search in parents turned off and false when search in parents turned on.
+  CheckerTwoMock CheckerTwo;
+  EXPECT_FALSE(Opts.getBooleanOption("Option", false, &CheckerTwo));
+  EXPECT_TRUE(Opts.getBooleanOption("Option", true, &CheckerTwo));
+  EXPECT_FALSE(Opts.getBooleanOption("Option", true, &CheckerTwo, true));
+}
+
+TEST(StaticAnalyzerOptions, StringOptions) {
+  AnalyzerOptions Opts;
+  Opts.Config["Outer.Inner.CheckerOne:Option"] = "StringValue";
+
+  struct CheckerOneMock : CheckerBase {
+    StringRef getTagDescription() const override {
+      return "Outer.Inner.CheckerOne";
+    }
+  };
+
+  CheckerOneMock CheckerOne;
+  EXPECT_TRUE("StringValue" ==
+              Opts.getOptionAsString("Option", "DefaultValue", &CheckerOne));
+  EXPECT_TRUE("DefaultValue" ==
+              Opts.getOptionAsString("Option2", "DefaultValue", &CheckerOne));
+}
+} // end namespace ento
+} // end namespace clang

Added: cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt?rev=231266&view=auto
==============================================================================
--- cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt (added)
+++ cfe/trunk/unittests/StaticAnalyzer/CMakeLists.txt Wed Mar  4 11:59:34 2015
@@ -0,0 +1,13 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+add_clang_unittest(StaticAnalysisTests
+  AnalyzerOptionsTest.cpp
+  )
+
+target_link_libraries(StaticAnalysisTests
+  clangBasic
+  clangAnalysis
+  clangStaticAnalyzerCore 
+  )

Added: cfe/trunk/unittests/StaticAnalyzer/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/StaticAnalyzer/Makefile?rev=231266&view=auto
==============================================================================
--- cfe/trunk/unittests/StaticAnalyzer/Makefile (added)
+++ cfe/trunk/unittests/StaticAnalyzer/Makefile Wed Mar  4 11:59:34 2015
@@ -0,0 +1,15 @@
+##===- unittests/Basic/Makefile ----------------------------*- Makefile -*-===##
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL = ../..
+TESTNAME = StaticAnalysis
+LINK_COMPONENTS := support mc
+USEDLIBS = clangBasic.a clangAnalysis.a clangStaticAnalyzerCore.a
+
+include $(CLANG_LEVEL)/unittests/Makefile





More information about the cfe-commits mailing list