r339135 - [analyzer][UninitializedObjectChecker] New flag to turn off dereferencing

2018-08-07 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Aug  7 05:55:26 2018
New Revision: 339135

URL: http://llvm.org/viewvc/llvm-project?rev=339135&view=rev
Log:
[analyzer][UninitializedObjectChecker] New flag to turn off dereferencing

Even for a checker being in alpha, some reports about pointees held so little
value to the user that it's safer to disable pointer/reference chasing for now.
It can be enabled with a new flag, in which case checker should function as it
has always been. This can be set with `CheckPointeeInitialization`.

Differential Revision: https://reviews.llvm.org/D49438

Added:
cfe/trunk/test/Analysis/cxx-uninitialized-object-no-dereference.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp?rev=339135&r1=339134&r2=339135&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp Tue 
Aug  7 05:55:26 2018
@@ -10,19 +10,33 @@
 // This file defines a checker that reports uninitialized fields in objects
 // created after a constructor call.
 //
-// This checker has two options:
+// This checker has several options:
 //   - "Pedantic" (boolean). If its not set or is set to false, the checker
 // won't emit warnings for objects that don't have at least one initialized
 // field. This may be set with
 //
-//  `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`.
+// `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`.
 //
 //   - "NotesAsWarnings" (boolean). If set to true, the checker will emit a
 // warning for each uninitalized field, as opposed to emitting one warning
 // per constructor call, and listing the uninitialized fields that belongs
 // to it in notes. Defaults to false.
 //
-//  `-analyzer-config 
alpha.cplusplus.UninitializedObject:NotesAsWarnings=true`.
+// `-analyzer-config \
+// alpha.cplusplus.UninitializedObject:NotesAsWarnings=true`.
+//
+//   - "CheckPointeeInitialization" (boolean). If set to false, the checker 
will
+// not analyze the pointee of pointer/reference fields, and will only check
+// whether the object itself is initialized. Defaults to false.
+//
+// `-analyzer-config \
+// 
alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true`.
+//
+// TODO: With some clever heuristics, some pointers should be dereferenced
+// by default. For example, if the pointee is constructed within the
+// constructor call, it's reasonable to say that no external object
+// references it, and we wouldn't generate multiple report on the same
+// pointee.
 //
 
//===--===//
 
@@ -44,6 +58,7 @@ public:
   // These fields will be initialized when registering the checker.
   bool IsPedantic;
   bool ShouldConvertNotesToWarnings;
+  bool CheckPointeeInitialization;
 
   UninitializedObjectChecker()
   : BT_uninitField(new BuiltinBug(this, "Uninitialized fields")) {}
@@ -109,13 +124,16 @@ class FindUninitializedFields {
   const TypedValueRegion *const ObjectR;
 
   const bool IsPedantic;
+  const bool CheckPointeeInitialization;
+
   bool IsAnyFieldInitialized = false;
 
   UninitFieldSet UninitFields;
 
 public:
   FindUninitializedFields(ProgramStateRef State,
-  const TypedValueRegion *const R, bool IsPedantic);
+  const TypedValueRegion *const R, bool IsPedantic,
+  bool CheckPointeeInitialization);
   const UninitFieldSet &getUninitFields();
 
 private:
@@ -262,8 +280,8 @@ void UninitializedObjectChecker::checkEn
   if (!Object)
 return;
 
-  FindUninitializedFields F(Context.getState(), Object->getRegion(),
-IsPedantic);
+  FindUninitializedFields F(Context.getState(), Object->getRegion(), 
IsPedantic,
+CheckPointeeInitialization);
 
   const UninitFieldSet &UninitFields = F.getUninitFields();
 
@@ -327,8 +345,10 @@ void UninitializedObjectChecker::checkEn
 
//===--===//
 
 FindUninitializedFields::FindUninitializedFields(
-ProgramStateRef State, const TypedValueRegion *const R, bool IsPedantic)
-: State(State), ObjectR(R), IsPedantic(IsPedantic) {}
+ProgramStateRef State, const TypedValueRegion *const R, bool IsPedantic,
+bool Ch

r339237 - [analyzer][UninitializedObjectChecker] Fixed a false negative by no longer filtering out certain constructor calls

2018-08-08 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed Aug  8 05:23:02 2018
New Revision: 339237

URL: http://llvm.org/viewvc/llvm-project?rev=339237&view=rev
Log:
[analyzer][UninitializedObjectChecker] Fixed a false negative by no longer 
filtering out certain constructor calls

As of now, all constructor calls are ignored that are being called
by a constructor. The point of this was not to analyze the fields
of an object, so an uninitialized field wouldn't be reported
multiple times.

This however introduced false negatives when the two constructors
were in no relation to one another -- see the test file for a neat
example for this with singletons. This patch aims so fix this issue.

Differential Revision: https://reviews.llvm.org/D48436

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp?rev=339237&r1=339236&r2=339237&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp Wed 
Aug  8 05:23:02 2018
@@ -225,12 +225,16 @@ static llvm::ImmutableListFactory
 getObjectVal(const CXXConstructorDecl *CtorDecl, CheckerContext &Context);
 
-/// Checks whether the constructor under checking is called by another
-/// constructor.
-static bool isCalledByConstructor(const CheckerContext &Context);
+/// Checks whether the object constructed by \p Ctor will be analyzed later
+/// (e.g. if the object is a field of another object, in which case we'd check
+/// it multiple times).
+static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
+   CheckerContext &Context);
 
 /// Returns whether FD can be (transitively) dereferenced to a void pointer 
type
 /// (void*, void**, ...). The type of the region behind a void pointer isn't
@@ -273,7 +277,7 @@ void UninitializedObjectChecker::checkEn
 return;
 
   // This avoids essentially the same error being reported multiple times.
-  if (isCalledByConstructor(Context))
+  if (willObjectBeAnalyzedLater(CtorDecl, Context))
 return;
 
   Optional Object = getObjectVal(CtorDecl, Context);
@@ -433,8 +437,8 @@ bool FindUninitializedFields::isNonUnion
   }
 
   // Checking bases.
-  // FIXME: As of now, because of `isCalledByConstructor`, objects whose type
-  // is a descendant of another type will emit warnings for uninitalized
+  // FIXME: As of now, because of `willObjectBeAnalyzedLater`, objects whose
+  // type is a descendant of another type will emit warnings for uninitalized
   // inherited members.
   // This is not the only way to analyze bases of an object -- if we didn't
   // filter them out, and didn't analyze the bases, this checker would run for
@@ -661,18 +665,32 @@ getObjectVal(const CXXConstructorDecl *C
   return Object.getAs();
 }
 
-// TODO: We should also check that if the constructor was called by another
-// constructor, whether those two are in any relation to one another. In it's
-// current state, this introduces some false negatives.
-static bool isCalledByConstructor(const CheckerContext &Context) {
-  const LocationContext *LC = Context.getLocationContext()->getParent();
+static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
+   CheckerContext &Context) {
 
-  while (LC) {
-if (isa(LC->getDecl()))
-  return true;
+  Optional CurrentObject = getObjectVal(Ctor, 
Context);
+  if (!CurrentObject)
+return false;
+
+  const LocationContext *LC = Context.getLocationContext();
+  while ((LC = LC->getParent())) {
+
+// If \p Ctor was called by another constructor.
+const auto *OtherCtor = dyn_cast(LC->getDecl());
+if (!OtherCtor)
+  continue;
 
-LC = LC->getParent();
+Optional OtherObject =
+getObjectVal(OtherCtor, Context);
+if (!OtherObject)
+  continue;
+
+// If the CurrentObject is a subregion of OtherObject, it will be analyzed
+// during the analysis of OtherObject.
+if (CurrentObject->getRegion()->isSubRegionOf(OtherObject->getRegion()))
+  return true;
   }
+
   return false;
 }
 

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp?rev=339237&r1=339236&r2=339237&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp Wed Aug  8 05:23:02 
2018
@@ -1040,13 +1040,12 @@ void assert(int b) {
 // While a singleton would make more sense as a static variable, that would 
zero
 // initialize all of its fields, he

r339240 - [analyzer][UninitializedObjectChecker] Pointer/reference objects are dereferenced according to dynamic type

2018-08-08 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed Aug  8 06:18:53 2018
New Revision: 339240

URL: http://llvm.org/viewvc/llvm-project?rev=339240&view=rev
Log:
[analyzer][UninitializedObjectChecker] Pointer/reference objects are 
dereferenced according to dynamic type

This patch fixed an issue where the dynamic type of pointer/reference
object was known by the analyzer, but wasn't obtained in the checker,
which resulted in false negatives. This should also increase reliability
of the checker, as derefencing is always done now according to the
dynamic type (even if that happens to be the same as the static type).

Special thanks to Artem Degrachev for setting me on the right track.

Differential Revision: https://reviews.llvm.org/D49199

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp?rev=339240&r1=339239&r2=339240&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp Wed 
Aug  8 06:18:53 2018
@@ -44,7 +44,7 @@
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include 
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
 
 using namespace clang;
 using namespace clang::ento;
@@ -236,10 +236,10 @@ getObjectVal(const CXXConstructorDecl *C
 static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
CheckerContext &Context);
 
-/// Returns whether FD can be (transitively) dereferenced to a void pointer 
type
+/// Returns whether T can be (transitively) dereferenced to a void pointer type
 /// (void*, void**, ...). The type of the region behind a void pointer isn't
 /// known, and thus FD can not be analyzed.
-static bool isVoidPointer(const FieldDecl *FD);
+static bool isVoidPointer(QualType T);
 
 /// Returns true if T is a primitive type. We defined this type so that for
 /// objects that we'd only like analyze as much as checking whether their
@@ -483,7 +483,7 @@ bool FindUninitializedFields::isPointerO
 
   SVal V = State->getSVal(FR);
 
-  if (V.isUnknown() || V.isZeroConstant()) {
+  if (V.isUnknown() || V.getAs()) {
 IsAnyFieldInitialized = true;
 return false;
   }
@@ -497,48 +497,70 @@ bool FindUninitializedFields::isPointerO
 return false;
   }
 
-  const FieldDecl *FD = FR->getDecl();
+  assert(V.getAs() &&
+ "At this point V must be loc::MemRegionVal!");
+  auto L = V.castAs();
+
+  // We can't reason about symbolic regions, assume its initialized.
+  // Note that this also avoids a potential infinite recursion, because
+  // constructors for list-like classes are checked without being called, and
+  // the Static Analyzer will construct a symbolic region for Node *next; or
+  // similar code snippets.
+  if (L.getRegion()->getSymbolicBase()) {
+IsAnyFieldInitialized = true;
+return false;
+  }
 
-  // TODO: The dynamic type of a void pointer may be retrieved with
-  // `getDynamicTypeInfo`.
-  if (isVoidPointer(FD)) {
+  DynamicTypeInfo DynTInfo = getDynamicTypeInfo(State, L.getRegion());
+  if (!DynTInfo.isValid()) {
 IsAnyFieldInitialized = true;
 return false;
   }
 
-  assert(V.getAs() && "V should be Loc at this point!");
+  QualType DynT = DynTInfo.getType();
+
+  if (isVoidPointer(DynT)) {
+IsAnyFieldInitialized = true;
+return false;
+  }
 
   // At this point the pointer itself is initialized and points to a valid
   // location, we'll now check the pointee.
-  SVal DerefdV = State->getSVal(V.castAs());
-
-  // TODO: Dereferencing should be done according to the dynamic type.
-  while (Optional L = DerefdV.getAs()) {
-DerefdV = State->getSVal(*L);
-  }
+  SVal DerefdV = State->getSVal(V.castAs(), DynT);
 
-  // If V is a pointer pointing to a record type.
-  if (Optional RecordV =
-  DerefdV.getAs()) {
+  // If DerefdV is still a pointer value, we'll dereference it again (e.g.:
+  // int** -> int*).
+  while (auto Tmp = DerefdV.getAs()) {
+if (Tmp->getRegion()->getSymbolicBase()) {
+  IsAnyFieldInitialized = true;
+  return false;
+}
 
-const TypedValueRegion *R = RecordV->getRegion();
+DynTInfo = getDynamicTypeInfo(State, Tmp->getRegion());
+if (!DynTInfo.isValid()) {
+  IsAnyFieldInitialized = true;
+  return false;
+}
 
-// We can't reason about symbolic regions, assume its initialized.
-// Note that this also avoids a potential infinite recursion, because
-// constructors f

r339591 - [analyzer][UninitializedObjectChecker] Refactoring p1.: ImmutableList factory is no longer static

2018-08-13 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Aug 13 10:55:52 2018
New Revision: 339591

URL: http://llvm.org/viewvc/llvm-project?rev=339591&view=rev
Log:
[analyzer][UninitializedObjectChecker] Refactoring p1.: ImmutableList factory 
is no longer static

This patch is the first part of a series of patches to refactor 
UninitializedObjectChecker. The goal of this effort is to

Separate pointer chasing from the rest of the checker,
Increase readability and reliability,
Don't impact performance (too bad).

In this one, ImmutableList's factory is moved to FindUninitializedFields.

Differential Revision: https://reviews.llvm.org/D50503

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp?rev=339591&r1=339590&r2=339591&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp Mon 
Aug 13 10:55:52 2018
@@ -73,17 +73,21 @@ public:
 /// Note that this class is immutable, and new fields may only be added through
 /// constructor calls.
 class FieldChainInfo {
+public:
   using FieldChain = llvm::ImmutableList;
 
+private:
+  FieldChain::Factory &Factory;
   FieldChain Chain;
 
   const bool IsDereferenced = false;
 
 public:
-  FieldChainInfo() = default;
+  FieldChainInfo() = delete;
+  FieldChainInfo(FieldChain::Factory &F) : Factory(F) {}
 
   FieldChainInfo(const FieldChainInfo &Other, const bool IsDereferenced)
-  : Chain(Other.Chain), IsDereferenced(IsDereferenced) {}
+  : Factory(Other.Factory), Chain(Other.Chain), 
IsDereferenced(IsDereferenced) {}
 
   FieldChainInfo(const FieldChainInfo &Other, const FieldRegion *FR,
  const bool IsDereferenced = false);
@@ -128,6 +132,7 @@ class FindUninitializedFields {
 
   bool IsAnyFieldInitialized = false;
 
+  FieldChainInfo::FieldChain::Factory Factory;
   UninitFieldSet UninitFields;
 
 public:
@@ -217,10 +222,6 @@ private:
 
 } // end of anonymous namespace
 
-// Static variable instantionations.
-
-static llvm::ImmutableListFactory Factory;
-
 // Utility function declarations.
 
 /// Returns the object that was constructed by CtorDecl, or None if that isn't
@@ -355,7 +356,7 @@ FindUninitializedFields::FindUninitializ
   CheckPointeeInitialization(CheckPointeeInitialization) {}
 
 const UninitFieldSet &FindUninitializedFields::getUninitFields() {
-  isNonUnionUninit(ObjectR, FieldChainInfo());
+  isNonUnionUninit(ObjectR, FieldChainInfo(Factory));
 
   if (!IsPedantic && !IsAnyFieldInitialized)
 UninitFields.clear();


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r339595 - [analyzer][UninitializedObjectChecker] Refactoring p2.: Moving pointer chasing to a separate file

2018-08-13 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Aug 13 11:17:05 2018
New Revision: 339595

URL: http://llvm.org/viewvc/llvm-project?rev=339595&view=rev
Log:
[analyzer][UninitializedObjectChecker] Refactoring p2.: Moving pointer chasing 
to a separate file

In this patch, the following classes and functions have been moved to a header 
file:

FieldChainInfo
FindUninitializedFields
isPrimitiveType

This also meant that they moved from anonymous namespace to clang::ento.

Code related to pointer chasing now relies in its own file.

There's absolutely no functional change in this patch -- its literally just 
copy pasting.

Differential Revision: https://reviews.llvm.org/D50504


Added:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
Removed:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=339595&r1=339594&r2=339595&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Mon Aug 13 11:17:05 
2018
@@ -93,7 +93,8 @@ add_clang_library(clangStaticAnalyzerChe
   UndefResultChecker.cpp
   UndefinedArraySubscriptChecker.cpp
   UndefinedAssignmentChecker.cpp
-  UninitializedObjectChecker.cpp
+  UninitializedObject/UninitializedObjectChecker.cpp
+  UninitializedObject/UninitializedPointee.cpp
   UnixAPIChecker.cpp
   UnreachableCodeChecker.cpp
   VforkChecker.cpp

Added: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=339595&view=auto
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(added)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Mon Aug 13 11:17:05 2018
@@ -0,0 +1,196 @@
+//===- UninitializedObject.h -*- 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 helper classes for UninitializedObjectChecker and
+// documentation about the logic of it.
+//
+// To read about command line options and a description what this checker does,
+// refer to UninitializedObjectChecker.cpp.
+//
+// Some methods are implemented in UninitializedPointee.cpp, to reduce the
+// complexity of the main checker file.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_UNINITIALIZEDOBJECT_H
+#define LLVM_CLANG_STATICANALYZER_UNINITIALIZEDOBJECT_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+namespace clang {
+namespace ento {
+
+/// Represents a field chain. A field chain is a vector of fields where the
+/// first element of the chain is the object under checking (not stored), and
+/// every other element is a field, and the element that precedes it is the
+/// object that contains it.
+///
+/// Note that this class is immutable, and new fields may only be added through
+/// constructor calls.
+class FieldChainInfo {
+public:
+  using FieldChain = llvm::ImmutableList;
+
+private:
+  FieldChain::Factory &Factory;
+  FieldChain Chain;
+
+  const bool IsDereferenced = false;
+
+public:
+  FieldChainInfo() = delete;
+  FieldChainInfo(FieldChain::Factory &F) : Factory(F) {}
+
+  FieldChainInfo(const FieldChainInfo &Other, const bool IsDereferenced)
+  : Factory(Other.Factory), Chain(Other.Chain), 
IsDereferenced(IsDereferenced) {}
+
+  FieldChainInfo(const FieldChainInfo &Other, const FieldRegion *FR,
+ const bool IsDereferenced = false);
+
+  bool contains(const FieldRegion *FR) const { return Chain.contains(FR); }
+  bool isPointer() const;
+
+  /// If this is a fieldchain whose last element is an uninitialized region of 
a
+  /// pointer type, `IsDereferenced` will store whether the pointer itself or
+  /// the pointee is uninitialized.
+  bool isDereferenced() const;
+  const FieldDecl *getEndOfChain() const;
+  void print(llvm::raw_ostream &Out) const;
+
+private:
+  /// Prints every element except the last to `Out`. Since ImmutableLists store
+  /// eleme

r339596 - [analyzer][UninitializedObjectChecker] Refactoring p3.: printTail moved out from FieldChainInfo

2018-08-13 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Aug 13 11:22:22 2018
New Revision: 339596

URL: http://llvm.org/viewvc/llvm-project?rev=339596&view=rev
Log:
[analyzer][UninitializedObjectChecker] Refactoring p3.: printTail moved out 
from FieldChainInfo

This is a standalone part of the effort to reduce FieldChainInfos inteerface.

Differential Revision: https://reviews.llvm.org/D50505

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=339596&r1=339595&r2=339596&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Mon Aug 13 11:22:22 2018
@@ -35,6 +35,7 @@ namespace ento {
 /// constructor calls.
 class FieldChainInfo {
 public:
+  using FieldChainImpl = llvm::ImmutableListImpl;
   using FieldChain = llvm::ImmutableList;
 
 private:
@@ -48,7 +49,8 @@ public:
   FieldChainInfo(FieldChain::Factory &F) : Factory(F) {}
 
   FieldChainInfo(const FieldChainInfo &Other, const bool IsDereferenced)
-  : Factory(Other.Factory), Chain(Other.Chain), 
IsDereferenced(IsDereferenced) {}
+  : Factory(Other.Factory), Chain(Other.Chain),
+IsDereferenced(IsDereferenced) {}
 
   FieldChainInfo(const FieldChainInfo &Other, const FieldRegion *FR,
  const bool IsDereferenced = false);
@@ -64,12 +66,6 @@ public:
   void print(llvm::raw_ostream &Out) const;
 
 private:
-  /// Prints every element except the last to `Out`. Since ImmutableLists store
-  /// elements in reverse order, and have no reverse iterators, we use a
-  /// recursive function to print the fieldchain correctly. The last element in
-  /// the chain is to be printed by `print`.
-  static void printTail(llvm::raw_ostream &Out,
-const llvm::ImmutableListImpl *L);
   friend struct FieldChainInfoComparator;
 };
 

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=339596&r1=339595&r2=339596&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Mon Aug 13 11:22:22 2018
@@ -46,8 +46,8 @@
 //
 
//===--===//
 
-#include "UninitializedObject.h"
 #include "ClangSACheckers.h"
+#include "UninitializedObject.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
@@ -87,7 +87,7 @@ getObjectVal(const CXXConstructorDecl *C
 /// (e.g. if the object is a field of another object, in which case we'd check
 /// it multiple times).
 static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
-   CheckerContext &Context);
+  CheckerContext &Context);
 
 /// Constructs a note message for a given FieldChainInfo object.
 static void printNoteMessage(llvm::raw_ostream &Out,
@@ -346,6 +346,13 @@ const FieldDecl *FieldChainInfo::getEndO
   return (*Chain.begin())->getDecl();
 }
 
+/// Prints every element except the last to `Out`. Since ImmutableLists store
+/// elements in reverse order, and have no reverse iterators, we use a
+/// recursive function to print the fieldchain correctly. The last element in
+/// the chain is to be printed by `print`.
+static void printTail(llvm::raw_ostream &Out,
+  const FieldChainInfo::FieldChainImpl *L);
+
 // TODO: This function constructs an incorrect string if a void pointer is a
 // part of the chain:
 //
@@ -383,15 +390,13 @@ void FieldChainInfo::print(llvm::raw_ost
   if (Chain.isEmpty())
 return;
 
-  const llvm::ImmutableListImpl *L =
-  Chain.getInternalPointer();
+  const FieldChainImpl *L = Chain.getInternalPointer();
   printTail(Out, L->getTail());
   Out << getVariableName(L->getHead()->getDecl());
 }
 
-void FieldChainInfo::printTail(
-llvm::raw_ostream &Out,
-const llvm::ImmutableListImpl *L) {
+static void printTail(llvm::raw_ostream &Out,
+  const FieldChainInfo::FieldChainImpl *L) {
   if (!L)
 return;
 
@@ -420,7 +425,

r339599 - [analyzer][UninitializedObjectChecker] Refactoring p4.: Wrap FieldRegions and reduce weight on FieldChainInfo

2018-08-13 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Aug 13 11:43:08 2018
New Revision: 339599

URL: http://llvm.org/viewvc/llvm-project?rev=339599&view=rev
Log:
[analyzer][UninitializedObjectChecker] Refactoring p4.: Wrap FieldRegions and 
reduce weight on FieldChainInfo

Before this patch, FieldChainInfo used a spaghetti: it took care of way too 
many cases,
even though it was always meant as a lightweight wrapper around
ImmutableList.
This problem is solved by introducing a lightweight polymorphic wrapper around 
const
FieldRegion *, FieldNode. It is an interface that abstracts away special cases 
like
pointers/references, objects that need to be casted to another type for a 
proper note
messages.

Changes to FieldChainInfo:

  * Now wraps ImmutableList.
  * Any pointer/reference related fields and methods were removed
  * Got a new add method. This replaces it's former constructors as a way to 
create a
new FieldChainInfo objects with a new element.

Changes to FindUninitializedField:

  * In order not to deal with dynamic memory management, when an uninitialized 
field is
found, the note message for it is constructed and is stored instead of a
FieldChainInfo object. (see doc around addFieldToUninits).

Some of the test files are changed too, from now on uninitialized pointees of 
references
always print "uninitialized pointee" instead of "uninitialized field" (which 
should've
really been like this from the beginning).

I also updated every comment according to these changes.

Differential Revision: https://reviews.llvm.org/D50506

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
cfe/trunk/test/Analysis/objcpp-uninitialized-object.mm

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=339599&r1=339598&r2=339599&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Mon Aug 13 11:43:08 2018
@@ -26,58 +26,85 @@
 namespace clang {
 namespace ento {
 
+/// Represent a single field. This is only an interface to abstract away 
special
+/// cases like pointers/references.
+class FieldNode {
+protected:
+  const FieldRegion *FR;
+
+public:
+  FieldNode(const FieldRegion *FR) : FR(FR) { assert(FR); }
+
+  FieldNode() = delete;
+  FieldNode(const FieldNode &) = delete;
+  FieldNode(FieldNode &&) = delete;
+  FieldNode &operator=(const FieldNode &) = delete;
+  FieldNode &operator=(const FieldNode &&) = delete;
+
+  /// Profile - Used to profile the contents of this object for inclusion in a
+  /// FoldingSet.
+  void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(this); }
+
+  bool operator<(const FieldNode &Other) const { return FR < Other.FR; }
+  bool isSameRegion(const FieldRegion *OtherFR) const { return FR == OtherFR; }
+
+  const FieldRegion *getRegion() const { return FR; }
+  const FieldDecl *getDecl() const { return FR->getDecl(); }
+
+  // When a fieldchain is printed (a list of FieldNode objects), it will have
+  // the following format:
+  // 'this->...'
+
+  /// If this is the last element of the fieldchain, this method will be 
called.
+  /// The note message should state something like "uninitialized field" or
+  /// "uninitialized pointee" etc.
+  virtual void printNoteMsg(llvm::raw_ostream &Out) const = 0;
+
+  /// Print any prefixes before the fieldchain.
+  virtual void printPrefix(llvm::raw_ostream &Out) const = 0;
+
+  /// Print the node. Should contain the name of the field stored in getRegion.
+  virtual void printNode(llvm::raw_ostream &Out) const = 0;
+
+  /// Print the separator. For example, fields may be separated with '.' or
+  /// "->".
+  virtual void printSeparator(llvm::raw_ostream &Out) const = 0;
+};
+
+/// Returns with Field's name. This is a helper function to get the correct 
name
+/// even if Field is a captured lambda variable.
+StringRef getVariableName(const FieldDecl *Field);
+
 /// Represents a field chain. A field chain is a vector of fields where the
 /// first element of the chain is the object under checking (not stored), and
 /// every other element is a field, and the element that precedes it is the
 /// object that contains it.
 ///
-/// Note that this class is immutable, and new fields may only be added through
-/// constructor calls.
+/// Note that this class is immutable (essentially a wrapper around an
+/// ImmutableList), and new elements can only be added by creating new
+/// FieldChainInfo object

r339601 - [analyzer][UninitializedObjectChecker] Refactoring p5.: Handle pedantic mode in the checker class only

2018-08-13 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Aug 13 11:48:34 2018
New Revision: 339601

URL: http://llvm.org/viewvc/llvm-project?rev=339601&view=rev
Log:
[analyzer][UninitializedObjectChecker] Refactoring p5.: Handle pedantic mode in 
the checker class only

Differential Revision: https://reviews.llvm.org/D50508

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=339601&r1=339600&r2=339601&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Mon Aug 13 11:48:34 2018
@@ -111,9 +111,7 @@ class FindUninitializedFields {
   ProgramStateRef State;
   const TypedValueRegion *const ObjectR;
 
-  const bool IsPedantic;
   const bool CheckPointeeInitialization;
-
   bool IsAnyFieldInitialized = false;
 
   FieldChainInfo::FieldChain::Factory ChainFactory;
@@ -131,10 +129,17 @@ class FindUninitializedFields {
   UninitFieldMap UninitFields;
 
 public:
+  /// Constructs the FindUninitializedField object, searches for and stores
+  /// uninitialized fields in R.
   FindUninitializedFields(ProgramStateRef State,
-  const TypedValueRegion *const R, bool IsPedantic,
+  const TypedValueRegion *const R,
   bool CheckPointeeInitialization);
-  const UninitFieldMap &getUninitFields();
+
+  const UninitFieldMap &getUninitFields() { return UninitFields; }
+
+  /// Returns whether the analyzed region contains at least one initialized
+  /// field.
+  bool isAnyFieldInitialized() { return IsAnyFieldInitialized; }
 
 private:
   // For the purposes of this checker, we'll regard the object under checking 
as

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=339601&r1=339600&r2=339601&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Mon Aug 13 11:48:34 2018
@@ -136,7 +136,7 @@ void UninitializedObjectChecker::checkEn
   if (!Object)
 return;
 
-  FindUninitializedFields F(Context.getState(), Object->getRegion(), 
IsPedantic,
+  FindUninitializedFields F(Context.getState(), Object->getRegion(),
 CheckPointeeInitialization);
 
   const UninitFieldMap &UninitFields = F.getUninitFields();
@@ -144,6 +144,12 @@ void UninitializedObjectChecker::checkEn
   if (UninitFields.empty())
 return;
 
+  // In non-pedantic mode, if Object's region doesn't contain a single
+  // initialized field, we'll assume that Object was intentionally left
+  // uninitialized.
+  if (!IsPedantic && !F.isAnyFieldInitialized())
+return;
+
   // There are uninitialized fields in the record.
 
   ExplodedNode *Node = Context.generateNonFatalErrorNode(Context.getState());
@@ -192,18 +198,12 @@ void UninitializedObjectChecker::checkEn
 
//===--===//
 
 FindUninitializedFields::FindUninitializedFields(
-ProgramStateRef State, const TypedValueRegion *const R, bool IsPedantic,
+ProgramStateRef State, const TypedValueRegion *const R,
 bool CheckPointeeInitialization)
-: State(State), ObjectR(R), IsPedantic(IsPedantic),
-  CheckPointeeInitialization(CheckPointeeInitialization) {}
+: State(State), ObjectR(R),
+  CheckPointeeInitialization(CheckPointeeInitialization) {
 
-const UninitFieldMap &FindUninitializedFields::getUninitFields() {
   isNonUnionUninit(ObjectR, FieldChainInfo(ChainFactory));
-
-  if (!IsPedantic && !IsAnyFieldInitialized)
-UninitFields.clear();
-
-  return UninitFields;
 }
 
 bool FindUninitializedFields::addFieldToUninits(FieldChainInfo Chain) {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r339653 - [analyzer][UninitializedObjectChecker] Void pointers are casted back to their dynamic type in note message

2018-08-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Aug 14 01:20:51 2018
New Revision: 339653

URL: http://llvm.org/viewvc/llvm-project?rev=339653&view=rev
Log:
[analyzer][UninitializedObjectChecker] Void pointers are casted back to their 
dynamic type in note message

Differential Revision: https://reviews.llvm.org/D49228

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp?rev=339653&r1=339652&r2=339653&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 Tue Aug 14 01:20:51 2018
@@ -60,6 +60,32 @@ public:
   }
 };
 
+/// Represents a void* field that needs to be casted back to its dynamic type
+/// for a correct note message.
+class NeedsCastLocField final : public FieldNode {
+  QualType CastBackType;
+
+public:
+  NeedsCastLocField(const FieldRegion *FR, const QualType &T)
+  : FieldNode(FR), CastBackType(T) {}
+
+  virtual void printNoteMsg(llvm::raw_ostream &Out) const override {
+Out << "uninitialized pointee ";
+  }
+
+  virtual void printPrefix(llvm::raw_ostream &Out) const override {
+Out << "static_cast" << '<' << CastBackType.getAsString() << ">(";
+  }
+
+  virtual void printNode(llvm::raw_ostream &Out) const override {
+Out << getVariableName(getDecl()) << ')';
+  }
+
+  virtual void printSeparator(llvm::raw_ostream &Out) const override {
+Out << "->";
+  }
+};
+
 } // end of anonymous namespace
 
 // Utility function declarations.
@@ -122,6 +148,10 @@ bool FindUninitializedFields::isPointerO
 
   QualType DynT = DynTInfo.getType();
 
+  // If the static type of the field is a void pointer, we need to cast it back
+  // to the dynamic type before dereferencing.
+  bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType());
+
   if (isVoidPointer(DynT)) {
 IsAnyFieldInitialized = true;
 return false;
@@ -160,11 +190,16 @@ bool FindUninitializedFields::isPointerO
 
 const TypedValueRegion *R = RecordV->getRegion();
 
-if (DynT->getPointeeType()->isStructureOrClassType())
+if (DynT->getPointeeType()->isStructureOrClassType()) {
+  if (NeedsCastBack)
+return isNonUnionUninit(R, LocalChain.add(NeedsCastLocField(FR, 
DynT)));
   return isNonUnionUninit(R, LocalChain.add(LocField(FR)));
+}
 
 if (DynT->getPointeeType()->isUnionType()) {
   if (isUnionUninit(R)) {
+if (NeedsCastBack)
+  return addFieldToUninits(LocalChain.add(NeedsCastLocField(FR, 
DynT)));
 return addFieldToUninits(LocalChain.add(LocField(FR)));
   } else {
 IsAnyFieldInitialized = true;
@@ -185,8 +220,11 @@ bool FindUninitializedFields::isPointerO
  "At this point FR must either have a primitive dynamic type, or it "
  "must be a null, undefined, unknown or concrete pointer!");
 
-  if (isPrimitiveUninit(DerefdV))
+  if (isPrimitiveUninit(DerefdV)) {
+if (NeedsCastBack)
+  return addFieldToUninits(LocalChain.add(NeedsCastLocField(FR, DynT)));
 return addFieldToUninits(LocalChain.add(LocField(FR)));
+  }
 
   IsAnyFieldInitialized = true;
   return false;

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp?rev=339653&r1=339652&r2=339653&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp Tue Aug 14 
01:20:51 2018
@@ -292,7 +292,7 @@ void fCyclicVoidPointerTest() {
 }
 
 struct IntDynTypedVoidPointerTest1 {
-  void *vptr; // expected-note{{uninitialized pointee 'this->vptr'}}
+  void *vptr; // expected-note{{uninitialized pointee 'static_cast(this->vptr)'}}
   int dontGetFilteredByNonPedanticMode = 0;
 
   IntDynTypedVoidPointerTest1(void *vptr) : vptr(vptr) {} // 
expected-warning{{1 uninitialized field}}
@@ -305,8 +305,8 @@ void fIntDynTypedVoidPointerTest1() {
 
 struct RecordDynTypedVoidPointerTest {
   struct RecordType {
-int x; // expected-note{{uninitialized field 'this->vptr->x'}}
-int y; // expected-note{{uninitialized field 'this->vptr->y'}}
+int x; // expected-note{{uninitialized field 'static_cast(this->vptr)->x'}}
+int y; // expected-note{{uninitialized field 'static_cast(this->vptr)->y'}}
   };
 
   void *vptr;
@@ -322,9 +322,9 @@ void fRecordDynTypedVoidPointerTest() {
 
 struct NestedNonVoidDynTypedVoidPointerTest {
   struct RecordType {
-int x;  

r339655 - [analyzer] Made a buildbot happy.

2018-08-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Aug 14 01:38:35 2018
New Revision: 339655

URL: http://llvm.org/viewvc/llvm-project?rev=339655&view=rev
Log:
[analyzer] Made a buildbot happy.

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp?rev=339655&r1=339654&r2=339655&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 Tue Aug 14 01:38:35 2018
@@ -215,10 +215,12 @@ bool FindUninitializedFields::isPointerO
 llvm_unreachable("All cases are handled!");
   }
 
-  assert((isPrimitiveType(DynT->getPointeeType()) || DynT->isPointerType() ||
-  DynT->isReferenceType()) &&
+  // Temporary variable to avoid warning from -Wunused-function.
+  bool IsPrimitive = isPrimitiveType(DynT->getPointeeType());
+  assert((IsPrimitive || DynT->isAnyPointerType() || DynT->isReferenceType()) 
&&
  "At this point FR must either have a primitive dynamic type, or it "
  "must be a null, undefined, unknown or concrete pointer!");
+  (void)IsPrimitive;
 
   if (isPrimitiveUninit(DerefdV)) {
 if (NeedsCastBack)


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r340265 - [analyzer][UninitializedObjectChecker] Refactoring p6.: Move dereferencing to a function

2018-08-21 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Aug 21 03:45:21 2018
New Revision: 340265

URL: http://llvm.org/viewvc/llvm-project?rev=340265&view=rev
Log:
[analyzer][UninitializedObjectChecker] Refactoring p6.: Move dereferencing to a 
function

Now that it has it's own file, it makes little sense for
isPointerOrReferenceUninit to be this large, so I moved
dereferencing to a separate function.

Differential Revision: https://reviews.llvm.org/D50509

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=340265&r1=340264&r2=340265&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Tue Aug 21 03:45:21 2018
@@ -265,7 +265,8 @@ bool FindUninitializedFields::isNonUnion
   continue;
 }
 
-if (T->isAnyPointerType() || T->isReferenceType() || 
T->isBlockPointerType()) {
+if (T->isAnyPointerType() || T->isReferenceType() ||
+T->isBlockPointerType()) {
   if (isPointerOrReferenceUninit(FR, LocalChain))
 ContainsUninitField = true;
   continue;

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp?rev=340265&r1=340264&r2=340265&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 Tue Aug 21 03:45:21 2018
@@ -95,6 +95,12 @@ public:
 /// known, and thus FD can not be analyzed.
 static bool isVoidPointer(QualType T);
 
+/// Dereferences \p V and returns the value and dynamic type of the pointee, as
+/// well as wether \p FR needs to be casted back to that type. If for whatever
+/// reason dereferencing fails, returns with None.
+static llvm::Optional>
+dereference(ProgramStateRef State, const FieldRegion *FR);
+
 
//===--===//
 //   Methods for FindUninitializedFields.
 
//===--===//
@@ -126,67 +132,22 @@ bool FindUninitializedFields::isPointerO
 return false;
   }
 
-  assert(V.getAs() &&
- "At this point V must be loc::MemRegionVal!");
-  auto L = V.castAs();
-
-  // We can't reason about symbolic regions, assume its initialized.
-  // Note that this also avoids a potential infinite recursion, because
-  // constructors for list-like classes are checked without being called, and
-  // the Static Analyzer will construct a symbolic region for Node *next; or
-  // similar code snippets.
-  if (L.getRegion()->getSymbolicBase()) {
-IsAnyFieldInitialized = true;
-return false;
-  }
-
-  DynamicTypeInfo DynTInfo = getDynamicTypeInfo(State, L.getRegion());
-  if (!DynTInfo.isValid()) {
+  // At this point the pointer itself is initialized and points to a valid
+  // location, we'll now check the pointee.
+  llvm::Optional> DerefInfo =
+  dereference(State, FR);
+  if (!DerefInfo) {
 IsAnyFieldInitialized = true;
 return false;
   }
 
-  QualType DynT = DynTInfo.getType();
-
-  // If the static type of the field is a void pointer, we need to cast it back
-  // to the dynamic type before dereferencing.
-  bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType());
-
-  if (isVoidPointer(DynT)) {
-IsAnyFieldInitialized = true;
-return false;
-  }
-
-  // At this point the pointer itself is initialized and points to a valid
-  // location, we'll now check the pointee.
-  SVal DerefdV = State->getSVal(V.castAs(), DynT);
-
-  // If DerefdV is still a pointer value, we'll dereference it again (e.g.:
-  // int** -> int*).
-  while (auto Tmp = DerefdV.getAs()) {
-if (Tmp->getRegion()->getSymbolicBase()) {
-  IsAnyFieldInitialized = true;
-  return false;
-}
-
-DynTInfo = getDynamicTypeInfo(State, Tmp->getRegion());
-if (!DynTInfo.isValid()) {
-  IsAnyFieldInitialized = true;
-  return false;
-}
-
-DynT = DynTInfo.getType();
-if (isVoidPointer(DynT)) {
-  IsAnyFieldInitialized = true;
-  return false;
-}
-
-DerefdV = State->getSVal(*Tmp, DynT);
-  }
+  V = std::get<0>(*DerefInfo);
+  QualType DynT = std::get<1>(*Deref

r340266 - [analyzer][UninitializedObjectChecker] Added documentation to the checker list

2018-08-21 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Aug 21 03:47:19 2018
New Revision: 340266

URL: http://llvm.org/viewvc/llvm-project?rev=340266&view=rev
Log:
[analyzer][UninitializedObjectChecker] Added documentation to the checker list

Differential Revision: https://reviews.llvm.org/D50904

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
cfe/trunk/www/analyzer/alpha_checks.html

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=340266&r1=340265&r2=340266&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Tue Aug 21 03:47:19 2018
@@ -286,18 +286,6 @@ bool FindUninitializedFields::isNonUnion
   }
 
   // Checking bases.
-  // FIXME: As of now, because of `willObjectBeAnalyzedLater`, objects whose
-  // type is a descendant of another type will emit warnings for uninitalized
-  // inherited members.
-  // This is not the only way to analyze bases of an object -- if we didn't
-  // filter them out, and didn't analyze the bases, this checker would run for
-  // each base of the object in order of base initailization and in theory 
would
-  // find every uninitalized field. This approach could also make handling
-  // diamond inheritances more easily.
-  //
-  // This rule (that a descendant type's cunstructor is responsible for
-  // initializing inherited data members) is not obvious, and should it should
-  // be.
   const auto *CXXRD = dyn_cast(RD);
   if (!CXXRD)
 return ContainsUninitField;

Modified: cfe/trunk/www/analyzer/alpha_checks.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/alpha_checks.html?rev=340266&r1=340265&r2=340266&view=diff
==
--- cfe/trunk/www/analyzer/alpha_checks.html (original)
+++ cfe/trunk/www/analyzer/alpha_checks.html Tue Aug 21 03:47:19 2018
@@ -323,6 +323,118 @@ public:
 };
 
 
+
+
+alpha.cplusplus.UninitializedObject
+(C++)
+This checker reports uninitialized fields in objects created
+after a constructor call. It doesn't only find direct uninitialized
+fields, but rather makes a deep inspection of the object,
+analyzing all of it's fields subfields. 
+The checker regards inherited fields as direct fields, so one
+will recieve warnings for uninitialized inherited data members
+as well. 
+
+It has several options:
+
+  
+"Pedantic" (boolean). If its not set or is set to false, the 
checker
+won't emit warnings for objects that don't have at least one initialized
+field. This may be set with 
+-analyzer-config 
alpha.cplusplus.UninitializedObject:Pedantic=true.
+  
+  
+"NotesAsWarnings" (boolean). If set to true, the checker will 
emit a
+warning for each uninitalized field, as opposed to emitting one warning
+per constructor call, and listing the uninitialized fields that belongs
+to it in notes. Defaults to false. 
+-analyzer-config 
alpha.cplusplus.UninitializedObject:NotesAsWarnings=true.
+  
+  
+"CheckPointeeInitialization" (boolean). If set to false, the 
checker will
+not analyze the pointee of pointer/reference fields, and will only check
+whether the object itself is initialized. Defaults to false. 
+-analyzer-config 
alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true.
+  
+
+
+
+// With Pedantic and CheckPointeeInitialization set to true
+
+struct A {
+  struct B {
+int x; // note: uninitialized field 'this->b.x'
+   // note: uninitialized field 'this->bptr->x'
+int y; // note: uninitialized field 'this->b.y'
+   // note: uninitialized field 'this->bptr->y'
+  };
+  int *iptr; // note: uninitialized pointer 'this->iptr'
+  B b;
+  B *bptr;
+  char *cptr; // note: uninitialized pointee 'this->cptr'
+
+  A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+};
+
+void f() {
+  A::B b;
+  char c;
+  A a(&b, &c); // warning: 6 uninitialized fields
+   //  after the constructor call
+}
+
+
+// With Pedantic set to false and
+// CheckPointeeInitialization set to true
+// (every field is uninitialized)
+
+struct A {
+  struct B {
+int x;
+int y;
+  };
+  int *iptr;
+  B b;
+  B *bptr;
+  char *cptr;
+
+  A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+};
+
+void f() {
+  A::B b;
+  char c;
+  A a(&b, &c); // no warning
+}
+
+
+// With Pedantic and CheckPointeeInitialization set to false
+// (pointees are regarded as initialized)
+
+struct A {
+  struct B {
+int x; // note: uninitialized field 'this->b.x'
+int y; // note: uninitialized field 'this->b.y'
+  };
+  int *iptr; // note: uniniti

r340272 - [analyzer][UninitializedObjectChecker] Explicit namespace resolution for inherited data members

2018-08-21 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Aug 21 05:16:59 2018
New Revision: 340272

URL: http://llvm.org/viewvc/llvm-project?rev=340272&view=rev
Log:
[analyzer][UninitializedObjectChecker] Explicit namespace resolution for 
inherited data members

For the following example:

  struct Base {
int x;
  };

  // In a different translation unit

  struct Derived : public Base {
Derived() {}
  };

For a call to Derived::Derived(), we'll receive a note that
this->x is uninitialized. Since x is not a direct field of Derived,
it could be a little confusing. This patch aims to fix this, as well
as the case when the derived object has a field that has the name as
an inherited uninitialized data member:

  struct Base {
int x; // note: uninitialized field 'this->Base::x'
  };

  struct Derived : public Base {
int x = 5;
Derived() {}
  };

Differential Revision: https://reviews.llvm.org/D50905

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=340272&r1=340271&r2=340272&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Tue Aug 21 05:16:59 2018
@@ -32,10 +32,10 @@ class FieldNode {
 protected:
   const FieldRegion *FR;
 
-  ~FieldNode() = default;
+  /* non-virtual */ ~FieldNode() = default;
 
 public:
-  FieldNode(const FieldRegion *FR) : FR(FR) { assert(FR); }
+  FieldNode(const FieldRegion *FR) : FR(FR) {}
 
   FieldNode() = delete;
   FieldNode(const FieldNode &) = delete;
@@ -47,11 +47,21 @@ public:
   /// FoldingSet.
   void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(this); }
 
-  bool operator<(const FieldNode &Other) const { return FR < Other.FR; }
-  bool isSameRegion(const FieldRegion *OtherFR) const { return FR == OtherFR; }
+  // Helper method for uniqueing.
+  bool isSameRegion(const FieldRegion *OtherFR) const {
+// Special FieldNode descendants may wrap nullpointers -- we wouldn't like
+// to unique these objects.
+if (FR == nullptr)
+  return false;
+
+return FR == OtherFR;
+  }
 
   const FieldRegion *getRegion() const { return FR; }
-  const FieldDecl *getDecl() const { return FR->getDecl(); }
+  const FieldDecl *getDecl() const {
+assert(FR);
+return FR->getDecl();
+  }
 
   // When a fieldchain is printed (a list of FieldNode objects), it will have
   // the following format:
@@ -71,6 +81,8 @@ public:
   /// Print the separator. For example, fields may be separated with '.' or
   /// "->".
   virtual void printSeparator(llvm::raw_ostream &Out) const = 0;
+
+  virtual bool isBase() const { return false; }
 };
 
 /// Returns with Field's name. This is a helper function to get the correct 
name
@@ -94,15 +106,24 @@ private:
   FieldChain::Factory &ChainFactory;
   FieldChain Chain;
 
+  FieldChainInfo(FieldChain::Factory &F, FieldChain NewChain)
+  : FieldChainInfo(F) {
+Chain = NewChain;
+  }
+
 public:
   FieldChainInfo() = delete;
   FieldChainInfo(FieldChain::Factory &F) : ChainFactory(F) {}
   FieldChainInfo(const FieldChainInfo &Other) = default;
 
   template  FieldChainInfo add(const FieldNodeT &FN);
+  template  FieldChainInfo replaceHead(const FieldNodeT &FN);
 
   bool contains(const FieldRegion *FR) const;
+  bool isEmpty() const { return Chain.isEmpty(); }
+
   const FieldRegion *getUninitRegion() const;
+  const FieldNode &getHead() { return Chain.getHead(); }
   void printNoteMsg(llvm::raw_ostream &Out) const;
 };
 
@@ -250,6 +271,12 @@ inline FieldChainInfo FieldChainInfo::ad
   return NewChain;
 }
 
+template 
+inline FieldChainInfo FieldChainInfo::replaceHead(const FieldNodeT &FN) {
+  FieldChainInfo NewChain(ChainFactory, Chain.getTail());
+  return NewChain.add(FN);
+}
+
 } // end of namespace ento
 } // end of namespace clang
 

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=340272&r1=340271&r2=340272&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Tue Aug 21 05:16:59 2018
@@ -93,6 +93,33 @@ public:
   }
 };
 
+/// Represents that the FieldNode that comes after this is

r340280 - [analyzer] Correctly marked a virtual function 'override'

2018-08-21 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Aug 21 08:09:22 2018
New Revision: 340280

URL: http://llvm.org/viewvc/llvm-project?rev=340280&view=rev
Log:
[analyzer] Correctly marked a virtual function 'override'

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=340280&r1=340279&r2=340280&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Tue Aug 21 08:09:22 2018
@@ -117,7 +117,7 @@ public:
 
   virtual void printSeparator(llvm::raw_ostream &Out) const override {}
 
-  virtual bool isBase() const { return true; }
+  virtual bool isBase() const override { return true; }
 };
 
 } // end of anonymous namespace


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r333080 - Test commit

2018-05-23 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed May 23 05:48:55 2018
New Revision: 333080

URL: http://llvm.org/viewvc/llvm-project?rev=333080&view=rev
Log:
Test commit

Modified:
cfe/trunk/examples/PrintFunctionNames/CMakeLists.txt

Modified: cfe/trunk/examples/PrintFunctionNames/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/examples/PrintFunctionNames/CMakeLists.txt?rev=333080&r1=333079&r2=333080&view=diff
==
--- cfe/trunk/examples/PrintFunctionNames/CMakeLists.txt (original)
+++ cfe/trunk/examples/PrintFunctionNames/CMakeLists.txt Wed May 23 05:48:55 
2018
@@ -1,7 +1,7 @@
 # If we don't need RTTI or EH, there's no reason to export anything
 # from the plugin.
-if( NOT MSVC )  # MSVC mangles symbols differently, and
-# PrintFunctionNames.export contains C++ symbols.
+if( NOT MSVC ) # MSVC mangles symbols differently, and
+   # PrintFunctionNames.export contains C++ symbols.
   if( NOT LLVM_REQUIRES_RTTI )
 if( NOT LLVM_REQUIRES_EH )
   set(LLVM_EXPORTED_SYMBOL_FILE 
${CMAKE_CURRENT_SOURCE_DIR}/PrintFunctionNames.exports)


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r333275 - [analyzer] Added template argument lists to the Pathdiagnostic output

2018-05-25 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri May 25 06:18:38 2018
New Revision: 333275

URL: http://llvm.org/viewvc/llvm-project?rev=333275&view=rev
Log:
[analyzer] Added template argument lists to the Pathdiagnostic output

Because template parameter lists were not displayed
in the plist output, it was difficult to decide in
some cases whether a given checker found a true or a
false positive. This patch aims to correct this.

Differential Revision: https://reviews.llvm.org/D46933

Added:
cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp
cfe/trunk/test/Analysis/plist-diagnostics-template-record.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=333275&r1=333274&r2=333275&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Fri May 25 06:18:38 
2018
@@ -16,6 +16,7 @@
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/OperationKinds.h"
@@ -1000,11 +1001,49 @@ void PathDiagnosticCallPiece::setCallee(
 CalleeCtx->getAnalysisDeclContext()->isBodyAutosynthesized());
 }
 
+static void describeTemplateParameters(raw_ostream &Out,
+   const ArrayRef TAList,
+   const LangOptions &LO,
+   StringRef Prefix = StringRef(),
+   StringRef Postfix = StringRef());
+
+static void describeTemplateParameter(raw_ostream &Out,
+  const TemplateArgument &TArg,
+  const LangOptions &LO) {
+
+  if (TArg.getKind() == TemplateArgument::ArgKind::Pack) {
+describeTemplateParameters(Out, TArg.getPackAsArray(), LO);
+  } else {
+TArg.print(PrintingPolicy(LO), Out);
+  }
+}
+
+static void describeTemplateParameters(raw_ostream &Out,
+   const ArrayRef TAList,
+   const LangOptions &LO,
+   StringRef Prefix, StringRef Postfix) {
+  if (TAList.empty())
+return;
+
+  Out << Prefix;
+  for (int I = 0, Last = TAList.size() - 1; I != Last; ++I) {
+describeTemplateParameter(Out, TAList[I], LO);
+Out << ", ";
+  }
+  describeTemplateParameter(Out, TAList[TAList.size() - 1], LO);
+  Out << Postfix;
+}
+
 static void describeClass(raw_ostream &Out, const CXXRecordDecl *D,
   StringRef Prefix = StringRef()) {
   if (!D->getIdentifier())
 return;
-  Out << Prefix << '\'' << *D << '\'';
+  Out << Prefix << '\'' << *D;
+  if (const auto T = dyn_cast(D))
+describeTemplateParameters(Out, T->getTemplateArgs().asArray(),
+   D->getASTContext().getLangOpts(), "<", ">");
+
+  Out << '\'';
 }
 
 static bool describeCodeDecl(raw_ostream &Out, const Decl *D,
@@ -1062,7 +1101,16 @@ static bool describeCodeDecl(raw_ostream
 return true;
   }
 
-  Out << Prefix << '\'' << cast(*D) << '\'';
+  Out << Prefix << '\'' << cast(*D);
+
+  // Adding template parameters.
+  if (const auto FD = dyn_cast(D))
+if (const TemplateArgumentList *TAList =
+FD->getTemplateSpecializationArgs())
+  describeTemplateParameters(Out, TAList->asArray(),
+ FD->getASTContext().getLangOpts(), "<", ">");
+
+  Out << '\'';
   return true;
 }
 

Added: cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp?rev=333275&view=auto
==
--- cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp (added)
+++ cfe/trunk/test/Analysis/plist-diagnostics-template-function.cpp Fri May 25 
06:18:38 2018
@@ -0,0 +1,41 @@
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 
-analyzer-checker=core %s
+// RUN: FileCheck --input-file=%t.plist %s
+
+bool ret();
+
+template 
+void f(int i) {
+  if (ret())
+i = i / (i - 5);
+}
+
+template <>
+void f(int i) {
+  if (ret())
+i = i / (i - 5);
+}
+
+template 
+void defaultTemplateParameterFunction(int i) {
+  if (ret())
+int a = 10 / i;
+}
+
+template 
+void variadicTemplateFunction(int i) {
+  if (ret())
+int a = 10 / i;
+}
+
+int main() {
+  f(5);
+  f(5);
+  defaultTemplateParameterFunction<>(0);
+  variadicTemplateFunction(0);
+}
+
+// CHECK:  Calling 'f'
+// CHECK:  Calling 'f'
+// CHECK:  Calling 
'defaultTemplateParamet

r333278 - [analyzer] Added a getLValue method to ProgramState for bases

2018-05-25 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri May 25 07:48:33 2018
New Revision: 333278

URL: http://llvm.org/viewvc/llvm-project?rev=333278&view=rev
Log:
[analyzer] Added a getLValue method to ProgramState for bases

Differential Revision: https://reviews.llvm.org/D46891


Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h

Modified: 
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=333278&r1=333277&r2=333278&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h 
Fri May 25 07:48:33 2018
@@ -294,6 +294,13 @@ public:
   ProgramStateRef enterStackFrame(const CallEvent &Call,
   const StackFrameContext *CalleeCtx) const;
 
+  /// Get the lvalue for a base class object reference.
+  Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) 
const;
+
+  /// Get the lvalue for a base class object reference.
+  Loc getLValue(const CXXRecordDecl *BaseClass, const SubRegion *Super,
+bool IsVirtual) const;
+
   /// Get the lvalue for a variable reference.
   Loc getLValue(const VarDecl *D, const LocationContext *LC) const;
 
@@ -724,6 +731,22 @@ inline ProgramStateRef ProgramState::bin
   return this;
 }
 
+inline Loc ProgramState::getLValue(const CXXBaseSpecifier &BaseSpec,
+   const SubRegion *Super) const {
+  const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl();
+  return loc::MemRegionVal(
+   getStateManager().getRegionManager().getCXXBaseObjectRegion(
+Base, Super, 
BaseSpec.isVirtual()));
+}
+
+inline Loc ProgramState::getLValue(const CXXRecordDecl *BaseClass,
+   const SubRegion *Super,
+   bool IsVirtual) const {
+  return loc::MemRegionVal(
+   getStateManager().getRegionManager().getCXXBaseObjectRegion(
+  BaseClass, Super, 
IsVirtual));
+}
+
 inline Loc ProgramState::getLValue(const VarDecl *VD,
const LocationContext *LC) const {
   return getStateManager().StoreMgr->getLValueVar(VD, LC);


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342213 - [analyzer][UninitializedObjectChecker] Fixed dereferencing

2018-09-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 14 01:58:21 2018
New Revision: 342213

URL: http://llvm.org/viewvc/llvm-project?rev=342213&view=rev
Log:
[analyzer][UninitializedObjectChecker] Fixed dereferencing

iThis patch aims to fix derefencing, which has been debated for months now.

Instead of working with SVals, the function now relies on TypedValueRegion.

Differential Revision: https://reviews.llvm.org/D51057

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
cfe/trunk/test/Analysis/objcpp-uninitialized-object.mm

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=342213&r1=342212&r2=342213&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Fri Sep 14 01:58:21 2018
@@ -87,7 +87,7 @@ public:
 
 /// Returns with Field's name. This is a helper function to get the correct 
name
 /// even if Field is a captured lambda variable.
-StringRef getVariableName(const FieldDecl *Field);
+std::string getVariableName(const FieldDecl *Field);
 
 /// Represents a field chain. A field chain is a vector of fields where the
 /// first element of the chain is the object under checking (not stored), and
@@ -255,7 +255,13 @@ private:
 /// ease. This also helps ensuring that every special field type is handled
 /// correctly.
 inline bool isPrimitiveType(const QualType &T) {
-  return T->isBuiltinType() || T->isEnumeralType() || T->isMemberPointerType();
+  return T->isBuiltinType() || T->isEnumeralType() ||
+ T->isMemberPointerType() || T->isBlockPointerType() ||
+ T->isFunctionType();
+}
+
+inline bool isDereferencableType(const QualType &T) {
+  return T->isAnyPointerType() || T->isReferenceType();
 }
 
 // Template method definitions.

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=342213&r1=342212&r2=342213&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Fri Sep 14 01:58:21 2018
@@ -252,9 +252,12 @@ bool FindUninitializedFields::isNonUnion
  !R->getValueType()->isUnionType() &&
  "This method only checks non-union record objects!");
 
-  const RecordDecl *RD =
-  R->getValueType()->getAs()->getDecl()->getDefinition();
-  assert(RD && "Referred record has no definition");
+  const RecordDecl *RD = R->getValueType()->getAsRecordDecl()->getDefinition();
+
+  if (!RD) {
+IsAnyFieldInitialized = true;
+return true;
+  }
 
   bool ContainsUninitField = false;
 
@@ -292,8 +295,7 @@ bool FindUninitializedFields::isNonUnion
   continue;
 }
 
-if (T->isAnyPointerType() || T->isReferenceType() ||
-T->isBlockPointerType()) {
+if (isDereferencableType(T)) {
   if (isPointerOrReferenceUninit(FR, LocalChain))
 ContainsUninitField = true;
   continue;
@@ -487,7 +489,7 @@ static bool willObjectBeAnalyzedLater(co
   return false;
 }
 
-StringRef clang::ento::getVariableName(const FieldDecl *Field) {
+std::string clang::ento::getVariableName(const FieldDecl *Field) {
   // If Field is a captured lambda variable, Field->getName() will return with
   // an empty string. We can however acquire it's name from the lambda's
   // captures.
@@ -496,7 +498,16 @@ StringRef clang::ento::getVariableName(c
   if (CXXParent && CXXParent->isLambda()) {
 assert(CXXParent->captures_begin());
 auto It = CXXParent->captures_begin() + Field->getFieldIndex();
-return It->getCapturedVar()->getName();
+
+if (It->capturesVariable())
+  return llvm::Twine("/*captured variable*/" +
+ It->getCapturedVar()->getName())
+  .str();
+
+if (It->capturesThis())
+  return "/*'this' capture*/";
+
+llvm_unreachable("No other capture type is expected!");
   }
 
   return Field->getName();

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedP

r342215 - [analyzer][UninitializedObjectChecker] Updated comments

2018-09-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 14 02:07:40 2018
New Revision: 342215

URL: http://llvm.org/viewvc/llvm-project?rev=342215&view=rev
Log:
[analyzer][UninitializedObjectChecker] Updated comments

Some of the comments are incorrect, imprecise, or simply nonexistent.
Since I have a better grasp on how the analyzer works, it makes sense
to update most of them in a single swoop.

I tried not to flood the code with comments too much, this amount
feels just right to me.

Differential Revision: https://reviews.llvm.org/D51417

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=342215&r1=342214&r2=342215&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Fri Sep 14 02:07:40 2018
@@ -26,31 +26,36 @@
 namespace clang {
 namespace ento {
 
-/// Represent a single field. This is only an interface to abstract away 
special
-/// cases like pointers/references.
+/// A lightweight polymorphic wrapper around FieldRegion *. We'll use this
+/// interface to store addinitional information about fields. As described
+/// later, a list of these objects (i.e. "fieldchain") will be constructed and
+/// used for printing note messages should an uninitialized value be found.
 class FieldNode {
 protected:
   const FieldRegion *FR;
 
+  /// FieldNodes are never meant to be created on the heap, see
+  /// FindUninitializedFields::addFieldToUninits().
   /* non-virtual */ ~FieldNode() = default;
 
 public:
   FieldNode(const FieldRegion *FR) : FR(FR) {}
 
+  // We'll delete all of these special member functions to force the users of
+  // this interface to only store references to FieldNode objects in 
containers.
   FieldNode() = delete;
   FieldNode(const FieldNode &) = delete;
   FieldNode(FieldNode &&) = delete;
   FieldNode &operator=(const FieldNode &) = delete;
   FieldNode &operator=(const FieldNode &&) = delete;
 
-  /// Profile - Used to profile the contents of this object for inclusion in a
-  /// FoldingSet.
   void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(this); }
 
-  // Helper method for uniqueing.
+  /// Helper method for uniqueing.
   bool isSameRegion(const FieldRegion *OtherFR) const {
-// Special FieldNode descendants may wrap nullpointers -- we wouldn't like
-// to unique these objects.
+// Special FieldNode descendants may wrap nullpointers (for example if they
+// describe a special relationship between two elements of the fieldchain)
+// -- we wouldn't like to unique these objects.
 if (FR == nullptr)
   return false;
 
@@ -63,19 +68,22 @@ public:
 return FR->getDecl();
   }
 
-  // When a fieldchain is printed (a list of FieldNode objects), it will have
-  // the following format:
-  // 'this->...'
+  // When a fieldchain is printed, it will have the following format (without
+  // newline, indices are in order of insertion, from 1 to n):
+  //
+  // '...
+  //   this->...'
 
-  /// If this is the last element of the fieldchain, this method will be 
called.
+  /// If this is the last element of the fieldchain, this method will print the
+  /// note message associated with it.
   /// The note message should state something like "uninitialized field" or
   /// "uninitialized pointee" etc.
   virtual void printNoteMsg(llvm::raw_ostream &Out) const = 0;
 
-  /// Print any prefixes before the fieldchain.
+  /// Print any prefixes before the fieldchain. Could contain casts, etc.
   virtual void printPrefix(llvm::raw_ostream &Out) const = 0;
 
-  /// Print the node. Should contain the name of the field stored in getRegion.
+  /// Print the node. Should contain the name of the field stored in FR.
   virtual void printNode(llvm::raw_ostream &Out) const = 0;
 
   /// Print the separator. For example, fields may be separated with '.' or
@@ -89,14 +97,14 @@ public:
 /// even if Field is a captured lambda variable.
 std::string getVariableName(const FieldDecl *Field);
 
-/// Represents a field chain. A field chain is a vector of fields where the
-/// first element of the chain is the object under checking (not stored), and
-/// every other element is a field, and the element that precedes it is the
-/// object that contains it.
+/// Represents a field chain. A field chain is a list of fields where the first
+/// element of the chain is the object under checking (not stored), and every
+/// other element is a field, and t

r342217 - [analyzer][UninitializedObjectChecker] Correct dynamic type is acquired for record pointees

2018-09-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 14 02:13:36 2018
New Revision: 342217

URL: http://llvm.org/viewvc/llvm-project?rev=342217&view=rev
Log:
[analyzer][UninitializedObjectChecker] Correct dynamic type is acquired for 
record pointees

Differential Revision: https://reviews.llvm.org/D50892

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp?rev=342217&r1=342216&r2=342217&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 Fri Sep 14 02:13:36 2018
@@ -234,5 +234,13 @@ static llvm::Optional d
   break;
   }
 
+  while (R->getAs()) {
+NeedsCastBack = true;
+
+if (!isa(R->getSuperRegion()))
+  break;
+R = R->getSuperRegion()->getAs();
+  }
+
   return std::make_pair(R, NeedsCastBack);
 }

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp?rev=342217&r1=342216&r2=342217&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp Fri Sep 14 
02:13:36 2018
@@ -781,21 +781,53 @@ void fVirtualDiamondInheritanceTest3() {
 // Dynamic type test.
 
//===--===//
 
-struct DynTBase {};
-struct DynTDerived : DynTBase {
-  // TODO: we'd expect the note: {{uninitialized field 'this->x'}}
-  int x; // no-note
+struct DynTBase1 {};
+struct DynTDerived1 : DynTBase1 {
+  int y; // expected-note{{uninitialized field 'static_cast(this->bptr)->y'}}
 };
 
-struct DynamicTypeTest {
-  DynTBase *bptr;
+struct DynamicTypeTest1 {
+  DynTBase1 *bptr;
   int i = 0;
 
-  // TODO: we'd expect the warning: {{1 uninitialized field}}
-  DynamicTypeTest(DynTBase *bptr) : bptr(bptr) {} // no-warning
+  DynamicTypeTest1(DynTBase1 *bptr) : bptr(bptr) {} // expected-warning{{1 
uninitialized field}}
 };
 
-void f() {
-  DynTDerived d;
-  DynamicTypeTest t(&d);
+void fDynamicTypeTest1() {
+  DynTDerived1 d;
+  DynamicTypeTest1 t(&d);
 };
+
+struct DynTBase2 {
+  int x; // expected-note{{uninitialized field 'static_cast(this->bptr)->DynTBase2::x'}}
+};
+struct DynTDerived2 : DynTBase2 {
+  int y; // expected-note{{uninitialized field 'static_cast(this->bptr)->y'}}
+};
+
+struct DynamicTypeTest2 {
+  DynTBase2 *bptr;
+  int i = 0;
+
+  DynamicTypeTest2(DynTBase2 *bptr) : bptr(bptr) {} // expected-warning{{2 
uninitialized fields}}
+};
+
+void fDynamicTypeTest2() {
+  DynTDerived2 d;
+  DynamicTypeTest2 t(&d);
+}
+
+struct SymbolicSuperRegionBase {
+  SymbolicSuperRegionBase() {}
+};
+
+struct SymbolicSuperRegionDerived : SymbolicSuperRegionBase {
+  SymbolicSuperRegionBase *bptr; // no-crash
+  SymbolicSuperRegionDerived(SymbolicSuperRegionBase *bptr) : bptr(bptr) {}
+};
+
+SymbolicSuperRegionDerived *getSymbolicRegion();
+
+void fSymbolicSuperRegionTest() {
+  SymbolicSuperRegionDerived test(getSymbolicRegion());
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342219 - [analyzer][UninitializedObjectChecker] Refactored checker options

2018-09-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 14 02:39:26 2018
New Revision: 342219

URL: http://llvm.org/viewvc/llvm-project?rev=342219&view=rev
Log:
[analyzer][UninitializedObjectChecker] Refactored checker options

Since I plan to add a number of new flags, it made sense to encapsulate
them in a new struct, in order not to pollute FindUninitializedFields's
constructor with new boolean options with super long names.

This revision practically reverts D50508, since FindUninitializedFields
now accesses the pedantic flag anyways.

Differential Revision: https://reviews.llvm.org/D51679

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=342219&r1=342218&r2=342219&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Fri Sep 14 02:39:26 2018
@@ -10,8 +10,39 @@
 // This file defines helper classes for UninitializedObjectChecker and
 // documentation about the logic of it.
 //
-// To read about command line options and a description what this checker does,
-// refer to UninitializedObjectChecker.cpp.
+// The checker reports uninitialized fields in objects created after a
+// constructor call.
+//
+// This checker has several options:
+//   - "Pedantic" (boolean). If its not set or is set to false, the checker
+// won't emit warnings for objects that don't have at least one initialized
+// field. This may be set with
+//
+// `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`.
+//
+//   - "NotesAsWarnings" (boolean). If set to true, the checker will emit a
+// warning for each uninitalized field, as opposed to emitting one warning
+// per constructor call, and listing the uninitialized fields that belongs
+// to it in notes. Defaults to false.
+//
+// `-analyzer-config \
+// alpha.cplusplus.UninitializedObject:NotesAsWarnings=true`.
+//
+//   - "CheckPointeeInitialization" (boolean). If set to false, the checker 
will
+// not analyze the pointee of pointer/reference fields, and will only check
+// whether the object itself is initialized. Defaults to false.
+//
+// `-analyzer-config \
+// 
alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true`.
+//
+// TODO: With some clever heuristics, some pointers should be dereferenced
+// by default. For example, if the pointee is constructed within the
+// constructor call, it's reasonable to say that no external object
+// references it, and we wouldn't generate multiple report on the same
+// pointee.
+//
+// Most of the following methods as well as the checker itself is defined in
+// UninitializedObjectChecker.cpp.
 //
 // Some methods are implemented in UninitializedPointee.cpp, to reduce the
 // complexity of the main checker file.
@@ -26,6 +57,12 @@
 namespace clang {
 namespace ento {
 
+struct UninitObjCheckerOptions {
+  bool IsPedantic = false;
+  bool ShouldConvertNotesToWarnings = false;
+  bool CheckPointeeInitialization =  false;
+};
+
 /// A lightweight polymorphic wrapper around FieldRegion *. We'll use this
 /// interface to store addinitional information about fields. As described
 /// later, a list of these objects (i.e. "fieldchain") will be constructed and
@@ -147,7 +184,7 @@ class FindUninitializedFields {
   ProgramStateRef State;
   const TypedValueRegion *const ObjectR;
 
-  const bool CheckPointeeInitialization;
+  const UninitObjCheckerOptions Opts;
   bool IsAnyFieldInitialized = false;
 
   FieldChainInfo::FieldChain::Factory ChainFactory;
@@ -169,7 +206,7 @@ public:
   /// uninitialized fields in R.
   FindUninitializedFields(ProgramStateRef State,
   const TypedValueRegion *const R,
-  bool CheckPointeeInitialization);
+  const UninitObjCheckerOptions &Opts);
 
   const UninitFieldMap &getUninitFields() { return UninitFields; }
 

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=342219&r1=342218&r2=342219&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/Uninitial

r342220 - [analyzer][UninitializedObjectChecker] New flag to ignore records based on it's fields

2018-09-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 14 03:10:09 2018
New Revision: 342220

URL: http://llvm.org/viewvc/llvm-project?rev=342220&view=rev
Log:
[analyzer][UninitializedObjectChecker] New flag to ignore records based on it's 
fields

Based on a suggestion from @george.karpenkov.

In some cases, structs are used as unions with a help of a tag/kind field.
This patch adds a new string flag (a pattern), that is matched against the
fields of a record, and should a match be found, the entire record is ignored.

For more info refer to 
http://lists.llvm.org/pipermail/cfe-dev/2018-August/058906.html
and to the responses to that, especially 
http://lists.llvm.org/pipermail/cfe-dev/2018-August/059215.html.

Differential Revision: https://reviews.llvm.org/D51680

Added:
cfe/trunk/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp
Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
cfe/trunk/www/analyzer/alpha_checks.html

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=342220&r1=342219&r2=342220&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Fri Sep 14 03:10:09 2018
@@ -35,6 +35,13 @@
 // `-analyzer-config \
 // 
alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true`.
 //
+//   - "IgnoreRecordsWithField" (string). If supplied, the checker will not
+// analyze structures that have a field with a name or type name that
+// matches the given pattern. Defaults to "".
+//
+// `-analyzer-config \
+// 
alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"`.
+//
 // TODO: With some clever heuristics, some pointers should be dereferenced
 // by default. For example, if the pointee is constructed within the
 // constructor call, it's reasonable to say that no external object
@@ -60,7 +67,8 @@ namespace ento {
 struct UninitObjCheckerOptions {
   bool IsPedantic = false;
   bool ShouldConvertNotesToWarnings = false;
-  bool CheckPointeeInitialization =  false;
+  bool CheckPointeeInitialization = false;
+  std::string IgnoredRecordsWithFieldPattern;
 };
 
 /// A lightweight polymorphic wrapper around FieldRegion *. We'll use this

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=342220&r1=342219&r2=342220&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Fri Sep 14 03:10:09 2018
@@ -109,6 +109,10 @@ getObjectVal(const CXXConstructorDecl *C
 static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
   CheckerContext &Context);
 
+/// Checks whether RD contains a field with a name or type name that matches
+/// \p Pattern.
+static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern);
+
 
//===--===//
 //  Methods for UninitializedObjectChecker.
 
//===--===//
@@ -228,6 +232,12 @@ bool FindUninitializedFields::isNonUnion
 return true;
   }
 
+  if (!Opts.IgnoredRecordsWithFieldPattern.empty() &&
+  shouldIgnoreRecord(RD, Opts.IgnoredRecordsWithFieldPattern)) {
+IsAnyFieldInitialized = true;
+return false;
+  }
+
   bool ContainsUninitField = false;
 
   // Are all of this non-union's fields initialized?
@@ -442,6 +452,19 @@ static bool willObjectBeAnalyzedLater(co
   return false;
 }
 
+static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern) {
+  llvm::Regex R(Pattern);
+
+  for (const FieldDecl *FD : RD->fields()) {
+if (R.match(FD->getType().getAsString()))
+  return true;
+if (R.match(FD->getName()))
+  return true;
+  }
+
+  return false;
+}
+
 std::string clang::ento::getVariableName(const FieldDecl *Field) {
   // If Field is a captured lambda variable, Field->getName() will return with
   // an empty string. We can however acquire it's name from the lambda's
@@ -472,10 +495,13 @@ void ento::registerUninitializedObjectCh
   AnalyzerOptions &AnOpts = Mgr.getAnalyzerOptions();
   UninitObjCheckerOptions &ChOpts = Chk->Opts;
 
-  ChOpts.IsPedantic = A

r342221 - [analyzer][UninitializedObjectChecker] Support for nonloc::LocAsInteger

2018-09-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 14 03:18:26 2018
New Revision: 342221

URL: http://llvm.org/viewvc/llvm-project?rev=342221&view=rev
Log:
[analyzer][UninitializedObjectChecker] Support for nonloc::LocAsInteger

Differential Revision: https://reviews.llvm.org/D49437

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=342221&r1=342220&r2=342221&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Fri Sep 14 03:18:26 2018
@@ -274,15 +274,15 @@ bool FindUninitializedFields::isNonUnion
   continue;
 }
 
-if (isDereferencableType(T)) {
+SVal V = State->getSVal(FieldVal);
+
+if (isDereferencableType(T) || V.getAs()) {
   if (isDereferencableUninit(FR, LocalChain))
 ContainsUninitField = true;
   continue;
 }
 
 if (isPrimitiveType(T)) {
-  SVal V = State->getSVal(FieldVal);
-
   if (isPrimitiveUninit(V)) {
 if (addFieldToUninits(LocalChain.add(RegularField(FR
   ContainsUninitField = true;

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp?rev=342221&r1=342220&r2=342221&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 Fri Sep 14 03:18:26 2018
@@ -57,9 +57,9 @@ public:
   }
 };
 
-/// Represents a void* field that needs to be casted back to its dynamic type
-/// for a correct note message.
-class NeedsCastLocField final : public FieldNode {
+/// Represents a nonloc::LocAsInteger or void* field, that point to objects, 
but
+/// needs to be casted back to its dynamic type for a correct note message.
+class NeedsCastLocField : public FieldNode {
   QualType CastBackType;
 
 public:
@@ -71,7 +71,13 @@ public:
   }
 
   virtual void printPrefix(llvm::raw_ostream &Out) const override {
-Out << "static_cast" << '<' << CastBackType.getAsString() << ">(";
+// If this object is a nonloc::LocAsInteger.
+if (getDecl()->getType()->isIntegerType())
+  Out << "reinterpret_cast";
+// If this pointer's dynamic type is different then it's static type.
+else
+  Out << "static_cast";
+Out << '<' << CastBackType.getAsString() << ">(";
   }
 
   virtual void printNode(llvm::raw_ostream &Out) const override {
@@ -106,11 +112,12 @@ static llvm::Optional d
 bool FindUninitializedFields::isDereferencableUninit(
 const FieldRegion *FR, FieldChainInfo LocalChain) {
 
-  assert(isDereferencableType(FR->getDecl()->getType()) &&
- "This method only checks dereferencable objects!");
-
   SVal V = State->getSVal(FR);
 
+  assert((isDereferencableType(FR->getDecl()->getType()) ||
+  V.getAs()) &&
+ "This method only checks dereferencable objects!");
+
   if (V.isUnknown() || V.getAs()) {
 IsAnyFieldInitialized = true;
 return false;
@@ -196,13 +203,15 @@ static llvm::Optional d
 
   llvm::SmallSet VisitedRegions;
 
-  // If the static type of the field is a void pointer, we need to cast it back
-  // to the dynamic type before dereferencing.
-  bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType());
-
   SVal V = State->getSVal(FR);
   assert(V.getAsRegion() && "V must have an underlying region!");
 
+  // If the static type of the field is a void pointer, or it is a
+  // nonloc::LocAsInteger, we need to cast it back to the dynamic type before
+  // dereferencing.
+  bool NeedsCastBack = isVoidPointer(FR->getDecl()->getType()) ||
+   V.getAs();
+
   // The region we'd like to acquire.
   const auto *R = V.getAsRegion()->getAs();
   if (!R)

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp?rev=342221&r1=342220&r2=342221&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp Fri Sep 14 
03:18:26 2018
@@ -22,6 +22,24 @@ void fConcreteInt

r342223 - [analyzer] Attempt to make a windows buildbot happy.

2018-09-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 14 04:20:16 2018
New Revision: 342223

URL: http://llvm.org/viewvc/llvm-project?rev=342223&view=rev
Log:
[analyzer] Attempt to make a windows buildbot happy.

Got an error that a cast is happening from a pointer type to long, which is
smaller.

Modified:
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp?rev=342223&r1=34&r2=342223&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp Fri Sep 14 
04:20:16 2018
@@ -25,7 +25,7 @@ void fConcreteIntLocTest() {
 // nonloc::LocAsInteger tests.
 
//===--===//
 
-using intptr_t = long;
+using intptr_t = unsigned long long;
 
 struct LocAsIntegerTest {
   intptr_t ptr; // expected-note{{uninitialized pointee 'reinterpret_cast(this->ptr)'}}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r334935 - [analyzer] Checker for uninitialized C++ objects

2018-06-18 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Jun 18 04:50:17 2018
New Revision: 334935

URL: http://llvm.org/viewvc/llvm-project?rev=334935&view=rev
Log:
[analyzer] Checker for uninitialized C++ objects

This checker analyzes C++ constructor calls, and reports uninitialized fields.

Due to the nature of this problem (uninitialized fields after an object
construction), this checker doesn't search for bugs, but rather is a tool to
enforce a specific programming model where every field needs to be initialized.

This checker lands in alpha for now, and a number of followup patches will be
made to reduce false negatives and to make it easier for the user to understand
what rules the checker relies on, eg. whether a derived class' constructor is
responsible for initializing inherited data members or whether it should be
handled in the base class' constructor.

Differential Revision: https://reviews.llvm.org/D45532

Added:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp

cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-cxx-uninitialized-object.h
cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=334935&r1=334934&r2=334935&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Mon Jun 18 
04:50:17 2018
@@ -319,6 +319,10 @@ def MisusedMovedObjectChecker: Checker<"
   "object will be reported">,
  DescFile<"MisusedMovedObjectChecker.cpp">;
 
+def UninitializedObjectChecker: Checker<"UninitializedObject">,
+ HelpText<"Reports uninitialized fields after object construction">,
+ DescFile<"UninitializedObjectChecker.cpp">;
+
 } // end: "alpha.cplusplus"
 
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=334935&r1=334934&r2=334935&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Mon Jun 18 04:50:17 
2018
@@ -92,6 +92,7 @@ add_clang_library(clangStaticAnalyzerChe
   UndefResultChecker.cpp
   UndefinedArraySubscriptChecker.cpp
   UndefinedAssignmentChecker.cpp
+  UninitializedObjectChecker.cpp
   UnixAPIChecker.cpp
   UnreachableCodeChecker.cpp
   VforkChecker.cpp

Added: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp?rev=334935&view=auto
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp (added)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp Mon 
Jun 18 04:50:17 2018
@@ -0,0 +1,669 @@
+//===- UninitializedObjectChecker.cpp *- 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 a checker that reports uninitialized fields in objects
+// created after a constructor call.
+//
+// This checker has an option "Pedantic" (boolean). If its not set or is set to
+// false, the checker won't emit warnings for objects that don't have at least
+// one initialized field. This may be set with
+// `-analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true`.
+//
+//===--===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include 
+
+using namespace clang;
+using namespace clang::ento;
+
+namespace {
+
+class UninitializedObjectChecker : public Checker {
+  std::unique_ptr BT_uninitField;
+
+public:
+  bool IsPedantic; // Will be initialized when registering the checker.
+
+  UninitializedObjectChecker()
+  : BT_uninitField(new BuiltinBug(this, "Uninitialized fields")) {}
+  void checkEndFunction(CheckerContext &C) const;
+};
+
+llvm::ImmutableListFactory Factory;
+
+/// Represents a field chain. A field chain is a vector of fields where 

r335030 - [analyzer] Made a buildbot happy.

2018-06-19 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Jun 19 01:35:02 2018
New Revision: 335030

URL: http://llvm.org/viewvc/llvm-project?rev=335030&view=rev
Log:
[analyzer] Made a buildbot happy.

Since `isPrimitiveType` was only used in an assert, a builbot with `-Werror`
and no asserts enabled failed to build it as it was unused.

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp?rev=335030&r1=335029&r2=335030&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp Tue 
Jun 19 01:35:02 2018
@@ -384,15 +384,17 @@ bool FindUninitializedFields::isNonUnion
   continue;
 }
 
-assert(isPrimitiveType(T) && "Non-primitive type! "
- "At this point FR must be primitive!");
+if (isPrimitiveType(T)) {
+  SVal V = State->getSVal(FieldVal);
 
-SVal V = State->getSVal(FieldVal);
-
-if (isPrimitiveUninit(V)) {
-  if (addFieldToUninits({LocalChain, FR}))
-ContainsUninitField = true;
+  if (isPrimitiveUninit(V)) {
+if (addFieldToUninits({LocalChain, FR}))
+  ContainsUninitField = true;
+  }
+  continue;
 }
+
+llvm_unreachable("All cases are handled!");
   }
 
   // Checking bases.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r344242 - [analyzer][UninitializedObjectChecker] Reports Loc fields pointing to themselves

2018-10-11 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Oct 11 04:58:53 2018
New Revision: 344242

URL: http://llvm.org/viewvc/llvm-project?rev=344242&view=rev
Log:
[analyzer][UninitializedObjectChecker] Reports Loc fields pointing to themselves

I've added a new functionality, the checker is now able to
detect and report fields pointing to themselves. I figured
this would fit well into the checker as there's no reason
for a pointer to point to itself instead of being nullptr.

Differential Revision: https://reviews.llvm.org/D51305

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp?rev=344242&r1=344241&r2=344242&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
 Thu Oct 11 04:58:53 2018
@@ -89,15 +89,39 @@ public:
   }
 };
 
+/// Represents a Loc field that points to itself.
+class CyclicLocField final : public FieldNode {
+
+public:
+  CyclicLocField(const FieldRegion *FR) : FieldNode(FR) {}
+
+  virtual void printNoteMsg(llvm::raw_ostream &Out) const override {
+Out << "object references itself ";
+  }
+
+  virtual void printPrefix(llvm::raw_ostream &Out) const override {}
+
+  virtual void printNode(llvm::raw_ostream &Out) const override {
+Out << getVariableName(getDecl());
+  }
+
+  virtual void printSeparator(llvm::raw_ostream &Out) const override {
+llvm_unreachable("CyclicLocField objects must be the last node of the "
+ "fieldchain!");
+  }
+};
+
 } // end of anonymous namespace
 
 // Utility function declarations.
 
-/// Returns whether \p T can be (transitively) dereferenced to a void pointer
-/// type (void*, void**, ...).
-static bool isVoidPointer(QualType T);
-
-using DereferenceInfo = std::pair;
+struct DereferenceInfo {
+  const TypedValueRegion *R;
+  const bool NeedsCastBack;
+  const bool IsCyclic;
+  DereferenceInfo(const TypedValueRegion *R, bool NCB, bool IC)
+  : R(R), NeedsCastBack(NCB), IsCyclic(IC) {}
+};
 
 /// Dereferences \p FR and returns with the pointee's region, and whether it
 /// needs to be casted back to it's location type. If for whatever reason
@@ -105,6 +129,10 @@ using DereferenceInfo = std::pair dereference(ProgramStateRef State,
const FieldRegion *FR);
 
+/// Returns whether \p T can be (transitively) dereferenced to a void pointer
+/// type (void*, void**, ...).
+static bool isVoidPointer(QualType T);
+
 
//===--===//
 //   Methods for FindUninitializedFields.
 
//===--===//
@@ -141,8 +169,11 @@ bool FindUninitializedFields::isDerefere
 return false;
   }
 
-  const TypedValueRegion *R = DerefInfo->first;
-  const bool NeedsCastBack = DerefInfo->second;
+  if (DerefInfo->IsCyclic)
+return addFieldToUninits(LocalChain.add(CyclicLocField(FR)));
+
+  const TypedValueRegion *R = DerefInfo->R;
+  const bool NeedsCastBack = DerefInfo->NeedsCastBack;
 
   QualType DynT = R->getLocationType();
   QualType PointeeT = DynT->getPointeeType();
@@ -189,15 +220,6 @@ bool FindUninitializedFields::isDerefere
 //   Utility functions.
 
//===--===//
 
-static bool isVoidPointer(QualType T) {
-  while (!T.isNull()) {
-if (T->isVoidPointerType())
-  return true;
-T = T->getPointeeType();
-  }
-  return false;
-}
-
 static llvm::Optional dereference(ProgramStateRef State,
const FieldRegion *FR) {
 
@@ -229,9 +251,8 @@ static llvm::Optional d
   return None;
 
 // We found a cyclic pointer, like int *ptr = (int *)&ptr.
-// TODO: Should we report these fields too?
 if (!VisitedRegions.insert(R).second)
-  return None;
+  return DereferenceInfo{R, NeedsCastBack, /*IsCyclic*/ true};
 
 DynT = R->getLocationType();
 // In order to ensure that this loop terminates, we're also checking the
@@ -248,5 +269,14 @@ static llvm::Optional d
 R = R->getSuperRegion()->getAs();
   }
 
-  return std::make_pair(R, NeedsCastBack);
+  return DereferenceInfo{R, NeedsCastBack, /*IsCyclic*/ false};
+}
+
+static bool isVoidPointer(QualType T) {
+  while (!T.isNull()) {
+if (T->isVoidPointerType())
+  return true;
+T = T->getPointeeType();
+  }
+  return false;
 }

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
URL: 
ht

r344870 - [analyzer][NFC] Fix inconsistencies in AnalyzerOptions

2018-10-21 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Oct 21 11:19:32 2018
New Revision: 344870

URL: http://llvm.org/viewvc/llvm-project?rev=344870&view=rev
Log:
[analyzer][NFC] Fix inconsistencies in AnalyzerOptions

I'm in the process of refactoring AnalyzerOptions. The main motivation behind
here is to emit warnings if an invalid -analyzer-config option is given from the
command line, and be able to list them all.

This first NFC patch contains small modifications to make AnalyzerOptions.cpp a
little more consistent.

Differential Revision: https://reviews.llvm.org/D53274

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp

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=344870&r1=344869&r2=344870&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Sun Oct 21 
11:19:32 2018
@@ -85,7 +85,7 @@ enum CXXInlineableMemberKind {
   // Uninitialized = 0,
 
   /// A dummy mode in which no C++ inlining is enabled.
-  CIMK_None = 1,
+  CIMK_None,
 
   /// Refers to regular member function and operator calls.
   CIMK_MemberFunctions,
@@ -102,8 +102,6 @@ enum CXXInlineableMemberKind {
 
 /// Describes the different modes of inter-procedural analysis.
 enum IPAKind {
-  IPAK_NotSet = 0,
-
   /// Perform only intra-procedural analysis.
   IPAK_None = 1,
 
@@ -188,16 +186,11 @@ public:
 UnexploredFirstQueue,
 UnexploredFirstLocationQueue,
 BFSBlockDFSContents,
-NotSet
   };
 
 private:
-  ExplorationStrategyKind ExplorationStrategy = 
ExplorationStrategyKind::NotSet;
-
   /// Describes the kinds for high-level analyzer mode.
   enum UserModeKind {
-UMK_NotSet = 0,
-
 /// Perform shallow but fast analyzes.
 UMK_Shallow = 1,
 
@@ -205,16 +198,18 @@ private:
 UMK_Deep = 2
   };
 
+  llvm::Optional ExplorationStrategy;
+
   /// Controls the high-level analyzer mode, which influences the default
   /// settings for some of the lower-level config options (such as IPAMode).
   /// \sa getUserMode
-  UserModeKind UserMode = UMK_NotSet;
+  llvm::Optional UserMode;
 
   /// Controls the mode of inter-procedural analysis.
-  IPAKind IPAMode = IPAK_NotSet;
+  llvm::Optional IPAMode;
 
   /// Controls which C++ member functions will be considered for inlining.
-  CXXInlineableMemberKind CXXMemberInliningMode;
+  llvm::Optional CXXMemberInliningMode;
 
   /// \sa includeImplicitDtorsInCFG
   Optional IncludeImplicitDtorsInCFG;
@@ -420,6 +415,12 @@ public:
  const ento::CheckerBase *C = nullptr,
  bool SearchInParents = false);
 
+
+  unsigned getOptionAsUInt(Optional &V, StringRef Name,
+   unsigned 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.
@@ -437,6 +438,11 @@ public:
   const ento::CheckerBase *C = nullptr,
   bool SearchInParents = false);
 
+  StringRef getOptionAsString(Optional &V, StringRef Name,
+  StringRef DefaultVal,
+  const ento::CheckerBase *C = nullptr,
+  bool SearchInParents = false);
+
   /// Retrieves and sets the UserMode. This is a high-level option,
   /// which is used to set other low-level options. It is not accessible
   /// outside of AnalyzerOptions.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=344870&r1=344869&r2=344870&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Sun Oct 21 11:19:32 
2018
@@ -50,27 +50,24 @@ AnalyzerOptions::getRegisteredCheckers(b
 }
 
 AnalyzerOptions::UserModeKind AnalyzerOptions::getUserMode() {
-  if (UserMode == UMK_NotSet) {
-StringRef ModeStr =
-Config.insert(std::make_pair("mode", "deep")).first->second;
-UserMode = llvm::StringSwitch(ModeStr)
+  if (!UserMode.hasValue()) {
+StringRef ModeStr = getOptionAsString("mode", "deep");
+UserMode = llvm::StringSwitch>(ModeStr)
   .Case("shallow", UMK_Shallow)
   .Case("deep", UMK_Deep)
-  .Default(UMK_NotSet);
-assert(UserMode != UMK_NotSet && "User mode is invalid.");
+  .Default(None);
+assert(UserMode.getValue() && "User mode is in

r344878 - [analyzer][www] Update alpha_checks.html

2018-10-21 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Oct 21 15:10:15 2018
New Revision: 344878

URL: http://llvm.org/viewvc/llvm-project?rev=344878&view=rev
Log:
[analyzer][www] Update alpha_checks.html

I added some missing doc. I have not developed any of these checkers, it might 
worth really inspecting whether I wrote something terribly incorrect.

Differential Revision: https://reviews.llvm.org/D52969

Modified:
cfe/trunk/www/analyzer/alpha_checks.html
cfe/trunk/www/analyzer/available_checks.html

Modified: cfe/trunk/www/analyzer/alpha_checks.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/alpha_checks.html?rev=344878&r1=344877&r2=344878&view=diff
==
--- cfe/trunk/www/analyzer/alpha_checks.html (original)
+++ cfe/trunk/www/analyzer/alpha_checks.html Sun Oct 21 15:10:15 2018
@@ -107,6 +107,7 @@ void test(void) {
 }
 
 
+
 
 alpha.core.CastSize
 (C)
@@ -276,6 +277,33 @@ int test(struct s *p) {
 
 
 
+alpha.core.StackAddressAsyncEscape
+(C)
+Check that addresses to stack memory do not escape the function that involves
+dispatch_after or dispatch_async. This checker is
+a part of core.StackAddressEscape, but is
+https://reviews.llvm.org/D41042>temporarily disabled until some
+false positives are fixed.
+
+
+dispatch_block_t test_block_inside_block_async_leak() {
+  int x = 123;
+  void (^inner)(void) = ^void(void) {
+int y = x;
+++y; 
+  };
+  void (^outer)(void) = ^void(void) {
+int z = x;
+++z;
+inner(); 
+  }; 
+  return outer; // warn: address of stack-allocated block is captured by a
+//   returned block
+}
+
+
+
+
 alpha.core.TestAfterDivZero
 (C, C++, ObjC)
 Check for division by variable that is later compared against 0. 
@@ -289,6 +317,7 @@ void test(int x) {
 }
 
 
+
 
 
 
@@ -296,72 +325,142 @@ void test(int x) {
 
 
 Name, DescriptionExample
-
 
+
+
 
-alpha.cplusplus.VirtualCall
+alpha.cplusplus.DeleteWithNonVirtualDtor
 (C++)
-Check virtual member function calls during construction or 
-destruction.
+Reports destructions of polymorphic objects with a non-virtual destructor in
+their base class
+
 
 
-class A {
-public:
-  A() { 
-f(); // warn
-  }
-  virtual void f();
-};
-
+NonVirtual *create() {
+  NonVirtual *x = new NVDerived(); // note: conversion from derived to base
+   //   happened here
+  return x;
+}
+
+void sink(NonVirtual *x) {
+  delete x; // warn: destruction of a polymorphic object with no virtual
+//   destructor
+}
+
+
+
+
+alpha.cplusplus.InvalidatedIterator
+(C++)
+Check for use of invalidated iterators.
+
+
 
-class A {
-public:
-  ~A() {
-this->f(); // warn
-  }
-  virtual void f();
+void bad_copy_assign_operator_list1(std::list &L1,
+const std::list &L2) {
+  auto i0 = L1.cbegin();
+  L1 = L2;
+  *i0; // warn: invalidated iterator accessed
+}
+
+
+
+
+alpha.cplusplus.IteratorRange
+(C++)
+Check for iterators used outside their valid ranges.
+
+
+
+void simple_bad_end(const std::vector &v) {
+  auto i = v.end();
+  *i; // warn: iterator accessed outside of its range
+}
+
+
+
+
+alpha.cplusplus.MismatchedIterator
+(C++)
+Check for use of iterators of different containers where iterators of the same
+container are expected.
+
+
+
+void bad_insert3(std::vector &v1, std::vector &v2) {
+  v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // warn: container accessed
+  //   using foreign
+  //   iterator argument
+  v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // warn: iterators of
+  //   different containers
+  //   used where the same
+  //   container is
+  //   expected
+  v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // warn: iterators of
+  //   different containers
+  //   used where the same
+  //   container is
+  //   expected
+}
+
+
+
+
+alpha.cplusplus.MisusedMovedObject
+(C++)
+Method calls on a moved-from object and copying a moved-from object will be
+reported.
+
+
+
+struct A {
+  void foo() {}
 };
+
+void f() {
+  A a;
+  A b = std::move(a); // note: 'a' became 'moved-from' here
+  a.foo();// warn: method call on a 'moved-from' object 'a'
+}
 
 
-
+
 
 alpha.cplusplus.UninitializedObject
 (C++)
-This checker reports uninitialized fields in objects created
-after a constructor call. It doesn't only find direct uninitialized
-fields, but rather makes a deep inspection of the object,
-analyzing all of it's fields subfields.

r344879 - [analyzer][UninitializedObjectChecker] No longer using nonloc::LazyCompoundVal

2018-10-21 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Oct 21 16:30:01 2018
New Revision: 344879

URL: http://llvm.org/viewvc/llvm-project?rev=344879&view=rev
Log:
[analyzer][UninitializedObjectChecker] No longer using nonloc::LazyCompoundVal

As rightly pointed out by @NoQ, nonloc::LazyCompoundVals were only used to 
acquire a constructed object's region, which isn't what LazyCompoundVal was 
made for.

Differential Revision: https://reviews.llvm.org/D51300

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=344879&r1=344878&r2=344879&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Sun Oct 21 16:30:01 2018
@@ -96,12 +96,11 @@ public:
 
 // Utility function declarations.
 
-/// Returns the object that was constructed by CtorDecl, or None if that isn't
-/// possible.
-// TODO: Refactor this function so that it returns the constructed object's
-// region.
-static Optional
-getObjectVal(const CXXConstructorDecl *CtorDecl, CheckerContext &Context);
+/// Returns the region that was constructed by CtorDecl, or nullptr if that
+/// isn't possible.
+static const TypedValueRegion *
+getConstructedRegion(const CXXConstructorDecl *CtorDecl,
+ CheckerContext &Context);
 
 /// Checks whether the object constructed by \p Ctor will be analyzed later
 /// (e.g. if the object is a field of another object, in which case we'd check
@@ -135,11 +134,11 @@ void UninitializedObjectChecker::checkEn
   if (willObjectBeAnalyzedLater(CtorDecl, Context))
 return;
 
-  Optional Object = getObjectVal(CtorDecl, Context);
-  if (!Object)
+  const TypedValueRegion *R = getConstructedRegion(CtorDecl, Context);
+  if (!R)
 return;
 
-  FindUninitializedFields F(Context.getState(), Object->getRegion(), Opts);
+  FindUninitializedFields F(Context.getState(), R, Opts);
 
   const UninitFieldMap &UninitFields = F.getUninitFields();
 
@@ -400,25 +399,27 @@ static void printTail(llvm::raw_ostream
 //   Utility functions.
 
//===--===//
 
-static Optional
-getObjectVal(const CXXConstructorDecl *CtorDecl, CheckerContext &Context) {
+static const TypedValueRegion *
+getConstructedRegion(const CXXConstructorDecl *CtorDecl,
+ CheckerContext &Context) {
 
-  Loc ThisLoc = Context.getSValBuilder().getCXXThis(CtorDecl->getParent(),
+  Loc ThisLoc = Context.getSValBuilder().getCXXThis(CtorDecl,
 Context.getStackFrame());
-  // Getting the value for 'this'.
-  SVal This = Context.getState()->getSVal(ThisLoc);
 
-  // Getting the value for '*this'.
-  SVal Object = Context.getState()->getSVal(This.castAs());
+  SVal ObjectV = Context.getState()->getSVal(ThisLoc);
 
-  return Object.getAs();
+  auto *R = ObjectV.getAsRegion()->getAs();
+  if (R && !R->getValueType()->getAsCXXRecordDecl())
+return nullptr;
+
+  return R;
 }
 
 static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor,
   CheckerContext &Context) {
 
-  Optional CurrentObject = getObjectVal(Ctor, 
Context);
-  if (!CurrentObject)
+  const TypedValueRegion *CurrRegion = getConstructedRegion(Ctor, Context);
+  if (!CurrRegion)
 return false;
 
   const LocationContext *LC = Context.getLocationContext();
@@ -429,14 +430,14 @@ static bool willObjectBeAnalyzedLater(co
 if (!OtherCtor)
   continue;
 
-Optional OtherObject =
-getObjectVal(OtherCtor, Context);
-if (!OtherObject)
+const TypedValueRegion *OtherRegion =
+getConstructedRegion(OtherCtor, Context);
+if (!OtherRegion)
   continue;
 
-// If the CurrentObject is a subregion of OtherObject, it will be analyzed
-// during the analysis of OtherObject.
-if (CurrentObject->getRegion()->isSubRegionOf(OtherObject->getRegion()))
+// If the CurrRegion is a subregion of OtherRegion, it will be analyzed
+// during the analysis of OtherRegion.
+if (CurrRegion->isSubRegionOf(OtherRegion))
   return true;
   }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r345531 - [analyzer][NFC] Refactor PlistDiagnostics to use a class instead of passing 9 parameters around

2018-10-29 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Oct 29 13:06:30 2018
New Revision: 345531

URL: http://llvm.org/viewvc/llvm-project?rev=345531&view=rev
Log:
[analyzer][NFC] Refactor PlistDiagnostics to use a class instead of passing 9 
parameters around

This has been a long time coming. Note the usage of AnalyzerOptions: I'll need
it for D52742, and added it in rC343620. The main motivation for this was that
I'll need to add yet another parameter to every single function, and some
functions would reach their 10th parameter with that change.

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=345531&r1=345530&r2=345531&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Mon Oct 29 13:06:30 
2018
@@ -24,10 +24,16 @@
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
+
 using namespace clang;
 using namespace ento;
 using namespace markup;
 
+//===--===//
+// Declarations of helper classes and functions for emitting bug reports in
+// plist format.
+//===--===//
+
 namespace {
   class PlistDiagnostics : public PathDiagnosticConsumer {
 const std::string OutputFile;
@@ -59,34 +65,91 @@ namespace {
   };
 } // end anonymous namespace
 
-PlistDiagnostics::PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
-   const std::string& output,
-   const Preprocessor &PP,
-   bool supportsMultipleFiles)
-  : OutputFile(output), PP(PP), AnOpts(AnalyzerOpts),
-SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
+namespace {
 
-void ento::createPlistDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
- PathDiagnosticConsumers &C,
- const std::string& s,
- const Preprocessor &PP) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP,
-   /*supportsMultipleFiles*/ false));
-}
+/// A helper class for emitting a single report.
+class PlistPrinter {
+  const FIDMap& FM;
+  AnalyzerOptions &AnOpts;
+  const Preprocessor &PP;
+
+public:
+  PlistPrinter(const FIDMap& FM, AnalyzerOptions &AnOpts,
+   const Preprocessor &PP)
+: FM(FM), AnOpts(AnOpts), PP(PP) {
+  }
 
-void ento::createPlistMultiFileDiagnosticConsumer(AnalyzerOptions 
&AnalyzerOpts,
-  PathDiagnosticConsumers &C,
-  const std::string &s,
-  const Preprocessor &PP) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP,
-   /*supportsMultipleFiles*/ true));
-}
+  void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P) {
+ReportPiece(o, P, /*indent*/ 4, /*depth*/ 0, /*includeControlFlow*/ true);
+
+// Don't emit a warning about an unused private field.
+(void)AnOpts;
+  }
+
+private:
+  void ReportPiece(raw_ostream &o, const PathDiagnosticPiece &P,
+   unsigned indent, unsigned depth, bool includeControlFlow,
+   bool isKeyEvent = false) {
+switch (P.getKind()) {
+  case PathDiagnosticPiece::ControlFlow:
+if (includeControlFlow)
+  ReportControlFlow(o, cast(P), 
indent);
+break;
+  case PathDiagnosticPiece::Call:
+ReportCall(o, cast(P), indent,
+   depth);
+break;
+  case PathDiagnosticPiece::Event:
+ReportEvent(o, cast(P), indent, depth,
+isKeyEvent);
+break;
+  case PathDiagnosticPiece::Macro:
+ReportMacro(o, cast(P), indent, depth);
+break;
+  case PathDiagnosticPiece::Note:
+ReportNote(o, cast(P), indent);
+break;
+}
+  }
+
+  void EmitRanges(raw_ostream &o, const ArrayRef Ranges,
+  unsigned indent);
+  void EmitMessage(raw_ostream &o, StringRef Message, unsigned indent);
+
+  void ReportControlFlow(raw_ostream &o,
+ const PathDiagnosticControlFlowPiece& P,
+ unsigned indent);
+  void ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
+   unsigned indent, unsigned depth, bool isKeyEvent = false);
+  void ReportCall(raw_ostream &o, const PathDiagnosticCallPiece &P,
+  unsigned indent, unsigned depth);
+  void ReportMacro(raw_ostream &o, const PathDiagnosticMacroPiece& P,
+   unsigned indent,

r352277 - [analyzer] Supply all checkers with a shouldRegister function

2019-01-26 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jan 26 06:23:08 2019
New Revision: 352277

URL: http://llvm.org/viewvc/llvm-project?rev=352277&view=rev
Log:
[analyzer] Supply all checkers with a shouldRegister function

Introduce the boolean ento::shouldRegister##CHECKERNAME(const LangOptions &LO)
function very similarly to ento::register##CHECKERNAME. This will force every
checker to implement this function, but maybe it isn't that bad: I saw a lot of
ObjC or C++ specific checkers that should probably not register themselves based
on some LangOptions (mine too), but they do anyways.

A big benefit of this is that all registry functions now register their checker,
once it is called, registration is guaranteed.

This patch is a part of a greater effort to reinvent checker registration, more
info here: D54438#1315953

Differential Revision: https://reviews.llvm.org/D55424

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
cfe/trunk/include/clang/StaticAnalyzer/Core/Checker.h
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ChrootChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/GTestChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/Obj

r352278 - [analyzer] Split unix.API up to UnixAPIMisuseChecker and UnixAPIPortabilityChecker

2019-01-26 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jan 26 07:56:40 2019
New Revision: 352278

URL: http://llvm.org/viewvc/llvm-project?rev=352278&view=rev
Log:
[analyzer] Split unix.API up to UnixAPIMisuseChecker and 
UnixAPIPortabilityChecker

The actual implementation of unix.API features a dual-checker: two checkers in
one, even though they don't even interact at all. Split them up, as this is a
problem for establishing dependencies.

I added no new code at all, just merely moved it around.

Since the plist files change (and that's a benefit!) this patch isn't NFC.

Differential Revision: https://reviews.llvm.org/D55425

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
cfe/trunk/test/Analysis/Inputs/expected-plists/unix-fns.c.plist

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp?rev=352278&r1=352277&r2=352278&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp Sat Jan 26 
07:56:40 2019
@@ -20,10 +20,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
-#include 
 
 using namespace clang;
 using namespace ento;
@@ -39,8 +36,9 @@ enum class OpenVariant {
 };
 
 namespace {
-class UnixAPIChecker : public Checker< check::PreStmt > {
-  mutable std::unique_ptr BT_open, BT_pthreadOnce, BT_mallocZero;
+
+class UnixAPIMisuseChecker : public Checker< check::PreStmt > {
+  mutable std::unique_ptr BT_open, BT_pthreadOnce;
   mutable Optional Val_O_CREAT;
 
 public:
@@ -50,8 +48,25 @@ public:
 
   void CheckOpen(CheckerContext &C, const CallExpr *CE) const;
   void CheckOpenAt(CheckerContext &C, const CallExpr *CE) const;
-
   void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE) const;
+
+  void CheckOpenVariant(CheckerContext &C,
+const CallExpr *CE, OpenVariant Variant) const;
+
+  void ReportOpenBug(CheckerContext &C,
+ ProgramStateRef State,
+ const char *Msg,
+ SourceRange SR) const;
+
+};
+
+class UnixAPIPortabilityChecker : public Checker< check::PreStmt > {
+public:
+  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
+
+private:
+  mutable std::unique_ptr BT_mallocZero;
+
   void CheckCallocZero(CheckerContext &C, const CallExpr *CE) const;
   void CheckMallocZero(CheckerContext &C, const CallExpr *CE) const;
   void CheckReallocZero(CheckerContext &C, const CallExpr *CE) const;
@@ -60,13 +75,6 @@ public:
   void CheckAllocaWithAlignZero(CheckerContext &C, const CallExpr *CE) const;
   void CheckVallocZero(CheckerContext &C, const CallExpr *CE) const;
 
-  typedef void (UnixAPIChecker::*SubChecker)(CheckerContext &,
- const CallExpr *) const;
-private:
-
-  void CheckOpenVariant(CheckerContext &C,
-const CallExpr *CE, OpenVariant Variant) const;
-
   bool ReportZeroByteAllocation(CheckerContext &C,
 ProgramStateRef falseState,
 const Expr *arg,
@@ -76,48 +84,75 @@ private:
 const unsigned numArgs,
 const unsigned sizeArg,
 const char *fn) const;
-  void LazyInitialize(std::unique_ptr &BT, const char *name) const {
-if (BT)
-  return;
-BT.reset(new BugType(this, name, categories::UnixAPI));
-  }
-  void ReportOpenBug(CheckerContext &C,
- ProgramStateRef State,
- const char *Msg,
- SourceRange SR) const;
 };
+
 } //end anonymous namespace
 
+static void LazyInitialize(const CheckerBase *Checker,
+   std::unique_ptr &BT,
+   const char *name) {
+  if (BT)
+return;
+  BT.reset(new BugType(Checker, name, categories::UnixAPI));
+}
+
 
//===--===//
 // "open" (man 2 open)
-//===--===//
+//===--===/
+
+void UnixAPIMisuseChecker::checkPreStmt(const CallExpr *CE,
+CheckerContext &C) const {
+  const FunctionDecl *FD = C.getCalleeDecl(CE);
+  if (!FD || FD->getKind() != Decl::Function)
+return;
+
+  // Don't treat functions in namespaces with the same name a Unix function
+  // as a call to the Unix function.
+  const DeclContext *NamespaceCtx = FD->getEnclosingNamespaceContext();
+  if (NamespaceCtx && isa(NamespaceCtx))
+return;
 
-void UnixAPIChecker::ReportOpenBug(CheckerContext &C,

r352279 - [analyzer][NFC] Supply CheckerRegistry with AnalyzerOptions

2019-01-26 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jan 26 07:59:21 2019
New Revision: 352279

URL: http://llvm.org/viewvc/llvm-project?rev=352279&view=rev
Log:
[analyzer][NFC] Supply CheckerRegistry with AnalyzerOptions

Since pretty much all methods of CheckerRegistry has AnalyzerOptions as an
argument, it makes sense to just simply require it in it's constructor.

Differential Revision: https://reviews.llvm.org/D56988

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h?rev=352279&r1=352278&r2=352279&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h Sat Jan 
26 07:59:21 2019
@@ -82,7 +82,7 @@ namespace ento {
 class CheckerRegistry {
 public:
   CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags,
-  const LangOptions &LangOpts);
+  AnalyzerOptions &AnOpts, const LangOptions &LangOpts);
 
   /// Initialization functions perform any necessary setup for a checker.
   /// They should include a call to CheckerManager::registerChecker.
@@ -137,24 +137,24 @@ public:
   /// all checkers specified by the given CheckerOptInfo list. The order of 
this
   /// list is significant; later options can be used to reverse earlier ones.
   /// This can be used to exclude certain checkers in an included package.
-  void initializeManager(CheckerManager &mgr,
- const AnalyzerOptions &Opts) const;
+  void initializeManager(CheckerManager &mgr) const;
 
   /// Check if every option corresponds to a specific checker or package.
-  void validateCheckerOptions(const AnalyzerOptions &opts) const;
+  void validateCheckerOptions() const;
 
   /// Prints the name and description of all checkers in this registry.
   /// This output is not intended to be machine-parseable.
   void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
-  void printList(raw_ostream &out, const AnalyzerOptions &opts) const;
+  void printList(raw_ostream &out) const;
 
 private:
-  CheckerInfoSet getEnabledCheckers(const AnalyzerOptions &Opts) const;
+  CheckerInfoSet getEnabledCheckers() const;
 
   mutable CheckerInfoList Checkers;
   mutable llvm::StringMap Packages;
 
   DiagnosticsEngine &Diags;
+  AnalyzerOptions &AnOpts;
   const LangOptions &LangOpts;
 };
 

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h?rev=352279&r1=352278&r2=352279&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h Sat Jan 
26 07:59:21 2019
@@ -51,10 +51,13 @@ private:
   llvm::StringMap &Bodies;
 };
 
-void printCheckerHelp(raw_ostream &OS, ArrayRef plugins,
-  DiagnosticsEngine &diags, const LangOptions &LangOpts);
+void printCheckerHelp(raw_ostream &OS,
+  ArrayRef plugins,
+  AnalyzerOptions &opts,
+  DiagnosticsEngine &diags,
+  const LangOptions &LangOpts);
 void printEnabledCheckerList(raw_ostream &OS, ArrayRef plugins,
- const AnalyzerOptions &opts,
+ AnalyzerOptions &opts,
  DiagnosticsEngine &diags,
  const LangOptions &LangOpts);
 void printAnalyzerConfigList(raw_ostream &OS);

Modified: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=352279&r1=352278&r2=352279&view=diff
==
--- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)
+++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp Sat Jan 26 
07:59:21 2019
@@ -237,8 +237,11 @@ bool ExecuteCompilerInvocation(CompilerI
   // Honor -analyzer-checker-help.
   // This should happen AFTER plugins have been loaded!
   if (Clang->getAnalyzerOpts()->ShowCheckerHelp) {
-ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins,
-   Clang->getDiagnostics(), Clang->getLangOpts());
+ento::printCheckerHelp(llvm::outs(),
+   Clang->ge

r352282 - [analyzer][NFC] Keep track of whether enabling a checker was explictly specified in command line arguments

2019-01-26 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jan 26 08:35:33 2019
New Revision: 352282

URL: http://llvm.org/viewvc/llvm-project?rev=352282&view=rev
Log:
[analyzer][NFC] Keep track of whether enabling a checker was explictly 
specified in command line arguments

I added a new enum to CheckerInfo, so we can easily track whether the check is
explicitly enabled, explicitly disabled, or isn't specified in this regard.
Checkers belonging in the latter category may be implicitly enabled through
dependencies in the followup patch. I also made sure that this is done within
CheckerRegisty's constructor, leading to very significant simplifications in
its query-like methods.

Differential Revision: https://reviews.llvm.org/D56989

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h?rev=352282&r1=352281&r2=352282&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h Sat Jan 
26 08:35:33 2019
@@ -90,11 +90,25 @@ public:
   using ShouldRegisterFunction = bool (*)(const LangOptions &);
 
   struct CheckerInfo {
+enum class StateFromCmdLine {
+  // This checker wasn't explicitly enabled or disabled.
+  State_Unspecified,
+  // This checker was explicitly disabled.
+  State_Disabled,
+  // This checker was explicitly enabled.
+  State_Enabled
+};
+
 InitializationFunction Initialize;
 ShouldRegisterFunction ShouldRegister;
 StringRef FullName;
 StringRef Desc;
 StringRef DocumentationUri;
+StateFromCmdLine State = StateFromCmdLine::State_Unspecified;
+
+bool isEnabled(const LangOptions &LO) const {
+  return State == StateFromCmdLine::State_Enabled && ShouldRegister(LO);
+}
 
 CheckerInfo(InitializationFunction Fn, ShouldRegisterFunction sfn,
 StringRef Name, StringRef Desc, StringRef DocsUri)
@@ -102,7 +116,9 @@ public:
   DocumentationUri(DocsUri) {}
   };
 
+  using StateFromCmdLine = CheckerInfo::StateFromCmdLine;
   using CheckerInfoList = std::vector;
+  using CheckerInfoListRange = llvm::iterator_range;
   using CheckerInfoSet = llvm::SetVector;
 
 private:
@@ -133,6 +149,7 @@ public:
&CheckerRegistry::returnTrue, FullName, Desc, DocsUri);
   }
 
+  // FIXME: This *really* should be added to the frontend flag descriptions.
   /// Initializes a CheckerManager by calling the initialization functions for
   /// all checkers specified by the given CheckerOptInfo list. The order of 
this
   /// list is significant; later options can be used to reverse earlier ones.
@@ -150,8 +167,13 @@ public:
 private:
   CheckerInfoSet getEnabledCheckers() const;
 
-  mutable CheckerInfoList Checkers;
-  mutable llvm::StringMap Packages;
+  /// Return an iterator range of mutable CheckerInfos \p CmdLineArg applies 
to.
+  /// For example, it'll return the checkers for the core package, if
+  /// \p CmdLineArg is "core".
+  CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg);
+
+  CheckerInfoList Checkers;
+  llvm::StringMap Packages;
 
   DiagnosticsEngine &Diags;
   AnalyzerOptions &AnOpts;

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp?rev=352282&r1=352281&r2=352282&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp Sat Jan 26 
08:35:33 2019
@@ -38,12 +38,66 @@ static bool isCompatibleAPIVersion(const
   return strcmp(versionString, CLANG_ANALYZER_API_VERSION_STRING) == 0;
 }
 
+static bool checkerNameLT(const CheckerRegistry::CheckerInfo &a,
+  const CheckerRegistry::CheckerInfo &b) {
+  return a.FullName < b.FullName;
+}
+
+static constexpr char PackageSeparator = '.';
+
+static bool isInPackage(const CheckerRegistry::CheckerInfo &checker,
+StringRef packageName) {
+  // Does the checker's full name have the package as a prefix?
+  if (!checker.FullName.startswith(packageName))
+return false;
+
+  // Is the package actually just the name of a specific checker?
+  if (checker.FullName.size() == packageName.size())
+return true;
+
+  // Is the checker in the package (or a subpackage)?
+  if (checker.FullName[packageName.size()] == PackageSeparator)
+return true;
+
+  return false;
+}
+
+CheckerRegistry::CheckerInfoListRange
+CheckerRegistry::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) {
+
+  assert(std::is_s

r352284 - [analyzer] Fix an bug where statically linked, but not registered checkers weren't recognized

2019-01-26 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jan 26 09:27:40 2019
New Revision: 352284

URL: http://llvm.org/viewvc/llvm-project?rev=352284&view=rev
Log:
[analyzer] Fix an bug where statically linked, but not registered checkers 
weren't recognized

My last patch, D56989, moved the validation of whether a checker exists into
its constructor, but we do support statically linked (and non-plugin) checkers
that were do not have an entry in Checkers.td. However, the handling of this
happens after the creation of the CheckerRegistry object.

This patch fixes this bug by moving even this functionality into
CheckerRegistry's constructor.

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h?rev=352284&r1=352283&r2=352284&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h Sat Jan 
26 09:27:40 2019
@@ -81,8 +81,11 @@ namespace ento {
 /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
 class CheckerRegistry {
 public:
-  CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags,
-  AnalyzerOptions &AnOpts, const LangOptions &LangOpts);
+  CheckerRegistry(
+  ArrayRef plugins, DiagnosticsEngine &diags,
+  AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
+  ArrayRef>
+  checkerRegistrationFns = {});
 
   /// Initialization functions perform any necessary setup for a checker.
   /// They should include a call to CheckerManager::registerChecker.

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp?rev=352284&r1=352283&r2=352284&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp Sat Jan 26 
09:27:40 2019
@@ -33,10 +33,8 @@ std::unique_ptr ento::cr
 DiagnosticsEngine &diags) {
   auto checkerMgr = llvm::make_unique(context, opts);
 
-  CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts());
-
-  for (const auto &Fn : checkerRegistrationFns)
-Fn(allCheckers);
+  CheckerRegistry allCheckers(plugins, diags, opts, context.getLangOpts(),
+  checkerRegistrationFns);
 
   allCheckers.initializeManager(*checkerMgr);
   allCheckers.validateCheckerOptions();

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp?rev=352284&r1=352283&r2=352284&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp Sat Jan 26 
09:27:40 2019
@@ -91,10 +91,11 @@ CheckerRegistry::getMutableCheckersForCm
   return { it, it + size };
 }
 
-CheckerRegistry::CheckerRegistry(ArrayRef plugins,
- DiagnosticsEngine &diags,
- AnalyzerOptions &AnOpts,
- const LangOptions &LangOpts)
+CheckerRegistry::CheckerRegistry(
+ ArrayRef plugins, DiagnosticsEngine &diags,
+ AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
+ ArrayRef>
+ checkerRegistrationFns)
   : Diags(diags), AnOpts(AnOpts), LangOpts(LangOpts) {
 
   // Register builtin checkers.
@@ -137,6 +138,13 @@ CheckerRegistry::CheckerRegistry(ArrayRe
   registerPluginCheckers(*this);
   }
 
+  // Register statically linked checkers, that aren't generated from the tblgen
+  // file, but rather passed their registry function as a parameter in 
+  // checkerRegistrationFns. 
+
+  for (const auto &Fn : checkerRegistrationFns)
+Fn(*this);
+
   // Sort checkers for efficient collection.
   // FIXME: Alphabetical sort puts 'experimental' in the middle.
   // Would it be better to name it '~experimental' or something else


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r352290 - Fix a lit test failure after D54438

2019-01-26 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jan 26 13:22:58 2019
New Revision: 352290

URL: http://llvm.org/viewvc/llvm-project?rev=352290&view=rev
Log:
Fix a lit test failure after D54438

Modified:
clang-tools-extra/trunk/test/clang-tidy/static-analyzer-config.cpp

Modified: clang-tools-extra/trunk/test/clang-tidy/static-analyzer-config.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/static-analyzer-config.cpp?rev=352290&r1=352289&r2=352290&view=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/static-analyzer-config.cpp 
(original)
+++ clang-tools-extra/trunk/test/clang-tidy/static-analyzer-config.cpp Sat Jan 
26 13:22:58 2019
@@ -1,5 +1,5 @@
 // REQUIRES: static-analyzer
-// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' 
-config='{CheckOptions: [{ key: "clang-analyzer-unix.Malloc:Optimistic", value: 
true}]}' -- | FileCheck %s
+// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' 
-config='{CheckOptions: [{ key: 
"clang-analyzer-unix.DynamicMemoryModeling:Optimistic", value: true}]}' -- | 
FileCheck %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r352292 - [analyzer] Add CheckerManager::getChecker, make sure that a registry function registers no more than 1 checker

2019-01-26 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jan 26 13:41:50 2019
New Revision: 352292

URL: http://llvm.org/viewvc/llvm-project?rev=352292&view=rev
Log:
[analyzer] Add CheckerManager::getChecker, make sure that a registry function 
registers no more than 1 checker

This patch effectively fixes the almost decade old checker naming issue.
The solution is to assert when CheckerManager::getChecker is called on an
unregistered checker, and assert when CheckerManager::registerChecker is called
on a checker that is already registered.

Differential Revision: https://reviews.llvm.org/D55429

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
cfe/trunk/test/Analysis/analyzer-checker-config.c
cfe/trunk/test/Analysis/free.c
cfe/trunk/test/Analysis/outofbound.c
cfe/trunk/test/Analysis/undef-buffers.c

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=352292&r1=352291&r2=352292&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Sat Jan 26 
13:41:50 2019
@@ -141,7 +141,7 @@ public:
   using CheckerDtor = CheckerFn;
 
 
//===--===//
-// registerChecker
+// Checker registration.
 
//===--===//
 
   /// Used to register checkers.
@@ -153,8 +153,7 @@ public:
   CHECKER *registerChecker(AT &&... Args) {
 CheckerTag tag = getTag();
 CheckerRef &ref = CheckerTags[tag];
-if (ref)
-  return static_cast(ref); // already registered.
+assert(!ref && "Checker already registered, use getChecker!");
 
 CHECKER *checker = new CHECKER(std::forward(Args)...);
 checker->Name = CurrentCheckName;
@@ -164,8 +163,17 @@ public:
 return checker;
   }
 
+  template 
+  CHECKER *getChecker() {
+CheckerTag tag = getTag();
+assert(CheckerTags.count(tag) != 0 &&
+   "Requested checker is not registered! Maybe you should add it as a "
+   "dependency in Checkers.td?");
+return static_cast(CheckerTags[tag]);
+  }
+
 
//===--===//
-// Functions for running checkers for AST traversing..
+// Functions for running checkers for AST traversing.
 
//===--===//
 
   /// Run checkers handling Decls.

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=352292&r1=352291&r2=352292&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp Sat Jan 26 
13:41:50 2019
@@ -2485,7 +2485,7 @@ bool ento::shouldRegisterCStringModeling
 
 #define REGISTER_CHECKER(name) 
\
   void ento::register##name(CheckerManager &mgr) { 
\
-CStringChecker *checker = mgr.registerChecker();   
\
+CStringChecker *checker = mgr.getChecker();
\
 checker->Filter.Check##name = true;
\
 checker->Filter.CheckName##name = mgr.getCurrentCheckName();   
\
   }
\

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp?rev=352292&r1=352291&r2=352292&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CallAnd

r352693 - [analyzer] Make NullReturnedFromNonnullChecker depend on NullabilityBase

2019-01-30 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed Jan 30 15:48:37 2019
New Revision: 352693

URL: http://llvm.org/viewvc/llvm-project?rev=352693&view=rev
Log:
[analyzer] Make NullReturnedFromNonnullChecker depend on NullabilityBase

Accidentally left this dependency out after D54438.

Added:
cfe/trunk/test/Analysis/checker-dependencies.c
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=352693&r1=352692&r2=352693&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Wed Jan 30 
15:48:37 2019
@@ -230,6 +230,7 @@ def NullPassedToNonnullChecker : Checker
 def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">,
   HelpText<"Warns when a null pointer is returned from a function that has "
"_Nonnull return type.">,
+  Dependencies<[NullabilityBase]>,
   Documentation;
 
 def NullableDereferencedChecker : Checker<"NullableDereferenced">,

Added: cfe/trunk/test/Analysis/checker-dependencies.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/checker-dependencies.c?rev=352693&view=auto
==
--- cfe/trunk/test/Analysis/checker-dependencies.c (added)
+++ cfe/trunk/test/Analysis/checker-dependencies.c Wed Jan 30 15:48:37 2019
@@ -0,0 +1,3 @@
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=nullability.NullReturnedFromNonnull


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r345724 - [analyzer][PlistMacroExpansion] Part 1.: New expand-macros flag

2018-10-31 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed Oct 31 07:54:27 2018
New Revision: 345724

URL: http://llvm.org/viewvc/llvm-project?rev=345724&view=rev
Log:
[analyzer][PlistMacroExpansion] Part 1.: New expand-macros flag

This is the first part of the implementation of the inclusion of macro
expansions into the plist output. It adds a new flag that adds a new
"macro_expansions" entry to each report that has PathDiagnosticPieces that were
expanded from a macro. While there's an entry for each macro expansion, both
the name of the macro and what it expands to is missing, and will be implemented
in followup patches.

Differential Revision: https://reviews.llvm.org/D52742


Added:

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

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=345724&r1=345723&r2=345724&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Wed Oct 31 
07:54:27 2018
@@ -307,6 +307,9 @@ private:
   /// \sa shouldDisplayNotesAsEvents
   Optional DisplayNotesAsEvents;
 
+  /// \sa shouldDisplayMacroExpansions
+  Optional DisplayMacroExpansions;
+
   /// \sa shouldAggressivelySimplifyBinaryOperation
   Optional AggressiveBinaryOperationSimplification;
 
@@ -693,6 +696,13 @@ public:
   /// to false when unset.
   bool shouldDisplayNotesAsEvents();
 
+  /// Returns true if macros related to the bugpath should be expanded and
+  /// included in the plist output.
+  ///
+  /// This is controlled by the 'expand-macros' option, which defaults to false
+  /// when unset.
+  bool shouldDisplayMacroExpansions();
+
   /// Returns true if SValBuilder should rearrange comparisons and additive
   /// operations of symbolic expressions which consist of a sum of a symbol and
   /// a concrete integer into the format where symbols are on the left-hand

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=345724&r1=345723&r2=345724&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Wed Oct 31 07:54:27 
2018
@@ -464,6 +464,13 @@ bool AnalyzerOptions::shouldDisplayNotes
   return DisplayNotesAsEvents.getValue();
 }
 
+bool AnalyzerOptions::shouldDisplayMacroExpansions() {
+  if (!DisplayMacroExpansions.hasValue())
+DisplayMacroExpansions =
+getBooleanOption("expand-macros", /*Default=*/false);
+  return DisplayMacroExpansions.getValue();
+}
+
 bool AnalyzerOptions::shouldAggressivelySimplifyBinaryOperation() {
   if (!AggressiveBinaryOperationSimplification.hasValue())
 AggressiveBinaryOperationSimplification =

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=345724&r1=345723&r2=345724&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Wed Oct 31 07:54:27 2018
@@ -546,7 +546,8 @@ static void updateStackPiecesWithMessage
   }
 }
 
-static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
+static void CompactMacroExpandedPieces(PathPieces &path,
+   const SourceManager& SM);
 
 
 std::shared_ptr generateDiagForSwitchOP(
@@ -1972,8 +1973,6 @@ static std::unique_ptr g
   PathDiagnosticLocation::createBegin(D, SM));
   }
 
-  if (!AddPathEdges && GenerateDiagnostics)
-CompactPathDiagnostic(PD->getMutablePieces(), SM);
 
   // Finally, prune the diagnostic path of uninteresting stuff.
   if (!PD->path.empty()) {
@@ -2007,6 +2006,10 @@ static std::unique_ptr g
 removeRedundantMsgs(PD->getMutablePieces());
 removeEdgesToDefaultInitializers(PD->getMutablePieces());
   }
+
+  if (GenerateDiagnostics && Opts.shouldDisplayMacroExpansions())
+CompactMacroExpandedPieces(PD->getMutablePieces(), SM);
+
   return PD;
 }
 
@@ -2436,9 +2439,10 @@ bool TrimmedGraph::popNextReportGraph(Re
   return true;
 }
 
-/// CompactPathDiagnostic - This function postprocesses a PathDiagnostic object
-///  and collapses PathDiagosticPieces that are expanded by macros.
-static void CompactPa

r345741 - [Lex] Make MacroDirective::findDirectiveAtLoc take const SourceManager

2018-10-31 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed Oct 31 10:19:20 2018
New Revision: 345741

URL: http://llvm.org/viewvc/llvm-project?rev=345741&view=rev
Log:
[Lex] Make MacroDirective::findDirectiveAtLoc take const SourceManager

I'm currently working on including macro expansions in the Static Analyzer's
plist output, where I can only access a const SourceManager.

Differential Revision: https://reviews.llvm.org/D53940

Modified:
cfe/trunk/include/clang/Lex/MacroInfo.h
cfe/trunk/lib/Lex/MacroInfo.cpp

Modified: cfe/trunk/include/clang/Lex/MacroInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/MacroInfo.h?rev=345741&r1=345740&r2=345741&view=diff
==
--- cfe/trunk/include/clang/Lex/MacroInfo.h (original)
+++ cfe/trunk/include/clang/Lex/MacroInfo.h Wed Oct 31 10:19:20 2018
@@ -395,7 +395,8 @@ public:
 
   /// Find macro definition active in the specified source location. If
   /// this macro was not defined there, return NULL.
-  const DefInfo findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const;
+  const DefInfo findDirectiveAtLoc(SourceLocation L,
+   const SourceManager &SM) const;
 
   void dump() const;
 

Modified: cfe/trunk/lib/Lex/MacroInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/MacroInfo.cpp?rev=345741&r1=345740&r2=345741&view=diff
==
--- cfe/trunk/lib/Lex/MacroInfo.cpp (original)
+++ cfe/trunk/lib/Lex/MacroInfo.cpp Wed Oct 31 10:19:20 2018
@@ -200,7 +200,8 @@ MacroDirective::DefInfo MacroDirective::
 }
 
 const MacroDirective::DefInfo
-MacroDirective::findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const {
+MacroDirective::findDirectiveAtLoc(SourceLocation L,
+   const SourceManager &SM) const {
   assert(L.isValid() && "SourceLocation is invalid.");
   for (DefInfo Def = getDefinition(); Def; Def = Def.getPreviousDefinition()) {
 if (Def.getLocation().isInvalid() ||  // For macros defined on the command 
line.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r345985 - [analyzer][NFC] Fix some incorrect uses of -analyzer-config options

2018-11-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov  2 08:48:10 2018
New Revision: 345985

URL: http://llvm.org/viewvc/llvm-project?rev=345985&view=rev
Log:
[analyzer][NFC] Fix some incorrect uses of -analyzer-config options

I'm in the process of refactoring AnalyzerOptions. The main motivation behind
here is to emit warnings if an invalid -analyzer-config option is given from
the command line, and be able to list them all.

In this patch, I found some flags that should've been used as checker options,
or have absolutely no mention of in AnalyzerOptions, or are nonexistent.

- NonLocalizedStringChecker now uses its "AggressiveReport" flag as a checker
option
- lib/StaticAnalyzer/Frontend/ModelInjector.cpp now accesses the "model-path"
option through a getter in AnalyzerOptions
- -analyzer-config path-diagnostics-alternate=false is not a thing, I removed 
it,
- lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp and
lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h are weird, they actually
only contain an option getter. I deleted them, and fixed RetainCountChecker
to get it's "leak-diagnostics-reference-allocation" option as a checker 
option,
- "region-store-small-struct-limit" has a proper getter now.

Differential Revision: https://reviews.llvm.org/D53276

Removed:
cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
cfe/trunk/test/Analysis/analyzer-config.c
cfe/trunk/test/Analysis/analyzer-config.cpp
cfe/trunk/test/Analysis/cstring-plist.c
cfe/trunk/test/Analysis/localization-aggressive.m

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=345985&r1=345984&r2=345985&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Nov  2 
08:48:10 2018
@@ -328,6 +328,11 @@ private:
   /// \sa shouldElideConstructors
   Optional ElideConstructors;
 
+  /// \sa getModelPath
+  Optional ModelPath;
+
+  /// \sa getRegionStoreSmallStructLimit
+  Optional RegionStoreSmallStructLimit;
 
   /// A helper function that retrieves option for a given full-qualified
   /// checker name.
@@ -745,6 +750,21 @@ public:
   /// Starting with C++17 some elisions become mandatory, and in these cases
   /// the option will be ignored.
   bool shouldElideConstructors();
+
+  /// The largest number of fields a struct can have and still be
+  /// considered "small".
+  ///
+  /// This is currently used to decide whether or not it is worth "forcing" a
+  /// LazyCompoundVal on bind.
+  ///
+  /// This is controlled by 'region-store-small-struct-limit' option.
+  /// To disable all small-struct-dependent behavior, set the option to "0".
+  unsigned getRegionStoreSmallStructLimit();
+
+  /// The analyzer can inline an alternative implementation written in C at the
+  /// call site if the called function's body is not available. This is a path
+  /// where to look for those alternative implementations (called models)
+  StringRef getModelPath();
 };
 
 using AnalyzerOptionsRef = IntrusiveRefCntPtr;

Removed: cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp?rev=345984&view=auto
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp (removed)
@@ -1,24 +0,0 @@
-//=- AllocationDiagnostics.cpp - Config options for allocation diags *- C++ 
-*-//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--===//
-//
-// Declares the configuration functions for leaks/allocation diagnostics.
-//
-//===--
-
-#include "AllocationDiagnostics.h"
-
-namespace clang {
-namespace ento {
-
-bool shouldIncludeAllocationSiteInLeakDiagnostics(AnalyzerOptions &AOpts) {
-  return AOpts.getBooleanOption("leak-diagnostics-refere

r345986 - [analyzer][NFC] Collect all -analyzer-config options in a .def file

2018-11-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov  2 08:50:44 2018
New Revision: 345986

URL: http://llvm.org/viewvc/llvm-project?rev=345986&view=rev
Log:
[analyzer][NFC] Collect all -analyzer-config options in a .def file

I'm in the process of refactoring AnalyzerOptions. The main motivation behind
here is to emit warnings if an invalid -analyzer-config option is given from the
command line, and be able to list them all.

In this patch, I'm moving all analyzer options to a def file, and move 2 enums
to global namespace.

Differential Revision: https://reviews.llvm.org/D53277

Added:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp

Added: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def?rev=345986&view=auto
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def (added)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def Fri Nov  2 
08:50:44 2018
@@ -0,0 +1,467 @@
+//===-- AnalyzerOptions.def - Metadata about Static Analyses *- 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 analyzer options avaible with -analyzer-config.
+//
+//  This file is in part intended for method generation. If it's not included
+//  for that purpose, the following function-like macros should be predefined,
+//  through which all registered options are accessible:
+//
+//* ANALYZER_OPTION: Register a new option.
+//* ANALYZER_OPTION_DEPENDS_ON_USER_MODE: Register a new option, default
+//  value depends on the "user-mode" option.
+//
+//  Options where a simple getter method is sufficient are registered with the
+//  following macros:
+//
+//* ANALYZER_OPTION_GEN_FN: Register a new option, and generate a getter
+//  method for it in AnalyzerOptions.
+//
+//* ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE: Same as above, but
+//  generates a getter function that depends on the "user-mode" option.
+//
+//  You can only include this file when both or none of the above two macros
+//  are defined!
+//  When they are defined, entries that do not generate functions  won't 
appear,
+//  and when they aren't, all entries are converted to ANALYZER_OPTION or to
+//  ANALYZER_OPTION_DEPENDS_ON_USER_MODE.
+//
+//===--===//
+
+#ifndef LLVM_ADT_STRINGREF_H
+#error This .def file is expected to be included in translation units where \
+"llvm/ADT/StringRef.h" is already included!
+#endif
+
+#ifdef ANALYZER_OPTION
+#ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+#error If you didn't include this file with the intent of generating methods, \
+define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' 
macros!
+#endif
+#endif
+
+#ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+#ifdef ANALYZER_OPTION
+#error If you didn't include this file with the intent of generating methods, \
+define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' 
macros!
+#endif
+#endif
+
+#ifdef ANALYZER_OPTION_GEN_FN
+#ifndef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE
+#error If you include this file with the intent of generating functions, \
+define both 'ANALYZER_OPTION_GEN_FN' and \
+'ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE' macros!
+#endif
+#endif
+
+#ifdef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE
+#ifndef ANALYZER_OPTION_GEN_FN
+#error If you include this file with the intent of generating functions, \
+define both 'ANALYZER_OPTION_GEN_FN' and \
+'ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE' macros!
+#endif
+#endif
+
+#ifndef ANALYZER_OPTION
+/// Create a new analyzer option, but dont generate a method for it in
+/// AnalyzerOptions.
+///
+///   TYPE - The type of the option object that will be stored in
+///  AnalyzerOptions. This file is expected to be icluded in 
translation
+///  units where AnalyzerOptions.h is included, so types from that
+///  header should be used.
+///   NAME - The name of the option object.
+///   CMDFLAG - The command line flag for the option.
+/// (-analyzer-config CMDFLAG=VALUE)
+///   DESC - Description of the flag.
+///   DEFAULT_VAL - The default value for CMDFLAG.
+#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)
+#endif
+
+#ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+/// Create a new analyzer option, but dont generate a method for it in
+/// AnalyzerOptions. It's value depends on the opti

r345989 - [analyzer] New flag to print all -analyzer-config options

2018-11-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov  2 08:59:37 2018
New Revision: 345989

URL: http://llvm.org/viewvc/llvm-project?rev=345989&view=rev
Log:
[analyzer] New flag to print all -analyzer-config options

A new -cc1 flag is avaible for the said purpose: -analyzer-config-help

Differential Revision: https://reviews.llvm.org/D53296

Added:
cfe/trunk/test/Analysis/analyzer-list-configs.c
Modified:
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=345989&r1=345988&r2=345989&view=diff
==
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Fri Nov  2 08:59:37 2018
@@ -129,6 +129,9 @@ def analyzer_disable_all_checks : Flag<[
 def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
   HelpText<"Display the list of analyzer checkers that are available">;
 
+def analyzer_config_help : Flag<["-"], "analyzer-config-help">,
+  HelpText<"Display the list of -analyzer-config options">;
+
 def analyzer_list_enabled_checkers : Flag<["-"], 
"analyzer-list-enabled-checkers">,
   HelpText<"Display the list of enabled analyzer checkers">;
 

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=345989&r1=345988&r2=345989&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Nov  2 
08:59:37 2018
@@ -175,6 +175,7 @@ public:
 
   unsigned ShowCheckerHelp : 1;
   unsigned ShowEnabledCheckerList : 1;
+  unsigned ShowConfigOptionsList : 1;
   unsigned AnalyzeAll : 1;
   unsigned AnalyzerDisplayProgress : 1;
   unsigned AnalyzeNestedBlocks : 1;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h?rev=345989&r1=345988&r2=345989&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/FrontendActions.h Fri Nov  
2 08:59:37 2018
@@ -55,6 +55,7 @@ private:
 void printCheckerHelp(raw_ostream &OS, ArrayRef plugins);
 void printEnabledCheckerList(raw_ostream &OS, ArrayRef plugins,
  const AnalyzerOptions &opts);
+void printAnalyzerConfigList(raw_ostream &OS);
 
 } // end GR namespace
 

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=345989&r1=345988&r2=345989&view=diff
==
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Nov  2 08:59:37 2018
@@ -279,6 +279,7 @@ static bool ParseAnalyzerArgs(AnalyzerOp
   }
 
   Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
+  Opts.ShowConfigOptionsList = Args.hasArg(OPT_analyzer_config_help);
   Opts.ShowEnabledCheckerList = 
Args.hasArg(OPT_analyzer_list_enabled_checkers);
   Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks);
 

Modified: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=345989&r1=345988&r2=345989&view=diff
==
--- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)
+++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp Fri Nov  2 
08:59:37 2018
@@ -241,11 +241,19 @@ bool ExecuteCompilerInvocation(CompilerI
 ento::printCheckerHelp(llvm::outs(), Clang->getFrontendOpts().Plugins);
 return true;
   }
+
+  // Honor -analyzer-list-enabled-checkers.
   if (Clang->getAnalyzerOpts()->ShowEnabledCheckerList) {
 ento::printEnabledCheckerList(llvm::outs(),
   Clang->getFrontendOpts().Plugins,
   *Clang->getAnalyzerOpts());
   }
+
+  // Honor -analyzer-config-help.
+  if (Clang->getAnalyzerOpts()->ShowConfigOptionsList) {
+ento::printAnalyzerConfigList(llvm::outs());
+return true;
+  }
 #endif
 
   // If there were errors in processing 

r345990 - [analyzer] Put llvm.Conventions back in alpha

2018-11-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov  2 09:02:10 2018
New Revision: 345990

URL: http://llvm.org/viewvc/llvm-project?rev=345990&view=rev
Log:
[analyzer] Put llvm.Conventions back in alpha

Interestingly, this many year old (when I last looked I remember 2010ish)
checker was committed without any tests, so I thought I'd implement them, but I
was shocked to see how I barely managed to get it working. The code is severely
outdated, I'm not even sure it has ever been used, so I'd propose to move it
back into alpha, and possibly even remove it.

Differential Revision: https://reviews.llvm.org/D53856

Added:
cfe/trunk/test/Analysis/llvm-conventions.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h
cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp
cfe/trunk/test/Analysis/inner-pointer.cpp
cfe/trunk/test/Analysis/temporaries.cpp
cfe/trunk/www/analyzer/alpha_checks.html

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=345990&r1=345989&r2=345990&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Fri Nov  2 
09:02:10 2018
@@ -83,6 +83,7 @@ def LocalizabilityOptIn : Package<"local
 def MPI : Package<"mpi">, InPackage;
 
 def LLVM : Package<"llvm">;
+def LLVMAlpha : Package<"llvm">, InPackage, Hidden;
 
 // The APIModeling package is for checkers that model APIs and don't perform
 // any diagnostics. These checkers are always turned on; this package is
@@ -730,7 +731,7 @@ let ParentPackage = MPI in {
 
//===--===//
 
 def LLVMConventionsChecker : Checker<"Conventions">,
-  InPackage,
+  InPackage,
   HelpText<"Check code for LLVM codebase conventions">,
   DescFile<"LLVMConventionsChecker.cpp">;
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp?rev=345990&r1=345989&r2=345990&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp Fri Nov  2 
09:02:10 2018
@@ -32,8 +32,7 @@ static bool IsLLVMStringRef(QualType T)
   if (!RT)
 return false;
 
-  return StringRef(QualType(RT, 0).getAsString()) ==
-  "class StringRef";
+  return StringRef(QualType(RT, 0).getAsString()) == "class StringRef";
 }
 
 /// Check whether the declaration is semantically inside the top-level

Modified: cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h?rev=345990&r1=345989&r2=345990&view=diff
==
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h (original)
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h Fri Nov  2 
09:02:10 2018
@@ -12,6 +12,13 @@ typedef __typeof__((char*)0-(char*)0) pt
 void *memmove(void *s1, const void *s2, size_t n);
 
 namespace std {
+  typedef size_t size_type;
+#if __cplusplus >= 201103L
+  using nullptr_t = decltype(nullptr);
+#endif
+}
+
+namespace std {
   struct input_iterator_tag { };
   struct output_iterator_tag { };
   struct forward_iterator_tag : public input_iterator_tag { };
@@ -517,6 +524,42 @@ namespace std {
 const T& front() const { return *begin(); }
   };
 
+  template 
+  class basic_string {
+  public:
+basic_string();
+basic_string(const CharT *s);
+
+~basic_string();
+void clear();
+
+basic_string &operator=(const basic_string &str);
+basic_string &operator+=(const basic_string &str);
+
+const CharT *c_str() const;
+const CharT *data() const;
+CharT *data();
+
+basic_string &append(size_type count, CharT ch);
+basic_string &assign(size_type count, CharT ch);
+basic_string &erase(size_type index, size_type count);
+basic_string &insert(size_type index, size_type count, CharT ch);
+basic_string &replace(size_type pos, size_type count, const basic_string 
&str);
+void pop_back();
+void push_back(CharT ch);
+void reserve(size_type new_cap);
+void resize(size_type count);
+void shrink_to_fit();
+void swap(basic_string &other);
+  };
+
+  typedef basic_string string;
+  typedef basic_string wstring;
+#if __cplusplus >= 201103L
+  typedef basic_string u16string;
+  typedef basic_string u32string;
+#endif
+
   class exception {
   public:

r345993 - Didn't -> didnt, because #errors complains about untermianted '

2018-11-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov  2 09:32:15 2018
New Revision: 345993

URL: http://llvm.org/viewvc/llvm-project?rev=345993&view=rev
Log:
Didn't -> didnt, because #errors complains about untermianted '

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def?rev=345993&r1=345992&r2=345993&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def Fri Nov  2 
09:32:15 2018
@@ -41,14 +41,14 @@
 
 #ifdef ANALYZER_OPTION
 #ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
-#error If you didn't include this file with the intent of generating methods, \
+#error If you didnt include this file with the intent of generating methods, \
 define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' 
macros!
 #endif
 #endif
 
 #ifndef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
 #ifdef ANALYZER_OPTION
-#error If you didn't include this file with the intent of generating methods, \
+#error If you didnt include this file with the intent of generating methods, \
 define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' 
macros!
 #endif
 #endif


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r345997 - Remove the duplicated definition of size_t

2018-11-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov  2 10:00:07 2018
New Revision: 345997

URL: http://llvm.org/viewvc/llvm-project?rev=345997&view=rev
Log:
Remove the duplicated definition of size_t

So hopefully windows won't complain.

Modified:
cfe/trunk/test/Analysis/llvm-conventions.cpp

Modified: cfe/trunk/test/Analysis/llvm-conventions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/llvm-conventions.cpp?rev=345997&r1=345996&r2=345997&view=diff
==
--- cfe/trunk/test/Analysis/llvm-conventions.cpp (original)
+++ cfe/trunk/test/Analysis/llvm-conventions.cpp Fri Nov  2 10:00:07 2018
@@ -7,7 +7,6 @@
 // Forward declarations for StringRef tests.
 
//===--===//
 
-using size_t = unsigned long;
 using size_type = size_t;
 
 namespace std {


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r346033 - Attempt to fix 'logical operation on address of string constant'

2018-11-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov  2 12:48:56 2018
New Revision: 346033

URL: http://llvm.org/viewvc/llvm-project?rev=346033&view=rev
Log:
Attempt to fix 'logical operation on address of string constant'

Caused a lot of warnings for Windows:
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/21178/steps/build/logs/warnings%20%2867%29

Modified:
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp?rev=346033&r1=346032&r2=346033&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp Fri Nov  2 
12:48:56 2018
@@ -178,7 +178,8 @@ void ento::printAnalyzerConfigList(raw_o
 {  
\
   CMDFLAG, 
\
   llvm::Twine(llvm::Twine() + "(" +
\
-  (#TYPE == "StringRef" ? "string" : #TYPE ) + ") " DESC   
\
+  (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) +  
\
+  ") " DESC
\
   " (default: " #DEFAULT_VAL ")").str()
\
 },
 
@@ -187,7 +188,8 @@ void ento::printAnalyzerConfigList(raw_o
 {  
\
   CMDFLAG, 
\
   llvm::Twine(llvm::Twine() + "(" +
\
-  (#TYPE == "StringRef" ? "string" : #TYPE ) + ") " DESC   
\
+  (StringRef(#TYPE) == "StringRef" ? "string" : #TYPE ) +  
\
+  ") " DESC
\
   " (default: " #SHALLOW_VAL " in shallow mode, " #DEEP_VAL
\
   " in deep mode)").str()  
\
 },


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r346095 - [analyzer][PlistMacroExpansion] Part 2.: Retrieving the macro name and primitive expansion

2018-11-04 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Nov  4 05:59:44 2018
New Revision: 346095

URL: http://llvm.org/viewvc/llvm-project?rev=346095&view=rev
Log:
[analyzer][PlistMacroExpansion] Part 2.: Retrieving the macro name and 
primitive expansion

This patch adds a couple new functions to acquire the macro's name, and also
expands it, although it doesn't expand the arguments, as seen from the test 
files

Differential Revision: https://reviews.llvm.org/D52794

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=346095&r1=346094&r2=346095&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Sun Nov  4 05:59:44 
2018
@@ -16,6 +16,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/TokenConcatenation.h"
 #include "clang/Rewrite/Core/HTMLRewrite.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
@@ -400,12 +401,6 @@ void PlistPrinter::ReportNote(raw_ostrea
 // Static function definitions.
 
//===--===//
 
-static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
-  const Preprocessor &PP) {
-  // TODO: Implement macro expansion.
-  return { "", "" };
-}
-
 /// Print coverage information to output stream {@code o}.
 /// May modify the used list of files {@code Fids} by inserting new ones.
 static void printCoverage(const PathDiagnostic *D,
@@ -721,3 +716,196 @@ void PlistDiagnostics::FlushDiagnosticsI
   // Finish.
   o << "\n";
 }
+
+//===--===//
+// Declarations of helper functions and data structures for expanding macros.
+//===--===//
+
+namespace {
+
+struct MacroNameAndInfo {
+  std::string Name;
+  const MacroInfo *MI = nullptr;
+
+  MacroNameAndInfo(std::string N, const MacroInfo *MI)
+: Name(std::move(N)), MI(MI) {}
+};
+
+/// Helper class for printing tokens.
+class TokenPrinter {
+  llvm::raw_ostream &OS;
+  const Preprocessor &PP;
+
+  Token PrevTok, PrevPrevTok;
+  TokenConcatenation ConcatInfo;
+
+public:
+  TokenPrinter(llvm::raw_ostream &OS, const Preprocessor &PP)
+: OS(OS), PP(PP), ConcatInfo(PP) {
+PrevTok.setKind(tok::unknown);
+PrevPrevTok.setKind(tok::unknown);
+  }
+
+  void printToken(const Token &Tok);
+};
+
+} // end of anonymous namespace
+
+static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
+ SourceLocation MacroLoc,
+ const Preprocessor &PP);
+
+/// Retrieves the name of the macro and its MacroInfo.
+static MacroNameAndInfo getMacroNameAndInfo(SourceLocation ExpanLoc,
+const Preprocessor &PP);
+
+/// Retrieves the ')' token that matches '(' \p It points to.
+static MacroInfo::tokens_iterator getMatchingRParen(
+MacroInfo::tokens_iterator It,
+MacroInfo::tokens_iterator End);
+
+/// Retrieves the macro info for \p II refers to at \p Loc. This is important
+/// because macros can be redefined or undefined.
+static const MacroInfo *getMacroInfoForLocation(const Preprocessor &PP,
+const SourceManager &SM,
+const IdentifierInfo *II,
+SourceLocation Loc);
+
+//===--===//
+// Definitions of helper functions and methods for expanding macros.
+//===--===//
+
+static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
+  const Preprocessor &PP) {
+
+  llvm::SmallString<200> ExpansionBuf;
+  llvm::raw_svector_ostream OS(ExpansionBuf);
+  TokenPrinter Printer(OS, PP);
+  return { getMacroNameAndPrintExpansion(Printer, MacroLoc, PP), OS.str() };
+}
+
+static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
+ SourceLocation MacroLoc,
+ const Preprocessor &PP) {
+
+  const SourceManager &SM = PP.getSourceManager();
+
+  MacroNameAndInfo Info = getMacroNameAndInfo(SM.getExpansionLoc(MacroLoc), 
PP);
+  const MacroInfo *MI =

r346096 - Revert '[analyzer][PlistMacroExpansion] Part 2.: Retrieving the macro name and primitive expansion'

2018-11-04 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Nov  4 06:18:37 2018
New Revision: 346096

URL: http://llvm.org/viewvc/llvm-project?rev=346096&view=rev
Log:
Revert '[analyzer][PlistMacroExpansion] Part 2.: Retrieving the macro name and 
primitive expansion'

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=346096&r1=346095&r2=346096&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Sun Nov  4 06:18:37 
2018
@@ -16,7 +16,6 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/TokenConcatenation.h"
 #include "clang/Rewrite/Core/HTMLRewrite.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
@@ -401,6 +400,12 @@ void PlistPrinter::ReportNote(raw_ostrea
 // Static function definitions.
 
//===--===//
 
+static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
+  const Preprocessor &PP) {
+  // TODO: Implement macro expansion.
+  return { "", "" };
+}
+
 /// Print coverage information to output stream {@code o}.
 /// May modify the used list of files {@code Fids} by inserting new ones.
 static void printCoverage(const PathDiagnostic *D,
@@ -716,196 +721,3 @@ void PlistDiagnostics::FlushDiagnosticsI
   // Finish.
   o << "\n";
 }
-
-//===--===//
-// Declarations of helper functions and data structures for expanding macros.
-//===--===//
-
-namespace {
-
-struct MacroNameAndInfo {
-  std::string Name;
-  const MacroInfo *MI = nullptr;
-
-  MacroNameAndInfo(std::string N, const MacroInfo *MI)
-: Name(std::move(N)), MI(MI) {}
-};
-
-/// Helper class for printing tokens.
-class TokenPrinter {
-  llvm::raw_ostream &OS;
-  const Preprocessor &PP;
-
-  Token PrevTok, PrevPrevTok;
-  TokenConcatenation ConcatInfo;
-
-public:
-  TokenPrinter(llvm::raw_ostream &OS, const Preprocessor &PP)
-: OS(OS), PP(PP), ConcatInfo(PP) {
-PrevTok.setKind(tok::unknown);
-PrevPrevTok.setKind(tok::unknown);
-  }
-
-  void printToken(const Token &Tok);
-};
-
-} // end of anonymous namespace
-
-static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
- SourceLocation MacroLoc,
- const Preprocessor &PP);
-
-/// Retrieves the name of the macro and its MacroInfo.
-static MacroNameAndInfo getMacroNameAndInfo(SourceLocation ExpanLoc,
-const Preprocessor &PP);
-
-/// Retrieves the ')' token that matches '(' \p It points to.
-static MacroInfo::tokens_iterator getMatchingRParen(
-MacroInfo::tokens_iterator It,
-MacroInfo::tokens_iterator End);
-
-/// Retrieves the macro info for \p II refers to at \p Loc. This is important
-/// because macros can be redefined or undefined.
-static const MacroInfo *getMacroInfoForLocation(const Preprocessor &PP,
-const SourceManager &SM,
-const IdentifierInfo *II,
-SourceLocation Loc);
-
-//===--===//
-// Definitions of helper functions and methods for expanding macros.
-//===--===//
-
-static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
-  const Preprocessor &PP) {
-
-  llvm::SmallString<200> ExpansionBuf;
-  llvm::raw_svector_ostream OS(ExpansionBuf);
-  TokenPrinter Printer(OS, PP);
-  return { getMacroNameAndPrintExpansion(Printer, MacroLoc, PP), OS.str() };
-}
-
-static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
- SourceLocation MacroLoc,
- const Preprocessor &PP) {
-
-  const SourceManager &SM = PP.getSourceManager();
-
-  MacroNameAndInfo Info = getMacroNameAndInfo(SM.getExpansionLoc(MacroLoc), 
PP);
-  const MacroInfo *MI = Info.MI;
-
-  // Iterate over the macro's tokens and stringify them.
-  for (auto It = MI->tokens_begin(), E = MI->tokens_end(); It != E; ++It) {
-Token T = *It;
-
-// If this token is not an identif

r346111 - Reland '[analyzer][PlistMacroExpansion] Part 2.: Retrieving the macro name and primitive expansion'

2018-11-04 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Nov  4 18:14:36 2018
New Revision: 346111

URL: http://llvm.org/viewvc/llvm-project?rev=346111&view=rev
Log:
Reland '[analyzer][PlistMacroExpansion] Part 2.: Retrieving the macro name and 
primitive expansion'

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=346111&r1=346110&r2=346111&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Sun Nov  4 18:14:36 
2018
@@ -16,6 +16,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/TokenConcatenation.h"
 #include "clang/Rewrite/Core/HTMLRewrite.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
@@ -400,12 +401,6 @@ void PlistPrinter::ReportNote(raw_ostrea
 // Static function definitions.
 
//===--===//
 
-static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
-  const Preprocessor &PP) {
-  // TODO: Implement macro expansion.
-  return { "", "" };
-}
-
 /// Print coverage information to output stream {@code o}.
 /// May modify the used list of files {@code Fids} by inserting new ones.
 static void printCoverage(const PathDiagnostic *D,
@@ -721,3 +716,196 @@ void PlistDiagnostics::FlushDiagnosticsI
   // Finish.
   o << "\n";
 }
+
+//===--===//
+// Declarations of helper functions and data structures for expanding macros.
+//===--===//
+
+namespace {
+
+struct MacroNameAndInfo {
+  std::string Name;
+  const MacroInfo *MI = nullptr;
+
+  MacroNameAndInfo(std::string N, const MacroInfo *MI)
+: Name(std::move(N)), MI(MI) {}
+};
+
+/// Helper class for printing tokens.
+class TokenPrinter {
+  llvm::raw_ostream &OS;
+  const Preprocessor &PP;
+
+  Token PrevTok, PrevPrevTok;
+  TokenConcatenation ConcatInfo;
+
+public:
+  TokenPrinter(llvm::raw_ostream &OS, const Preprocessor &PP)
+: OS(OS), PP(PP), ConcatInfo(PP) {
+PrevTok.setKind(tok::unknown);
+PrevPrevTok.setKind(tok::unknown);
+  }
+
+  void printToken(const Token &Tok);
+};
+
+} // end of anonymous namespace
+
+static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
+ SourceLocation MacroLoc,
+ const Preprocessor &PP);
+
+/// Retrieves the name of the macro and its MacroInfo.
+static MacroNameAndInfo getMacroNameAndInfo(SourceLocation ExpanLoc,
+const Preprocessor &PP);
+
+/// Retrieves the ')' token that matches '(' \p It points to.
+static MacroInfo::tokens_iterator getMatchingRParen(
+MacroInfo::tokens_iterator It,
+MacroInfo::tokens_iterator End);
+
+/// Retrieves the macro info for \p II refers to at \p Loc. This is important
+/// because macros can be redefined or undefined.
+static const MacroInfo *getMacroInfoForLocation(const Preprocessor &PP,
+const SourceManager &SM,
+const IdentifierInfo *II,
+SourceLocation Loc);
+
+//===--===//
+// Definitions of helper functions and methods for expanding macros.
+//===--===//
+
+static ExpansionInfo getExpandedMacro(SourceLocation MacroLoc,
+  const Preprocessor &PP) {
+
+  llvm::SmallString<200> ExpansionBuf;
+  llvm::raw_svector_ostream OS(ExpansionBuf);
+  TokenPrinter Printer(OS, PP);
+  return { getMacroNameAndPrintExpansion(Printer, MacroLoc, PP), OS.str() };
+}
+
+static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
+ SourceLocation MacroLoc,
+ const Preprocessor &PP) {
+
+  const SourceManager &SM = PP.getSourceManager();
+
+  MacroNameAndInfo Info = getMacroNameAndInfo(SM.getExpansionLoc(MacroLoc), 
PP);
+  const MacroInfo *MI = Info.MI;
+
+  // Iterate over the macro's tokens and stringify them.
+  for (auto It = MI->tokens_begin(), E = MI->tokens_end(); It != E; ++It) {
+Token T = *It;
+
+// If this token is not an identif

r346112 - Ensure the correct order of evaluation in part 2. of PlistMacroExpansion

2018-11-04 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Nov  4 18:37:29 2018
New Revision: 346112

URL: http://llvm.org/viewvc/llvm-project?rev=346112&view=rev
Log:
Ensure the correct order of evaluation in part 2. of PlistMacroExpansion

Windows buildbots break with the previous commit 
'[analyzer][PlistMacroExpansion]
Part 2.: Retrieving the macro name and primitive expansion'. This patch attempts
to solve this issue.

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=346112&r1=346111&r2=346112&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Sun Nov  4 18:37:29 
2018
@@ -781,7 +781,8 @@ static ExpansionInfo getExpandedMacro(So
   llvm::SmallString<200> ExpansionBuf;
   llvm::raw_svector_ostream OS(ExpansionBuf);
   TokenPrinter Printer(OS, PP);
-  return { getMacroNameAndPrintExpansion(Printer, MacroLoc, PP), OS.str() };
+  std::string MacroName = getMacroNameAndPrintExpansion(Printer, MacroLoc, PP);
+  return { MacroName, OS.str() };
 }
 
 static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r346113 - [analyzer] Restrict AnalyzerOptions' interface so that non-checker objects have to be registered

2018-11-04 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Nov  4 19:50:37 2018
New Revision: 346113

URL: http://llvm.org/viewvc/llvm-project?rev=346113&view=rev
Log:
[analyzer] Restrict AnalyzerOptions' interface so that non-checker objects have 
to be registered

One of the reasons why AnalyzerOptions is so chaotic is that options can be
retrieved from the command line whenever and wherever. This allowed for some
options to be forgotten for a looong time. Have you ever heard of
"region-store-small-struct-limit"? In order to prevent this in the future, I'm
proposing to restrict AnalyzerOptions' interface so that only checker options
can be retrieved without special getters. I would like to make every option be
accessible only through a getter, but checkers from plugins are a thing, so I'll
have to figure something out for that.

This also forces developers who'd like to add a new option to register it
properly in the .def file.

This is done by

* making the third checker pointer parameter non-optional, and checked by an
  assert to be non-null.
* I added new, but private non-checkers option initializers, meant only for
  internal use,
* Renamed these methods accordingly (mind the consistent name for once with
  getBooleanOption!):
  - getOptionAsString -> getCheckerStringOption,
  - getOptionAsInteger -> getCheckerIntegerOption
* The 3 functions meant for initializing data members (with the not very
  descriptive getBooleanOption, getOptionAsString and getOptionAsUInt names)
  were renamed to be overloads of the getAndInitOption function name.
* All options were in some way retrieved via getCheckerOption. I removed it, and
  moved the logic to getStringOption and getCheckerStringOption. This did cause
  some code duplication, but that's the only way I could do it, now that checker
  and non-checker options are separated. Note that the non-checker version
  inserts the new option to the ConfigTable with the default value, but the
  checker version only attempts to find already existing entries. This is how
  it always worked, but this is clunky and I might end reworking that too, so we
  can eventually get a ConfigTable that contains the entire configuration of the
  analyzer.

Differential Revision: https://reviews.llvm.org/D53483

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp

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=346113&r1=346112&r2=346113&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Sun Nov  4 
19:50:37 2018
@@ -137,6 +137,28 @@ enum UserModeKind {
   UMK_Deep = 2
 };
 
+/// Stores options for the analyzer from the command line.
+///
+/// Some options are frontend flags (e.g.: -analyzer-output), but some are
+/// analyzer configuration options, which are preceded by -analyzer-config
+/// (e.g.: -analyzer-config notes-as-events=true).
+///
+/// If you'd like to add a new frontend flag, add it to
+/// include/clang/Driver/CC1Options.td, add a new field to store the value of
+/// that flag in this class, and initialize it in
+/// lib/Frontend/CompilerInvocation.cpp.
+///
+/// If you'd like to add a new non-checker configuration, register it in
+/// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the
+/// top of the file for documentation.
+///
+/// If you'd like to add a new checker option, call getChecker*Option()
+/// whenever.
+///
+/// Some of the options are controlled by raw frontend flags for no good 
reason,
+/// and should be eventually converted into -analyzer-config flags. New 
analyzer
+/// options should not be implemented as frontend flags. Frontend flags still
+/// make sense for things that do not affect the actual analysis.
 class AnalyzerOptions : public RefCountedBase {
 public:
   using ConfigTable = llvm::StringMap;
@@ -209,32 +231,21 @@ private:
 #undef ANALYZER_OPTIO

r346680 - [analyzer] Drastically simplify the tblgen files used for checkers

2018-11-12 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Nov 12 09:49:51 2018
New Revision: 346680

URL: http://llvm.org/viewvc/llvm-project?rev=346680&view=rev
Log:
[analyzer] Drastically simplify the tblgen files used for checkers

Interestingly, only about the quarter of the emitter file is used, the DescFile
entry hasn't ever been touched [1], and the entire concept of groups is a
mystery, so I removed them.

[1] http://lists.llvm.org/pipermail/cfe-dev/2018-October/059664.html

Differential Revision: https://reviews.llvm.org/D53995

Modified:
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/ClangCheckers.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ClangSACheckers.h
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
cfe/trunk/utils/TableGen/ClangSACheckersEmitter.cpp

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=346680&r1=346679&r2=346680&view=diff
==
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Mon Nov 12 09:49:51 2018
@@ -106,11 +106,11 @@ def analyzer_checker : Separate<["-"], "
   ValuesCode<[{
 const char *Values =
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, DESCFILE, HT, G, H)  FULLNAME ","
+#define CHECKER(FULLNAME, CLASS, HT)  FULLNAME ","
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef GET_CHECKERS
 #define GET_PACKAGES
-#define PACKAGE(FULLNAME, G, D)  FULLNAME ","
+#define PACKAGE(FULLNAME)  FULLNAME ","
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef GET_PACKAGES
 ;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td?rev=346680&r1=346679&r2=346680&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td Mon Nov 12 
09:49:51 2018
@@ -11,29 +11,34 @@
 //
 
//===--===//
 
-class CheckerGroup {
-  string GroupName = name;
-}
-class InGroup { CheckerGroup Group = G; }
-
+/// Describes a package. Every checker is a part of a package, for example,
+/// 'NullDereference' is part of the 'core' package, hence it's full name is
+/// 'core.NullDereference'.
+/// Example:
+///   def Core : Package<"core">;
 class Package {
   string   PackageName = name;
-  bit  Hidden = 0;
   Package ParentPackage;
-  CheckerGroup Group;
 }
-class InPackage { Package ParentPackage = P; }
 
-// All checkers are an indirect subclass of this.
+/// Describes a 'super' package that holds another package inside it. This is
+/// used to nest packages in one another. One may, for example, create the
+/// 'builtin' package inside 'core', thus creating the package 'core.builtin'.
+/// Example:
+///   def CoreBuiltin : Package<"builtin">, ParentPackage;
+class ParentPackage { Package ParentPackage = P; }
+
+/// A description. May be displayed to the user when clang is invoked with
+/// a '-help'-like command line option.
+class HelpText { string HelpText = text; }
+
+/// Describes a checker. Every builtin checker has to be registered with the 
use
+/// of this class (out-of-trunk checkers loaded from plugins obviously don't).
+/// Note that a checker has a name (e.g.: 'NullDereference'), and a fullname,
+/// that is autogenerated with the help of the ParentPackage field, that also
+/// includes package names (e.g.: 'core.NullDereference').
 class Checker {
   string  CheckerName = name;
-  string  DescFile;
   string  HelpText;
-  bit Hidden = 0;
   Package ParentPackage;
-  CheckerGroup Group;
 }
-
-class DescFile { string DescFile = filename; }
-class HelpText { string HelpText = text; }
-class Hidden { bit Hidden = 1; }

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=346680&r1=346679&r2=346680&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Mon Nov 12 
09:49:51 2018
@@ -21,9 +21,9 @@ include "CheckerBase.td"
 def Alpha : Package<"alpha">;
 
 def Core : Package<"core">;
-def CoreBuiltin : Package<"builtin">, InPackage;
-def CoreUninitialized  : Package<"uninitialized">, InPackage;
-def CoreAlp

r347006 - [analyzer] ConversionChecker: handle floating point

2018-11-15 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Nov 15 17:00:55 2018
New Revision: 347006

URL: http://llvm.org/viewvc/llvm-project?rev=347006&view=rev
Log:
[analyzer] ConversionChecker: handle floating point

Extend the alpha.core.Conversion checker to handle implicit converions
where a too large integer value is converted to a floating point type. Each
floating point type has a range where it can exactly represent all integers; we
emit a warning when the integer value is above this range. Although it is
possible to exactly represent some integers which are outside of this range
(those that are divisible by a large enough power of 2); we still report cast
involving those, because their usage may lead to bugs. (For example, if 1<<24
is stored in a float variable x, then x==x+1 holds.)

Patch by: Donát Nagy!

Differential Revision: https://reviews.llvm.org/D52730

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
cfe/trunk/test/Analysis/conversion.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp?rev=347006&r1=347005&r2=347006&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp Thu Nov 15 
17:00:55 2018
@@ -14,8 +14,10 @@
 // of expressions. A warning is reported when:
 // * a negative value is implicitly converted to an unsigned value in an
 //   assignment, comparison or multiplication.
-// * assignment / initialization when source value is greater than the max
-//   value of target
+// * assignment / initialization when the source value is greater than the max
+//   value of the target integer type
+// * assignment / initialization when the source integer is above the range
+//   where the target floating point type can represent all integers
 //
 // Many compilers and tools have similar checks that are based on semantic
 // analysis. Those checks are sound but have poor precision. ConversionChecker
@@ -28,6 +30,9 @@
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/ADT/APFloat.h"
+
+#include 
 
 using namespace clang;
 using namespace ento;
@@ -40,11 +45,9 @@ public:
 private:
   mutable std::unique_ptr BT;
 
-  // Is there loss of precision
   bool isLossOfPrecision(const ImplicitCastExpr *Cast, QualType DestType,
  CheckerContext &C) const;
 
-  // Is there loss of sign
   bool isLossOfSign(const ImplicitCastExpr *Cast, CheckerContext &C) const;
 
   void reportBug(ExplodedNode *N, CheckerContext &C, const char Msg[]) const;
@@ -132,19 +135,51 @@ bool ConversionChecker::isLossOfPrecisio
 
   QualType SubType = Cast->IgnoreParenImpCasts()->getType();
 
-  if (!DestType->isIntegerType() || !SubType->isIntegerType())
+  if (!DestType->isRealType() || !SubType->isIntegerType())
 return false;
 
-  if (C.getASTContext().getIntWidth(DestType) >=
-  C.getASTContext().getIntWidth(SubType))
+  const bool isFloat = DestType->isFloatingType();
+
+  const auto &AC = C.getASTContext();
+
+  // We will find the largest RepresentsUntilExp value such that the DestType
+  // can exactly represent all nonnegative integers below 2^RepresentsUntilExp.
+  unsigned RepresentsUntilExp;
+
+  if (isFloat) {
+const llvm::fltSemantics &Sema = AC.getFloatTypeSemantics(DestType);
+RepresentsUntilExp = llvm::APFloat::semanticsPrecision(Sema);
+  } else {
+RepresentsUntilExp = AC.getIntWidth(DestType);
+if (RepresentsUntilExp == 1) {
+  // This is just casting a number to bool, probably not a bug.
+  return false;
+}
+if (DestType->isSignedIntegerType())
+  RepresentsUntilExp--;
+  }
+
+  if (RepresentsUntilExp >= sizeof(unsigned long long) * CHAR_BIT) {
+// Avoid overflow in our later calculations.
 return false;
+  }
+
+  unsigned CorrectedSrcWidth = AC.getIntWidth(SubType);
+  if (SubType->isSignedIntegerType())
+CorrectedSrcWidth--;
 
-  unsigned W = C.getASTContext().getIntWidth(DestType);
-  if (W == 1 || W >= 64U)
+  if (RepresentsUntilExp >= CorrectedSrcWidth) {
+// Simple case: the destination can store all values of the source type.
 return false;
+  }
 
-  unsigned long long MaxVal = 1ULL << W;
+  unsigned long long MaxVal = 1ULL << RepresentsUntilExp;
+  if (isFloat) {
+// If this is a floating point type, it can also represent MaxVal exactly.
+MaxVal++;
+  }
   return C.isGreaterOrEqual(Cast->getSubExpr(), MaxVal);
+  // TODO: maybe also check negative values with too large magnitude.
 }
 
 bool ConversionChecker::isLossOfSign(const ImplicitCastExpr *Cast,

Modified: cfe/trunk/test/Analysis/conversion.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/conversion.c?rev=3

r347153 - [analyzer][UninitializedObjectChecker] Uninit regions are only reported once

2018-11-18 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Nov 18 03:34:10 2018
New Revision: 347153

URL: http://llvm.org/viewvc/llvm-project?rev=347153&view=rev
Log:
[analyzer][UninitializedObjectChecker] Uninit regions are only reported once

Especially with pointees, a lot of meaningless reports came from uninitialized
regions that were already reported. This is fixed by storing all reported fields
to the GDM.

Differential Revision: https://reviews.llvm.org/D51531

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=347153&r1=347152&r2=347153&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Sun Nov 18 03:34:10 2018
@@ -215,7 +215,11 @@ public:
   const TypedValueRegion *const R,
   const UninitObjCheckerOptions &Opts);
 
-  const UninitFieldMap &getUninitFields() { return UninitFields; }
+  /// Returns with the modified state and a map of (uninitialized region,
+  /// note message) pairs.
+  std::pair getResults() {
+return {State, UninitFields};
+  }
 
   /// Returns whether the analyzed region contains at least one initialized
   /// field. Note that this includes subfields as well, not just direct ones,
@@ -296,14 +300,16 @@ private:
   // TODO: Add a support for nonloc::LocAsInteger.
 
   /// Processes LocalChain and attempts to insert it into UninitFields. Returns
-  /// true on success.
+  /// true on success. Also adds the head of the list and \p PointeeR (if
+  /// supplied) to the GDM as already analyzed objects.
   ///
   /// Since this class analyzes regions with recursion, we'll only store
   /// references to temporary FieldNode objects created on the stack. This 
means
   /// that after analyzing a leaf of the directed tree described above, the
   /// elements LocalChain references will be destructed, so we can't store it
   /// directly.
-  bool addFieldToUninits(FieldChainInfo LocalChain);
+  bool addFieldToUninits(FieldChainInfo LocalChain,
+ const MemRegion *PointeeR = nullptr);
 };
 
 /// Returns true if T is a primitive type. An object of a primitive type only

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=347153&r1=347152&r2=347153&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Sun Nov 18 03:34:10 2018
@@ -28,9 +28,14 @@
 using namespace clang;
 using namespace clang::ento;
 
+/// We'll mark fields (and pointee of fields) that are confirmed to be
+/// uninitialized as already analyzed.
+REGISTER_SET_WITH_PROGRAMSTATE(AnalyzedRegions, const MemRegion *)
+
 namespace {
 
-class UninitializedObjectChecker : public Checker {
+class UninitializedObjectChecker
+: public Checker {
   std::unique_ptr BT_uninitField;
 
 public:
@@ -39,7 +44,9 @@ public:
 
   UninitializedObjectChecker()
   : BT_uninitField(new BuiltinBug(this, "Uninitialized fields")) {}
+
   void checkEndFunction(const ReturnStmt *RS, CheckerContext &C) const;
+  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
 };
 
 /// A basic field type, that is not a pointer or a reference, it's dynamic and
@@ -140,14 +147,20 @@ void UninitializedObjectChecker::checkEn
 
   FindUninitializedFields F(Context.getState(), R, Opts);
 
-  const UninitFieldMap &UninitFields = F.getUninitFields();
+  std::pair UninitInfo =
+  F.getResults();
 
-  if (UninitFields.empty())
+  ProgramStateRef UpdatedState = UninitInfo.first;
+  const UninitFieldMap &UninitFields = UninitInfo.second;
+
+  if (UninitFields.empty()) {
+Context.addTransition(UpdatedState);
 return;
+  }
 
   // There are uninitialized fields in the record.
 
-  ExplodedNode *Node = Context.generateNonFatalErrorNode(Context.getState());
+  ExplodedNode *Node = Context.generateNonFatalErrorNode(UpdatedState);
   if (!Node)
 return;
 
@@ -188,6 +201,15 @@ void UninitializedObjectChecker::checkEn
   Context.emitReport(std::move(Report));
 }
 
+void Uninitiali

r347157 - [analyzer][NFC] Move CheckerOptInfo to CheckerRegistry.cpp, and make it local

2018-11-18 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Nov 18 04:47:03 2018
New Revision: 347157

URL: http://llvm.org/viewvc/llvm-project?rev=347157&view=rev
Log:
[analyzer][NFC] Move CheckerOptInfo to CheckerRegistry.cpp, and make it local

CheckerOptInfo feels very much out of place in CheckerRegistration.cpp, so I
moved it to CheckerRegistry.h.

Differential Revision: https://reviews.llvm.org/D54397

Removed:
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp

Removed: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h?rev=347156&view=auto
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h (removed)
@@ -1,44 +0,0 @@
-//===--- CheckerOptInfo.h - Specifies which checkers to use -*- C++ 
-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===--===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
-#define LLVM_CLANG_STATICANALYZER_CORE_CHECKEROPTINFO_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/StringRef.h"
-
-namespace clang {
-namespace ento {
-
-/// Represents a request to include or exclude a checker or package from a
-/// specific analysis run.
-///
-/// \sa CheckerRegistry::initializeManager
-class CheckerOptInfo {
-  StringRef Name;
-  bool Enable;
-  bool Claimed;
-
-public:
-  CheckerOptInfo(StringRef name, bool enable)
-: Name(name), Enable(enable), Claimed(false) { }
-
-  StringRef getName() const { return Name; }
-  bool isEnabled() const { return Enable; }
-  bool isDisabled() const { return !isEnabled(); }
-
-  bool isClaimed() const { return Claimed; }
-  bool isUnclaimed() const { return !isClaimed(); }
-  void claim() { Claimed = true; }
-};
-
-} // end namespace ento
-} // end namespace clang
-
-#endif

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h?rev=347157&r1=347156&r2=347157&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerRegistry.h Sun Nov 18 
04:47:03 2018
@@ -73,8 +73,6 @@ class DiagnosticsEngine;
 
 namespace ento {
 
-class CheckerOptInfo;
-
 /// Manages a set of available checkers for running a static analysis.
 /// The checkers are organized into packages by full name, where including
 /// a package will recursively include all subpackages and checkers within it.
@@ -123,8 +121,8 @@ public:
   /// all checkers specified by the given CheckerOptInfo list. The order of 
this
   /// list is significant; later options can be used to reverse earlier ones.
   /// This can be used to exclude certain checkers in an included package.
-  void initializeManager(CheckerManager &mgr,
- SmallVectorImpl &opts) const;
+  void initializeManager(CheckerManager &mgr, const AnalyzerOptions &Opts,
+ DiagnosticsEngine &diags) const;
 
   /// Check if every option corresponds to a specific checker or package.
   void validateCheckerOptions(const AnalyzerOptions &opts,
@@ -133,8 +131,7 @@ public:
   /// Prints the name and description of all checkers in this registry.
   /// This output is not intended to be machine-parseable.
   void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
-  void printList(raw_ostream &out,
- SmallVectorImpl &opts) const;
+  void printList(raw_ostream &out, const AnalyzerOptions &opts) const;
 
 private:
   mutable CheckerInfoList Checkers;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp?rev=347157&r1=347156&r2=347157&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CheckerRegistry.cpp Sun Nov 18 04:47:03 
2018
@@ -12,7 +12,6 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/CheckerOptInfo.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
@@ -30,6 +29,41 

r347513 - [analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

2018-11-24 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Nov 24 04:24:27 2018
New Revision: 347513

URL: http://llvm.org/viewvc/llvm-project?rev=347513&view=rev
Log:
[analyzer] INT50-CPP. Do not cast to an out-of-range enumeration checker

This checker implements a solution to the "INT50-CPP. Do not cast to an
out-of-range enumeration value" rule [1].
It lands in alpha for now, and a number of followup patches are planned in order
to enable it by default.

[1] 
https://www.securecoding.cert.org/confluence/display/cplusplus/INT50-CPP.+Do+not+cast+to+an+out-of-range+enumeration+value

Patch by: Endre Fülöp and Alexander Zaitsev!

Differential Revision: https://reviews.llvm.org/D33672

Added:
cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
cfe/trunk/test/Analysis/enum-cast-out-of-range.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
cfe/trunk/www/analyzer/alpha_checks.html

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=347513&r1=347512&r2=347513&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Sat Nov 24 
04:24:27 2018
@@ -290,6 +290,9 @@ def DeleteWithNonVirtualDtorChecker : Ch
   HelpText<"Reports destructions of polymorphic objects with a non-virtual "
"destructor in their base class">;
 
+def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">,
+  HelpText<"Check integer to enumeration casts for out of range values">;
+
 def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">,
   HelpText<"Check for use of invalidated iterators">;
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=347513&r1=347512&r2=347513&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Sat Nov 24 04:24:27 
2018
@@ -34,6 +34,7 @@ add_clang_library(clangStaticAnalyzerChe
   DivZeroChecker.cpp
   DynamicTypePropagation.cpp
   DynamicTypeChecker.cpp
+  EnumCastOutOfRangeChecker.cpp
   ExprInspectionChecker.cpp
   FixedAddressChecker.cpp
   GCDAntipatternChecker.cpp

Added: cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp?rev=347513&view=auto
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp (added)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp Sat Nov 
24 04:24:27 2018
@@ -0,0 +1,128 @@
+//===- EnumCastOutOfRangeChecker.cpp ---*- C++ 
-*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// The EnumCastOutOfRangeChecker is responsible for checking integer to
+// enumeration casts that could result in undefined values. This could happen
+// if the value that we cast from is out of the value range of the enumeration.
+// Reference:
+// [ISO/IEC 14882-2014] ISO/IEC 14882-2014.
+//   Programming Languages — C++, Fourth Edition. 2014.
+// C++ Standard, [dcl.enum], in paragraph 8, which defines the range of an enum
+// C++ Standard, [expr.static.cast], paragraph 10, which defines the behaviour
+//   of casting an integer value that is out of range
+// SEI CERT C++ Coding Standard, INT50-CPP. Do not cast to an out-of-range
+//   enumeration value
+//===--===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+// This evaluator checks two SVals for equality. The first SVal is provided via
+// the constructor, the second is the parameter of the overloaded () operator.
+// It uses the in-built ConstraintManager to resolve the equlity to possible or
+// not possible ProgramStates.
+class ConstraintBasedEQEvaluator {
+  const DefinedOrUnknownSVal CompareValue;
+  const ProgramStateRef PS;
+  SValBuilder &SVB;
+
+public:
+  ConstraintBasedEQEvaluator(CheckerContext &C,
+ const DefinedOrUnknownSVal CompareValue)
+  : CompareValue(CompareValue), PS(C.getState()), SVB(C.getSValBuilder()) 
{}
+

r347888 - [analyzer][PlistMacroExpansion] Part 4.: Support for __VA_ARGS__

2018-11-29 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Nov 29 09:09:41 2018
New Revision: 347888

URL: http://llvm.org/viewvc/llvm-project?rev=347888&view=rev
Log:
[analyzer][PlistMacroExpansion] Part 4.: Support for __VA_ARGS__

Differential Revision: https://reviews.llvm.org/D52986

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=347888&r1=347887&r2=347888&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Thu Nov 29 09:09:41 
2018
@@ -962,41 +962,62 @@ static MacroNameAndArgs getMacroNameAndA
   //   CALL_FN(someFunctionName(param1, param2))
   // we will find tok::l_paren, tok::r_paren, and tok::comma that do not divide
   // actual macro arguments, or do not represent the macro argument's closing
-  // parentheses, so we'll count how many parentheses aren't closed yet.
+  // parantheses, so we'll count how many parantheses aren't closed yet.
+  // If ParanthesesDepth
+  //   * = 0, then there are no more arguments to lex.
+  //   * = 1, then if we find a tok::comma, we can start lexing the next arg.
+  //   * > 1, then tok::comma is a part of the current arg.
   int ParenthesesDepth = 1;
 
+  // If we encounter __VA_ARGS__, we will lex until the closing tok::r_paren,
+  // even if we lex a tok::comma and ParanthesesDepth == 1.
+  const IdentifierInfo *__VA_ARGS__II = PP.getIdentifierInfo("__VA_ARGS__");
+
   for (const IdentifierInfo *UnexpArgII : MacroArgs) {
 MacroArgMap::mapped_type ExpandedArgTokens;
 
-// Lex the first token of the next macro parameter.
-RawLexer.LexFromRawLexer(TheTok);
-
-while (TheTok.isNot(tok::comma) || ParenthesesDepth != 1) {
-  assert(TheTok.isNot(tok::eof) &&
- "EOF encountered while looking for expanded macro args!");
-
-  if (TheTok.is(tok::l_paren))
-++ParenthesesDepth;
-
-  if (TheTok.is(tok::r_paren))
---ParenthesesDepth;
+// One could also simply not supply a single argument to __VA_ARGS__ -- 
this
+// results in a preprocessor warning, but is not an error:
+//   #define VARIADIC(ptr, ...) \
+// someVariadicTemplateFunction(__VA_ARGS__)
+//
+//   int *ptr;
+//   VARIADIC(ptr); // Note that there are no commas, this isn't just an
+//  // empty parameter -- there are no parameters for 
'...'.
+// In any other case, ParenthesesDepth mustn't be 0 here.
+if (ParenthesesDepth != 0) {
 
-  if (ParenthesesDepth == 0)
-break;
-
-  if (TheTok.is(tok::raw_identifier))
-PP.LookUpIdentifierInfo(TheTok);
-
-  ExpandedArgTokens.push_back(TheTok);
+  // Lex the first token of the next macro parameter.
   RawLexer.LexFromRawLexer(TheTok);
+
+  while (!(ParenthesesDepth == 1 &&
+  (UnexpArgII == __VA_ARGS__II ? false : TheTok.is(tok::comma {
+assert(TheTok.isNot(tok::eof) &&
+   "EOF encountered while looking for expanded macro args!");
+
+if (TheTok.is(tok::l_paren))
+  ++ParenthesesDepth;
+
+if (TheTok.is(tok::r_paren))
+  --ParenthesesDepth;
+
+if (ParenthesesDepth == 0)
+  break;
+
+if (TheTok.is(tok::raw_identifier))
+  PP.LookUpIdentifierInfo(TheTok);
+
+ExpandedArgTokens.push_back(TheTok);
+RawLexer.LexFromRawLexer(TheTok);
+  }
+} else {
+  assert(UnexpArgII == __VA_ARGS__II);
 }
 
 Args.emplace(UnexpArgII, std::move(ExpandedArgTokens));
   }
 
-  // TODO: The condition really should be TheTok.is(tok::r_paren), but variadic
-  // macro arguments are not handled yet.
-  assert(TheTok.isOneOf(tok::r_paren, tok::comma) &&
+  assert(TheTok.is(tok::r_paren) &&
  "Expanded macro argument acquisition failed! After the end of the 
loop"
  " this token should be ')'!");
 

Modified: 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist?rev=347888&r1=347887&r2=347888&view=diff
==
--- 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 (original)
+++ 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 Thu Nov 29 09:09:41 2018
@@ -4217,7 +4217,7 @@
   file0
  
  nameVARIADIC_SET_TO_NULL
- expansionptr = nullptr; variadicFunc( 1)
+ expansionptr = nullptr; variadicFunc( 1, 5, 
"haha!")
 

  

r348025 - [analyzer][PlistMacroExpansion] Part 5.: Support for # and ##

2018-11-30 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov 30 11:21:35 2018
New Revision: 348025

URL: http://llvm.org/viewvc/llvm-project?rev=348025&view=rev
Log:
[analyzer][PlistMacroExpansion] Part 5.: Support for # and ##

From what I can see, this should be the last patch needed to replicate macro
argument expansions.

Differential Revision: https://reviews.llvm.org/D52988

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=348025&r1=348024&r2=348025&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Fri Nov 30 11:21:35 
2018
@@ -904,8 +904,6 @@ static std::string getMacroNameAndPrintE
   continue;
 }
 
-// TODO: Handle tok::hash and tok::hashhash.
-
 // If control reached here, then this token isn't a macro identifier, nor 
an
 // unexpanded macro argument that we need to handle, print it.
 Printer.printToken(T);
@@ -1094,14 +1092,25 @@ void MacroArgMap::expandFromPrevMacro(co
 }
 
 void TokenPrinter::printToken(const Token &Tok) {
-  // If the tokens were already space separated, or if they must be to avoid
-  // them being implicitly pasted, add a space between them.
   // If this is the first token to be printed, don't print space.
-  if (PrevTok.isNot(tok::unknown) && (Tok.hasLeadingSpace() ||
-  ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok)))
-OS << ' ';
+  if (PrevTok.isNot(tok::unknown)) {
+// If the tokens were already space separated, or if they must be to avoid
+// them being implicitly pasted, add a space between them.
+if(Tok.hasLeadingSpace() || ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok,
+   Tok)) {
+  // AvoidConcat doesn't check for ##, don't print a space around it.
+  if (PrevTok.isNot(tok::hashhash) && Tok.isNot(tok::hashhash)) {
+OS << ' ';
+  }
+}
+  }
 
-  OS << PP.getSpelling(Tok);
+  if (!Tok.isOneOf(tok::hash, tok::hashhash)) {
+if (PrevTok.is(tok::hash))
+  OS << '\"' << PP.getSpelling(Tok) << '\"';
+else
+  OS << PP.getSpelling(Tok);
+  }
 
   PrevPrevTok = PrevTok;
   PrevTok = Tok;

Modified: 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist?rev=348025&r1=348024&r2=348025&view=diff
==
--- 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 (original)
+++ 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 Fri Nov 30 11:21:35 2018
@@ -4555,7 +4555,7 @@
   file0
  
  nameDECLARE_FUNC_AND_SET_TO_NULL
- expansionvoid generated_##whatever(); ptr = 
nullptr;
+ expansionvoid generated_whatever(); ptr = 
nullptr;
 

descriptionDereference of null pointer (loaded from 
variable 'ptr')
@@ -4595,12 +4595,12 @@
 start
  
   
-   line357
+   line352
col3
file0
   
   
-   line357
+   line352
col5
file0
   
@@ -4608,12 +4608,181 @@
 end
  
   
-   line358
+   line353
col3
file0
   
   
-   line358
+   line353
+   col19
+   file0
+  
+ 
+   
+  
+
+
+ kindevent
+ location
+ 
+  line353
+  col3
+  file0
+ 
+ ranges
+ 
+   
+
+ line353
+ col3
+ file0
+
+
+ line353
+ col53
+ file0
+
+   
+ 
+ depth0
+ extended_message
+ Null pointer value stored to 'a'
+ message
+ Null pointer value stored to 'a'
+
+
+ kindcontrol
+ edges
+  
+   
+start
+ 
+  
+   line354
+   col3
+   file0
+  
+  
+   line354
+   col3
+   file0
+  
+ 
+end
+ 
+  
+   line354
+   col6
+   file0
+  
+  
+   line354
+   col6
+   file0
+  
+ 
+   
+  
+
+
+ kindevent
+ location
+ 
+  line354
+  col6
+  file0
+ 
+ ranges
+ 
+   
+
+ line354
+ col4
+ file0
+ 

r348031 - [analyzer] Evaluate all non-checker config options before analysis

2018-11-30 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov 30 12:44:00 2018
New Revision: 348031

URL: http://llvm.org/viewvc/llvm-project?rev=348031&view=rev
Log:
[analyzer] Evaluate all non-checker config options before analysis

In earlier patches regarding AnalyzerOptions, a lot of effort went into
gathering all config options, and changing the interface so that potential
misuse can be eliminited.

Up until this point, AnalyzerOptions only evaluated an option when it was
querried. For example, if we had a "-no-false-positives" flag, AnalyzerOptions
would store an Optional field for it that would be None up until somewhere in
the code until the flag's getter function is called.

However, now that we're confident that we've gathered all configs, we can
evaluate off of them before analysis, so we can emit a error on invalid input
even if that prticular flag will not matter in that particular run of the
analyzer. Another very big benefit of this is that debug.ConfigDumper will now
show the value of all configs every single time.

Also, almost all options related class have a similar interface, so uniformity
is also a benefit.

The implementation for errors on invalid input will be commited shorty.

Differential Revision: https://reviews.llvm.org/D53692

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SValBuilder.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
cfe/trunk/test/Analysis/analyzer-config.c
cfe/trunk/test/Analysis/analyzer-config.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def?rev=348031&r1=348030&r2=348031&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def Fri Nov 30 
12:44:00 2018
@@ -9,29 +9,6 @@
 //
 //  This file defines the analyzer options avaible with -analyzer-config.
 //
-//  This file is in part intended for method generation. If it's not included
-//  for that purpose, the following function-like macros should be predefined,
-//  through which all registered options are accessible:
-//
-//* ANALYZER_OPTION: Register a new option.
-//* ANALYZER_OPTION_DEPENDS_ON_USER_MODE: Register a new option, default
-//  value depends on the "user-mode" option.
-//
-//  Options where a simple getter method is sufficient are registered with the
-//  following macros:
-//
-//* ANALYZER_OPTION_GEN_FN: Register a new option, and generate a getter
-//  method for it in AnalyzerOptions.
-//
-//* ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE: Same as above, but
-//  generates a getter function that depends on the "user-mode" option.
-//
-//  You can only include this file when both or none of the above two macros
-//  are defined!
-//  When they are defined, entries that do not generate functions  won't 
appear,
-//  and when they aren't, all entries are converted to ANALYZER_OPTION or to
-//  ANALYZER_OPTION_DEPENDS_ON_USER_MODE.
-//
 
//===--===//
 
 #ifndef LLVM_ADT_STRINGREF_H
@@ -53,22 +30,6 @@ define both 'ANALYZER_OPTION' and 'ANALY
 #endif
 #endif
 
-#ifdef ANALYZER_OPTION_GEN_FN
-#ifndef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE
-#error If you include this file with the intent of generating functions, \
-define both 'ANALYZER_OPTION_GEN_FN' and \
-'ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE' macros!
-#endif
-#endif
-
-#ifdef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE
-#ifndef ANALYZER_OPTION_GEN_FN
-#error If you include this file with the intent of generating functions, \
-define both 'ANALYZER_OPTION_GEN_FN' and \
-'ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE' macros!
-#endif
-#endif
-
 #ifndef ANALYZER_OPTION
 /// Create a new analyzer option, but 

r348038 - [analyzer] Emit an error for invalid -analyzer-config inputs

2018-11-30 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov 30 13:24:31 2018
New Revision: 348038

URL: http://llvm.org/viewvc/llvm-project?rev=348038&view=rev
Log:
[analyzer] Emit an error for invalid -analyzer-config inputs

Differential Revision: https://reviews.llvm.org/D53280

Added:
cfe/trunk/test/Analysis/invalid-analyzer-config-value.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/Driver/ToolChains/Clang.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=348038&r1=348037&r2=348038&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Fri Nov 30 13:24:31 
2018
@@ -299,6 +299,9 @@ def err_analyzer_config_no_value : Error
   "analyzer-config option '%0' has a key but no value">;
 def err_analyzer_config_multiple_values : Error<
   "analyzer-config option '%0' should contain only one '='">;
+def err_analyzer_config_invalid_input : Error<
+  "invalid input for analyzer-config option '%0', that expects %1 value">;
+def err_analyzer_config_unknown : Error<"unknown analyzer-config '%0'">;
 
 def err_drv_invalid_hvx_length : Error<
   "-mhvx-length is not supported without a -mhvx/-mhvx= flag">;

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=348038&r1=348037&r2=348038&view=diff
==
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Fri Nov 30 13:24:31 2018
@@ -138,6 +138,12 @@ def analyzer_list_enabled_checkers : Fla
 def analyzer_config : Separate<["-"], "analyzer-config">,
   HelpText<"Choose analyzer options to enable">;
 
+def analyzer_config_compatibility_mode : Separate<["-"], 
"analyzer-config-compatibility-mode">,
+  HelpText<"Don't emit errors on invalid analyzer-config inputs">;
+
+def analyzer_config_compatibility_mode_EQ : Joined<["-"], 
"analyzer-config-compatibility-mode=">,
+  Alias;
+
 
//===--===//
 // Migrator Options
 
//===--===//

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=348038&r1=348037&r2=348038&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Nov 30 
13:24:31 2018
@@ -200,6 +200,7 @@ public:
   unsigned ShowCheckerHelp : 1;
   unsigned ShowEnabledCheckerList : 1;
   unsigned ShowConfigOptionsList : 1;
+  unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
   unsigned AnalyzeAll : 1;
   unsigned AnalyzerDisplayProgress : 1;
   unsigned AnalyzeNestedBlocks : 1;
@@ -222,6 +223,7 @@ public:
   /// The mode of function selection used during inlining.
   AnalysisInliningMode InliningMode = NoRedundancy;
 
+  // Create a field for each -analyzer-config option.
 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,
\
  SHALLOW_VAL, DEEP_VAL)
\
   ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
@@ -233,13 +235,39 @@ public:
 #undef ANALYZER_OPTION
 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
 
+  // Create an array of all -analyzer-config command line options. Sort it in
+  // the constructor.
+  std::vector AnalyzerConfigCmdFlags = {
+#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,
\
+ SHALLOW_VAL, DEEP_VAL)
\
+  ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
+
+#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)
\
+CMDFLAG,
+
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
+#undef ANALYZER_OPTION
+#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
+  };
+
+  bool isUnknownAnalyzerConfig(StringRef Name) const {
+
+assert(std::is_sorted(AnalyzerConfigCmdFlags.begin(),
+  AnalyzerConfigCmdFlags.end()));
+
+return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
+   AnalyzerConfigCmdFlags.end(), Name);
+  }
+
   AnalyzerOptions()
   : DisableAllChecks(false), ShowCheckerHelp(false),
 ShowEnabledCheckerList(false), ShowConfigOptionsList(false),
 AnalyzeAll(fa

r348044 - [analyzer] Deleting unnecessary test file

2018-11-30 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Nov 30 14:32:17 2018
New Revision: 348044

URL: http://llvm.org/viewvc/llvm-project?rev=348044&view=rev
Log:
[analyzer] Deleting unnecessary test file

That I really should've done in rC348031.

Removed:
cfe/trunk/test/Analysis/analyzer-config.cpp

Removed: cfe/trunk/test/Analysis/analyzer-config.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.cpp?rev=348043&view=auto
==
--- cfe/trunk/test/Analysis/analyzer-config.cpp (original)
+++ cfe/trunk/test/Analysis/analyzer-config.cpp (removed)
@@ -1,54 +0,0 @@
-// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null 
-analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 
2>&1
-// RUN: FileCheck --input-file=%t %s --match-full-lines
-
-// CHECK: [config]
-// CHECK-NEXT: aggressive-binary-operation-simplification = false
-// CHECK-NEXT: avoid-suppressing-null-argument-paths = false
-// CHECK-NEXT: c++-allocator-inlining = true
-// CHECK-NEXT: c++-container-inlining = false
-// CHECK-NEXT: c++-inlining = destructors
-// CHECK-NEXT: c++-shared_ptr-inlining = false
-// CHECK-NEXT: c++-stdlib-inlining = true
-// CHECK-NEXT: c++-temp-dtor-inlining = true
-// CHECK-NEXT: c++-template-inlining = true
-// CHECK-NEXT: cfg-conditional-static-initializers = true
-// CHECK-NEXT: cfg-implicit-dtors = true
-// CHECK-NEXT: cfg-lifetime = false
-// CHECK-NEXT: cfg-loopexit = false
-// CHECK-NEXT: cfg-rich-constructors = true
-// CHECK-NEXT: cfg-scopes = false
-// CHECK-NEXT: cfg-temporary-dtors = true
-// CHECK-NEXT: crosscheck-with-z3 = false
-// CHECK-NEXT: ctu-dir = ""
-// CHECK-NEXT: ctu-index-name = externalFnMap.txt
-// CHECK-NEXT: eagerly-assume = true
-// CHECK-NEXT: elide-constructors = true
-// CHECK-NEXT:expand-macros = false
-// CHECK-NEXT: experimental-enable-naive-ctu-analysis = false
-// CHECK-NEXT: exploration_strategy = unexplored_first_queue
-// CHECK-NEXT: faux-bodies = true
-// CHECK-NEXT: graph-trim-interval = 1000
-// CHECK-NEXT: inline-lambdas = true
-// CHECK-NEXT: ipa = dynamic-bifurcate
-// CHECK-NEXT: ipa-always-inline-size = 3
-// CHECK-NEXT: max-inlinable-size = 100
-// CHECK-NEXT: max-nodes = 225000
-// CHECK-NEXT: max-symbol-complexity = 35
-// CHECK-NEXT: max-times-inline-large = 32
-// CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
-// CHECK-NEXT: mode = deep
-// CHECK-NEXT: model-path = ""
-// CHECK-NEXT: notes-as-events = false
-// CHECK-NEXT: objc-inlining = true
-// CHECK-NEXT: prune-paths = true
-// CHECK-NEXT: region-store-small-struct-limit = 2
-// CHECK-NEXT: report-in-main-source-file = false
-// CHECK-NEXT: serialize-stats = false
-// CHECK-NEXT: stable-report-filename = false
-// CHECK-NEXT: suppress-c++-stdlib = true
-// CHECK-NEXT: suppress-inlined-defensive-checks = true
-// CHECK-NEXT: suppress-null-return-paths = true
-// CHECK-NEXT: unroll-loops = false
-// CHECK-NEXT: widen-loops = false
-// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 48


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r355297 - [analyzer] Enable subcheckers to possess checker options

2019-03-03 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Mar  3 16:28:16 2019
New Revision: 355297

URL: http://llvm.org/viewvc/llvm-project?rev=355297&view=rev
Log:
[analyzer] Enable subcheckers to possess checker options

Under the term "subchecker", I mean checkers that do not have a checker class on
their own, like unix.MallocChecker to unix.DynamicMemoryModeling.

Since a checker object was required in order to retrieve checker options,
subcheckers couldn't possess options on their own.

This patch is also an excuse to change the argument order of getChecker*Option,
it always bothered me, now it resembles the actual command line argument
(checkername:option=value).

Differential Revision: https://reviews.llvm.org/D57579

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/unittests/StaticAnalyzer/AnalyzerOptionsTest.cpp

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=355297&r1=355296&r2=355297&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Sun Mar  3 
16:28:16 2019
@@ -272,54 +272,74 @@ public:
   /// interpreted as true and the "false" string is interpreted as false.
   ///
   /// If an option value is not provided, returns the given \p DefaultVal.
-  /// @param [in] Name Name for option to retrieve.
+  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
+  /// this from the checker object's field \c Name, or through \c
+  /// CheckerManager::getCurrentCheckName within the checker's registry
+  /// function.
+  /// Checker options are retrieved in the following format:
+  /// `-analyzer-config CheckerName:OptionName=Value.
+  /// @param [in] OptionName Name for option to retrieve.
   /// @param [in] DefaultVal Default value returned if no such option was
   /// specified.
-  /// @param [in] C The checker object the option belongs to. Checker options
-  /// are retrieved in the following format:
-  /// `-analyzer-config :OptionName=Value.
   /// @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 getCheckerBooleanOption(StringRef Name, bool DefaultVal,
-const ento::CheckerBase *C,
-bool SearchInParents = false) const;
+  bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName,
+   bool DefaultVal,
+   bool SearchInParents = false) const;
 
+  bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef 
OptionName,
+   bool DefaultVal,
+   bool SearchInParents = false) const;
 
   /// Interprets an option's string value as an integer value.
   ///
   /// If an option value is not provided, returns the given \p DefaultVal.
-  /// @param [in] Name Name for option to retrieve.
+  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
+  /// this from the checker object's field \c Name, or through \c
+  /// CheckerManager::getCurrentCheckName within the checker's registry
+  /// function.
+  /// Checker options are retrieved in the following format:
+  /// `-analyzer-config CheckerName:OptionName=Value.
+  /// @param [in] OptionName Name for option to retrieve.
   /// @param [in] DefaultVal Default value returned if no such option was
   /// specified.
-  /// @param [in] C The checker object the option belongs to. Checker options
-  /// are retrieved in the following format:
-  /// `-analyzer-config :OptionName=Value.
   /// @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 getCh

r355396 - [analyzer] Fix taint propagation in GenericTaintChecker

2019-03-05 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Mar  5 04:42:59 2019
New Revision: 355396

URL: http://llvm.org/viewvc/llvm-project?rev=355396&view=rev
Log:
[analyzer] Fix taint propagation in GenericTaintChecker

The gets function has no SrcArgs. Because the default value for isTainted was
false, it didn't mark its DstArgs as tainted.

Patch by Gábor Borsik!

Differential Revision: https://reviews.llvm.org/D58828

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
cfe/trunk/test/Analysis/taint-generic.c

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=355396&r1=355395&r2=355396&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Tue Mar  5 
04:42:59 2019
@@ -458,7 +458,7 @@ GenericTaintChecker::TaintPropagationRul
   ProgramStateRef State = C.getState();
 
   // Check for taint in arguments.
-  bool IsTainted = false;
+  bool IsTainted = true;
   for (unsigned ArgNum : SrcArgs) {
 if (ArgNum >= CE->getNumArgs())
   return State;

Modified: cfe/trunk/test/Analysis/taint-generic.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/taint-generic.c?rev=355396&r1=355395&r2=355396&view=diff
==
--- cfe/trunk/test/Analysis/taint-generic.c (original)
+++ cfe/trunk/test/Analysis/taint-generic.c Tue Mar  5 04:42:59 2019
@@ -2,6 +2,7 @@
 // RUN: %clang_analyze_cc1  -DFILE_IS_STRUCT 
-analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 
-Wno-format-security -verify %s
 
 int scanf(const char *restrict format, ...);
+char *gets(char *str);
 int getchar(void);
 
 typedef struct _FILE FILE;
@@ -142,6 +143,12 @@ void testTaintSystemCall3() {
   system(buffern2); // expected-warning {{Untrusted data is passed to a system 
call}}
 }
 
+void testGets() {
+  char str[50];
+  gets(str);
+  system(str); // expected-warning {{Untrusted data is passed to a system 
call}}
+}
+
 void testTaintedBufferSize() {
   size_t ts;
   scanf("%zd", &ts);


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r355703 - [analyzer] Use the new infrastructure of expressing taint propagation, NFC

2019-03-08 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Mar  8 07:47:56 2019
New Revision: 355703

URL: http://llvm.org/viewvc/llvm-project?rev=355703&view=rev
Log:
[analyzer] Use the new infrastructure of expressing taint propagation, NFC

In D55734, we implemented a far more general way of describing taint propagation
rules for functions, like being able to specify an unlimited amount of
source and destination parameters. Previously, we didn't have a particularly
elegant way of expressing the propagation rules for functions that always return
(either through an out-param or return value) a tainted value. In this patch,
we model these functions similarly to other ones, by assigning them a
TaintPropagationRule that describes that they "create a tainted value out of
nothing".

The socket C function is somewhat special, because for certain parameters (for
example, if we supply localhost as parameter), none of the out-params should
be tainted. For this, we added a general solution of being able to specify
custom taint propagation rules through function pointers.

Patch by Gábor Borsik!

Differential Revision: https://reviews.llvm.org/D59055

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=355703&r1=355702&r2=355703&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Fri Mar  8 
07:47:56 2019
@@ -62,9 +62,6 @@ private:
   /// Propagate taint generated at pre-visit.
   bool propagateFromPre(const CallExpr *CE, CheckerContext &C) const;
 
-  /// Add taint sources on a post visit.
-  void addSourcesPost(const CallExpr *CE, CheckerContext &C) const;
-
   /// Check if the region the expression evaluates to is the standard input,
   /// and thus, is tainted.
   static bool isStdin(const Expr *E, CheckerContext &C);
@@ -72,16 +69,6 @@ private:
   /// Given a pointer argument, return the value it points to.
   static Optional getPointedToSVal(CheckerContext &C, const Expr *Arg);
 
-  /// Functions defining the attack surface.
-  using FnCheck = ProgramStateRef (GenericTaintChecker::*)(
-  const CallExpr *, CheckerContext &C) const;
-  ProgramStateRef postScanf(const CallExpr *CE, CheckerContext &C) const;
-  ProgramStateRef postSocket(const CallExpr *CE, CheckerContext &C) const;
-  ProgramStateRef postRetTaint(const CallExpr *CE, CheckerContext &C) const;
-
-  /// Taint the scanned input if the file is tainted.
-  ProgramStateRef preFscanf(const CallExpr *CE, CheckerContext &C) const;
-
   /// Check for CWE-134: Uncontrolled Format String.
   static const char MsgUncontrolledFormatString[];
   bool checkUncontrolledFormatString(const CallExpr *CE,
@@ -118,6 +105,9 @@ private:
   struct TaintPropagationRule {
 enum class VariadicType { None, Src, Dst };
 
+using PropagationFuncType = bool (*)(bool IsTainted, const CallExpr *,
+ CheckerContext &C);
+
 /// List of arguments which can be taint sources and should be checked.
 ArgVector SrcArgs;
 /// List of arguments which should be tainted on function return.
@@ -127,16 +117,21 @@ private:
 /// Show when a function has variadic parameters. If it has, it marks all
 /// of them as source or destination.
 VariadicType VarType;
+/// Special function for tainted source determination. If defined, it can
+/// override the default behavior.
+PropagationFuncType PropagationFunc;
 
 TaintPropagationRule()
-: VariadicIndex(InvalidArgIndex), VarType(VariadicType::None) {}
+: VariadicIndex(InvalidArgIndex), VarType(VariadicType::None),
+  PropagationFunc(nullptr) {}
 
 TaintPropagationRule(std::initializer_list &&Src,
  std::initializer_list &&Dst,
  VariadicType Var = VariadicType::None,
- unsigned VarIndex = InvalidArgIndex)
+ unsigned VarIndex = InvalidArgIndex,
+ PropagationFuncType Func = nullptr)
 : SrcArgs(std::move(Src)), DstArgs(std::move(Dst)),
-  VariadicIndex(VarIndex), VarType(Var) {}
+  VariadicIndex(VarIndex), VarType(Var), PropagationFunc(Func) {}
 
 /// Get the propagation rule for a given function.
 static TaintPropagationRule
@@ -170,6 +165,10 @@ private:
 /// Pre-process a function which propagates taint according to the
 /// taint rule.
 ProgramStateRef process(const CallExpr *CE, CheckerContext &C) const;
+
+// Functions for custom taintedness propagation.
+static bool postSocket(bool IsTainted, const CallExpr *CE,
+   CheckerContext &C);
   };
 };
 
@@ -206,25 +205,42 @@ GenericTaintChecker::Taint

r355704 - [analyzer] Emit an error rather than assert on invalid checker option input

2019-03-08 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Mar  8 08:00:42 2019
New Revision: 355704

URL: http://llvm.org/viewvc/llvm-project?rev=355704&view=rev
Log:
[analyzer] Emit an error rather than assert on invalid checker option input

Asserting on invalid input isn't very nice, hence the patch to emit an error
instead.

This is the first of many patches to overhaul the way we handle checker options.

Differential Revision: https://reviews.llvm.org/D57850

Modified:
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/CheckerManager.cpp
cfe/trunk/test/Analysis/copypaste/suspicious-clones.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp
cfe/trunk/test/Analysis/outofbound.c
cfe/trunk/test/Analysis/padding_c.c
cfe/trunk/test/Analysis/undef-buffers.c
cfe/trunk/test/Analysis/use-after-move.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=355704&r1=355703&r2=355704&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Fri Mar  8 08:00:42 
2019
@@ -303,6 +303,8 @@ def err_analyzer_config_multiple_values
 def err_analyzer_config_invalid_input : Error<
   "invalid input for analyzer-config option '%0', that expects %1 value">;
 def err_analyzer_config_unknown : Error<"unknown analyzer-config '%0'">;
+def err_analyzer_checker_option_invalid_input : Error<
+  "invalid input for checker option '%0', that expects %1">;
 
 def err_drv_invalid_hvx_length : Error<
   "-mhvx-length is not supported without a -mhvx/-mhvx= flag">;

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=355704&r1=355703&r2=355704&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/CheckerManager.h Fri Mar  8 
08:00:42 2019
@@ -136,6 +136,12 @@ public:
   AnalyzerOptions &getAnalyzerOptions() { return AOptions; }
   ASTContext &getASTContext() { return Context; }
 
+  /// Emits an error through a DiagnosticsEngine about an invalid user supplied
+  /// checker option value.
+  void reportInvalidCheckerOptionValue(const CheckerBase *C,
+   StringRef OptionName,
+   StringRef ExpectedValueDesc);
+
   using CheckerRef = CheckerBase *;
   using CheckerTag = const void *;
   using CheckerDtor = CheckerFn;

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp?rev=355704&r1=355703&r2=355704&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp Fri Mar  8 
08:00:42 2019
@@ -1086,14 +1086,10 @@ bool ObjCDeallocChecker::isNibLoadedIvar
 }
 
 void ento::registerObjCDeallocChecker(CheckerManager &Mgr) {
-  const LangOptions &LangOpts = Mgr.getLangOpts();
-  // These checker only makes sense under MRR.
-  if (LangOpts.getGC() == LangOptions::GCOnly || LangOpts.ObjCAutoRefCount)
-return;
-
   Mgr.registerChecker();
 }
 
 bool ento::shouldRegisterObjCDeallocChecker(const LangOptions &LO) {
-  return true;
+  // These checker only makes sense under MRR.
+  return LO.getGC() != LangOptions::GCOnly && !LO.ObjCAutoRefCount;
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp?rev=355704&r1=355703&r2=355704&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CloneChecker.cpp Fri Mar  8 08:00:42 
2019
@@ -27,6 +27,13 @@ using namespace ento;
 namespace {
 class CloneChecker
 : public Checker {
+public:
+  // Checker options.
+  int MinComplexity;
+  bool ReportNormalClones;
+  StringRef IgnoredFilesPattern;
+
+private:
   mutable CloneDetector Detector;
   mutable std::unique_ptr BT_Exact, BT_Suspicious;
 
@@ -62,19 +69,6

r355705 - [analyzer] Fix infinite recursion in printing macros

2019-03-08 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Mar  8 08:26:29 2019
New Revision: 355705

URL: http://llvm.org/viewvc/llvm-project?rev=355705&view=rev
Log:
[analyzer] Fix infinite recursion in printing macros

In the commited testfile, macro expansion (the one implemented for the plist
output) runs into an infinite recursion. The issue originates from the algorithm
being faulty, as in

#define value REC_MACRO_FUNC(value)

the "value" is being (or at least attempted) expanded from the same macro.

The solved this issue by gathering already visited macros in a set, which does
resolve the crash, but will result in an incorrect macro expansion, that would
preferably be fixed down the line.

Patch by Tibor Brunner!

Differential Revision: https://reviews.llvm.org/D57891


Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=355705&r1=355704&r2=355705&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Fri Mar  8 08:26:29 
2019
@@ -22,6 +22,7 @@
 #include "clang/StaticAnalyzer/Core/IssueHash.h"
 #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
 
@@ -776,10 +777,20 @@ public:
 /// As we expand the last line, we'll immediately replace PRINT(str) with
 /// print(x). The information that both 'str' and 'x' refers to the same string
 /// is an information we have to forward, hence the argument \p PrevArgs.
-static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
- SourceLocation MacroLoc,
- const Preprocessor &PP,
- const MacroArgMap &PrevArgs);
+///
+/// To avoid infinite recursion we maintain the already processed tokens in
+/// a set. This is carried as a parameter through the recursive calls. The set
+/// is extended with the currently processed token and after processing it, the
+/// token is removed. If the token is already in the set, then recursion stops:
+///
+/// #define f(y) x
+/// #define x f(x)
+static std::string getMacroNameAndPrintExpansion(
+TokenPrinter &Printer,
+SourceLocation MacroLoc,
+const Preprocessor &PP,
+const MacroArgMap &PrevArgs,
+llvm::SmallPtrSet &AlreadyProcessedTokens);
 
 /// Retrieves the name of the macro and what it's arguments expand into
 /// at \p ExpanLoc.
@@ -828,19 +839,35 @@ static ExpansionInfo getExpandedMacro(So
   llvm::SmallString<200> ExpansionBuf;
   llvm::raw_svector_ostream OS(ExpansionBuf);
   TokenPrinter Printer(OS, PP);
+  llvm::SmallPtrSet AlreadyProcessedTokens;
+
   std::string MacroName =
-getMacroNameAndPrintExpansion(Printer, MacroLoc, PP, 
MacroArgMap{});
+getMacroNameAndPrintExpansion(Printer, MacroLoc, PP, MacroArgMap{},
+ AlreadyProcessedTokens);
   return { MacroName, OS.str() };
 }
 
-static std::string getMacroNameAndPrintExpansion(TokenPrinter &Printer,
- SourceLocation MacroLoc,
- const Preprocessor &PP,
- const MacroArgMap &PrevArgs) {
+static std::string getMacroNameAndPrintExpansion(
+TokenPrinter &Printer,
+SourceLocation MacroLoc,
+const Preprocessor &PP,
+const MacroArgMap &PrevArgs,
+llvm::SmallPtrSet &AlreadyProcessedTokens) {
 
   const SourceManager &SM = PP.getSourceManager();
 
   MacroNameAndArgs Info = getMacroNameAndArgs(SM.getExpansionLoc(MacroLoc), 
PP);
+  IdentifierInfo* IDInfo = PP.getIdentifierInfo(Info.Name);
+
+  // TODO: If the macro definition contains another symbol then this function 
is
+  // called recursively. In case this symbol is the one being defined, it will
+  // be an infinite recursion which is stopped by this "if" statement. However,
+  // in this case we don't get the full expansion text in the Plist file. See
+  // the test file where "value" is expanded to "garbage_" instead of
+  // "garbage_value".
+  if (AlreadyProcessedTokens.find(IDInfo) != AlreadyProcessedTokens.end())
+return Info.Name;
+  AlreadyProcessedTokens.insert(IDInfo);
 
   if (!Info.MI)
 return Info.Name;
@@ -867,7 +894,8 @@ static std::string getMacroNameAndPrintE
 // macro.
 if (const MacroInfo *MI =
  getMacroInfoForLocation(PP, SM, II, T.getLocation())) 
{
-  getMacroNa

r355903 - [analyzer] Fix function macro crash

2019-03-12 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Mar 12 03:03:32 2019
New Revision: 355903

URL: http://llvm.org/viewvc/llvm-project?rev=355903&view=rev
Log:
[analyzer] Fix function macro crash

When there is a functor-like macro which is passed as parameter to another
"function" macro then its parameters are not listed at the place of expansion:

#define foo(x) int bar() { return x; }
#define hello(fvar) fvar(0)
hello(foo)
int main() { 1 / bar(); }

Expansion of hello(foo) asserted Clang, because it expected an l_paren token in
the 3rd line after "foo", since it is a function-like token.

Patch by Tibor Brunner!

Differential Revision: https://reviews.llvm.org/D57893

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=355903&r1=355902&r2=355903&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Tue Mar 12 03:03:32 
2019
@@ -900,7 +900,7 @@ static std::string getMacroNameAndPrintE
   // If this is a function-like macro, skip its arguments, as
   // getExpandedMacro() already printed them. If this is the case, let's
   // first jump to the '(' token.
-  if (MI->getNumParams() != 0)
+  if (std::next(It)->is(tok::l_paren))
 It = getMatchingRParen(++It, E);
   continue;
 }
@@ -928,7 +928,15 @@ static std::string getMacroNameAndPrintE
 
 getMacroNameAndPrintExpansion(Printer, ArgIt->getLocation(), PP,
   Info.Args, AlreadyProcessedTokens);
-if (MI->getNumParams() != 0)
+// Peek the next token if it is a tok::l_paren. This way we can decide
+// if this is the application or just a reference to a function maxro
+// symbol:
+//
+// #define apply(f) ...
+// #define func(x) ...
+// apply(func)
+// apply(func(42))
+if (std::next(ArgIt)->is(tok::l_paren))
   ArgIt = getMatchingRParen(++ArgIt, ArgEnd);
   }
   continue;
@@ -990,8 +998,16 @@ static MacroNameAndArgs getMacroNameAndA
 return { MacroName, MI, {} };
 
   RawLexer.LexFromRawLexer(TheTok);
-  assert(TheTok.is(tok::l_paren) &&
- "The token after the macro's identifier token should be '('!");
+  // When this is a token which expands to another macro function then its
+  // parentheses are not at its expansion locaiton. For example:
+  //
+  // #define foo(x) int bar() { return x; }
+  // #define apply_zero(f) f(0)
+  // apply_zero(foo)
+  //   ^
+  //   This is not a tok::l_paren, but foo is a function.
+  if (TheTok.isNot(tok::l_paren))
+return { MacroName, MI, {} };
 
   MacroArgMap Args;
 

Modified: 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist?rev=355903&r1=355902&r2=355903&view=diff
==
--- 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 (original)
+++ 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 Tue Mar 12 03:03:32 2019
@@ -5577,6 +5577,484 @@

   
   
+  
+   path
+   
+
+ kindcontrol
+ edges
+  
+   
+start
+ 
+  
+   line459
+   col33
+   file0
+  
+  
+   line459
+   col33
+   file0
+  
+ 
+end
+ 
+  
+   line459
+   col37
+   file0
+  
+  
+   line459
+   col39
+   file0
+  
+ 
+   
+  
+
+
+ kindevent
+ location
+ 
+  line459
+  col37
+  file0
+ 
+ ranges
+ 
+   
+
+ line459
+ col37
+ file0
+
+
+ line459
+ col41
+ file0
+
+   
+ 
+ depth0
+ extended_message
+ Calling 'foo'
+ message
+ Calling 'foo'
+
+
+ kindevent
+ location
+ 
+  line458
+  col1
+  file0
+ 
+ depth1
+ extended_message
+ Entered call from 'useZeroApplier1'
+ message
+ Entered call from 'useZeroApplier1'
+
+
+ kindevent
+ location
+ 
+  line458
+  col1
+  file0
+ 
+ ranges
+ 
+   
+
+ line458
+ col1
+ file0
+
+
+ line458
+ col16

r355911 - Revert "[analyzer] Fix function macro crash"

2019-03-12 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Mar 12 04:22:30 2019
New Revision: 355911

URL: http://llvm.org/viewvc/llvm-project?rev=355911&view=rev
Log:
Revert "[analyzer] Fix function macro crash"

Buildbot breaks when LLVm is compiled with memory sanitizer.

WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0xa3d16d8 in getMacroNameAndPrintExpansion(blahblah)
 lib/StaticAnalyzer/Core/PlistDiagnostics.cpp:903:11

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=355911&r1=355910&r2=355911&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Tue Mar 12 04:22:30 
2019
@@ -900,7 +900,7 @@ static std::string getMacroNameAndPrintE
   // If this is a function-like macro, skip its arguments, as
   // getExpandedMacro() already printed them. If this is the case, let's
   // first jump to the '(' token.
-  if (std::next(It)->is(tok::l_paren))
+  if (MI->getNumParams() != 0)
 It = getMatchingRParen(++It, E);
   continue;
 }
@@ -928,15 +928,7 @@ static std::string getMacroNameAndPrintE
 
 getMacroNameAndPrintExpansion(Printer, ArgIt->getLocation(), PP,
   Info.Args, AlreadyProcessedTokens);
-// Peek the next token if it is a tok::l_paren. This way we can decide
-// if this is the application or just a reference to a function maxro
-// symbol:
-//
-// #define apply(f) ...
-// #define func(x) ...
-// apply(func)
-// apply(func(42))
-if (std::next(ArgIt)->is(tok::l_paren))
+if (MI->getNumParams() != 0)
   ArgIt = getMatchingRParen(++ArgIt, ArgEnd);
   }
   continue;
@@ -998,16 +990,8 @@ static MacroNameAndArgs getMacroNameAndA
 return { MacroName, MI, {} };
 
   RawLexer.LexFromRawLexer(TheTok);
-  // When this is a token which expands to another macro function then its
-  // parentheses are not at its expansion locaiton. For example:
-  //
-  // #define foo(x) int bar() { return x; }
-  // #define apply_zero(f) f(0)
-  // apply_zero(foo)
-  //   ^
-  //   This is not a tok::l_paren, but foo is a function.
-  if (TheTok.isNot(tok::l_paren))
-return { MacroName, MI, {} };
+  assert(TheTok.is(tok::l_paren) &&
+ "The token after the macro's identifier token should be '('!");
 
   MacroArgMap Args;
 

Modified: 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist?rev=355911&r1=355910&r2=355911&view=diff
==
--- 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 (original)
+++ 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 Tue Mar 12 04:22:30 2019
@@ -5577,484 +5577,6 @@

   
   
-  
-   path
-   
-
- kindcontrol
- edges
-  
-   
-start
- 
-  
-   line459
-   col33
-   file0
-  
-  
-   line459
-   col33
-   file0
-  
- 
-end
- 
-  
-   line459
-   col37
-   file0
-  
-  
-   line459
-   col39
-   file0
-  
- 
-   
-  
-
-
- kindevent
- location
- 
-  line459
-  col37
-  file0
- 
- ranges
- 
-   
-
- line459
- col37
- file0
-
-
- line459
- col41
- file0
-
-   
- 
- depth0
- extended_message
- Calling 'foo'
- message
- Calling 'foo'
-
-
- kindevent
- location
- 
-  line458
-  col1
-  file0
- 
- depth1
- extended_message
- Entered call from 'useZeroApplier1'
- message
- Entered call from 'useZeroApplier1'
-
-
- kindevent
- location
- 
-  line458
-  col1
-  file0
- 
- ranges
- 
-   
-
- line458
- col1
- file0
-
-
- line458
- col16
- file0
-
-   
- 
- depth1
- extended_message
- Returning zero
- message
- Returning zero
-
-
- kindevent
- location
- 
-  line459
-  col37
-

r356142 - [analyzer] Fix function macro crash

2019-03-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Mar 14 06:38:16 2019
New Revision: 356142

URL: http://llvm.org/viewvc/llvm-project?rev=356142&view=rev
Log:
[analyzer] Fix function macro crash

Re-commit D57893.

Differential Revision: https://reviews.llvm.org/D57893

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=356142&r1=356141&r2=356142&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Thu Mar 14 06:38:16 
2019
@@ -900,7 +900,8 @@ static std::string getMacroNameAndPrintE
   // If this is a function-like macro, skip its arguments, as
   // getExpandedMacro() already printed them. If this is the case, let's
   // first jump to the '(' token.
-  if (MI->getNumParams() != 0)
+  auto N = std::next(It);
+  if (N != E && N->is(tok::l_paren))
 It = getMatchingRParen(++It, E);
   continue;
 }
@@ -928,7 +929,16 @@ static std::string getMacroNameAndPrintE
 
 getMacroNameAndPrintExpansion(Printer, ArgIt->getLocation(), PP,
   Info.Args, AlreadyProcessedTokens);
-if (MI->getNumParams() != 0)
+// Peek the next token if it is a tok::l_paren. This way we can decide
+// if this is the application or just a reference to a function maxro
+// symbol:
+//
+// #define apply(f) ...
+// #define func(x) ...
+// apply(func)
+// apply(func(42))
+auto N = std::next(ArgIt);
+if (N != ArgEnd && N->is(tok::l_paren))
   ArgIt = getMatchingRParen(++ArgIt, ArgEnd);
   }
   continue;
@@ -990,8 +1000,16 @@ static MacroNameAndArgs getMacroNameAndA
 return { MacroName, MI, {} };
 
   RawLexer.LexFromRawLexer(TheTok);
-  assert(TheTok.is(tok::l_paren) &&
- "The token after the macro's identifier token should be '('!");
+  // When this is a token which expands to another macro function then its
+  // parentheses are not at its expansion locaiton. For example:
+  //
+  // #define foo(x) int bar() { return x; }
+  // #define apply_zero(f) f(0)
+  // apply_zero(foo)
+  //   ^
+  //   This is not a tok::l_paren, but foo is a function.
+  if (TheTok.isNot(tok::l_paren))
+return { MacroName, MI, {} };
 
   MacroArgMap Args;
 

Modified: 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist?rev=356142&r1=356141&r2=356142&view=diff
==
--- 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 (original)
+++ 
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-macros-with-expansion.cpp.plist
 Thu Mar 14 06:38:16 2019
@@ -5577,6 +5577,484 @@

   
   
+  
+   path
+   
+
+ kindcontrol
+ edges
+  
+   
+start
+ 
+  
+   line459
+   col33
+   file0
+  
+  
+   line459
+   col33
+   file0
+  
+ 
+end
+ 
+  
+   line459
+   col37
+   file0
+  
+  
+   line459
+   col39
+   file0
+  
+ 
+   
+  
+
+
+ kindevent
+ location
+ 
+  line459
+  col37
+  file0
+ 
+ ranges
+ 
+   
+
+ line459
+ col37
+ file0
+
+
+ line459
+ col41
+ file0
+
+   
+ 
+ depth0
+ extended_message
+ Calling 'foo'
+ message
+ Calling 'foo'
+
+
+ kindevent
+ location
+ 
+  line458
+  col1
+  file0
+ 
+ depth1
+ extended_message
+ Entered call from 'useZeroApplier1'
+ message
+ Entered call from 'useZeroApplier1'
+
+
+ kindevent
+ location
+ 
+  line458
+  col1
+  file0
+ 
+ ranges
+ 
+   
+
+ line458
+ col1
+ file0
+
+
+ line458
+ col16
+ file0
+
+   
+ 
+ depth1
+ extended_message
+ Returning zero
+ message
+ Returning zero
+
+
+ kindevent
+ location
+ 
+  line459
+  col37
+  file0
+ 
+ ranges
+ 
+   
+
+ line459
+ col37
+ file0
+
+
+

r356161 - [analyzer] Fix an assertation failure for invalid sourcelocation, add a new debug checker

2019-03-14 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Mar 14 09:10:29 2019
New Revision: 356161

URL: http://llvm.org/viewvc/llvm-project?rev=356161&view=rev
Log:
[analyzer] Fix an assertation failure for invalid sourcelocation, add a new 
debug checker

For a rather short code snippet, if debug.ReportStmts (added in this patch) was
enabled, a bug reporter visitor crashed:

struct h {
  operator int();
};

int k() {
  return h();
}

Ultimately, this originated from PathDiagnosticLocation::createMemberLoc, as it
didn't handle the case where it's MemberExpr typed parameter returned and
invalid SourceLocation for MemberExpr::getMemberLoc. The solution was to find
any related valid SourceLocaion, and Stmt::getBeginLoc happens to be just that.

Differential Revision: https://reviews.llvm.org/D58777

Added:
cfe/trunk/test/Analysis/diagnostics/invalid-srcloc-fix.cpp
Modified:
cfe/trunk/docs/analyzer/developer-docs/DebugChecks.rst
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
cfe/trunk/test/Analysis/plist-html-macros.c

Modified: cfe/trunk/docs/analyzer/developer-docs/DebugChecks.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/developer-docs/DebugChecks.rst?rev=356161&r1=356160&r2=356161&view=diff
==
--- cfe/trunk/docs/analyzer/developer-docs/DebugChecks.rst (original)
+++ cfe/trunk/docs/analyzer/developer-docs/DebugChecks.rst Thu Mar 14 09:10:29 
2019
@@ -285,3 +285,10 @@ There is also an additional -analyzer-st
 statistics within the analyzer engine. Note the Stats checker (which produces 
at
 least one bug report per function) may actually change the values reported by
 -analyzer-stats.
+
+Output testing checkers
+===
+
+- debug.ReportStmts reports a warning at **every** statement, making it a very
+  useful tool for testing thoroughly bug report construction and output
+  emission.

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=356161&r1=356160&r2=356161&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Thu Mar 14 
09:10:29 2019
@@ -1019,6 +1019,10 @@ def ExplodedGraphViewer : Checker<"ViewE
   HelpText<"View Exploded Graphs using GraphViz">,
   Documentation;
 
+def ReportStmts : Checker<"ReportStmts">,
+  HelpText<"Emits a warning for every statement.">,
+  Documentation;
+
 } // end "debug"
 
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp?rev=356161&r1=356160&r2=356161&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp Thu Mar 14 09:10:29 
2019
@@ -266,3 +266,34 @@ void ento::registerExplodedGraphViewer(C
 bool ento::shouldRegisterExplodedGraphViewer(const LangOptions &LO) {
   return true;
 }
+
+//===--===//
+// Emits a report for every Stmt that the analyzer visits.
+//===--===//
+
+namespace {
+
+class ReportStmts : public Checker> {
+  BuiltinBug BT_stmtLoc{this, "Statement"};
+
+public:
+  void checkPreStmt(const Stmt *S, CheckerContext &C) const {
+ExplodedNode *Node = C.generateNonFatalErrorNode();
+if (!Node)
+  return;
+
+auto Report = llvm::make_unique(BT_stmtLoc, "Statement", Node);
+
+C.emitReport(std::move(Report));
+  }
+};
+
+} // end of anonymous namespace
+
+void ento::registerReportStmts(CheckerManager &mgr) {
+  mgr.registerChecker();
+}
+
+bool ento::shouldRegisterReportStmts(const LangOptions &LO) {
+  return true;
+}

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp?rev=356161&r1=356160&r2=356161&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp Thu Mar 14 09:10:29 
2019
@@ -571,6 +571,8 @@ static SourceLocation getValidSourceLoca
 } while (!L.isValid());
   }
 
+  // FIXME: Ironically, this assert actually fails in some cases.
+  //assert(L.isValid());
   return L;
 }
 
@@ -671,7 +673,15 @@ PathDiagnosticLocation::createConditiona
 PathDiagnosticLocation
 PathDiagnosticLocation::createMemberLoc(const MemberExpr *ME,

r358609 - [analyzer] PR41185: Fix regression where __builtin_* functions weren't recognized

2019-04-17 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed Apr 17 12:56:40 2019
New Revision: 358609

URL: http://llvm.org/viewvc/llvm-project?rev=358609&view=rev
Log:
[analyzer] PR41185: Fix regression where __builtin_* functions weren't 
recognized

For the following code snippet:

void builtin_function_call_crash_fixes(char *c) {
  __builtin_strncpy(c, "", 6);
  __builtin_memset(c, '\0', (0));
  __builtin_memcpy(c, c, 0);
}
security.insecureAPI.DeprecatedOrUnsafeBufferHandling caused a regression, as it
didn't recognize functions starting with __builtin_. Fixed exactly that.

I wanted to modify an existing test file, but the two I found didn't seem like
perfect candidates. While I was there, I prettified their RUN: lines.

Differential Revision: https://reviews.llvm.org/D59812


Added:
cfe/trunk/test/Analysis/security-syntax-checks.c
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
cfe/trunk/test/Analysis/security-syntax-checks-no-emit.c
cfe/trunk/test/Analysis/security-syntax-checks.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp?rev=358609&r1=358608&r2=358609&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp Wed Apr 
17 12:56:40 2019
@@ -740,7 +740,11 @@ void WalkAST::checkDeprecatedOrUnsafeBuf
   // Issue a warning. ArgIndex == -1: Deprecated but not unsafe (has size
   // restrictions).
   enum { DEPR_ONLY = -1, UNKNOWN_CALL = -2 };
+
   StringRef Name = FD->getIdentifier()->getName();
+  if (Name.startswith("__builtin_"))
+Name = Name.substr(10);
+
   int ArgIndex =
   llvm::StringSwitch(Name)
   .Cases("scanf", "wscanf", "vscanf", "vwscanf", 0)

Modified: cfe/trunk/test/Analysis/security-syntax-checks-no-emit.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/security-syntax-checks-no-emit.c?rev=358609&r1=358608&r2=358609&view=diff
==
--- cfe/trunk/test/Analysis/security-syntax-checks-no-emit.c (original)
+++ cfe/trunk/test/Analysis/security-syntax-checks-no-emit.c Wed Apr 17 
12:56:40 2019
@@ -1,4 +1,7 @@
-// RUN: %clang_analyze_cc1 -triple i686-pc-linux-gnu 
-analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i686-pc-linux-gnu %s -verify \
+// RUN:   -analyzer-checker=security.insecureAPI \
+// RUN:   -analyzer-checker=security.FloatLoopCounter
+
 // expected-no-diagnostics
 
 // This file complements 'security-syntax-checks.m', but tests that we omit

Added: cfe/trunk/test/Analysis/security-syntax-checks.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/security-syntax-checks.c?rev=358609&view=auto
==
--- cfe/trunk/test/Analysis/security-syntax-checks.c (added)
+++ cfe/trunk/test/Analysis/security-syntax-checks.c Wed Apr 17 12:56:40 2019
@@ -0,0 +1,8 @@
+// RUN: %clang_analyze_cc1 %s -verify \
+// RUN:   -analyzer-checker=security.insecureAPI
+
+void builtin_function_call_crash_fixes(char *c) {
+  __builtin_strncpy(c, "", 6); // expected-warning{{Call to function 'strncpy' 
is insecure as it does not provide security checks introduced in the C11 
standard.}}
+  __builtin_memset(c, '\0', (0)); // expected-warning{{Call to function 
'memset' is insecure as it does not provide security checks introduced in the 
C11 standard.}}
+  __builtin_memcpy(c, c, 0); // expected-warning{{Call to function 'memcpy' is 
insecure as it does not provide security checks introduced in the C11 
standard.}}
+}

Modified: cfe/trunk/test/Analysis/security-syntax-checks.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/security-syntax-checks.m?rev=358609&r1=358608&r2=358609&view=diff
==
--- cfe/trunk/test/Analysis/security-syntax-checks.m (original)
+++ cfe/trunk/test/Analysis/security-syntax-checks.m Wed Apr 17 12:56:40 2019
@@ -1,11 +1,40 @@
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 
-analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS 
-analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DVARIANT 
-analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS 
-DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s 
-verify
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi 
-analyzer-checker=security.insecureAPI,security.FloatLoopCoun

r358676 - [analyzer][NFC] Use capital variable names, move methods out-of-line, rename some in CheckerRegistry

2019-04-18 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Apr 18 08:19:16 2019
New Revision: 358676

URL: http://llvm.org/viewvc/llvm-project?rev=358676&view=rev
Log:
[analyzer][NFC] Use capital variable names, move methods out-of-line, rename 
some in CheckerRegistry

There are barely any lines I haven't changed in these files, so I think I could
might as well leave it in an LLVM coding style conforming state. I also renamed
2 functions and moved addDependency out of line to ease on followup patches.

Differential Revision: https://reviews.llvm.org/D59457

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h?rev=358676&r1=358675&r2=358676&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h Thu Apr 
18 08:19:16 2019
@@ -164,40 +164,23 @@ public:
 
   /// Makes the checker with the full name \p fullName depends on the checker
   /// called \p dependency.
-  void addDependency(StringRef fullName, StringRef dependency) {
-auto CheckerThatNeedsDeps =
-   [&fullName](const CheckerInfo &Chk) { return Chk.FullName == fullName; 
};
-auto Dependency =
-  [&dependency](const CheckerInfo &Chk) {
-return Chk.FullName == dependency;
-  };
-
-auto CheckerIt = llvm::find_if(Checkers, CheckerThatNeedsDeps);
-assert(CheckerIt != Checkers.end() &&
-   "Failed to find the checker while attempting to set up it's "
-   "dependencies!");
-
-auto DependencyIt = llvm::find_if(Checkers, Dependency);
-assert(DependencyIt != Checkers.end() &&
-   "Failed to find the dependency of a checker!");
-
-CheckerIt->Dependencies.push_back(&*DependencyIt);
-  }
+  void addDependency(StringRef FullName, StringRef Dependency);
 
   // FIXME: This *really* should be added to the frontend flag descriptions.
   /// Initializes a CheckerManager by calling the initialization functions for
   /// all checkers specified by the given CheckerOptInfo list. The order of 
this
   /// list is significant; later options can be used to reverse earlier ones.
   /// This can be used to exclude certain checkers in an included package.
-  void initializeManager(CheckerManager &mgr) const;
+  void initializeManager(CheckerManager &CheckerMgr) const;
 
   /// Check if every option corresponds to a specific checker or package.
   void validateCheckerOptions() const;
 
   /// Prints the name and description of all checkers in this registry.
   /// This output is not intended to be machine-parseable.
-  void printHelp(raw_ostream &out, size_t maxNameChars = 30) const;
-  void printList(raw_ostream &out) const;
+  void printCheckerWithDescList(raw_ostream &Out,
+size_t MaxNameChars = 30) const;
+  void printEnabledCheckerList(raw_ostream &Out) const;
 
 private:
   /// Collect all enabled checkers. The returned container preserves the order
@@ -211,7 +194,7 @@ private:
   CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg);
 
   CheckerInfoList Checkers;
-  llvm::StringMap Packages;
+  llvm::StringMap PackageSizes;
 
   DiagnosticsEngine &Diags;
   AnalyzerOptions &AnOpts;

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp?rev=358676&r1=358675&r2=358676&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp Thu Apr 18 
08:19:16 2019
@@ -50,7 +50,8 @@ void ento::printCheckerHelp(raw_ostream
   out << "OVERVIEW: Clang Static Analyzer Checkers List\n\n";
   out << "USAGE: -analyzer-checker \n\n";
 
-  CheckerRegistry(plugins, diags, anopts, langOpts).printHelp(out);
+  CheckerRegistry(plugins, diags, anopts, langOpts)
+  .printCheckerWithDescList(out);
 }
 
 void ento::printEnabledCheckerList(raw_ostream &out,
@@ -60,7 +61,8 @@ void ento::printEnabledCheckerList(raw_o
const LangOptions &langOpts) {
   out << "OVERVIEW: Clang Static Analyzer Enabled Checkers List\n\n";
 
-  CheckerRegistry(plugins, diags, anopts, langOpts).printList(out);
+  CheckerRegistry(plugins, diags, anopts, langOpts)
+  .printEnabledCheckerList(out);
 }
 
 void ento::printAnalyzerConfigList(raw_ostream &out) {

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyze

r358695 - [analyzer][NFC] Prefer binary searches in CheckerRegistry

2019-04-18 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Apr 18 10:34:45 2019
New Revision: 358695

URL: http://llvm.org/viewvc/llvm-project?rev=358695&view=rev
Log:
[analyzer][NFC] Prefer binary searches in CheckerRegistry

Differential Revision: https://reviews.llvm.org/D59459

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h?rev=358695&r1=358694&r2=358695&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h Thu Apr 
18 10:34:45 2019
@@ -108,8 +108,8 @@ public:
   State_Enabled
 };
 
-InitializationFunction Initialize;
-ShouldRegisterFunction ShouldRegister;
+InitializationFunction Initialize = nullptr;
+ShouldRegisterFunction ShouldRegister = nullptr;
 StringRef FullName;
 StringRef Desc;
 StringRef DocumentationUri;
@@ -129,6 +129,9 @@ public:
 StringRef Name, StringRef Desc, StringRef DocsUri)
 : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc),
   DocumentationUri(DocsUri) {}
+
+// Used for lower_bound.
+explicit CheckerInfo(StringRef FullName) : FullName(FullName) {}
   };
 
   using StateFromCmdLine = CheckerInfo::StateFromCmdLine;

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp?rev=358695&r1=358694&r2=358695&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp Thu Apr 18 
10:34:45 2019
@@ -48,6 +48,28 @@ template  struct FullNameLT {
 using CheckerNameLT = FullNameLT;
 } // end of anonymous namespace
 
+template 
+static
+typename std::conditional::value,
+  typename 
CheckerOrPackageInfoList::const_iterator,
+  typename 
CheckerOrPackageInfoList::iterator>::type
+binaryFind(CheckerOrPackageInfoList &Collection, StringRef FullName) {
+
+  using CheckerOrPackage = typename CheckerOrPackageInfoList::value_type;
+  using CheckerOrPackageFullNameLT = FullNameLT;
+
+  assert(std::is_sorted(Collection.begin(), Collection.end(),
+CheckerOrPackageFullNameLT{}) &&
+ "In order to efficiently gather checkers/packages, this function "
+ "expects them to be already sorted!");
+
+  typename CheckerOrPackageInfoList::value_type Info(FullName);
+
+  return llvm::lower_bound(
+  Collection, Info,
+  FullNameLT{});
+}
+
 static constexpr char PackageSeparator = '.';
 
 static bool isInPackage(const CheckerRegistry::CheckerInfo &Checker,
@@ -69,16 +91,7 @@ static bool isInPackage(const CheckerReg
 
 CheckerRegistry::CheckerInfoListRange
 CheckerRegistry::getMutableCheckersForCmdLineArg(StringRef CmdLineArg) {
-
-  assert(std::is_sorted(Checkers.begin(), Checkers.end(), CheckerNameLT{}) &&
- "In order to efficiently gather checkers, this function expects them "
- "to be already sorted!");
-
-  // Use a binary search to find the possible start of the package.
-  CheckerRegistry::CheckerInfo PackageInfo(nullptr, nullptr, CmdLineArg, "",
-   "");
-  auto It = std::lower_bound(Checkers.begin(), Checkers.end(), PackageInfo,
- CheckerNameLT{});
+  auto It = binaryFind(Checkers, CmdLineArg);
 
   if (!isInPackage(*It, CmdLineArg))
 return {Checkers.end(), Checkers.end()};
@@ -268,24 +281,18 @@ void CheckerRegistry::addChecker(Initial
   }
 }
 
-void CheckerRegistry::addDependency(StringRef FullName, StringRef dependency) {
-  auto CheckerThatNeedsDeps = [&FullName](const CheckerInfo &Chk) {
-return Chk.FullName == FullName;
-  };
-  auto Dependency = [&dependency](const CheckerInfo &Chk) {
-return Chk.FullName == dependency;
-  };
-
-  auto CheckerIt = llvm::find_if(Checkers, CheckerThatNeedsDeps);
-  assert(CheckerIt != Checkers.end() &&
+void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) {
+  auto CheckerIt = binaryFind(Checkers, FullName);
+  assert(CheckerIt != Checkers.end() && CheckerIt->FullName == FullName &&
  "Failed to find the checker while attempting to set up its "
  "dependencies!");
 
-  auto DependencyIt = llvm::find_if(Checkers, Dependency);
+  auto DependencyIt = binaryFind(Checkers, Dependency);
   assert(DependencyIt != Checkers.end() &&
+ DependencyIt->FullName == Dependency &&
  "Failed to find the dependency of a checker!");
 
-  Check

r358694 - [analyzer][NFC] Clang-format CheckerRegistry

2019-04-18 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Apr 18 10:32:51 2019
New Revision: 358694

URL: http://llvm.org/viewvc/llvm-project?rev=358694&view=rev
Log:
[analyzer][NFC] Clang-format CheckerRegistry

Differential Revision: https://reviews.llvm.org/D59458

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h?rev=358694&r1=358693&r2=358694&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h Thu Apr 
18 10:32:51 2019
@@ -81,11 +81,10 @@ namespace ento {
 /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker".
 class CheckerRegistry {
 public:
-  CheckerRegistry(
-  ArrayRef plugins, DiagnosticsEngine &diags,
-  AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
-  ArrayRef>
-  checkerRegistrationFns = {});
+  CheckerRegistry(ArrayRef plugins, DiagnosticsEngine &diags,
+  AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
+  ArrayRef>
+  checkerRegistrationFns = {});
 
   /// Initialization functions perform any necessary setup for a checker.
   /// They should include a call to CheckerManager::registerChecker.
@@ -135,14 +134,11 @@ public:
   using StateFromCmdLine = CheckerInfo::StateFromCmdLine;
 
 private:
-  template 
-  static void initializeManager(CheckerManager &mgr) {
+  template  static void initializeManager(CheckerManager &mgr) {
 mgr.registerChecker();
   }
 
-
-  template 
-  static bool returnTrue(const LangOptions &LO) {
+  template  static bool returnTrue(const LangOptions &LO) {
 return true;
   }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp?rev=358694&r1=358693&r2=358694&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp Thu Apr 18 
10:32:51 2019
@@ -11,8 +11,8 @@
 #include "clang/Basic/LLVM.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/StringMap.h"
@@ -39,8 +39,7 @@ static bool isCompatibleAPIVersion(const
 }
 
 namespace {
-template 
-struct FullNameLT {
+template  struct FullNameLT {
   bool operator()(const T &Lhs, const T &Rhs) {
 return Lhs.FullName < Rhs.FullName;
   }
@@ -76,13 +75,13 @@ CheckerRegistry::getMutableCheckersForCm
  "to be already sorted!");
 
   // Use a binary search to find the possible start of the package.
-  CheckerRegistry::CheckerInfo
-  PackageInfo(nullptr, nullptr, CmdLineArg, "", "");
-  auto It = std::lower_bound(Checkers.begin(), Checkers.end(),
- PackageInfo, CheckerNameLT{});
+  CheckerRegistry::CheckerInfo PackageInfo(nullptr, nullptr, CmdLineArg, "",
+   "");
+  auto It = std::lower_bound(Checkers.begin(), Checkers.end(), PackageInfo,
+ CheckerNameLT{});
 
   if (!isInPackage(*It, CmdLineArg))
-return { Checkers.end(), Checkers.end() };
+return {Checkers.end(), Checkers.end()};
 
   // See how large the package is.
   // If the package doesn't exist, assume the option refers to a single
@@ -94,15 +93,14 @@ CheckerRegistry::getMutableCheckersForCm
   if (PackageSize != PackageSizes.end())
 Size = PackageSize->getValue();
 
-  return { It, It + Size };
+  return {It, It + Size};
 }
 
 CheckerRegistry::CheckerRegistry(
- ArrayRef Plugins, DiagnosticsEngine &Diags,
- AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
- ArrayRef>
- CheckerRegistrationFns)
-  : Diags(Diags), AnOpts(AnOpts), LangOpts(LangOpts) {
+ArrayRef Plugins, DiagnosticsEngine &Diags,
+AnalyzerOptions &AnOpts, const LangOptions &LangOpts,
+ArrayRef> CheckerRegistrationFns)
+: Diags(Diags), AnOpts(AnOpts), LangOpts(LangOpts) {
 
   // Register builtin checkers.
 #define GET_CHECKERS
@@ -135,22 +133,21 @@ CheckerRegistry::CheckerRegistry(
   Diags.Report(diag::warn_incompatible_analyzer_plugin_api)
   << llvm::sys::path::filename(Plugin);
   Diags.Report(diag::note_incompatible_analyzer_plugin_api)
-  << CLANG_ANALYZER_API_VERSION_STRING
-  <

r358750 - [analyzer] Fix an assertion failure if plugins added dependencies

2019-04-19 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Apr 19 04:01:35 2019
New Revision: 358750

URL: http://llvm.org/viewvc/llvm-project?rev=358750&view=rev
Log:
[analyzer] Fix an assertion failure if plugins added dependencies

Ideally, there is no reason behind not being able to depend on checkers that
come from a different plugin (or on builtin checkers) -- however, this is only
possible if all checkers are added to the registry before resolving checker
dependencies. Since I used a binary search in my addDependency method, this also
resulted in an assertion failure (due to CheckerRegistry::Checkers not being
sorted), since the function used by plugins to register their checkers
(clang_registerCheckers) calls addDependency.

This patch resolves this issue by only noting which dependencies have to
established when addDependency is called, and resolves them at a later stage
when no more checkers are added to the registry, by which point
CheckerRegistry::Checkers is already sorted.

Differential Revision: https://reviews.llvm.org/D59461

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
cfe/trunk/test/Analysis/checker-dependencies.c

Modified: cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h?rev=358750&r1=358749&r2=358750&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h Fri Apr 
19 04:01:35 2019
@@ -195,6 +195,12 @@ private:
   CheckerInfoList Checkers;
   llvm::StringMap PackageSizes;
 
+  /// Contains all (Dependendent checker, Dependency) pairs. We need this, as
+  /// we'll resolve dependencies after all checkers were added first.
+  llvm::SmallVector, 0> Dependencies;
+
+  void resolveDependencies();
+
   DiagnosticsEngine &Diags;
   AnalyzerOptions &AnOpts;
   const LangOptions &LangOpts;

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp?rev=358750&r1=358749&r2=358750&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp Fri Apr 19 
04:01:35 2019
@@ -177,6 +177,8 @@ CheckerRegistry::CheckerRegistry(
 #undef CHECKER_DEPENDENCY
 #undef GET_CHECKER_DEPENDENCIES
 
+  resolveDependencies();
+
   // Parse '-analyzer-checker' and '-analyzer-disable-checker' options from the
   // command line.
   for (const std::pair &Opt : AnOpts.CheckersControlList) {
@@ -278,18 +280,26 @@ void CheckerRegistry::addChecker(Initial
   }
 }
 
-void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) {
-  auto CheckerIt = binaryFind(Checkers, FullName);
-  assert(CheckerIt != Checkers.end() && CheckerIt->FullName == FullName &&
- "Failed to find the checker while attempting to set up its "
- "dependencies!");
-
-  auto DependencyIt = binaryFind(Checkers, Dependency);
-  assert(DependencyIt != Checkers.end() &&
- DependencyIt->FullName == Dependency &&
- "Failed to find the dependency of a checker!");
+void CheckerRegistry::resolveDependencies() {
+  for (const std::pair &Entry : Dependencies) {
+auto CheckerIt = binaryFind(Checkers, Entry.first);
+assert(CheckerIt != Checkers.end() && CheckerIt->FullName == Entry.first &&
+   "Failed to find the checker while attempting to set up its "
+   "dependencies!");
+
+auto DependencyIt = binaryFind(Checkers, Entry.second);
+assert(DependencyIt != Checkers.end() &&
+   DependencyIt->FullName == Entry.second &&
+   "Failed to find the dependency of a checker!");
+
+CheckerIt->Dependencies.emplace_back(&*DependencyIt);
+  }
 
-  CheckerIt->Dependencies.emplace_back(&*DependencyIt);
+  Dependencies.clear();
+}
+
+void CheckerRegistry::addDependency(StringRef FullName, StringRef Dependency) {
+  Dependencies.emplace_back(FullName, Dependency);
 }
 
 void CheckerRegistry::initializeManager(CheckerManager &CheckerMgr) const {

Modified: cfe/trunk/test/Analysis/checker-dependencies.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/checker-dependencies.c?rev=358750&r1=358749&r2=358750&view=diff
==
--- cfe/trunk/test/Analysis/checker-dependencies.c (original)
+++ cfe/trunk/test/Analysis/checker-dependencies.c Fri Apr 19 04:01:35 2019
@@ -1,3 +1,20 @@
 // RUN: %clang_analyze_cc1 %s \
 // RUN:   -analyzer-checker=core \
 // RUN:   -analyzer-checker=nullability.NullReturnedFromNonnull
+
+// RUN: %clang_analyze_cc1 %s \
+// RUN:   -analyzer

r358752 - [analyzer][NFC] Reimplement checker options

2019-04-19 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Apr 19 05:32:10 2019
New Revision: 358752

URL: http://llvm.org/viewvc/llvm-project?rev=358752&view=rev
Log:
[analyzer][NFC] Reimplement checker options

TL;DR:

* Add checker and package options to the TableGen files
* Added a new class called CmdLineOption, and both Package and Checker recieved
   a list field.
* Added every existing checker and package option to Checkers.td.
* The CheckerRegistry class
  * Received some comments to most of it's inline classes
  * Received the CmdLineOption and PackageInfo inline classes, a list of
 CmdLineOption was added to CheckerInfo and PackageInfo
  * Added addCheckerOption and addPackageOption
  * Added a new field called Packages, used in addPackageOptions, filled up in
 addPackage

Detailed description:

In the last couple months, a lot of effort was put into tightening the
analyzer's command line interface. The main issue is that it's spectacularly
easy to mess up a lenghty enough invocation of the analyzer, and the user was
given no warnings or errors at all in that case.

We can divide the effort of resolving this into several chapters:

* Non-checker analyzer configurations:
Gather every analyzer configuration into a dedicated file. Emit errors for
non-existent configurations or incorrect values. Be able to list these
configurations. Tighten AnalyzerOptions interface to disallow making such
a mistake in the future.

* Fix the "Checker Naming Bug" by reimplementing checker dependencies:
When cplusplus.InnerPointer was enabled, it implicitly registered
unix.Malloc, which implicitly registered some sort of a modeling checker
from the CStringChecker family. This resulted in all of these checker
objects recieving the name "cplusplus.InnerPointer", making AnalyzerOptions
asking for the wrong checker options from the command line:
  cplusplus.InnerPointer:Optimisic
istead of
  unix.Malloc:Optimistic.
This was resolved by making CheckerRegistry responsible for checker
dependency handling, instead of checkers themselves.

* Checker options: (this patch included!)
Same as the first item, but for checkers.

(+ minor fixes here and there, and everything else that is yet to come)

There were several issues regarding checker options, that non-checker
configurations didn't suffer from: checker plugins are loaded runtime, and they
could add new checkers and new options, meaning that unlike for non-checker
configurations, we can't collect every checker option purely by generating code.
Also, as seen from the "Checker Naming Bug" issue raised above, they are very
rarely used in practice, and all sorts of skeletons fell out of the closet while
working on this project.

They were extremely problematic for users as well, purely because of how long
they were. Consider the following monster of a checker option:

  alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=false

While we were able to verify whether the checker itself (the part before the
colon) existed, any errors past that point were unreported, easily resulting
in 7+ hours of analyses going to waste.

This patch, similarly to how dependencies were reimplemented, uses TableGen to
register checker options into Checkers.td, so that Checkers.inc now contains
entries for both checker and package options. Using the preprocessor,
Checkers.inc is converted into code in CheckerRegistry, adding every builtin
(checkers and packages that have an entry in the Checkers.td file) checker and
package option to the registry. The new addPackageOption and addCheckerOption
functions expose the same functionality to statically-linked non-builtin and
plugin checkers and packages as well.

Emitting errors for incorrect user input, being able to list these options, and
some other functionalies will land in later patches.

Differential Revision: https://reviews.llvm.org/D57855


Added:
cfe/trunk/test/Analysis/invalid-checker-option.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
cfe/trunk/test/Analysis/disable-all-checks.c
cfe/trunk/utils/TableGen/ClangSACheckersEmitter.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td?rev=358752&r1=358751&r2=358752&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Fri Apr 19 05:32:10 
2019
@@ -292,7 +292,7 @@ def err_omp_more_one_clause : Error<
 
 // Static Analyzer Core
 def err_unk

r358797 - [analyzer] Move UninitializedObjectChecker out of alpha

2019-04-19 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Apr 19 16:33:50 2019
New Revision: 358797

URL: http://llvm.org/viewvc/llvm-project?rev=358797&view=rev
Log:
[analyzer] Move UninitializedObjectChecker out of alpha

Moved UninitializedObjectChecker from the 'alpha.cplusplus' to the
'optin.cplusplus' package.

Differential Revision: https://reviews.llvm.org/D58573

Modified:
cfe/trunk/docs/analyzer/checkers.rst
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
cfe/trunk/test/Analysis/cxx-uninitialized-object-inheritance.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-no-dereference.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-notes-as-warnings.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
cfe/trunk/test/Analysis/objcpp-uninitialized-object.mm
cfe/trunk/www/analyzer/alpha_checks.html
cfe/trunk/www/analyzer/available_checks.html

Modified: cfe/trunk/docs/analyzer/checkers.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/checkers.rst?rev=358797&r1=358796&r2=358797&view=diff
==
--- cfe/trunk/docs/analyzer/checkers.rst (original)
+++ cfe/trunk/docs/analyzer/checkers.rst Fri Apr 19 16:33:50 2019
@@ -339,6 +339,110 @@ optin
 
 Checkers for portability, performance or coding style specific rules.
 
+optin.cplusplus.UninitializedObject (C++)
+"""
+
+This checker reports uninitialized fields in objects created after a 
constructor
+call. It doesn't only find direct uninitialized fields, but rather makes a deep
+inspection of the object, analyzing all of it's fields subfields.
+The checker regards inherited fields as direct fields, so one will recieve
+warnings for uninitialized inherited data members as well.
+
+.. code-block:: cpp
+
+ // With Pedantic and CheckPointeeInitialization set to true
+
+ struct A {
+   struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ // note: uninitialized field 'this->bptr->x'
+ int y; // note: uninitialized field 'this->b.y'
+ // note: uninitialized field 'this->bptr->y'
+   };
+   int *iptr; // note: uninitialized pointer 'this->iptr'
+   B b;
+   B *bptr;
+   char *cptr; // note: uninitialized pointee 'this->cptr'
+
+   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+   A::B b;
+   char c;
+   A a(&b, &c); // warning: 6 uninitialized fields
+  //  after the constructor call
+ }
+
+ // With Pedantic set to false and
+ // CheckPointeeInitialization set to true
+ // (every field is uninitialized)
+
+ struct A {
+   struct B {
+ int x;
+ int y;
+   };
+   int *iptr;
+   B b;
+   B *bptr;
+   char *cptr;
+
+   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+   A::B b;
+   char c;
+   A a(&b, &c); // no warning
+ }
+
+ // With Pedantic set to true and
+ // CheckPointeeInitialization set to false
+ // (pointees are regarded as initialized)
+
+ struct A {
+   struct B {
+ int x; // note: uninitialized field 'this->b.x'
+ int y; // note: uninitialized field 'this->b.y'
+   };
+   int *iptr; // note: uninitialized pointer 'this->iptr'
+   B b;
+   B *bptr;
+   char *cptr;
+
+   A (B *bptr, char *cptr) : bptr(bptr), cptr(cptr) {}
+ };
+
+ void f() {
+   A::B b;
+   char c;
+   A a(&b, &c); // warning: 3 uninitialized fields
+  //  after the constructor call
+ }
+
+
+**Options**
+
+This checker has several options which can be set from command line (e.g.
+``-analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true``):
+
+* ``Pedantic`` (boolean). If to false, the checker won't emit warnings for
+  objects that don't have at least one initialized field. Defaults to false.
+
+* ``NotesAsWarnings``  (boolean). If set to true, the checker will emit a
+  warning for each uninitalized field, as opposed to emitting one warning per
+  constructor call, and listing the uninitialized fields that belongs to it in
+  notes. *Defaults to false*.
+
+* ``CheckPointeeInitialization`` (boolean). If set to false, the checker will
+  not analyze the pointee of pointer/reference fields, and will only check
+  whether the object itself is initialized. *Defaults to false*.
+
+* ``IgnoreRecordsWithField`` (string). If supplied, the checker will not 
analyze
+  structures that have a field with a name or type name that matches  the given
+  pattern. *Defaults to ""*.
+
 optin.cplusplus.VirtualCall (C++)
 "
 Check virtual function calls during construction or destruction.
@@ -1383,102 +1487,6 @@ Method calls on a moved-from object and
a.foo();// warn: method call on a 'moved-from' objec

r358877 - [analyzer][www] Moving MoveChecker out of alpha is no longer an open project.

2019-04-22 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Apr 22 02:20:23 2019
New Revision: 358877

URL: http://llvm.org/viewvc/llvm-project?rev=358877&view=rev
Log:
[analyzer][www] Moving MoveChecker out of alpha is no longer an open project.

Modified:
cfe/trunk/www/analyzer/open_projects.html

Modified: cfe/trunk/www/analyzer/open_projects.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/open_projects.html?rev=358877&r1=358876&r2=358877&view=diff
==
--- cfe/trunk/www/analyzer/open_projects.html (original)
+++ cfe/trunk/www/analyzer/open_projects.html Mon Apr 22 02:20:23 2019
@@ -48,16 +48,6 @@ mailing list to notify other members
   (Difficulty: Medium)
   
 
-  alpha.cplusplus.MisusedMovedObject
-The checker emits a warning on objects which were used after
-https://en.cppreference.com/w/cpp/utility/move";>move.
-Currently it has an overly high false positive rate due to classes
-which have a well-defined semantics for use-after-move.
-This property does not hold for STL objects, but is often the case
-for custom containers.
-  (Difficulty: Medium)
-  
-
   alpha.unix.StreamChecker
 A SimpleStreamChecker has been presented in the Building a Checker 
in 24 
 Hours talk 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r359230 - [analyzer][UninitializedObjectChecker] PR41590: Regard _Atomic types as primitive

2019-04-25 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Apr 25 13:00:51 2019
New Revision: 359230

URL: http://llvm.org/viewvc/llvm-project?rev=359230&view=rev
Log:
[analyzer][UninitializedObjectChecker] PR41590: Regard _Atomic types as 
primitive

https://bugs.llvm.org/show_bug.cgi?id=41590

For the following code snippet, UninitializedObjectChecker crashed:

struct MyAtomicInt {
  _Atomic(int) x;
  MyAtomicInt() {}
};

void entry() {
  MyAtomicInt b;
}

The problem was that _Atomic types were not regular records, unions,
dereferencable or primitive, making the checker hit the llvm_unreachable at
lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp:347.
The solution is to regard these types as primitive as well. The test case shows
that with this addition, not only are we able to get rid of the crash, but we
can identify x as uninitialized.

Differential Revision: https://reviews.llvm.org/D61106

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=359230&r1=359229&r2=359230&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Thu Apr 25 13:00:51 2019
@@ -324,7 +324,7 @@ private:
 inline bool isPrimitiveType(const QualType &T) {
   return T->isBuiltinType() || T->isEnumeralType() ||
  T->isMemberPointerType() || T->isBlockPointerType() ||
- T->isFunctionType();
+ T->isFunctionType() || T->isAtomicType();
 }
 
 inline bool isDereferencableType(const QualType &T) {

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp?rev=359230&r1=359229&r2=359230&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp Thu Apr 25 13:00:51 
2019
@@ -1130,3 +1130,18 @@ void fCXX11MemberInitTest2() {
   // TODO: we'd expect the warning: {{2 uninitializeds field}}
   CXX11MemberInitTest2(); // no-warning
 }
+
+//===--===//
+// _Atomic tests.
+//===--===//
+
+struct MyAtomicInt {
+  _Atomic(int) x; // expected-note{{uninitialized field 'this->x'}}
+  int dontGetFilteredByNonPedanticMode = 0;
+
+  MyAtomicInt() {} // expected-warning{{1 uninitialized field}}
+};
+
+void entry() {
+  MyAtomicInt b;
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r359539 - [analyzer][UninitializedObjectChecker] PR41611: Regard vector types as primitive

2019-04-30 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Apr 30 01:47:56 2019
New Revision: 359539

URL: http://llvm.org/viewvc/llvm-project?rev=359539&view=rev
Log:
[analyzer][UninitializedObjectChecker] PR41611: Regard vector types as primitive

https://bugs.llvm.org/show_bug.cgi?id=41611

Similarly to D61106, the checker ran over an llvm_unreachable for vector types:

struct VectorSizeLong {
  VectorSizeLong() {}
  __attribute__((__vector_size__(16))) long x;
};

void __vector_size__LongTest() {
  VectorSizeLong v;
}
Since, according to my short research,

"The vector_size attribute is only applicable to integral and float scalars,
although arrays, pointers, and function return values are allowed in conjunction
with this construct."
[src: 
https://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Vector-Extensions.html#Vector-Extensions]

vector types are safe to regard as primitive.

Differential Revision: https://reviews.llvm.org/D61246


Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=359539&r1=359538&r2=359539&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Tue Apr 30 01:47:56 2019
@@ -324,7 +324,8 @@ private:
 inline bool isPrimitiveType(const QualType &T) {
   return T->isBuiltinType() || T->isEnumeralType() ||
  T->isMemberPointerType() || T->isBlockPointerType() ||
- T->isFunctionType() || T->isAtomicType();
+ T->isFunctionType() || T->isAtomicType() ||
+ T->isVectorType();
 }
 
 inline bool isDereferencableType(const QualType &T) {

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp?rev=359539&r1=359538&r2=359539&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp Tue Apr 30 
01:47:56 2019
@@ -256,6 +256,29 @@ void fCharPointerTest() {
   CharPointerTest();
 }
 
+struct VectorSizePointer {
+  VectorSizePointer() {} // expected-warning{{1 uninitialized field}}
+  __attribute__((__vector_size__(8))) int *x; // expected-note{{uninitialized 
pointer 'this->x'}}
+  int dontGetFilteredByNonPedanticMode = 0;
+};
+
+void __vector_size__PointerTest() {
+  VectorSizePointer v;
+}
+
+struct VectorSizePointee {
+  using MyVectorType = __attribute__((__vector_size__(8))) int;
+  MyVectorType *x;
+
+  VectorSizePointee(decltype(x) x) : x(x) {}
+};
+
+void __vector_size__PointeeTest() {
+  VectorSizePointee::MyVectorType i;
+  // TODO: Report v.x's pointee.
+  VectorSizePointee v(&i);
+}
+
 struct CyclicPointerTest1 {
   int *ptr; // expected-note{{object references itself 'this->ptr'}}
   int dontGetFilteredByNonPedanticMode = 0;

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp?rev=359539&r1=359538&r2=359539&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp Tue Apr 30 01:47:56 
2019
@@ -1132,7 +1132,7 @@ void fCXX11MemberInitTest2() {
 }
 
 
//===--===//
-// _Atomic tests.
+// "Esoteric" primitive type tests.
 
//===--===//
 
 struct MyAtomicInt {
@@ -1142,6 +1142,17 @@ struct MyAtomicInt {
   MyAtomicInt() {} // expected-warning{{1 uninitialized field}}
 };
 
-void entry() {
+void _AtomicTest() {
   MyAtomicInt b;
 }
+
+struct VectorSizeLong {
+  VectorSizeLong() {}
+  __attribute__((__vector_size__(16))) long x;
+};
+
+void __vector_size__LongTest() {
+  // TODO: Warn for v.x.
+  VectorSizeLong v;
+  v.x[0] = 0;
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r359720 - [analyzer] Don't display implementation checkers under -analyzer-checker-help, but do under the new flag -analyzer-checker-help-hidden

2019-05-01 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed May  1 12:56:47 2019
New Revision: 359720

URL: http://llvm.org/viewvc/llvm-project?rev=359720&view=rev
Log:
[analyzer] Don't display implementation checkers under -analyzer-checker-help, 
but do under the new flag -analyzer-checker-help-hidden

During my work on analyzer dependencies, I created a great amount of new
checkers that emitted no diagnostics at all, and were purely modeling some
function or another.

However, the user shouldn't really disable/enable these by hand, hence this
patch, which hides these by default. I intentionally chose not to hide alpha
checkers, because they have a scary enough name, in my opinion, to cause no
surprise when they emit false positives or cause crashes.

The patch introduces the Hidden bit into the TableGen files (you may remember
it before I removed it in D53995), and checkers that are either marked as
hidden, or are in a package that is marked hidden won't be displayed under
-analyzer-checker-help. -analyzer-checker-help-hidden, a new flag meant for
developers only, displays the full list.

Differential Revision: https://reviews.llvm.org/D60925

Added:
cfe/trunk/test/Analysis/show-checker-list.c
Modified:
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp
cfe/trunk/utils/TableGen/ClangSACheckersEmitter.cpp

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=359720&r1=359719&r2=359720&view=diff
==
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed May  1 12:56:47 2019
@@ -107,7 +107,7 @@ def analyzer_checker : Separate<["-"], "
   ValuesCode<[{
 const char *Values =
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HT, DOC_URI)  FULLNAME ","
+#define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN)  FULLNAME ","
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef GET_CHECKERS
 #define GET_PACKAGES
@@ -130,6 +130,10 @@ def analyzer_disable_all_checks : Flag<[
 def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">,
   HelpText<"Display the list of analyzer checkers that are available">;
 
+def analyzer_checker_help_hidden : Flag<["-"], "analyzer-checker-help-hidden">,
+  HelpText<"Display the list of analyzer checkers that are available, "
+   "including modeling checkers">;
+
 def analyzer_config_help : Flag<["-"], "analyzer-config-help">,
   HelpText<"Display the list of -analyzer-config options">;
 

Modified: 
cfe/trunk/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h?rev=359720&r1=359719&r2=359720&view=diff
==
--- 
cfe/trunk/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h 
(original)
+++ 
cfe/trunk/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h 
Wed May  1 12:56:47 2019
@@ -26,7 +26,7 @@ class CheckerManager;
 class CheckerRegistry;
 
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI)
\
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) 
\
   void register##CLASS(CheckerManager &mgr);   
\
   bool shouldRegister##CLASS(const LangOptions &LO);
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td?rev=359720&r1=359719&r2=359720&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/CheckerBase.td Wed May  1 
12:56:47 2019
@@ -49,6 +49,7 @@ class Package {
   // This field is optional.
   list PackageOptions;
   Package ParentPackage;
+  bit Hidden = 0;
 }
 
 /// Describes a 'super' package that holds another package inside it. This is
@@ -91,6 +92,7 @@ class Checker {
   list   Dependenc

r359727 - [analyzer] Fix buildbot failures caused by a forgotten initialization

2019-05-01 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Wed May  1 14:09:32 2019
New Revision: 359727

URL: http://llvm.org/viewvc/llvm-project?rev=359727&view=rev
Log:
[analyzer] Fix buildbot failures caused by a forgotten initialization

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h

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=359727&r1=359726&r2=359727&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Wed May  1 
14:09:32 2019
@@ -261,11 +261,12 @@ public:
 
   AnalyzerOptions()
   : DisableAllChecks(false), ShowCheckerHelp(false),
-ShowEnabledCheckerList(false), ShowConfigOptionsList(false),
-AnalyzeAll(false), AnalyzerDisplayProgress(false),
-AnalyzeNestedBlocks(false), eagerlyAssumeBinOpBifurcation(false),
-TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
-UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false) {
+ShowCheckerHelpHidden(false), ShowEnabledCheckerList(false),
+ShowConfigOptionsList(false), AnalyzeAll(false),
+AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
+eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
+visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
+PrintStats(false), NoRetryExhausted(false) {
 llvm::sort(AnalyzerConfigCmdFlags);
   }
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r359998 - [analyzer][UninitializedObjectChecker] PR41741: Regard all scalar types as primitive.

2019-05-05 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun May  5 12:42:33 2019
New Revision: 359998

URL: http://llvm.org/viewvc/llvm-project?rev=359998&view=rev
Log:
[analyzer][UninitializedObjectChecker] PR41741: Regard all scalar types as 
primitive.

https://bugs.llvm.org/show_bug.cgi?id=41741

Pretty much the same as D61246 and D61106, this time for __complex__ types. Upon
further investigation, I realized that we should regard all types
Type::isScalarType returns true for as primitive, so I merged 
isMemberPointerType(), isBlockPointerType() and isAnyComplexType()` into that
instead.

I also stumbled across yet another bug,
https://bugs.llvm.org/show_bug.cgi?id=41753, but it seems to be unrelated to
this checker.

Differential Revision: https://reviews.llvm.org/D61569

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=359998&r1=359997&r2=359998&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Sun May  5 12:42:33 2019
@@ -323,9 +323,8 @@ private:
 /// needs to be analyzed as much as checking whether their value is undefined.
 inline bool isPrimitiveType(const QualType &T) {
   return T->isBuiltinType() || T->isEnumeralType() ||
- T->isMemberPointerType() || T->isBlockPointerType() ||
  T->isFunctionType() || T->isAtomicType() ||
- T->isVectorType();
+ T->isVectorType() || T->isScalarType();
 }
 
 inline bool isDereferencableType(const QualType &T) {

Modified: cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp?rev=359998&r1=359997&r2=359998&view=diff
==
--- cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp (original)
+++ cfe/trunk/test/Analysis/cxx-uninitialized-object.cpp Sun May  5 12:42:33 
2019
@@ -1,11 +1,15 @@
-// RUN: %clang_analyze_cc1 
-analyzer-checker=core,optin.cplusplus.UninitializedObject \
+// RUN: %clang_analyze_cc1 -std=c++14 -verify  %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=optin.cplusplus.UninitializedObject \
 // RUN:   -analyzer-config optin.cplusplus.UninitializedObject:Pedantic=true 
-DPEDANTIC \
-// RUN:   -analyzer-config 
optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
-// RUN:   -std=c++14 -verify  %s
+// RUN:   -analyzer-config \
+// RUN: optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true
 
-// RUN: %clang_analyze_cc1 
-analyzer-checker=core,optin.cplusplus.UninitializedObject \
-// RUN:   -analyzer-config 
optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true \
-// RUN:   -std=c++14 -verify  %s
+// RUN: %clang_analyze_cc1 -std=c++14 -verify  %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-checker=optin.cplusplus.UninitializedObject \
+// RUN:   -analyzer-config \
+// RUN: optin.cplusplus.UninitializedObject:CheckPointeeInitialization=true
 
 
//===--===//
 // Default constructor test.
@@ -1156,3 +1160,28 @@ void __vector_size__LongTest() {
   VectorSizeLong v;
   v.x[0] = 0;
 }
+
+struct ComplexUninitTest {
+  ComplexUninitTest() {}
+  __complex__ float x;
+  __complex__ int y;
+};
+
+// FIXME: Currently this causes (unrelated to this checker) an assertion
+// failure.
+//
+//struct ComplexInitTest {
+//  ComplexInitTest() {
+//x = {1.0f, 1.0f};
+//y = {1, 1};
+//  }
+//  __complex__ float x;
+//  __complex__ int y;
+//};
+
+void fComplexTest() {
+//  ComplexInitTest x;
+
+  // TODO: we should emit a warning for x2.x and x2.y.
+  ComplexUninitTest x2;
+}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r342834 - [analyzer][UninitializedObjectChecker] Using the new const methods of ImmutableList

2018-09-23 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Sep 23 02:16:27 2018
New Revision: 342834

URL: http://llvm.org/viewvc/llvm-project?rev=342834&view=rev
Log:
[analyzer][UninitializedObjectChecker] Using the new const methods of 
ImmutableList

Differential Revision: https://reviews.llvm.org/D51886

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=342834&r1=342833&r2=342834&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Sun Sep 23 02:16:27 2018
@@ -152,7 +152,6 @@ std::string getVariableName(const FieldD
 /// functions such as add() and replaceHead().
 class FieldChainInfo {
 public:
-  using FieldChainImpl = llvm::ImmutableListImpl;
   using FieldChain = llvm::ImmutableList;
 
 private:
@@ -179,8 +178,8 @@ public:
   bool contains(const FieldRegion *FR) const;
   bool isEmpty() const { return Chain.isEmpty(); }
 
-  const FieldRegion *getUninitRegion() const;
-  const FieldNode &getHead() { return Chain.getHead(); }
+  const FieldNode &getHead() const { return Chain.getHead(); }
+  const FieldRegion *getUninitRegion() const { return getHead().getRegion(); }
 
   void printNoteMsg(llvm::raw_ostream &Out) const;
 };

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=342834&r1=342833&r2=342834&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Sun Sep 23 02:16:27 2018
@@ -339,14 +339,6 @@ bool FindUninitializedFields::isPrimitiv
 //   Methods for FieldChainInfo.
 
//===--===//
 
-const FieldRegion *FieldChainInfo::getUninitRegion() const {
-  assert(!Chain.isEmpty() && "Empty fieldchain!");
-
-  // ImmutableList::getHead() isn't a const method, hence the not too nice
-  // implementation.
-  return (*Chain.begin()).getRegion();
-}
-
 bool FieldChainInfo::contains(const FieldRegion *FR) const {
   for (const FieldNode &Node : Chain) {
 if (Node.isSameRegion(FR))
@@ -360,7 +352,7 @@ bool FieldChainInfo::contains(const Fiel
 /// recursive function to print the fieldchain correctly. The last element in
 /// the chain is to be printed by `FieldChainInfo::print`.
 static void printTail(llvm::raw_ostream &Out,
-  const FieldChainInfo::FieldChainImpl *L);
+  const FieldChainInfo::FieldChain L);
 
 // FIXME: This function constructs an incorrect string in the following case:
 //
@@ -379,8 +371,7 @@ void FieldChainInfo::printNoteMsg(llvm::
   if (Chain.isEmpty())
 return;
 
-  const FieldChainImpl *L = Chain.getInternalPointer();
-  const FieldNode &LastField = L->getHead();
+  const FieldNode &LastField = getHead();
 
   LastField.printNoteMsg(Out);
   Out << '\'';
@@ -389,20 +380,20 @@ void FieldChainInfo::printNoteMsg(llvm::
 Node.printPrefix(Out);
 
   Out << "this->";
-  printTail(Out, L->getTail());
+  printTail(Out, Chain.getTail());
   LastField.printNode(Out);
   Out << '\'';
 }
 
 static void printTail(llvm::raw_ostream &Out,
-  const FieldChainInfo::FieldChainImpl *L) {
-  if (!L)
+  const FieldChainInfo::FieldChain L) {
+  if (L.isEmpty())
 return;
 
-  printTail(Out, L->getTail());
+  printTail(Out, L.getTail());
 
-  L->getHead().printNode(Out);
-  L->getHead().printSeparator(Out);
+  L.getHead().printNode(Out);
+  L.getHead().printSeparator(Out);
 }
 
 
//===--===//


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r343204 - [Lex] TokenConcatenation now takes const Preprocessor

2018-09-27 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Sep 27 05:40:16 2018
New Revision: 343204

URL: http://llvm.org/viewvc/llvm-project?rev=343204&view=rev
Log:
[Lex] TokenConcatenation now takes const Preprocessor

Differential Revision: https://reviews.llvm.org/D52502

Modified:
cfe/trunk/include/clang/Lex/TokenConcatenation.h
cfe/trunk/lib/Lex/TokenConcatenation.cpp

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

Modified: cfe/trunk/include/clang/Lex/TokenConcatenation.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/TokenConcatenation.h?rev=343204&r1=343203&r2=343204&view=diff
==
--- cfe/trunk/include/clang/Lex/TokenConcatenation.h (original)
+++ cfe/trunk/include/clang/Lex/TokenConcatenation.h Thu Sep 27 05:40:16 2018
@@ -29,7 +29,7 @@ namespace clang {
   /// and ")" next to each other is safe.
   ///
   class TokenConcatenation {
-Preprocessor &PP;
+const Preprocessor &PP;
 
 enum AvoidConcatInfo {
   /// By default, a token never needs to avoid concatenation.  Most tokens
@@ -56,7 +56,7 @@ namespace clang {
 /// method.
 char TokenInfo[tok::NUM_TOKENS];
   public:
-TokenConcatenation(Preprocessor &PP);
+TokenConcatenation(const Preprocessor &PP);
 
 bool AvoidConcat(const Token &PrevPrevTok,
  const Token &PrevTok,

Modified: cfe/trunk/lib/Lex/TokenConcatenation.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/TokenConcatenation.cpp?rev=343204&r1=343203&r2=343204&view=diff
==
--- cfe/trunk/lib/Lex/TokenConcatenation.cpp (original)
+++ cfe/trunk/lib/Lex/TokenConcatenation.cpp Thu Sep 27 05:40:16 2018
@@ -67,7 +67,7 @@ bool TokenConcatenation::IsIdentifierStr
   return IsStringPrefix(StringRef(PP.getSpelling(Tok)), LangOpts.CPlusPlus11);
 }
 
-TokenConcatenation::TokenConcatenation(Preprocessor &pp) : PP(pp) {
+TokenConcatenation::TokenConcatenation(const Preprocessor &pp) : PP(pp) {
   memset(TokenInfo, 0, sizeof(TokenInfo));
 
   // These tokens have custom code in AvoidConcat.
@@ -126,7 +126,7 @@ TokenConcatenation::TokenConcatenation(P
 
 /// GetFirstChar - Get the first character of the token \arg Tok,
 /// avoiding calls to getSpelling where possible.
-static char GetFirstChar(Preprocessor &PP, const Token &Tok) {
+static char GetFirstChar(const Preprocessor &PP, const Token &Tok) {
   if (IdentifierInfo *II = Tok.getIdentifierInfo()) {
 // Avoid spelling identifiers, the most common form of token.
 return II->getNameStart()[0];

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=343204&r1=343203&r2=343204&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Thu Sep 27 05:40:16 2018
@@ -79,9 +79,9 @@ class FieldNode {
 protected:
   const FieldRegion *FR;
 
-  /// FieldNodes are never meant to be created on the heap, see
-  /// FindUninitializedFields::addFieldToUninits().
-  /* non-virtual */ ~FieldNode() = default;
+  // TODO: This destructor shouldn't be virtual, but breaks buildbots with
+  // -Werror -Wnon-virtual-dtor.
+  virtual ~FieldNode() = default;
 
 public:
   FieldNode(const FieldRegion *FR) : FR(FR) {}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r343205 - Revert untintentionally commited changes

2018-09-27 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Thu Sep 27 05:46:37 2018
New Revision: 343205

URL: http://llvm.org/viewvc/llvm-project?rev=343205&view=rev
Log:
Revert untintentionally commited changes

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=343205&r1=343204&r2=343205&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Thu Sep 27 05:46:37 2018
@@ -79,9 +79,9 @@ class FieldNode {
 protected:
   const FieldRegion *FR;
 
-  // TODO: This destructor shouldn't be virtual, but breaks buildbots with
-  // -Werror -Wnon-virtual-dtor.
-  virtual ~FieldNode() = default;
+  /// FieldNodes are never meant to be created on the heap, see
+  /// FindUninitializedFields::addFieldToUninits().
+  /* non-virtual */ ~FieldNode() = default;
 
 public:
   FieldNode(const FieldRegion *FR) : FR(FR) {}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r343511 - [analyzer][NFC] Refactor functions in PlistDiagnostics to take Preproc as parameter

2018-10-01 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Oct  1 11:11:51 2018
New Revision: 343511

URL: http://llvm.org/viewvc/llvm-project?rev=343511&view=rev
Log:
[analyzer][NFC] Refactor functions in PlistDiagnostics to take Preproc as 
parameter

This is patch is a preparation for the proposed inclusion of macro expansions 
in the plist output.

Differential Revision: https://reviews.llvm.org/D52735

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=343511&r1=343510&r2=343511&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Mon Oct  1 11:11:51 
2018
@@ -31,13 +31,13 @@ using namespace markup;
 namespace {
   class PlistDiagnostics : public PathDiagnosticConsumer {
 const std::string OutputFile;
-const LangOptions &LangOpts;
+const Preprocessor &PP;
 const bool SupportsCrossFileDiagnostics;
 const bool SerializeStatistics;
   public:
 PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
  const std::string& prefix,
- const LangOptions &LangOpts,
+ const Preprocessor &PP,
  bool supportsMultipleFiles);
 
 ~PlistDiagnostics() override {}
@@ -61,10 +61,9 @@ namespace {
 
 PlistDiagnostics::PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
const std::string& output,
-   const LangOptions &LO,
+   const Preprocessor &PP,
bool supportsMultipleFiles)
-  : OutputFile(output),
-LangOpts(LO),
+  : OutputFile(output), PP(PP),
 SupportsCrossFileDiagnostics(supportsMultipleFiles),
 SerializeStatistics(AnalyzerOpts.shouldSerializeStats()) {}
 
@@ -72,23 +71,20 @@ void ento::createPlistDiagnosticConsumer
  PathDiagnosticConsumers &C,
  const std::string& s,
  const Preprocessor &PP) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s,
-   PP.getLangOpts(), false));
+  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, false));
 }
 
 void ento::createPlistMultiFileDiagnosticConsumer(AnalyzerOptions 
&AnalyzerOpts,
   PathDiagnosticConsumers &C,
   const std::string &s,
   const Preprocessor &PP) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s,
-   PP.getLangOpts(), true));
+  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, true));
 }
 
 static void EmitRanges(raw_ostream &o,
const ArrayRef Ranges,
const FIDMap& FM,
-   const SourceManager &SM,
-   const LangOptions &LangOpts,
+   const Preprocessor &PP,
unsigned indent) {
 
   if (Ranges.empty())
@@ -97,6 +93,10 @@ static void EmitRanges(raw_ostream &o,
   Indent(o, indent) << "ranges\n";
   Indent(o, indent) << "\n";
   ++indent;
+
+  const SourceManager &SM = PP.getSourceManager();
+  const LangOptions &LangOpts = PP.getLangOpts();
+
   for (auto &R : Ranges)
 EmitRange(o, SM,
   Lexer::getAsCharRange(SM.getExpansionRange(R), SM, LangOpts),
@@ -122,10 +122,12 @@ static void EmitMessage(raw_ostream &o,
 static void ReportControlFlow(raw_ostream &o,
   const PathDiagnosticControlFlowPiece& P,
   const FIDMap& FM,
-  const SourceManager &SM,
-  const LangOptions &LangOpts,
+  const Preprocessor &PP,
   unsigned indent) {
 
+  const SourceManager &SM = PP.getSourceManager();
+  const LangOptions &LangOpts = PP.getLangOpts();
+
   Indent(o, indent) << "\n";
   ++indent;
 
@@ -175,12 +177,13 @@ static void ReportControlFlow(raw_ostrea
 
 static void ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
 const FIDMap& FM,
-const SourceManager &SM,
-const LangOptions &LangOpts,
+const Preprocessor &PP,
 unsigned indent,
 unsigned depth,
 bool isKeyEvent = false) {
 
+  const SourceManager &SM = PP.getSourceManager();
+
   Indent(o, indent) << "\n";
   ++indent;
 
@@ -198,7 +201,7 @@ static void ReportEvent(raw_ostream &o,
 
   // Output the ranges (if any).
   ArrayRef Ranges = P.getRange

r343620 - [analyzer][NFC] Refactor functions in PlistDiagnostics to take AnalyzerOptions as parameter

2018-10-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Oct  2 12:27:34 2018
New Revision: 343620

URL: http://llvm.org/viewvc/llvm-project?rev=343620&view=rev
Log:
[analyzer][NFC] Refactor functions in PlistDiagnostics to take AnalyzerOptions 
as parameter

I intend to add a new flag macro-expnasions-as-events, and unfortunately
I'll only be able to convert the macro piece into an event one once I'm
about to emit it, due to the lack of an avaible Preprocessor object in
the BugReporter.

Differential Revision: https://reviews.llvm.org/D52787

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=343620&r1=343619&r2=343620&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Tue Oct  2 12:27:34 
2018
@@ -32,8 +32,8 @@ namespace {
   class PlistDiagnostics : public PathDiagnosticConsumer {
 const std::string OutputFile;
 const Preprocessor &PP;
+AnalyzerOptions &AnOpts;
 const bool SupportsCrossFileDiagnostics;
-const bool SerializeStatistics;
   public:
 PlistDiagnostics(AnalyzerOptions &AnalyzerOpts,
  const std::string& prefix,
@@ -63,22 +63,23 @@ PlistDiagnostics::PlistDiagnostics(Analy
const std::string& output,
const Preprocessor &PP,
bool supportsMultipleFiles)
-  : OutputFile(output), PP(PP),
-SupportsCrossFileDiagnostics(supportsMultipleFiles),
-SerializeStatistics(AnalyzerOpts.shouldSerializeStats()) {}
+  : OutputFile(output), PP(PP), AnOpts(AnalyzerOpts),
+SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
 
 void ento::createPlistDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
  PathDiagnosticConsumers &C,
  const std::string& s,
  const Preprocessor &PP) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, false));
+  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP,
+   /*supportsMultipleFiles*/ false));
 }
 
 void ento::createPlistMultiFileDiagnosticConsumer(AnalyzerOptions 
&AnalyzerOpts,
   PathDiagnosticConsumers &C,
   const std::string &s,
   const Preprocessor &PP) {
-  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP, true));
+  C.push_back(new PlistDiagnostics(AnalyzerOpts, s, PP,
+   /*supportsMultipleFiles*/ true));
 }
 
 static void EmitRanges(raw_ostream &o,
@@ -175,7 +176,8 @@ static void ReportControlFlow(raw_ostrea
   Indent(o, indent) << "\n";
 }
 
-static void ReportEvent(raw_ostream &o, const PathDiagnosticEventPiece& P,
+static void ReportEvent(raw_ostream &o,
+const PathDiagnosticEventPiece& P,
 const FIDMap& FM,
 const Preprocessor &PP,
 unsigned indent,
@@ -219,6 +221,7 @@ static void ReportPiece(raw_ostream &o,
 const PathDiagnosticPiece &P,
 const FIDMap& FM, 
 const Preprocessor &PP,
+AnalyzerOptions &AnOpts,
 unsigned indent,
 unsigned depth,
 bool includeControlFlow,
@@ -228,28 +231,29 @@ static void ReportCall(raw_ostream &o,
const PathDiagnosticCallPiece &P,
const FIDMap& FM,
const Preprocessor &PP,
+   AnalyzerOptions &AnOpts,
unsigned indent,
unsigned depth) {
 
   if (auto callEnter = P.getCallEnterEvent())
-ReportPiece(o, *callEnter, FM, PP, indent, depth,
+ReportPiece(o, *callEnter, FM, PP, AnOpts, indent, depth,
 /*includeControlFlow*/ true, P.isLastInMainSourceFile());
 
 
   ++depth;
 
   if (auto callEnterWithinCaller = P.getCallEnterWithinCallerEvent())
-ReportPiece(o, *callEnterWithinCaller, FM, PP, indent, depth,
+ReportPiece(o, *callEnterWithinCaller, FM, PP, AnOpts, indent, depth,
 /*includeControlFlow*/ true);
 
   for (PathPieces::const_iterator I = P.path.begin(), E = 
P.path.end();I!=E;++I)
-ReportPiece(o, **I, FM, PP, indent, depth,
+ReportPiece(o, **I, FM, PP, AnOpts, indent, depth,
 /*includeControlFlow*/ true);
 
   --depth;
 
   if (auto callExit = P.getCallExitEvent())
-ReportPiece(o, *callExit, FM, PP, indent, depth,
+ReportPiece(o, *callExit, FM, PP

r344031 - [analyzer][www] Add more useful links

2018-10-09 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Oct  9 03:05:08 2018
New Revision: 344031

URL: http://llvm.org/viewvc/llvm-project?rev=344031&view=rev
Log:
[analyzer][www] Add more useful links

Differential Revision: https://reviews.llvm.org/D52993

Modified:
cfe/trunk/www/analyzer/checker_dev_manual.html

Modified: cfe/trunk/www/analyzer/checker_dev_manual.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/checker_dev_manual.html?rev=344031&r1=344030&r2=344031&view=diff
==
--- cfe/trunk/www/analyzer/checker_dev_manual.html (original)
+++ cfe/trunk/www/analyzer/checker_dev_manual.html Tue Oct  9 03:05:08 2018
@@ -681,28 +681,37 @@ Here are some additional resources that
 Static Analyzer:
 
 
+http://lcs.ios.ac.cn/~xuzb/canalyze/memmodel.pdf";>Xu, Zhongxing &
+Kremenek, Ted & Zhang, Jian. (2010). A Memory Model for Static Analysis of C
+Programs.
+https://github.com/llvm-mirror/clang/blob/master/lib/StaticAnalyzer/README.txt";>
+The Clang Static Analyzer README
+https://github.com/llvm-mirror/clang/blob/master/docs/analyzer/RegionStore.txt";>
+Documentation for how the Store works
+https://github.com/llvm-mirror/clang/blob/master/docs/analyzer/IPA.txt";>
+Documentation about inlining
+ The "Building a Checker in 24 hours" presentation given at the http://llvm.org/devmtg/2012-11";>November 2012 LLVM Developer's
+meeting. Describes the construction of SimpleStreamChecker. http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf";>Slides
+and https://youtu.be/kdxlsP5QVPw";>video
+are available.
+
+https://github.com/haoNoQ/clang-analyzer-guide/releases/download/v0.1/clang-analyzer-guide-v0.1.pdf";>
+Artem Degrachev: Clang Static Analyzer: A Checker Developer's Guide
+ (reading the previous items first might be a good idea)
+The list of Implicit Checkers
  http://clang.llvm.org/doxygen";>Clang doxygen. Contains
 up-to-date documentation about the APIs available in Clang. Relevant entries
 have been linked throughout this page. Also of use is the
 http://llvm.org/doxygen";>LLVM doxygen, when dealing with classes
-from LLVM.
+from LLVM.
  The http://lists.llvm.org/mailman/listinfo/cfe-dev";>
 cfe-dev mailing list. This is the primary mailing list used for
 discussion of Clang development (including static code analysis). The
 http://lists.llvm.org/pipermail/cfe-dev";>archive also contains
-a lot of information.
- The "Building a Checker in 24 hours" presentation given at the http://llvm.org/devmtg/2012-11";>November 2012 LLVM Developer's
-meeting. Describes the construction of SimpleStreamChecker. http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf";>Slides
-and https://youtu.be/kdxlsP5QVPw";>video
-are available.
-
-
-Useful Links
-
-The list of Implicit Checkers
+a lot of information.
 
 
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r352959 - [analyzer][UninitializedObjectChecker] New flag to ignore guarded uninitialized fields

2019-02-02 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Feb  2 06:50:04 2019
New Revision: 352959

URL: http://llvm.org/viewvc/llvm-project?rev=352959&view=rev
Log:
[analyzer][UninitializedObjectChecker] New flag to ignore guarded uninitialized 
fields

This patch is an implementation of the ideas discussed on the mailing list[1].

The idea is to somewhat heuristically guess whether the field that was confirmed
to be uninitialized is actually guarded with ifs, asserts, switch/cases and so
on. Since this is a syntactic check, it is very much prone to drastically
reduce the amount of reports the checker emits. The reports however that do not
get filtered out though have greater likelihood of them manifesting into actual
runtime errors.

[1] http://lists.llvm.org/pipermail/cfe-dev/2018-September/059255.html

Differential Revision: https://reviews.llvm.org/D51866

Added:
cfe/trunk/test/Analysis/cxx-uninitialized-object-unguarded-access.cpp
Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h

cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h?rev=352959&r1=352958&r2=352959&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h 
Sat Feb  2 06:50:04 2019
@@ -34,6 +34,12 @@
 // `-analyzer-config \
 // 
alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true`.
 //
+// TODO: With some clever heuristics, some pointers should be dereferenced
+// by default. For example, if the pointee is constructed within the
+// constructor call, it's reasonable to say that no external object
+// references it, and we wouldn't generate multiple report on the same
+// pointee.
+//
 //   - "IgnoreRecordsWithField" (string). If supplied, the checker will not
 // analyze structures that have a field with a name or type name that
 // matches the given pattern. Defaults to "".
@@ -41,11 +47,12 @@
 // `-analyzer-config \
 // 
alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind"`.
 //
-// TODO: With some clever heuristics, some pointers should be dereferenced
-// by default. For example, if the pointee is constructed within the
-// constructor call, it's reasonable to say that no external object
-// references it, and we wouldn't generate multiple report on the same
-// pointee.
+//   - "IgnoreGuardedFields" (boolean). If set to true, the checker will 
analyze
+// _syntactically_ whether the found uninitialized object is used without a
+// preceding assert call. Defaults to false.
+//
+// `-analyzer-config \
+// alpha.cplusplus.UninitializedObject:IgnoreGuardedFields=true`.
 //
 // Most of the following methods as well as the checker itself is defined in
 // UninitializedObjectChecker.cpp.
@@ -68,6 +75,7 @@ struct UninitObjCheckerOptions {
   bool ShouldConvertNotesToWarnings = false;
   bool CheckPointeeInitialization = false;
   std::string IgnoredRecordsWithFieldPattern;
+  bool IgnoreGuardedFields = false;
 };
 
 /// A lightweight polymorphic wrapper around FieldRegion *. We'll use this

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp?rev=352959&r1=352958&r2=352959&view=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
 Sat Feb  2 06:50:04 2019
@@ -19,6 +19,7 @@
 
 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
 #include "UninitializedObject.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
@@ -26,6 +27,7 @@
 
 using namespace clang;
 using namespace clang::ento;
+using namespace clang::ast_matchers;
 
 /// We'll mark fields (and pointee of fields) that are confirmed to be
 /// uninitialized as already analyzed.
@@ -118,6 +120,16 @@ static bool willObjectBeAnalyzedLater(co
 /// \p Pattern.
 static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern);
 
+/// Checks _syntactically_ whether it is possible to access FD from the record
+/// that contains it without a preceding assert (even if that access happens
+/// inside a 

r353150 - Fix the sphinx buildbot after D54429

2019-02-05 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Tue Feb  5 02:19:39 2019
New Revision: 353150

URL: http://llvm.org/viewvc/llvm-project?rev=353150&view=rev
Log:
Fix the sphinx buildbot after D54429

Modified:
cfe/trunk/docs/analyzer/checkers.rst

Modified: cfe/trunk/docs/analyzer/checkers.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/checkers.rst?rev=353150&r1=353149&r2=353150&view=diff
==
--- cfe/trunk/docs/analyzer/checkers.rst (original)
+++ cfe/trunk/docs/analyzer/checkers.rst Tue Feb  5 02:19:39 2019
@@ -1943,7 +1943,7 @@ debug
 ^
 
 Checkers used for debugging the analyzer.
-:doc:`DebugChecks` page contains a detailed description.
+:doc:`developer-docs/DebugChecks` page contains a detailed description.
 
 debug.AnalysisOrder
 """


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r353698 - [analyzer] New checker for detecting usages of unsafe I/O functions

2019-02-11 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Feb 11 05:46:43 2019
New Revision: 353698

URL: http://llvm.org/viewvc/llvm-project?rev=353698&view=rev
Log:
[analyzer] New checker for detecting usages of unsafe I/O functions

There are certain unsafe or deprecated (since C11) buffer handling
functions which should be avoided in safety critical code. They
could cause buffer overflows. A new checker,
'security.insecureAPI.DeprecatedOrUnsafeBufferHandling' warns for
every occurrence of such functions (unsafe or deprecated printf,
scanf family, and other buffer handling functions, which now have
a secure variant).

Patch by Dániel Kolozsvári!

Differential Revision: https://reviews.llvm.org/D35068

Modified:
cfe/trunk/docs/analyzer/checkers.rst
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
cfe/trunk/test/Analysis/security-syntax-checks.m

Modified: cfe/trunk/docs/analyzer/checkers.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/checkers.rst?rev=353698&r1=353697&r2=353698&view=diff
==
--- cfe/trunk/docs/analyzer/checkers.rst (original)
+++ cfe/trunk/docs/analyzer/checkers.rst Mon Feb 11 05:46:43 2019
@@ -566,6 +566,17 @@ security.insecureAPI.vfork (C)
vfork(); // warn
  }
 
+security.insecureAPI.DeprecatedOrUnsafeBufferHandling (C) 
+""
+ Warn on occurrences of unsafe or deprecated buffer handling functions, which 
now have a secure variant: ``sprintf, vsprintf, scanf, wscanf, fscanf, fwscanf, 
vscanf, vwscanf, vfscanf, vfwscanf, sscanf, swscanf, vsscanf, vswscanf, 
swprintf, snprintf, vswprintf, vsnprintf, memcpy, memmove, strncpy, strncat, 
memset``
+
+.. code-block:: c
+ 
+ void test() {
+   char buf [5];
+   strncpy(buf, "a", 1); // warn
+ }
+
 .. _unix-checkers:
 
 unix

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=353698&r1=353697&r2=353698&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Mon Feb 11 
05:46:43 2019
@@ -622,6 +622,13 @@ def UncheckedReturn : Checker<"Unchecked
   Dependencies<[SecuritySyntaxChecker]>,
   Documentation;
 
+def DeprecatedOrUnsafeBufferHandling :
+  Checker<"DeprecatedOrUnsafeBufferHandling">,
+  HelpText<"Warn on uses of unsecure or deprecated buffer manipulating "
+   "functions">,
+  Dependencies<[SecuritySyntaxChecker]>,
+  Documentation;
+
 } // end "security.insecureAPI"
 
 let ParentPackage = Security in {

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp?rev=353698&r1=353697&r2=353698&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp Mon Feb 
11 05:46:43 2019
@@ -44,6 +44,7 @@ struct ChecksFilter {
   DefaultBool check_mktemp;
   DefaultBool check_mkstemp;
   DefaultBool check_strcpy;
+  DefaultBool check_DeprecatedOrUnsafeBufferHandling;
   DefaultBool check_rand;
   DefaultBool check_vfork;
   DefaultBool check_FloatLoopCounter;
@@ -57,6 +58,7 @@ struct ChecksFilter {
   CheckName checkName_mktemp;
   CheckName checkName_mkstemp;
   CheckName checkName_strcpy;
+  CheckName checkName_DeprecatedOrUnsafeBufferHandling;
   CheckName checkName_rand;
   CheckName checkName_vfork;
   CheckName checkName_FloatLoopCounter;
@@ -103,6 +105,8 @@ public:
   void checkCall_mkstemp(const CallExpr *CE, const FunctionDecl *FD);
   void checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD);
   void checkCall_strcat(const CallExpr *CE, const FunctionDecl *FD);
+  void checkDeprecatedOrUnsafeBufferHandling(const CallExpr *CE,
+ const FunctionDecl *FD);
   void checkCall_rand(const CallExpr *CE, const FunctionDecl *FD);
   void checkCall_random(const CallExpr *CE, const FunctionDecl *FD);
   void checkCall_vfork(const CallExpr *CE, const FunctionDecl *FD);
@@ -148,6 +152,14 @@ void WalkAST::VisitCallExpr(CallExpr *CE
 .Case("mkstemps", &WalkAST::checkCall_mkstemp)
 .Cases("strcpy", "__strcpy_chk", &WalkAST::checkCall_strcpy)
 .Cases("strcat", "__strcat_chk", &WalkAST::checkCall_strcat)
+.Cases("sprintf", "vsprintf", "scanf", "wscanf", "fscanf", "fwscanf",
+   "vscanf", "vwscanf", "vfscanf", "vfwscanf",
+   &WalkAST::checkDeprecatedOrUnsafeBufferHandling)
+.Cases("sscanf", "swscanf", "vsscanf", "vswscanf", "swprintf",
+   "snprintf", "vswprintf", "vsnprintf", "me

r354235 - [analyzer] Make valist.Uninitialized depend on ValistBase

2019-02-17 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Feb 17 11:51:42 2019
New Revision: 354235

URL: http://llvm.org/viewvc/llvm-project?rev=354235&view=rev
Log:
[analyzer] Make valist.Uninitialized depend on ValistBase

Accidentally left this dependency out, resulting in an assert failure if
only valist.Uninitialized is enabled from the valist package.

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/test/Analysis/valist-uninitialized.c

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=354235&r1=354234&r2=354235&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Sun Feb 17 
11:51:42 2019
@@ -508,6 +508,7 @@ def ValistBase : Checker<"ValistBase">,
 
 def UninitializedChecker : Checker<"Uninitialized">,
   HelpText<"Check for usages of uninitialized (or already released) 
va_lists.">,
+  Dependencies<[ValistBase]>,
   Documentation;
 
 def UnterminatedChecker : Checker<"Unterminated">,

Modified: cfe/trunk/test/Analysis/valist-uninitialized.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/valist-uninitialized.c?rev=354235&r1=354234&r2=354235&view=diff
==
--- cfe/trunk/test/Analysis/valist-uninitialized.c (original)
+++ cfe/trunk/test/Analysis/valist-uninitialized.c Sun Feb 17 11:51:42 2019
@@ -1,5 +1,15 @@
-// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux 
-analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf 
-analyzer-disable-checker=core.CallAndMessage -analyzer-output=text 
-analyzer-store=region -verify %s
-// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu 
-analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf 
-analyzer-disable-checker=core.CallAndMessage -analyzer-output=text 
-analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -verify %s \
+// RUN:   -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf \
+// RUN:   -analyzer-disable-checker=core.CallAndMessage \
+// RUN:   -analyzer-output=text
+//
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -verify %s \
+// RUN:   -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf \
+// RUN:   -analyzer-disable-checker=core.CallAndMessage \
+// RUN:   -analyzer-output=text
+//
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu %s \
+// RUN:   -analyzer-checker=core,valist.Uninitialized
 
 #include "Inputs/system-header-simulator-for-valist.h"
 


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r354806 - [analyzer] Fix infinite recursion in printing macros

2019-02-25 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Mon Feb 25 10:49:42 2019
New Revision: 354806

URL: http://llvm.org/viewvc/llvm-project?rev=354806&view=rev
Log:
[analyzer] Fix infinite recursion in printing macros

#define f(y) x
#define x f(x)
int main() { x; }

This example results a compilation error since "x" in the first line was not
defined earlier. However, the macro expression printer goes to an infinite
recursion on this example.

Patch by Tibor Brunner!

Differential Revision: https://reviews.llvm.org/D57892

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp?rev=354806&r1=354805&r2=354806&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp Mon Feb 25 10:49:42 
2019
@@ -842,6 +842,9 @@ static std::string getMacroNameAndPrintE
 
   MacroNameAndArgs Info = getMacroNameAndArgs(SM.getExpansionLoc(MacroLoc), 
PP);
 
+  if (!Info.MI)
+return Info.Name;
+
   // Manually expand its arguments from the previous macro.
   Info.Args.expandFromPrevMacro(PrevArgs);
 
@@ -936,7 +939,14 @@ static MacroNameAndArgs getMacroNameAndA
   assert(II && "Failed to acquire the IndetifierInfo for the macro!");
 
   const MacroInfo *MI = getMacroInfoForLocation(PP, SM, II, ExpanLoc);
-  assert(MI && "The macro must've been defined at it's expansion location!");
+  // assert(MI && "The macro must've been defined at it's expansion 
location!");
+  //
+  // We should always be able to obtain the MacroInfo in a given TU, but if
+  // we're running the analyzer with CTU, the Preprocessor won't contain the
+  // directive history (or anything for that matter) from another TU.
+  // TODO: assert when we're not running with CTU.
+  if (!MI)
+return { MacroName, MI, {} };
 
   // Acquire the macro's arguments.
   //


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r362887 - [analyzer][NFC] Add dividers to BugReporterVisitors.cpp

2019-06-08 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sat Jun  8 13:25:39 2019
New Revision: 362887

URL: http://llvm.org/viewvc/llvm-project?rev=362887&view=rev
Log:
[analyzer][NFC] Add dividers to BugReporterVisitors.cpp

Some minor formatting to make the file more readable.
Added //===--===// around the implementation of class methods
and divided anonymous namespaces as per
https://llvm.org/docs/CodingStandards.html#anonymous-namespaces

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=362887&r1=362886&r2=362887&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Sat Jun  8 
13:25:39 2019
@@ -197,7 +197,7 @@ getConcreteIntegerValue(const Expr *Cond
 }
 
 
//===--===//
-// Definitions for bug reporter visitors.
+// Implementation of BugReporterVisitor.
 
//===--===//
 
 std::shared_ptr
@@ -694,6 +694,10 @@ private:
   }
 };
 
+} // end of anonymous namespace
+
+namespace {
+
 /// Suppress null-pointer-dereference bugs where dereferenced null was returned
 /// the macro.
 class MacroNullReturnSuppressionVisitor final : public BugReporterVisitor {
@@ -782,6 +786,10 @@ private:
   }
 };
 
+} // end of anonymous namespace
+
+namespace {
+
 /// Emits an extra note at the return statement of an interesting stack frame.
 ///
 /// The returned value is marked as an interesting value, and if it's null,
@@ -1057,7 +1065,11 @@ public:
   }
 };
 
-} // namespace
+} // end of anonymous namespace
+
+//===--===//
+// Implementation of FindLastStoreBRVisitor.
+//===--===//
 
 void FindLastStoreBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
   static int tag = 0;
@@ -1367,6 +1379,10 @@ FindLastStoreBRVisitor::VisitNode(const
   return std::make_shared(L, os.str());
 }
 
+//===--===//
+// Implementation of TrackConstraintBRVisitor.
+//===--===//
+
 void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
   static int tag = 0;
   ID.AddPointer(&tag);
@@ -1439,6 +1455,10 @@ TrackConstraintBRVisitor::VisitNode(cons
   return nullptr;
 }
 
+//===--===//
+// Implementation of SuppressInlineDefensiveChecksVisitor.
+//===--===//
+
 SuppressInlineDefensiveChecksVisitor::
 SuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N)
 : V(Value) {
@@ -1534,6 +1554,10 @@ SuppressInlineDefensiveChecksVisitor::Vi
   return nullptr;
 }
 
+//===--===//
+// Implementation of trackExpressionValue.
+//===--===//
+
 static const MemRegion *getLocationRegionIfReference(const Expr *E,
  const ExplodedNode *N) {
   if (const auto *DR = dyn_cast(E)) {
@@ -1753,6 +1777,10 @@ bool bugreporter::trackExpressionValue(c
   return true;
 }
 
+//===--===//
+// Implementation of NulReceiverBRVisitor.
+//===--===//
+
 const Expr *NilReceiverBRVisitor::getNilReceiver(const Stmt *S,
  const ExplodedNode *N) {
   const auto *ME = dyn_cast(S);
@@ -1803,6 +1831,10 @@ NilReceiverBRVisitor::VisitNode(const Ex
   return std::make_shared(L, OS.str());
 }
 
+//===--===//
+// Implementation of FindLastStoreBRVisitor.
+//===--===//
+
 // Registers every VarDecl inside a Stmt with a last store visitor.
 void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
 const Stmt *S,
@@ -2349,6 +2381,10 @@ bool ConditionBRVisitor::isPieceMessageG
  Piece->getString() == GenericFalseMessage;
 }
 
+//===--===//
+// Implementation of LikelyFalsePositiveSuppressionBRVisitor.
+//===--===//
+
 void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor(
 B

r363509 - [analyzer][NFC] Tease apart and clang-format NoStoreFuncVisitor

2019-06-16 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Jun 16 07:09:11 2019
New Revision: 363509

URL: http://llvm.org/viewvc/llvm-project?rev=363509&view=rev
Log:
[analyzer][NFC] Tease apart and clang-format NoStoreFuncVisitor

Make several methods static functions
Move non-trivial methods out-of-line
Add a divider
Turn non-obvious autos into Optional
clang-format affected lines

Differential Revision: https://reviews.llvm.org/D63086

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=363509&r1=363508&r2=363509&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Sun Jun 16 
07:09:11 2019
@@ -196,37 +196,6 @@ getConcreteIntegerValue(const Expr *Cond
   return {};
 }
 
-//===--===//
-// Implementation of BugReporterVisitor.
-//===--===//
-
-std::shared_ptr
-BugReporterVisitor::getEndPath(BugReporterContext &,
-   const ExplodedNode *, BugReport &) {
-  return nullptr;
-}
-
-void
-BugReporterVisitor::finalizeVisitor(BugReporterContext &,
-const ExplodedNode *, BugReport &) {}
-
-std::shared_ptr BugReporterVisitor::getDefaultEndPath(
-BugReporterContext &BRC, const ExplodedNode *EndPathNode, BugReport &BR) {
-  PathDiagnosticLocation L =
-
PathDiagnosticLocation::createEndOfPath(EndPathNode,BRC.getSourceManager());
-
-  const auto &Ranges = BR.getRanges();
-
-  // Only add the statement itself as a range if we didn't specify any
-  // special ranges for this report.
-  auto P = std::make_shared(
-  L, BR.getDescription(), Ranges.begin() == Ranges.end());
-  for (SourceRange Range : Ranges)
-P->addRange(Range);
-
-  return P;
-}
-
 /// \return name of the macro inside the location \p Loc.
 static StringRef getMacroName(SourceLocation Loc,
 BugReporterContext &BRC) {
@@ -251,36 +220,70 @@ static bool isFunctionMacroExpansion(Sou
 }
 
 /// \return Whether \c RegionOfInterest was modified at \p N,
-/// where \p ReturnState is a state associated with the return
-/// from the current frame.
-static bool wasRegionOfInterestModifiedAt(
-const SubRegion *RegionOfInterest,
-const ExplodedNode *N,
-SVal ValueAfter) {
+/// where \p ValueAfter is \c RegionOfInterest's value at the end of the
+/// stack frame.
+static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest,
+  const ExplodedNode *N,
+  SVal ValueAfter) {
   ProgramStateRef State = N->getState();
   ProgramStateManager &Mgr = N->getState()->getStateManager();
 
-  if (!N->getLocationAs()
-  && !N->getLocationAs()
-  && !N->getLocationAs())
+  if (!N->getLocationAs() && !N->getLocationAs() &&
+  !N->getLocationAs())
 return false;
 
   // Writing into region of interest.
   if (auto PS = N->getLocationAs())
 if (auto *BO = PS->getStmtAs())
   if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(
-N->getSVal(BO->getLHS()).getAsRegion()))
+  N->getSVal(BO->getLHS()).getAsRegion()))
 return true;
 
   // SVal after the state is possibly different.
   SVal ValueAtN = N->getState()->getSVal(RegionOfInterest);
-  if (!Mgr.getSValBuilder().areEqual(State, ValueAtN, 
ValueAfter).isConstrainedTrue() &&
+  if (!Mgr.getSValBuilder()
+   .areEqual(State, ValueAtN, ValueAfter)
+   .isConstrainedTrue() &&
   (!ValueAtN.isUndef() || !ValueAfter.isUndef()))
 return true;
 
   return false;
 }
 
+//===--===//
+// Implementation of BugReporterVisitor.
+//===--===//
+
+std::shared_ptr
+BugReporterVisitor::getEndPath(BugReporterContext &,
+   const ExplodedNode *, BugReport &) {
+  return nullptr;
+}
+
+void
+BugReporterVisitor::finalizeVisitor(BugReporterContext &,
+const ExplodedNode *, BugReport &) {}
+
+std::shared_ptr BugReporterVisitor::getDefaultEndPath(
+BugReporterContext &BRC, const ExplodedNode *EndPathNode, BugReport &BR) {
+  PathDiagnosticLocation L =
+
PathDiagnosticLocation::createEndOfPath(EndPathNode,BRC.getSourceManager());
+
+  const auto &Ranges = BR.getRanges();
+
+  // Only add the statement itself as a range if we didn't specify any
+  // special ranges for this report.
+  auto P = std::make_shared(
+  L, BR.getDescription(), Ranges.begin() == Ranges.end());
+  for (SourceRa

r363510 - [analyzer] Track indices of arrays

2019-06-16 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Jun 16 07:52:56 2019
New Revision: 363510

URL: http://llvm.org/viewvc/llvm-project?rev=363510&view=rev
Log:
[analyzer] Track indices of arrays

Often times, when an ArraySubscriptExpr was reported as null or
undefined, the bug report was difficult to understand, because the
analyzer explained why arr[i] has that value, but didn't realize that in
fact i's value is very important as well. This patch fixes this by
tracking the indices of arrays.

Differential Revision: https://reviews.llvm.org/D63080

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=363510&r1=363509&r2=363510&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Sun Jun 16 
07:52:56 2019
@@ -1740,6 +1740,10 @@ bool bugreporter::trackExpressionValue(c
   if (const Expr *Receiver = NilReceiverBRVisitor::getNilReceiver(Inner, 
LVNode))
 trackExpressionValue(LVNode, Receiver, report, EnableNullFPSuppression);
 
+  if (const auto *Arr = dyn_cast(Inner))
+trackExpressionValue(
+LVNode, Arr->getIdx(), report, EnableNullFPSuppression);
+
   // See if the expression we're interested refers to a variable.
   // If so, we can track both its contents and constraints on its value.
   if (ExplodedGraph::isInterestingLValueExpr(Inner)) {

Modified: cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp?rev=363510&r1=363509&r2=363510&view=diff
==
--- cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp (original)
+++ cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp Sun Jun 16 
07:52:56 2019
@@ -17,3 +17,28 @@ void shift_by_undefined_value() {
   (void)(TCP_MAXWIN << shift_amount); // expected-warning{{The result of the 
left shift is undefined due to shifting by '255', which is greater or equal to 
the width of type 'int'}}
   // expected-note@-1{{The result of the 
left shift is undefined due to shifting by '255', which is greater or equal to 
the width of type 'int'}}
 }
+
+namespace array_index_tracking {
+void consume(int);
+
+int getIndex(int x) {
+  int a;
+  if (x > 0)
+a = 3;
+  else
+a = 2;
+  return a;
+}
+
+int getInt();
+
+void testArrayIndexTracking() {
+  int arr[10];
+
+  for (int i = 0; i < 3; ++i)
+arr[i] = 0;
+  int x = getInt();
+  int n = getIndex(x);
+  consume(arr[n]);
+}
+} // end of namespace array_index_tracking


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r363512 - [analyzer] Push correct version of 'Track indices of arrays'

2019-06-16 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Sun Jun 16 08:41:25 2019
New Revision: 363512

URL: http://llvm.org/viewvc/llvm-project?rev=363512&view=rev
Log:
[analyzer] Push correct version of 'Track indices of arrays'

Messed up the commit, oops.

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=363512&r1=363511&r2=363512&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Sun Jun 16 
08:41:25 2019
@@ -1740,9 +1740,10 @@ bool bugreporter::trackExpressionValue(c
   if (const Expr *Receiver = NilReceiverBRVisitor::getNilReceiver(Inner, 
LVNode))
 trackExpressionValue(LVNode, Receiver, report, EnableNullFPSuppression);
 
+  // Track the index if this is an array subscript.
   if (const auto *Arr = dyn_cast(Inner))
 trackExpressionValue(
-LVNode, Arr->getIdx(), report, EnableNullFPSuppression);
+LVNode, Arr->getIdx(), report, /*EnableNullFPSuppression*/ false);
 
   // See if the expression we're interested refers to a variable.
   // If so, we can track both its contents and constraints on its value.

Modified: cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp?rev=363512&r1=363511&r2=363512&view=diff
==
--- cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp (original)
+++ cfe/trunk/test/Analysis/diagnostics/track_subexpressions.cpp Sun Jun 16 
08:41:25 2019
@@ -23,11 +23,12 @@ void consume(int);
 
 int getIndex(int x) {
   int a;
-  if (x > 0)
-a = 3;
+  if (x > 0) // expected-note {{Assuming 'x' is > 0}}
+ // expected-note@-1 {{Taking true branch}}
+a = 3; // expected-note {{The value 3 is assigned to 'a'}}
   else
 a = 2;
-  return a;
+  return a; // expected-note {{Returning the value 3 (loaded from 'a')}}
 }
 
 int getInt();
@@ -36,9 +37,47 @@ void testArrayIndexTracking() {
   int arr[10];
 
   for (int i = 0; i < 3; ++i)
+// expected-note@-1 3{{Loop condition is true.  Entering loop body}}
+// expected-note@-2 {{Loop condition is false. Execution continues on line 
43}}
 arr[i] = 0;
   int x = getInt();
-  int n = getIndex(x);
+  int n = getIndex(x); // expected-note {{Calling 'getIndex'}}
+   // expected-note@-1 {{Returning from 'getIndex'}}
+   // expected-note@-2 {{'n' initialized to 3}}
   consume(arr[n]);
+  // expected-note@-1 {{1st function call argument is an uninitialized value}}
+  // expected-warning@-2{{1st function call argument is an uninitialized 
value}}
 }
 } // end of namespace array_index_tracking
+
+namespace multi_array_index_tracking {
+void consume(int);
+
+int getIndex(int x) {
+  int a;
+  if (x > 0) // expected-note {{Assuming 'x' is > 0}}
+ // expected-note@-1 {{Taking true branch}}
+a = 3; // expected-note {{The value 3 is assigned to 'a'}}
+  else
+a = 2;
+  return a; // expected-note {{Returning the value 3 (loaded from 'a')}}
+}
+
+int getInt();
+
+void testArrayIndexTracking() {
+  int arr[2][10];
+
+  for (int i = 0; i < 3; ++i)
+// expected-note@-1 3{{Loop condition is true.  Entering loop body}}
+// expected-note@-2 {{Loop condition is false. Execution continues on line 
75}}
+arr[1][i] = 0;
+  int x = getInt();
+  int n = getIndex(x); // expected-note {{Calling 'getIndex'}}
+   // expected-note@-1 {{Returning from 'getIndex'}}
+   // expected-note@-2 {{'n' initialized to 3}}
+  consume(arr[1][n]);
+  // expected-note@-1 {{1st function call argument is an uninitialized value}}
+  // expected-warning@-2{{1st function call argument is an uninitialized 
value}}
+}
+} // end of namespace mulit_array_index_tracking


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >