r369020 - Test commit #2.

2019-08-15 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Aug 15 10:17:21 2019
New Revision: 369020

URL: http://llvm.org/viewvc/llvm-project?rev=369020=rev
Log:
Test commit #2.

Modified:
cfe/trunk/www/index.html

Modified: cfe/trunk/www/index.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/index.html?rev=369020=369019=369020=diff
==
--- cfe/trunk/www/index.html (original)
+++ cfe/trunk/www/index.html Thu Aug 15 10:17:21 2019
@@ -105,6 +105,7 @@
  interested in
  following the development of Clang, signing up for a mailing list is a 
good
  way to learn about how the project works.
+
 
 
 


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


r353566 - [analyzer] Opt-in C Style Cast Checker for OSObject pointers

2019-02-08 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Feb  8 13:09:00 2019
New Revision: 353566

URL: http://llvm.org/viewvc/llvm-project?rev=353566=rev
Log:
[analyzer] Opt-in C Style Cast Checker for OSObject pointers

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

Added:
cfe/trunk/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp
cfe/trunk/test/Analysis/osobjectcstylecastchecker_test.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=353566=353565=353566=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Fri Feb  8 
13:09:00 2019
@@ -812,6 +812,14 @@ def GCDAntipattern : Checker<"GCDAntipat
   Documentation;
 } // end "optin.performance"
 
+let ParentPackage = OSXOptIn in {
+
+def OSObjectCStyleCast : Checker<"OSObjectCStyleCast">,
+  HelpText<"Checker for C-style casts of OSObjects">,
+  Documentation;
+
+} // end "optin.osx"
+
 let ParentPackage = CocoaAlpha in {
 
 def IvarInvalidationModeling : Checker<"IvarInvalidationModeling">,

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=353566=353565=353566=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Fri Feb  8 13:09:00 
2019
@@ -71,6 +71,7 @@ add_clang_library(clangStaticAnalyzerChe
   ObjCSelfInitChecker.cpp
   ObjCSuperDeallocChecker.cpp
   ObjCUnusedIVarsChecker.cpp
+  OSObjectCStyleCast.cpp
   PaddingChecker.cpp
   PointerArithChecker.cpp
   PointerSubChecker.cpp

Added: cfe/trunk/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp?rev=353566=auto
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp (added)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp Fri Feb  8 
13:09:00 2019
@@ -0,0 +1,90 @@
+//===- OSObjectCStyleCast.cpp *- C++ 
-*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This file defines OSObjectCStyleCast checker, which checks for C-style casts
+// of OSObjects. Such casts almost always indicate a code smell,
+// as an explicit static or dynamic cast should be used instead.
+//===--===//
+
+#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
+#include "llvm/Support/Debug.h"
+
+using namespace clang;
+using namespace ento;
+using namespace ast_matchers;
+
+namespace {
+
+const char *WarnAtNode = "OSObjCast";
+
+class OSObjectCStyleCastChecker : public Checker {
+public:
+  void checkASTCodeBody(const Decl *D,
+AnalysisManager ,
+BugReporter ) const;
+};
+
+static void emitDiagnostics(const BoundNodes ,
+BugReporter ,
+AnalysisDeclContext *ADC,
+const OSObjectCStyleCastChecker *Checker) {
+  const auto *CE = Nodes.getNodeAs(WarnAtNode);
+  assert(CE);
+
+  std::string Diagnostics;
+  llvm::raw_string_ostream OS(Diagnostics);
+  OS << "C-style cast of OSObject. Use OSDynamicCast instead.";
+
+  BR.EmitBasicReport(
+ADC->getDecl(),
+Checker,
+/*Name=*/"OSObject C-Style Cast",
+/*Category=*/"Security",
+OS.str(),
+PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), ADC),
+CE->getSourceRange());
+}
+
+static auto hasTypePointingTo(DeclarationMatcher DeclM)
+-> decltype(hasType(pointerType())) {
+  return hasType(pointerType(pointee(hasDeclaration(DeclM;
+}
+
+void OSObjectCStyleCastChecker::checkASTCodeBody(const Decl *D, 
AnalysisManager ,
+ BugReporter ) const {
+
+  AnalysisDeclContext *ADC = AM.getAnalysisDeclContext(D);
+
+  auto DynamicCastM = 

r353229 - [analyzer] Document RetainCountChecker behavior and annotations

2019-02-05 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb  5 14:27:10 2019
New Revision: 353229

URL: http://llvm.org/viewvc/llvm-project?rev=353229=rev
Log:
[analyzer] Document RetainCountChecker behavior and annotations

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

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

Modified: cfe/trunk/www/analyzer/annotations.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/annotations.html?rev=353229=353228=353229=diff
==
--- cfe/trunk/www/analyzer/annotations.html (original)
+++ cfe/trunk/www/analyzer/annotations.html Tue Feb  5 14:27:10 2019
@@ -60,6 +60,16 @@ recognized by GCC. Their use can be cond
   Attribute 
'ns_consumes_self'
 
 
+Libkern Memory Management Annotations
+  
+Attribute 
'os_returns_retained'
+Attribute 
'os_returns_not_retained'
+Attribute 'os_consumed'
+Attribute 
'os_consumes_this'
+Out Parameters
+  
+
+
   
 
 Custom Assertion Handlers
@@ -482,6 +492,183 @@ a +1 retain count.
 which is functionally equivalent to the combination of 
NS_CONSUMES_SELF
 and NS_RETURNS_RETAINED shown above.
 
+Libkern Memory Management Annotations
+
+https://developer.apple.com/documentation/kernel/osobject?language=objc;>Libkern
+requires developers to inherit all heap allocated objects from 
OSObject
+and to perform manual reference counting.
+The reference counting model is very similar to MRR (manual retain-release) 
mode in
+https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html;>Objective-C
+or to CoreFoundation reference counting.
+Freshly-allocated objects start with a reference count of 1,
+and calls to retain increment it,
+while calls to release decrement it.
+The object is deallocated whenever its reference count reaches zero.
+
+Manually incrementing and decrementing reference counts is error-prone:
+over-retains lead to leaks, and over-releases lead to uses-after-free.
+The analyzer can help the programmer to check for unbalanced
+retain/release calls.
+
+The reference count checking is based on the principle of
+locality: it should be possible to establish correctness
+(lack of leaks/uses after free) by looking at each function body,
+and the declarations (not the definitions) of all the functions it interacts
+with.
+
+In order to support such reasoning, it should be possible to 
summarize
+the behavior of each function, with respect to reference count
+of its returned values and attributes.
+
+By default, the following summaries are assumed:
+
+  All functions starting with get or Get,
+unless they are returning subclasses of OSIterator,
+  are assumed to be returning at +0.
+  That is, the caller has no reference
+  count obligations with respect to the reference count of the 
returned object
+  and should leave it untouched.
+  
+
+  
+All other functions are assumed to return at +1.
+That is, the caller has an obligation to release such objects.
+  
+
+  
+Functions are assumed not to change the reference count of their 
parameters,
+including the implicit this parameter.
+  
+
+
+These summaries can be overriden with the following
+https://clang.llvm.org/docs/AttributeReference.html#os-returns-not-retained;>attributes:
+
+Attribute 'os_returns_retained'
+
+The os_returns_retained attribute (accessed through the macro 
+LIBKERN_RETURNS_RETAINED) plays a role identical to ns_returns_retained for functions
+returning OSObject subclasses.
+The attribute indicates that it is a callers responsibility to release the
+returned object.
+
+
+
+Attribute 'os_returns_not_retained'
+
+The os_returns_not_retained attribute (accessed through the macro 

+LIBKERN_RETURNS_NOT_RETAINED) plays a role identical to ns_returns_not_retained for functions
+returning OSObject subclasses.
+The attribute indicates that the caller should not change the retain
+count of the returned object.
+
+
+Example
+
+
+class MyClass {
+  OSObject *f;
+  LIBKERN_RETURNS_NOT_RETAINED OSObject *myFieldGetter();
+}
+ 
+ 
+// Note that the annotation only has to be applied to the function declaration.
+OSObject * MyClass::myFieldGetter() {
+  return f;
+}
+
+
+Attribute 'os_consumed'
+
+Similarly to ns_consumed attribute,
+os_consumed (accessed through LIBKERN_CONSUMED) attribute,
+applied to a parameter,
+indicates that the call to the function consumes the parameter:
+the callee should either release it or store it and release it in the 
destructor,
+while the caller should assume one is subtracted from the reference count
+after the call.
+
+
+IOReturn addToList(LIBKERN_CONSUMED IOPMinformee *newInformee);
+
+
+Attribute 'os_consumes_this'
+
+Similarly to ns_consumes_self,
+the os_consumes_self attribute indicates that the method call
+consumes the implicit this argument: the caller
+should assume one was subtracted from the reference count of the 

r353227 - [analyzer] [RetainCountChecker] Bugfix: in non-OSObject-mode, do not track CXX method calls

2019-02-05 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb  5 14:26:44 2019
New Revision: 353227

URL: http://llvm.org/viewvc/llvm-project?rev=353227=rev
Log:
[analyzer] [RetainCountChecker] Bugfix: in non-OSObject-mode, do not track CXX 
method calls

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

Modified:
cfe/trunk/lib/Analysis/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/retain-release.mm

Modified: cfe/trunk/lib/Analysis/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RetainSummaryManager.cpp?rev=353227=353226=353227=diff
==
--- cfe/trunk/lib/Analysis/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/Analysis/RetainSummaryManager.cpp Tue Feb  5 14:26:44 2019
@@ -499,19 +499,19 @@ RetainSummaryManager::generateSummary(co
 if (const RetainSummary *S = getSummaryForOSObject(FD, FName, RetTy))
   return S;
 
-  if (TrackObjCAndCFObjects)
-if (const RetainSummary *S =
-getSummaryForObjCOrCFObject(FD, FName, RetTy, FT, 
AllowAnnotations))
-  return S;
-
   if (const auto *MD = dyn_cast(FD))
-if (!(TrackOSObjects && isOSObjectRelated(MD)))
+if (!isOSObjectRelated(MD))
   return getPersistentSummary(RetEffect::MakeNoRet(),
   ArgEffects(AF.getEmptyMap()),
   ArgEffect(DoNothing),
   ArgEffect(StopTracking),
   ArgEffect(DoNothing));
 
+  if (TrackObjCAndCFObjects)
+if (const RetainSummary *S =
+getSummaryForObjCOrCFObject(FD, FName, RetTy, FT, 
AllowAnnotations))
+  return S;
+
   return getDefaultSummary();
 }
 

Modified: cfe/trunk/test/Analysis/retain-release.mm
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/retain-release.mm?rev=353227=353226=353227=diff
==
--- cfe/trunk/test/Analysis/retain-release.mm (original)
+++ cfe/trunk/test/Analysis/retain-release.mm Tue Feb  5 14:26:44 2019
@@ -471,7 +471,6 @@ void rdar33832412() {
   void* x = IOBSDNameMatching(); // no-warning
 }
 
-
 namespace member_CFRetains {
 class Foo {
 public:
@@ -485,3 +484,22 @@ void bar() {
   foo.CFRetain(0); // no-warning
 }
 }
+
+namespace cxx_method_escaping {
+
+struct S {
+  static CFArrayRef testGetNoTracking();
+  CFArrayRef testGetNoTrackingMember();
+};
+
+void test_cxx_static_method_escaping() {
+  CFArrayRef arr = S::testGetNoTracking();
+  CFRelease(arr);
+}
+
+void test_cxx_method_escaping(S *s) {
+  CFArrayRef arr = s->testGetNoTrackingMember();
+  CFRelease(arr);
+}
+
+}


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


r353228 - [analyzer] [testing] Inside CmpRuns.py output also print the filename of the first item in the path

2019-02-05 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb  5 14:26:57 2019
New Revision: 353228

URL: http://llvm.org/viewvc/llvm-project?rev=353228=rev
Log:
[analyzer] [testing] Inside CmpRuns.py output also print the filename of the 
first item in the path

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

Modified:
cfe/trunk/utils/analyzer/CmpRuns.py

Modified: cfe/trunk/utils/analyzer/CmpRuns.py
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/CmpRuns.py?rev=353228=353227=353228=diff
==
--- cfe/trunk/utils/analyzer/CmpRuns.py (original)
+++ cfe/trunk/utils/analyzer/CmpRuns.py Tue Feb  5 14:26:57 2019
@@ -73,6 +73,21 @@ class AnalysisDiagnostic(object):
 return fileName[len(root) + 1:]
 return fileName
 
+def getRootFileName(self):
+path = self._data['path']
+if not path:
+return self.getFileName()
+p = path[0]
+if 'location' in p:
+fIdx = p['location']['file']
+else: # control edge
+fIdx = path[0]['edges'][0]['start'][0]['file']
+out = self._report.files[fIdx]
+root = self._report.run.root
+if out.startswith(root):
+return out[len(root):]
+return out
+
 def getLine(self):
 return self._loc['line']
 
@@ -106,7 +121,13 @@ class AnalysisDiagnostic(object):
 funcnamePostfix = "#" + self._data['issue_context']
 else:
 funcnamePostfix = ""
-return '%s%s:%d:%d, %s: %s' % (self.getFileName(),
+rootFilename = self.getRootFileName()
+fileName = self.getFileName()
+if rootFilename != fileName:
+filePrefix = "[%s] %s" % (rootFilename, fileName)
+else:
+filePrefix = rootFilename
+return '%s%s:%d:%d, %s: %s' % (filePrefix,
funcnamePostfix,
self.getLine(),
self.getColumn(), self.getCategory(),


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


r352938 - [analyzer] Hotfix for RetainCountChecker: assert was too strong.

2019-02-01 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Feb  1 15:06:44 2019
New Revision: 352938

URL: http://llvm.org/viewvc/llvm-project?rev=352938=rev
Log:
[analyzer] Hotfix for RetainCountChecker: assert was too strong.

Bridged casts can happen to non-CF objects as well.

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/objc-arc.m

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=352938=352937=352938=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Fri Feb  1 15:06:44 2019
@@ -187,11 +187,10 @@ void RetainCountChecker::checkPostStmt(c
 
   QualType QT = CE->getType();
   ObjKind K;
-  if (coreFoundation::isCFObjectRef(QT)) {
-K = ObjKind::CF;
-  } else {
-assert(cocoa::isCocoaObjectRef(QT));
+  if (QT->isObjCObjectPointerType()) {
 K = ObjKind::ObjC;
+  } else {
+K = ObjKind::CF;
   }
 
   ArgEffect AE = ArgEffect(IncRef, K);

Modified: cfe/trunk/test/Analysis/objc-arc.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/objc-arc.m?rev=352938=352937=352938=diff
==
--- cfe/trunk/test/Analysis/objc-arc.m (original)
+++ cfe/trunk/test/Analysis/objc-arc.m Fri Feb  1 15:06:44 2019
@@ -239,8 +239,23 @@ extern const CFAllocatorRef kCFAllocator
 extern CFTypeRef CFRetain(CFTypeRef cf);
 extern void CFRelease(CFTypeRef cf);
 
+
 void check_bridge_retained_cast() {
 NSString *nsStr = [[NSString alloc] init];
 CFStringRef cfStr = (__bridge_retained CFStringRef)nsStr;
 CFRelease(cfStr); // no-warning
 }
+
+@interface A;
+@end
+
+void check_bridge_to_non_cocoa(CFStringRef s) {
+  A *a = (__bridge_transfer A *) s; // no-crash
+}
+
+struct B;
+
+struct B * check_bridge_to_non_cf() {
+  NSString *s = [[NSString alloc] init];
+  return (__bridge struct B*) s;
+}


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


r352824 - [analyzer] [RetainCountChecker] Fix object type for CF/Obj-C bridged casts

2019-01-31 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 31 18:13:02 2019
New Revision: 352824

URL: http://llvm.org/viewvc/llvm-project?rev=352824=rev
Log:
[analyzer] [RetainCountChecker] Fix object type for CF/Obj-C bridged casts

Having an incorrect type for a cast causes the checker to incorrectly
dismiss the operation under ARC, leading to a false positive
use-after-release on the test.

rdar://47709885

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/objc-arc.m

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=352824=352823=352824=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Jan 31 18:13:02 2019
@@ -185,7 +185,16 @@ void RetainCountChecker::checkPostStmt(c
   if (!BE)
 return;
 
-  ArgEffect AE = ArgEffect(IncRef, ObjKind::ObjC);
+  QualType QT = CE->getType();
+  ObjKind K;
+  if (coreFoundation::isCFObjectRef(QT)) {
+K = ObjKind::CF;
+  } else {
+assert(cocoa::isCocoaObjectRef(QT));
+K = ObjKind::ObjC;
+  }
+
+  ArgEffect AE = ArgEffect(IncRef, K);
 
   switch (BE->getBridgeKind()) {
 case OBC_Bridge:

Modified: cfe/trunk/test/Analysis/objc-arc.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/objc-arc.m?rev=352824=352823=352824=diff
==
--- cfe/trunk/test/Analysis/objc-arc.m (original)
+++ cfe/trunk/test/Analysis/objc-arc.m Thu Jan 31 18:13:02 2019
@@ -123,7 +123,7 @@ void rdar9424882() {
 typedef const void *CFTypeRef;
 typedef const struct __CFString *CFStringRef;
 
-@interface NSString
+@interface NSString : NSObject
 - (id) self;
 @end
 
@@ -231,3 +231,16 @@ id rdar14061675() {
   return result;
 }
 
+typedef const void * CFTypeRef;
+typedef const struct __CFString * CFStringRef;
+typedef const struct __CFAllocator * CFAllocatorRef;
+extern const CFAllocatorRef kCFAllocatorDefault;
+
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+
+void check_bridge_retained_cast() {
+NSString *nsStr = [[NSString alloc] init];
+CFStringRef cfStr = (__bridge_retained CFStringRef)nsStr;
+CFRelease(cfStr); // no-warning
+}


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


r352533 - [analyzer] [RetainSummaryManager] [NFC] Split one function into two, as it's really doing two things

2019-01-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Jan 29 11:29:45 2019
New Revision: 352533

URL: http://llvm.org/viewvc/llvm-project?rev=352533=rev
Log:
[analyzer] [RetainSummaryManager] [NFC] Split one function into two, as it's 
really doing two things

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

Modified:
cfe/trunk/include/clang/Analysis/RetainSummaryManager.h
cfe/trunk/lib/Analysis/RetainSummaryManager.cpp

Modified: cfe/trunk/include/clang/Analysis/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/RetainSummaryManager.h?rev=352533=352532=352533=diff
==
--- cfe/trunk/include/clang/Analysis/RetainSummaryManager.h (original)
+++ cfe/trunk/include/clang/Analysis/RetainSummaryManager.h Tue Jan 29 11:29:45 
2019
@@ -693,10 +693,22 @@ private:
   void updateSummaryFromAnnotations(const RetainSummary *,
 const FunctionDecl *FD);
 
-  void updateSummaryForCall(const RetainSummary *,
-AnyCall C,
-bool HasNonZeroCallbackArg,
-bool IsReceiverUnconsumedSelf);
+  const RetainSummary *updateSummaryForNonZeroCallbackArg(const RetainSummary 
*S,
+  AnyCall );
+
+  /// Special case '[super init];' and '[self init];'
+  ///
+  /// Even though calling '[super init]' without assigning the result to self
+  /// and checking if the parent returns 'nil' is a bad pattern, it is common.
+  /// Additionally, our Self Init checker already warns about it. To avoid
+  /// overwhelming the user with messages from both checkers, we model the case
+  /// of '[super init]' in cases when it is not consumed by another expression
+  /// as if the call preserves the value of 'self'; essentially, assuming it 
can
+  /// never fail and return 'nil'.
+  /// Note, we don't want to just stop tracking the value since we want the
+  /// RetainCount checker to report leaks and use-after-free if SelfInit 
checker
+  /// is turned off.
+  void updateSummaryForReceiverUnconsumedSelf(const RetainSummary *);
 
   /// Determine whether a declaration {@code D} of correspondent type (return
   /// type for functions/methods) {@code QT} has any of the given attributes,

Modified: cfe/trunk/lib/Analysis/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RetainSummaryManager.cpp?rev=352533=352532=352533=diff
==
--- cfe/trunk/lib/Analysis/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/Analysis/RetainSummaryManager.cpp Tue Jan 29 11:29:45 2019
@@ -557,64 +557,47 @@ static ArgEffect getStopTrackingHardEqui
   llvm_unreachable("Unknown ArgEffect kind");
 }
 
-void RetainSummaryManager::updateSummaryForCall(const RetainSummary *,
-AnyCall C,
-bool HasNonZeroCallbackArg,
-bool IsReceiverUnconsumedSelf) 
{
-
-  if (HasNonZeroCallbackArg) {
-ArgEffect RecEffect =
-  getStopTrackingHardEquivalent(S->getReceiverEffect());
-ArgEffect DefEffect =
-  getStopTrackingHardEquivalent(S->getDefaultArgEffect());
-
-ArgEffects ScratchArgs(AF.getEmptyMap());
-ArgEffects CustomArgEffects = S->getArgEffects();
-for (ArgEffects::iterator I = CustomArgEffects.begin(),
-  E = CustomArgEffects.end();
- I != E; ++I) {
-  ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
-  if (Translated.getKind() != DefEffect.getKind())
-ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
-}
-
-RetEffect RE = RetEffect::MakeNoRetHard();
+const RetainSummary *
+RetainSummaryManager::updateSummaryForNonZeroCallbackArg(const RetainSummary 
*S,
+ AnyCall ) {
+  ArgEffect RecEffect = getStopTrackingHardEquivalent(S->getReceiverEffect());
+  ArgEffect DefEffect = 
getStopTrackingHardEquivalent(S->getDefaultArgEffect());
+
+  ArgEffects ScratchArgs(AF.getEmptyMap());
+  ArgEffects CustomArgEffects = S->getArgEffects();
+  for (ArgEffects::iterator I = CustomArgEffects.begin(),
+E = CustomArgEffects.end();
+   I != E; ++I) {
+ArgEffect Translated = getStopTrackingHardEquivalent(I->second);
+if (Translated.getKind() != DefEffect.getKind())
+  ScratchArgs = AF.add(ScratchArgs, I->first, Translated);
+  }
 
-// Special cases where the callback argument CANNOT free the return value.
-// This can generally only happen if we know that the callback will only be
-// called when the return value is already being deallocated.
-if (C.getKind() == AnyCall::Function) {
-  if (const IdentifierInfo *Name = C.getIdentifier()) {
-

r352532 - [analyzer] [ARCMT] [NFC] Unify entry point into RetainSummaryManager

2019-01-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Jan 29 11:29:33 2019
New Revision: 352532

URL: http://llvm.org/viewvc/llvm-project?rev=352532=rev
Log:
[analyzer] [ARCMT] [NFC] Unify entry point into RetainSummaryManager

Just use one single entry point, since we have AnyCall utility now.

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

Modified:
cfe/trunk/include/clang/Analysis/RetainSummaryManager.h
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
cfe/trunk/lib/Analysis/RetainSummaryManager.cpp

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

Modified: cfe/trunk/include/clang/Analysis/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/RetainSummaryManager.h?rev=352532=352531=352532=diff
==
--- cfe/trunk/include/clang/Analysis/RetainSummaryManager.h (original)
+++ cfe/trunk/include/clang/Analysis/RetainSummaryManager.h Tue Jan 29 11:29:33 
2019
@@ -203,40 +203,6 @@ public:
   }
 };
 
-/// Encapsulates the retain count semantics on the arguments, return value,
-/// and receiver (if any) of a function/method call.
-///
-/// Note that construction of these objects is not highly efficient.  That
-/// is okay for clients where creating these objects isn't really a bottleneck.
-/// The purpose of the API is to provide something simple.  The actual
-/// static analyzer checker that implements retain/release typestate
-/// tracking uses something more efficient.
-class CallEffects {
-  llvm::SmallVector Args;
-  RetEffect Ret;
-  ArgEffect Receiver;
-
-  CallEffects(const RetEffect ,
-  ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj))
-  : Ret(R), Receiver(Receiver) {}
-
-public:
-  /// Returns the argument effects for a call.
-  ArrayRef getArgs() const { return Args; }
-
-  /// Returns the effects on the receiver.
-  ArgEffect getReceiver() const { return Receiver; }
-
-  /// Returns the effect on the return value.
-  RetEffect getReturnValue() const { return Ret; }
-
-  /// Return the CallEfect for a given Objective-C method.
-  static CallEffects getEffect(const ObjCMethodDecl *MD);
-
-  /// Return the CallEfect for a given C/C++ function.
-  static CallEffects getEffect(const FunctionDecl *FD);
-};
-
 /// A key identifying a summary.
 class ObjCSummaryKey {
   IdentifierInfo* II;
@@ -690,9 +656,13 @@ public:
   bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
 
   const RetainSummary *getSummary(AnyCall C,
-  bool HasNonZeroCallbackArg,
-  bool IsReceiverUnconsumedSelf,
-  QualType ReceiverType=QualType());
+  bool HasNonZeroCallbackArg=false,
+  bool IsReceiverUnconsumedSelf=false,
+  QualType ReceiverType={});
+
+  RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
+
+private:
 
   /// getMethodSummary - This version of getMethodSummary is used to query
   ///  the summary for the current method being analyzed.
@@ -700,9 +670,6 @@ public:
 
   const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
 
-  RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
-
-private:
   const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl 
*ID,
 const ObjCMethodDecl *MD,
 QualType RetTy,

Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=352532=352531=352532=diff
==
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Tue Jan 29 11:29:33 2019
@@ -64,9 +64,11 @@ class ObjCMigrateASTConsumer : public AS
 ObjCInstanceTypeFamily OIT_Family = OIT_None);
 
   void migrateCFAnnotation(ASTContext , const Decl *Decl);
-  void AddCFAnnotations(ASTContext , const CallEffects ,
+  void AddCFAnnotations(ASTContext ,
+const RetainSummary *RS,
 const FunctionDecl *FuncDecl, bool ResultAnnotated);
-  void AddCFAnnotations(ASTContext , const CallEffects ,
+  void AddCFAnnotations(ASTContext ,
+const RetainSummary *RS,
 const ObjCMethodDecl *MethodDecl, bool 
ResultAnnotated);
 
   void AnnotateImplicitBridging(ASTContext );
@@ -84,6 +86,8 @@ class ObjCMigrateASTConsumer : public AS
 
   bool InsertFoundation(ASTContext , SourceLocation Loc);
 
+  std::unique_ptr Summaries;
+
 public:
   std::string MigrateDir;
   unsigned ASTMigrateActions;
@@ -102,6 +106,14 @@ public:
   llvm::SmallVector CFFunctionIBCandidates;
   llvm::StringSet<> WhiteListFilenames;
 
+  RetainSummaryManager (ASTContext ) {
+if 

r352531 - Extend AnyCall to handle callable declarations without the call expressions

2019-01-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Jan 29 11:29:19 2019
New Revision: 352531

URL: http://llvm.org/viewvc/llvm-project?rev=352531=rev
Log:
Extend AnyCall to handle callable declarations without the call expressions

That weakens inner invariants, but allows the class to be more generic,
allowing usage in situations where the call expression is not known (or
should not matter).

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

Modified:
cfe/trunk/include/clang/Analysis/AnyCall.h

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

Modified: cfe/trunk/include/clang/Analysis/AnyCall.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnyCall.h?rev=352531=352530=352531=diff
==
--- cfe/trunk/include/clang/Analysis/AnyCall.h (original)
+++ cfe/trunk/include/clang/Analysis/AnyCall.h Tue Jan 29 11:29:19 2019
@@ -19,7 +19,9 @@
 
 namespace clang {
 
-/// An instance of this class corresponds to a 'callable' call.
+/// An instance of this class corresponds to a call.
+/// It might be a syntactically-concrete call, done as a part of evaluating an
+/// expression, or it may be an abstract callee with no associated expression.
 class AnyCall {
 public:
   enum Kind {
@@ -48,7 +50,11 @@ public:
   };
 
 private:
-  /// Call expression, remains null iff the call is an implicit destructor 
call.
+  /// Either expression or declaration (but not both at the same time)
+  /// can be null.
+
+  /// Call expression, is null when is not known (then declaration is 
non-null),
+  /// or for implicit destructor calls (when no expression exists.)
   const Expr *E = nullptr;
 
   /// Corresponds to a statically known declaration of the called function,
@@ -56,8 +62,6 @@ private:
   const Decl *D = nullptr;
   Kind K;
 
-  AnyCall(const Expr *E, const Decl *D, Kind K) : E(E), D(D), K(K) {}
-
 public:
   AnyCall(const CallExpr *CE) : E(CE) {
 D = CE->getCalleeDecl();
@@ -80,6 +84,23 @@ public:
   AnyCall(const CXXConstructExpr *NE)
   : E(NE), D(NE->getConstructor()), K(Constructor) {}
 
+  AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {}
+
+  AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {}
+
+  AnyCall(const ObjCMethodDecl *D) : E(nullptr), D(D), K(ObjCMethod) {}
+
+  AnyCall(const FunctionDecl *D) : E(nullptr), D(D) {
+if (isa(D)) {
+  K = Constructor;
+} else if (isa (D)) {
+  K = Destructor;
+} else {
+  K = Function;
+}
+
+  }
+
   /// If {@code E} is a generic call (to ObjC method /function/block/etc),
   /// return a constructed {@code AnyCall} object. Return None otherwise.
   static Optional forExpr(const Expr *E) {
@@ -98,8 +119,16 @@ public:
 }
   }
 
-  static AnyCall forDestructorCall(const CXXDestructorDecl *D) {
-return AnyCall(/*E=*/nullptr, D, Destructor);
+  /// If {@code D} is a callable (Objective-C method or a function), return
+  /// a constructed {@code AnyCall} object. Return None otherwise.
+  // FIXME: block support.
+  static Optional forDecl(const Decl *D) {
+if (const auto *FD = dyn_cast(D)) {
+  return AnyCall(FD);
+} else if (const auto *MD = dyn_cast(D)) {
+  return AnyCall(MD);
+}
+return None;
   }
 
   /// \returns formal parameters for direct calls (including virtual calls)
@@ -111,8 +140,6 @@ public:
   return FD->parameters();
 } else if (const auto *MD = dyn_cast(D)) {
   return MD->parameters();
-} else if (const auto *CD = dyn_cast(D)) {
-  return CD->parameters();
 } else if (const auto *BD = dyn_cast(D)) {
   return BD->parameters();
 } else {
@@ -129,10 +156,17 @@ public:
   QualType getReturnType(ASTContext ) const {
 switch (K) {
 case Function:
+  if (E)
+return cast(E)->getCallReturnType(Ctx);
+  return cast(D)->getReturnType();
+case ObjCMethod:
+  if (E)
+return cast(E)->getCallReturnType(Ctx);
+  return cast(D)->getReturnType();
 case Block:
+  // FIXME: BlockDecl does not know its return type,
+  // hence the asymmetry with the function and method cases above.
   return cast(E)->getCallReturnType(Ctx);
-case ObjCMethod:
-  return cast(E)->getCallReturnType(Ctx);
 case Destructor:
 case Constructor:
 case Allocator:

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=352531=352530=352531=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Tue Jan 29 11:29:19 2019
@@ -347,7 +347,7 @@ const static RetainSummary *getSummary(R
   const Expr *CE 

r352530 - [analyzer] [RetainCountChecker] Support 'taggedRetain' and 'taggedRelease'

2019-01-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Jan 29 11:29:07 2019
New Revision: 352530

URL: http://llvm.org/viewvc/llvm-project?rev=352530=rev
Log:
[analyzer] [RetainCountChecker] Support 'taggedRetain' and 'taggedRelease'

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

Modified:
cfe/trunk/lib/Analysis/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/os_object_base.h
cfe/trunk/test/Analysis/os_smart_ptr.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/lib/Analysis/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RetainSummaryManager.cpp?rev=352530=352529=352530=diff
==
--- cfe/trunk/lib/Analysis/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/Analysis/RetainSummaryManager.cpp Tue Jan 29 11:29:07 2019
@@ -242,10 +242,10 @@ RetainSummaryManager::getSummaryForOSObj
   if (const auto *MD = dyn_cast(FD)) {
 const CXXRecordDecl *Parent = MD->getParent();
 if (TrackOSObjects && Parent && isOSObjectSubclass(Parent)) {
-  if (FName == "release")
+  if (FName == "release" || FName == "taggedRelease")
 return getOSSummaryReleaseRule(FD);
 
-  if (FName == "retain")
+  if (FName == "retain" || FName == "taggedRetain")
 return getOSSummaryRetainRule(FD);
 
   if (FName == "free")

Modified: cfe/trunk/test/Analysis/os_object_base.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/os_object_base.h?rev=352530=352529=352530=diff
==
--- cfe/trunk/test/Analysis/os_object_base.h (original)
+++ cfe/trunk/test/Analysis/os_object_base.h Tue Jan 29 11:29:07 2019
@@ -27,6 +27,10 @@ struct OSMetaClassBase {
 
   virtual void retain() const;
   virtual void release() const;
+
+  virtual void taggedRetain(const void * tag = nullptr) const;
+  virtual void taggedRelease(const void * tag = nullptr) const;
+
   virtual void free();
   virtual ~OSMetaClassBase(){};
 };

Modified: cfe/trunk/test/Analysis/os_smart_ptr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/os_smart_ptr.h?rev=352530=352529=352530=diff
==
--- cfe/trunk/test/Analysis/os_smart_ptr.h (original)
+++ cfe/trunk/test/Analysis/os_smart_ptr.h Tue Jan 29 11:29:07 2019
@@ -51,7 +51,6 @@ struct smart_ptr {
   }
 
   T * operator->() const {
-OSPTR_LOG("Dereference smart_ptr with %p\n", pointer);
 return pointer;
   }
 
@@ -84,6 +83,6 @@ struct smart_ptr {
 
   T *pointer;
 };
-}
+} // namespace os
 
 #endif /* _OS_SMART_POINTER_H */

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=352530=352529=352530=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Tue Jan 29 11:29:07 2019
@@ -593,12 +593,12 @@ void test_smart_ptr_uaf() {
// expected-note@-1{{Returning from constructor for 'smart_ptr'}}
 // expected-note@os_smart_ptr.h:13{{Taking true branch}}
 // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}
-// expected-note@os_smart_ptr.h:72{{Reference count incremented. The 
object now has a +2 retain count}}
+// expected-note@os_smart_ptr.h:71{{Reference count incremented. The 
object now has a +2 retain count}}
 // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
   } // expected-note{{Calling '~smart_ptr'}}
   // expected-note@os_smart_ptr.h:35{{Taking true branch}}
   // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
-  // expected-note@os_smart_ptr.h:77{{Reference count decremented. The object 
now has a +1 retain count}}
+  // expected-note@os_smart_ptr.h:76{{Reference count decremented. The object 
now has a +1 retain count}}
   // expected-note@os_smart_ptr.h:36{{Returning from 'smart_ptr::_release'}}
  // expected-note@-5{{Returning from '~smart_ptr'}}
   obj->release(); // expected-note{{Object released}}
@@ -613,12 +613,12 @@ void test_smart_ptr_leak() {
// expected-note@-1{{Returning from constructor for 'smart_ptr'}}
 // expected-note@os_smart_ptr.h:13{{Taking true branch}}
 // expected-note@os_smart_ptr.h:14{{Calling 'smart_ptr::_retain'}}
-// expected-note@os_smart_ptr.h:72{{Reference count incremented. The 
object now has a +2 retain count}}
+// expected-note@os_smart_ptr.h:71{{Reference count incremented. The 
object now has a +2 retain count}}
 // expected-note@os_smart_ptr.h:14{{Returning from 'smart_ptr::_retain'}}
   } // expected-note{{Calling '~smart_ptr'}}
   // expected-note@os_smart_ptr.h:35{{Taking true branch}}
   // expected-note@os_smart_ptr.h:36{{Calling 'smart_ptr::_release'}}
-  // 

r352148 - [analysis] Introduce an AnyCall helper class, for abstraction over different callables

2019-01-24 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 24 17:23:51 2019
New Revision: 352148

URL: http://llvm.org/viewvc/llvm-project?rev=352148=rev
Log:
[analysis] Introduce an AnyCall helper class, for abstraction over different 
callables

A lot of code, particularly in the analyzer, has to perform a lot of
duplication to handle functions/ObjCMessages/destructors/constructors in
a generic setting.
The analyzer already has a CallEvent helper class abstracting over such
calls, but it's not always suitable, since it's tightly coupled to other
analyzer classes (ExplodedNode, ProgramState, etc.) and it's not always
possible to construct.

This change introduces a very simple, very lightweight helper class to
do simple generic operations over callables.

In future, parts of CallEvent could be changed to use this class to
avoid some duplication.

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

Added:
cfe/trunk/include/clang/Analysis/AnyCall.h

Added: cfe/trunk/include/clang/Analysis/AnyCall.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnyCall.h?rev=352148=auto
==
--- cfe/trunk/include/clang/Analysis/AnyCall.h (added)
+++ cfe/trunk/include/clang/Analysis/AnyCall.h Thu Jan 24 17:23:51 2019
@@ -0,0 +1,174 @@
+//=== AnyCall.h - Abstraction over different callables *- C++ -*--//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// A utility class for performing generic operations over different callables.
+//
+//===--===//
+//
+#ifndef LLVM_CLANG_ANALYSIS_ANY_CALL_H
+#define LLVM_CLANG_ANALYSIS_ANY_CALL_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+
+namespace clang {
+
+/// An instance of this class corresponds to a 'callable' call.
+class AnyCall {
+public:
+  enum Kind {
+/// A function, function pointer, or a C++ method call
+Function,
+
+/// A call to an Objective-C method
+ObjCMethod,
+
+/// A call to an Objective-C block
+Block,
+
+/// An implicit C++ destructor call (called implicitly
+/// or by operator 'delete')
+Destructor,
+
+/// An implicit or explicit C++ constructor call
+Constructor,
+
+/// A C++ allocation function call (operator `new`), via C++ new-expression
+Allocator,
+
+/// A C++ deallocation function call (operator `delete`), via C++
+/// delete-expression
+Deallocator
+  };
+
+private:
+  /// Call expression, remains null iff the call is an implicit destructor 
call.
+  const Expr *E = nullptr;
+
+  /// Corresponds to a statically known declaration of the called function,
+  /// or null if it is not known (e.g. for a function pointer).
+  const Decl *D = nullptr;
+  Kind K;
+
+  AnyCall(const Expr *E, const Decl *D, Kind K) : E(E), D(D), K(K) {}
+
+public:
+  AnyCall(const CallExpr *CE) : E(CE) {
+D = CE->getCalleeDecl();
+K = (CE->getCallee()->getType()->getAs()) ? Block
+: Function;
+if (D && ((K == Function && !isa(D)) ||
+  (K == Block && !isa(D
+  D = nullptr;
+  }
+
+  AnyCall(const ObjCMessageExpr *ME)
+  : E(ME), D(ME->getMethodDecl()), K(ObjCMethod) {}
+
+  AnyCall(const CXXNewExpr *NE)
+  : E(NE), D(NE->getOperatorNew()), K(Allocator) {}
+
+  AnyCall(const CXXDeleteExpr *NE)
+  : E(NE), D(NE->getOperatorDelete()), K(Deallocator) {}
+
+  AnyCall(const CXXConstructExpr *NE)
+  : E(NE), D(NE->getConstructor()), K(Constructor) {}
+
+  /// If {@code E} is a generic call (to ObjC method /function/block/etc),
+  /// return a constructed {@code AnyCall} object. Return None otherwise.
+  static Optional forExpr(const Expr *E) {
+if (const auto *ME = dyn_cast(E)) {
+  return AnyCall(ME);
+} else if (const auto *CE = dyn_cast(E)) {
+  return AnyCall(CE);
+} else if (const auto *CXNE = dyn_cast(E)) {
+  return AnyCall(CXNE);
+} else if (const auto *CXDE = dyn_cast(E)) {
+  return AnyCall(CXDE);
+} else if (const auto *CXCE = dyn_cast(E)) {
+  return AnyCall(CXCE);
+} else {
+  return None;
+}
+  }
+
+  static AnyCall forDestructorCall(const CXXDestructorDecl *D) {
+return AnyCall(/*E=*/nullptr, D, Destructor);
+  }
+
+  /// \returns formal parameters for direct calls (including virtual calls)
+  ArrayRef parameters() const {
+if (!D)
+  return None;
+
+if (const auto *FD = dyn_cast(D)) {
+  return FD->parameters();
+} else if (const auto *MD = dyn_cast(D)) {
+  return MD->parameters();
+} else if (const auto *CD = dyn_cast(D)) {
+  return CD->parameters();
+  

r352147 - [AST] Add a method to get a call type from an ObjCMessageExpr

2019-01-24 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 24 17:23:37 2019
New Revision: 352147

URL: http://llvm.org/viewvc/llvm-project?rev=352147=rev
Log:
[AST] Add a method to get a call type from an ObjCMessageExpr

Due to references, expression type does not always correspond to an
expected method return type (e.g. for a method returning int & the
expression type of the call would still be int).
We have a helper method for getting the expected type on CallExpr, but
not on ObjCMessageExpr.

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

Modified:
cfe/trunk/include/clang/AST/ExprObjC.h
cfe/trunk/lib/AST/ExprObjC.cpp

Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=352147=352146=352147=diff
==
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Thu Jan 24 17:23:37 2019
@@ -1180,6 +1180,13 @@ public:
   /// sent to.
   ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
 
+  /// \return the return type of the message being sent.
+  /// This is not always the type of the message expression itself because
+  /// of references (the expression would not have a reference type).
+  /// It is also not always the declared return type of the method because
+  /// of `instancetype` (in that case it's an expression type).
+  QualType getCallReturnType(ASTContext ) const;
+
   /// Source range of the receiver.
   SourceRange getReceiverRange() const;
 

Modified: cfe/trunk/lib/AST/ExprObjC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprObjC.cpp?rev=352147=352146=352147=diff
==
--- cfe/trunk/lib/AST/ExprObjC.cpp (original)
+++ cfe/trunk/lib/AST/ExprObjC.cpp Thu Jan 24 17:23:37 2019
@@ -292,6 +292,31 @@ void ObjCMessageExpr::getSelectorLocs(
 SelLocs.push_back(getSelectorLoc(i));
 }
 
+
+QualType ObjCMessageExpr::getCallReturnType(ASTContext ) const {
+  if (const ObjCMethodDecl *MD = getMethodDecl()) {
+QualType QT = MD->getReturnType();
+if (QT == Ctx.getObjCInstanceType()) {
+  // instancetype corresponds to expression types.
+  return getType();
+}
+return QT;
+  }
+
+  // Expression type might be different from an expected call return type,
+  // as expression type would never be a reference even if call returns a
+  // reference. Reconstruct the original expression type.
+  QualType QT = getType();
+  switch (getValueKind()) {
+  case VK_LValue:
+return Ctx.getLValueReferenceType(QT);
+  case VK_XValue:
+return Ctx.getRValueReferenceType(QT);
+  case VK_RValue:
+return QT;
+  }
+}
+
 SourceRange ObjCMessageExpr::getReceiverRange() const {
   switch (getReceiverKind()) {
   case Instance:


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


r351865 - [analyzer] Insert notes in RetainCountChecker where our dynamic cast modeling assumes 'null' output

2019-01-22 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Jan 22 11:51:00 2019
New Revision: 351865

URL: http://llvm.org/viewvc/llvm-project?rev=351865=rev
Log:
[analyzer] Insert notes in RetainCountChecker where our dynamic cast modeling 
assumes 'null' output

rdar://47397214

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

Modified:

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351865=351864=351865=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Tue Jan 22 11:51:00 2019
@@ -575,7 +575,6 @@ void RetainCountChecker::checkSummary(co
 
   // Helper tag for providing diagnostics: indicate whether dealloc was sent
   // at this location.
-  static CheckerProgramPointTag DeallocSentTag(this, DeallocTagDescription);
   bool DeallocSent = false;
 
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
@@ -903,8 +902,7 @@ bool RetainCountChecker::evalCall(const
   // Assume that output is zero on the other branch.
   NullOutputState = NullOutputState->BindExpr(
   CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
-
-  C.addTransition(NullOutputState);
+  C.addTransition(NullOutputState, );
 
   // And on the original branch assume that both input and
   // output are non-zero.

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h?rev=351865=351864=351865=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
Tue Jan 22 11:51:00 2019
@@ -260,9 +260,11 @@ class RetainCountChecker
   RefCountBug leakWithinFunction{this, RefCountBug::LeakWithinFunction};
   RefCountBug leakAtReturn{this, RefCountBug::LeakAtReturn};
 
+  CheckerProgramPointTag DeallocSentTag{this, "DeallocSent"};
+  CheckerProgramPointTag CastFailTag{this, "DynamicCastFail"};
+
   mutable std::unique_ptr Summaries;
 public:
-  static constexpr const char *DeallocTagDescription = "DeallocSent";
 
   /// Track Objective-C and CoreFoundation objects.
   bool TrackObjCAndCFObjects = false;
@@ -361,6 +363,14 @@ public:
  CheckerContext ,
  ExplodedNode *Pred = nullptr) const;
 
+  const CheckerProgramPointTag () const {
+return DeallocSentTag;
+  }
+
+  const CheckerProgramPointTag () const {
+return CastFailTag;
+  }
+
 private:
   /// Perform the necessary checks and state adjustments at the end of the
   /// function.

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=351865=351864=351865=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Tue Jan 22 11:51:00 2019
@@ -66,7 +66,7 @@ StringRef RefCountBug::getDescription()
 RefCountBug::RefCountBug(const CheckerBase *Checker, RefCountBugType BT)
 : BugType(Checker, bugTypeToName(BT), categories::MemoryRefCount,
   /*SupressOnSink=*/BT == LeakWithinFunction || BT == 
LeakAtReturn),
-  BT(BT) {}
+  BT(BT), Checker(Checker) {}
 
 static bool isNumericLiteralExpression(const Expr *E) {
   // FIXME: This set of cases was copied from SemaExprObjC.
@@ -423,6 +423,8 @@ RefCountReportVisitor::VisitNode(const E
   BugReporterContext , BugReport ) {
 
   const auto  = static_cast(BR.getBugType());
+  const auto *Checker =
+  static_cast(BT.getChecker());
 
   bool IsFreeUnowned = BT.getBugType() == RefCountBug::FreeNotOwned ||
BT.getBugType() == RefCountBug::DeallocNotOwned;
@@ -509,8 +511,12 @@ RefCountReportVisitor::VisitNode(const E
   bool DeallocSent = false;
 
   const ProgramPointTag *Tag = 

r351864 - [analyzer] Model another special-case kind of cast for OSObject RetainCountChecker

2019-01-22 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Jan 22 11:50:47 2019
New Revision: 351864

URL: http://llvm.org/viewvc/llvm-project?rev=351864=rev
Log:
[analyzer] Model another special-case kind of cast for OSObject 
RetainCountChecker

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/os_object_base.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=351864=351863=351864=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Tue Jan 
22 11:50:47 2019
@@ -677,6 +677,9 @@ public:
 // Function returns the first argument.
 Identity,
 
+// Function returns "this" argument.
+IdentityThis,
+
 // Function either returns zero, or the input parameter.
 IdentityOrZero
   };

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351864=351863=351864=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Tue Jan 22 11:50:47 2019
@@ -849,7 +849,6 @@ void RetainCountChecker::processNonLeakE
 
//===--===//
 
 bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext ) const 
{
-  // Get the callee. We're only interested in simple C functions.
   ProgramStateRef state = C.getState();
   const FunctionDecl *FD = C.getCalleeDecl(CE);
   if (!FD)
@@ -874,18 +873,27 @@ bool RetainCountChecker::evalCall(const
 
   // Bind the return value.
   if (BSmr == BehaviorSummary::Identity ||
-  BSmr == BehaviorSummary::IdentityOrZero) {
-SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
+  BSmr == BehaviorSummary::IdentityOrZero ||
+  BSmr == BehaviorSummary::IdentityThis) {
+
+const Expr *BindReturnTo =
+(BSmr == BehaviorSummary::IdentityThis)
+? cast(CE)->getImplicitObjectArgument()
+: CE->getArg(0);
+SVal RetVal = state->getSVal(BindReturnTo, LCtx);
 
 // If the receiver is unknown or the function has
 // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
 // return value.
+// FIXME: this branch is very strange.
 if (RetVal.isUnknown() ||
 (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
   SValBuilder  = C.getSValBuilder();
   RetVal =
   SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
 }
+
+// Bind the value.
 state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
 
 if (BSmr == BehaviorSummary::IdentityOrZero) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=351864=351863=351864=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Tue Jan 22 
11:50:47 2019
@@ -152,6 +152,10 @@ static bool isOSObjectDynamicCast(String
   return S == "safeMetaCast";
 }
 
+static bool isOSObjectThisCast(StringRef S) {
+  return S == "metaCast";
+}
+
 static bool isOSIteratorSubclass(const Decl *D) {
   return isSubclass(D, "OSIterator");
 }
@@ -219,13 +223,13 @@ RetainSummaryManager::getSummaryForOSObj
 const CXXRecordDecl *PD = RetTy->getPointeeType()->getAsCXXRecordDecl();
 if (PD && isOSObjectSubclass(PD)) {
   if (const IdentifierInfo *II = FD->getIdentifier()) {
-if (isOSObjectDynamicCast(II->getName()))
+StringRef FuncName = II->getName();
+if (isOSObjectDynamicCast(FuncName) || isOSObjectThisCast(FuncName))
   return getDefaultSummary();
 
 // All objects returned with functions *not* starting with
 // get, or iterators, are returned at +1.
-if ((!II->getName().startswith("get") &&
- !II->getName().startswith("Get")) ||
+if ((!FuncName.startswith("get") && !FuncName.startswith("Get")) ||
 isOSIteratorSubclass(PD)) {
   return getOSSummaryCreateRule(FD);
 } else {
@@ -703,8 

r351575 - Revert "Fix failing MSan bots"

2019-01-18 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Jan 18 11:24:55 2019
New Revision: 351575

URL: http://llvm.org/viewvc/llvm-project?rev=351575=rev
Log:
Revert "Fix failing MSan bots"

This reverts commit 2cedaaef383d8d6142046074ffebc2bb5a914778.

Revert with a fix.

Added:
cfe/trunk/test/Analysis/os_object_base.h
cfe/trunk/test/Analysis/os_smart_ptr.h
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp
cfe/trunk/test/Analysis/test-separate-retaincount.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=351575=351574=351575=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h Fri 
Jan 18 11:24:55 2019
@@ -95,7 +95,7 @@ protected:
   friend class BugReportEquivClass;
   friend class BugReporter;
 
-  BugType& BT;
+  const BugType& BT;
   const Decl *DeclWithIssue = nullptr;
   std::string ShortDescription;
   std::string Description;
@@ -164,15 +164,15 @@ private:
   void popInterestingSymbolsAndRegions();
 
 public:
-  BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
+  BugReport(const BugType& bt, StringRef desc, const ExplodedNode *errornode)
   : BT(bt), Description(desc), ErrorNode(errornode) {}
 
-  BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
+  BugReport(const BugType& bt, StringRef shortDesc, StringRef desc,
 const ExplodedNode *errornode)
   : BT(bt), ShortDescription(shortDesc), Description(desc),
 ErrorNode(errornode) {}
 
-  BugReport(BugType , StringRef desc, PathDiagnosticLocation l)
+  BugReport(const BugType , StringRef desc, PathDiagnosticLocation l)
   : BT(bt), Description(desc), Location(l) {}
 
   /// Create a BugReport with a custom uniqueing location.
@@ -190,7 +190,7 @@ public:
   virtual ~BugReport();
 
   const BugType& getBugType() const { return BT; }
-  BugType& getBugType() { return BT; }
+  //BugType& getBugType() { return BT; }
 
   /// True when the report has an execution path associated with it.
   ///
@@ -481,7 +481,7 @@ public:
 return {};
   }
 
-  void Register(BugType *BT);
+  void Register(const BugType *BT);
 
   /// Add the given report to the set of reports tracked by BugReporter.
   ///

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h?rev=351575=351574=351575=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h Fri Jan 
18 11:24:55 2019
@@ -38,12 +38,14 @@ private:
   virtual void anchor();
 
 public:
-  BugType(CheckName Check, StringRef Name, StringRef Cat)
+  BugType(CheckName Check, StringRef Name, StringRef Cat,
+  bool SuppressOnSink=false)
   : Check(Check), Name(Name), Category(Cat), Checker(nullptr),
-SuppressOnSink(false) {}
-  BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat)
+SuppressOnSink(SuppressOnSink) {}
+  BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat,
+  bool SuppressOnSink=false)
   : Check(Checker->getCheckName()), Name(Name), Category(Cat),
-Checker(Checker), SuppressOnSink(false) {}
+Checker(Checker), SuppressOnSink(SuppressOnSink) {}
   virtual ~BugType() = default;
 
   StringRef getName() const { return Name; }
@@ -64,7 +66,6 @@ public:
   ///  type should be suppressed if the end node of the report is 
post-dominated
   ///  by a sink node.
   bool isSuppressOnSink() const { return 

Re: r351514 - [analyzer] Introduce proper diagnostic for freeing unowned object

2019-01-18 Thread George Karpenkov via cfe-commits
ystem 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm_build_msan/lib/clang/9.0.0/include
>  -nostdsysteminc -analyze -analyzer-constraints=range 
> -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection
>  -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc 
> -analyzer-config eagerly-assume=false 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/test/Analysis/properties.m
> --
> Exit Code: 77
> 
> Command Output (stderr):
> --
> ==94119==WARNING: MemorySanitizer: use-of-uninitialized-value
> #0 0xa0635a8 in 
> clang::ento::retaincountchecker::RefCountReport::getRanges() 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h:65:9
> #1 0xa18bb67 in 
> clang::ento::BugReporterVisitor::getDefaultEndPath(clang::ento::BugReporterContext&,
>  clang::ento::ExplodedNode const*, clang::ento::BugReport&) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp:176:27
> #2 0xa05cf02 in 
> clang::ento::retaincountchecker::RefCountReportVisitor::getEndPath(clang::ento::BugReporterContext&,
>  clang::ento::ExplodedNode const*, clang::ento::BugReport&) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp:681:10
> #3 0xa15b9aa in generateVisitorsDiagnostics(clang::ento::BugReport*, 
> clang::ento::ExplodedNode const*, clang::ento::BugReporterContext&) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporter.cpp:2564:29
> #4 0xa1429dc in findValidReport 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporter.cpp:2621:9
> #5 0xa1429dc in 
> clang::ento::GRBugReporter::generatePathDiagnostics(llvm::ArrayRef,
>  llvm::ArrayRef&) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporter.cpp:2670
> #6 0xa14f991 in 
> clang::ento::BugReporter::generateDiagnosticForConsumerMap(clang::ento::BugReport*,
>  llvm::ArrayRef, 
> llvm::ArrayRef) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporter.cpp:3092:5
> #7 0xa13cbc1 in 
> clang::ento::BugReporter::FlushReport(clang::ento::BugReportEquivClass&) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporter.cpp:2948:7
> #8 0xa13a171 in clang::ento::BugReporter::FlushReports() 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporter.cpp:2254:5
> #9 0x99e9463 in RunPathSensitiveChecks 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:752:24
> #10 0x99e9463 in (anonymous 
> namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int, 
> clang::ento::ExprEngine::InliningModes, llvm::DenseSet llvm::DenseMapInfo >*) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:716
> #11 0x99ca7d6 in HandleDeclsCallGraph 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:507:5
> #12 0x99ca7d6 in runAnalysisOnTranslationUnit 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:554
> #13 0x99ca7d6 in (anonymous 
> namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:585
> #14 0xa5083e5 in clang::ParseAST(clang::Sema&, bool, bool) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/Parse/ParseAST.cpp:170:13
> #15 0x7660470 in clang::FrontendAction::Execute() 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/Frontend/FrontendAction.cpp:935:8
> #16 0x757956b in 
> clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp:955:11
> #17 0x788b6ea in 
> clang::ExecuteCompilerInvocation(clang::CompilerInstance*) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:268:25
> #18 0xb2c545 in cc1_main(llvm::ArrayRef, char const*, void*) 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/tools/driver/cc1_main.cpp:219:13
> #19 0xb2567e in ExecuteCC1Tool 
> /b/sanitizer-x86_64-linux-bootstrap-msan/build/llvm/tools/clang/tool

r351514 - [analyzer] Introduce proper diagnostic for freeing unowned object

2019-01-17 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 17 19:13:53 2019
New Revision: 351514

URL: http://llvm.org/viewvc/llvm-project?rev=351514=rev
Log:
[analyzer] Introduce proper diagnostic for freeing unowned object

Insert a note when the object becomes not (exclusively) owned.

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

Modified:

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351514=351513=351514=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Jan 17 19:13:53 2019
@@ -803,13 +803,16 @@ ProgramStateRef RetainCountChecker::upda
 }
 
 const RefCountBug &
-RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind) const {
+RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind,
+   SymbolRef Sym) const {
   switch (ErrorKind) {
 case RefVal::ErrorUseAfterRelease:
   return useAfterRelease;
 case RefVal::ErrorReleaseNotOwned:
   return releaseNotOwned;
 case RefVal::ErrorDeallocNotOwned:
+  if (Sym->getType()->getPointeeCXXRecordDecl())
+return freeNotOwned;
   return deallocNotOwned;
 default:
   llvm_unreachable("Unhandled error.");
@@ -836,7 +839,8 @@ void RetainCountChecker::processNonLeakE
 return;
 
   auto report = llvm::make_unique(
-  errorKindToBugKind(ErrorKind), C.getASTContext().getLangOpts(), N, Sym);
+  errorKindToBugKind(ErrorKind, Sym),
+  C.getASTContext().getLangOpts(), N, Sym);
   report->addRange(ErrorRange);
   C.emitReport(std::move(report));
 }

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h?rev=351514=351513=351514=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
Thu Jan 17 19:13:53 2019
@@ -255,6 +255,7 @@ class RetainCountChecker
   RefCountBug useAfterRelease{this, RefCountBug::UseAfterRelease};
   RefCountBug releaseNotOwned{this, RefCountBug::ReleaseNotOwned};
   RefCountBug deallocNotOwned{this, RefCountBug::DeallocNotOwned};
+  RefCountBug freeNotOwned{this, RefCountBug::FreeNotOwned};
   RefCountBug overAutorelease{this, RefCountBug::OverAutorelease};
   RefCountBug returnNotOwnedForOwned{this, 
RefCountBug::ReturnNotOwnedForOwned};
   RefCountBug leakWithinFunction{this, RefCountBug::LeakWithinFunction};
@@ -336,8 +337,8 @@ public:
RefVal V, ArgEffect E, RefVal::Kind ,
CheckerContext ) const;
 
-
-  const RefCountBug (RefVal::Kind ErrorKind) const;
+  const RefCountBug (RefVal::Kind ErrorKind,
+SymbolRef Sym) const;
 
   void processNonLeakError(ProgramStateRef St, SourceRange ErrorRange,
RefVal::Kind ErrorKind, SymbolRef Sym,

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=351514=351513=351514=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Jan 17 19:13:53 2019
@@ -27,6 +27,8 @@ StringRef RefCountBug::bugTypeToName(Ref
 return "Bad release";
   case DeallocNotOwned:
 return "-dealloc sent to non-exclusively owned object";
+  case FreeNotOwned:
+return "freeing non-exclusively owned object";
   case OverAutorelease:
 return "Object autoreleased too many times";
   case ReturnNotOwnedForOwned:
@@ -47,6 +49,8 @@ StringRef RefCountBug::getDescription()
"not owned at this point by the caller";
   case DeallocNotOwned:
 return "-dealloc sent to object that may be referenced elsewhere";
+  case FreeNotOwned:
+return  "'free' called on an object that may be 

r351513 - [analyzer] Extend the PathDiagnosticLocation constructor to handle CallExitEnd

2019-01-17 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 17 19:13:40 2019
New Revision: 351513

URL: http://llvm.org/viewvc/llvm-project?rev=351513=rev
Log:
[analyzer] Extend the PathDiagnosticLocation constructor to handle CallExitEnd

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=351513=351512=351513=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Jan 17 19:13:40 2019
@@ -408,15 +408,7 @@ annotateConsumedSummaryMismatch(const Ex
   if (os.str().empty())
 return nullptr;
 
-  // FIXME: remove the code duplication with NoStoreFuncVisitor.
-  PathDiagnosticLocation L;
-  if (const ReturnStmt *RS = CallExitLoc.getReturnStmt()) {
-L = PathDiagnosticLocation::createBegin(RS, SM, N->getLocationContext());
-  } else {
-L = PathDiagnosticLocation(
-Call->getRuntimeDefinition().getDecl()->getSourceRange().getEnd(), SM);
-  }
-
+  PathDiagnosticLocation L = PathDiagnosticLocation::create(CallExitLoc, SM);
   return std::make_shared(L, os.str());
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=351513=351512=351513=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Thu Jan 17 
19:13:40 2019
@@ -308,9 +308,8 @@ public:
 if (RegionOfInterest->isSubRegionOf(SelfRegion) &&
 potentiallyWritesIntoIvar(Call->getRuntimeDefinition().getDecl(),
   IvarR->getDecl()))
-  return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, 
SelfRegion,
-"self", /*FirstIsReferenceType=*/false,
-1);
+  return notModifiedDiagnostics(N, {}, SelfRegion, "self",
+/*FirstIsReferenceType=*/false, 1);
   }
 }
 
@@ -318,8 +317,7 @@ public:
   const MemRegion *ThisR = CCall->getCXXThisVal().getAsRegion();
   if (RegionOfInterest->isSubRegionOf(ThisR)
   && !CCall->getDecl()->isImplicit())
-return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, ThisR,
-  "this",
+return notModifiedDiagnostics(N, {}, ThisR, "this",
   /*FirstIsReferenceType=*/false, 1);
 
   // Do not generate diagnostics for not modified parameters in
@@ -338,18 +336,17 @@ public:
   QualType T = PVD->getType();
   while (const MemRegion *R = S.getAsRegion()) {
 if (RegionOfInterest->isSubRegionOf(R) && !isPointerToConst(T))
-  return notModifiedDiagnostics(Ctx, *CallExitLoc, Call, {}, R,
-ParamName, ParamIsReferenceType,
-IndirectionLevel);
+  return notModifiedDiagnostics(N, {}, R, ParamName,
+ParamIsReferenceType, 
IndirectionLevel);
 
 QualType PT = T->getPointeeType();
 if (PT.isNull() || PT->isVoidType()) break;
 
 if (const RecordDecl *RD = PT->getAsRecordDecl())
   if (auto P = findRegionOfInterestInRecord(RD, State, R))
-return notModifiedDiagnostics(
-  Ctx, *CallExitLoc, Call, *P, RegionOfInterest, ParamName,
-  ParamIsReferenceType, IndirectionLevel);
+return notModifiedDiagnostics(N, *P, RegionOfInterest, ParamName,
+  ParamIsReferenceType,
+  IndirectionLevel);
 
 S = State->getSVal(R, PT);
 T = PT;
@@ -523,19 +520,12 @@ private:
 
   /// \return Diagnostics piece for region not modified in the current 
function.
   std::shared_ptr
-  notModifiedDiagnostics(const LocationContext *Ctx, CallExitBegin 
,
- CallEventRef<> Call, const RegionVector ,
+  notModifiedDiagnostics(const ExplodedNode *N, const RegionVector ,
  const MemRegion *MatchedRegion, StringRef 
FirstElement,
  bool FirstIsReferenceType, unsigned IndirectionLevel) 
{
 
-PathDiagnosticLocation L;
-if (const ReturnStmt *RS = 

r351511 - [analyzer] const-ify reference to bug type used in BugReporter

2019-01-17 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 17 19:13:14 2019
New Revision: 351511

URL: http://llvm.org/viewvc/llvm-project?rev=351511=rev
Log:
[analyzer] const-ify reference to bug type used in BugReporter

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=351511=351510=351511=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h Thu 
Jan 17 19:13:14 2019
@@ -95,7 +95,7 @@ protected:
   friend class BugReportEquivClass;
   friend class BugReporter;
 
-  BugType& BT;
+  const BugType& BT;
   const Decl *DeclWithIssue = nullptr;
   std::string ShortDescription;
   std::string Description;
@@ -164,15 +164,15 @@ private:
   void popInterestingSymbolsAndRegions();
 
 public:
-  BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
+  BugReport(const BugType& bt, StringRef desc, const ExplodedNode *errornode)
   : BT(bt), Description(desc), ErrorNode(errornode) {}
 
-  BugReport(BugType& bt, StringRef shortDesc, StringRef desc,
+  BugReport(const BugType& bt, StringRef shortDesc, StringRef desc,
 const ExplodedNode *errornode)
   : BT(bt), ShortDescription(shortDesc), Description(desc),
 ErrorNode(errornode) {}
 
-  BugReport(BugType , StringRef desc, PathDiagnosticLocation l)
+  BugReport(const BugType , StringRef desc, PathDiagnosticLocation l)
   : BT(bt), Description(desc), Location(l) {}
 
   /// Create a BugReport with a custom uniqueing location.
@@ -190,7 +190,7 @@ public:
   virtual ~BugReport();
 
   const BugType& getBugType() const { return BT; }
-  BugType& getBugType() { return BT; }
+  //BugType& getBugType() { return BT; }
 
   /// True when the report has an execution path associated with it.
   ///
@@ -481,7 +481,7 @@ public:
 return {};
   }
 
-  void Register(BugType *BT);
+  void Register(const BugType *BT);
 
   /// Add the given report to the set of reports tracked by BugReporter.
   ///

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h?rev=351511=351510=351511=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
 Thu Jan 17 19:13:14 2019
@@ -51,7 +51,7 @@ public:
   StringRef endText);
 
   llvm::iterator_range getRanges() override {
-const RefCountBug& BugTy = static_cast(getBugType());
+const RefCountBug& BugTy = static_cast(getBugType());
 if (!BugTy.isLeak())
   return BugReport::getRanges();
 return llvm::make_range(ranges_iterator(), ranges_iterator());

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=351511=351510=351511=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Thu Jan 17 19:13:14 2019
@@ -1247,7 +1247,7 @@ static void generatePathDiagnosticsForNo
 
 static std::unique_ptr
 generateEmptyDiagnosticForReport(BugReport *R, SourceManager ) {
-  BugType  = R->getBugType();
+  const BugType  = R->getBugType();
   return llvm::make_unique(
   R->getBugType().getCheckName(), R->getDeclWithIssue(),
   R->getBugType().getName(), R->getDescription(),
@@ -2684,7 +2684,7 @@ GRBugReporter::generatePathDiagnostics(
   return Out;
 }
 
-void BugReporter::Register(BugType *BT) {
+void BugReporter::Register(const BugType *BT) {
   BugTypes = F.add(BugTypes, BT);
 }
 
@@ -2718,7 +2718,7 @@ void BugReporter::emitReport(std::unique
   R->Profile(ID);
 
   // Lookup the equivance class.  If there isn't one, create it.
-  BugType& BT = R->getBugType();
+  const BugType& BT = R->getBugType();
   Register();
   void *InsertPos;
   BugReportEquivClass* EQ = EQClasses.FindNodeOrInsertPos(ID, InsertPos);
@@ -2836,7 +2836,7 @@ FindReportInEquivalenceClass(BugReportEq
  SmallVectorImpl ) {
   BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
   assert(I != E);
-  BugType& BT = I->getBugType();
+  const BugType& BT = I->getBugType();
 
   

r351512 - [analyzer] [NFC] Clean up messy handling of bug categories in RetainCountChecker

2019-01-17 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 17 19:13:27 2019
New Revision: 351512

URL: http://llvm.org/viewvc/llvm-project?rev=351512=rev
Log:
[analyzer] [NFC] Clean up messy handling of bug categories in RetainCountChecker

https://reviews.llvm.org/D56887

Modified:

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351512=351511=351512=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Jan 17 19:13:27 2019
@@ -29,6 +29,10 @@ const RefVal *getRefBinding(ProgramState
   return State->get(Sym);
 }
 
+} // end namespace retaincountchecker
+} // end namespace ento
+} // end namespace clang
+
 static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
  RefVal Val) {
   assert(Sym != nullptr);
@@ -39,73 +43,6 @@ static ProgramStateRef removeRefBinding(
   return State->remove(Sym);
 }
 
-class UseAfterRelease : public RefCountBug {
-public:
-  UseAfterRelease(const CheckerBase *checker)
-  : RefCountBug(checker, "Use-after-release") {}
-
-  const char *getDescription() const override {
-return "Reference-counted object is used after it is released";
-  }
-};
-
-class BadRelease : public RefCountBug {
-public:
-  BadRelease(const CheckerBase *checker) : RefCountBug(checker, "Bad release") 
{}
-
-  const char *getDescription() const override {
-return "Incorrect decrement of the reference count of an object that is "
-   "not owned at this point by the caller";
-  }
-};
-
-class DeallocNotOwned : public RefCountBug {
-public:
-  DeallocNotOwned(const CheckerBase *checker)
-  : RefCountBug(checker, "-dealloc sent to non-exclusively owned object") 
{}
-
-  const char *getDescription() const override {
-return "-dealloc sent to object that may be referenced elsewhere";
-  }
-};
-
-class OverAutorelease : public RefCountBug {
-public:
-  OverAutorelease(const CheckerBase *checker)
-  : RefCountBug(checker, "Object autoreleased too many times") {}
-
-  const char *getDescription() const override {
-return "Object autoreleased too many times";
-  }
-};
-
-class ReturnedNotOwnedForOwned : public RefCountBug {
-public:
-  ReturnedNotOwnedForOwned(const CheckerBase *checker)
-  : RefCountBug(checker, "Method should return an owned object") {}
-
-  const char *getDescription() const override {
-return "Object with a +0 retain count returned to caller where a +1 "
-   "(owning) retain count is expected";
-  }
-};
-
-class Leak : public RefCountBug {
-public:
-  // Leaks should not be reported if they are post-dominated by a sink.
-  Leak(const CheckerBase *checker, StringRef name)
-  : RefCountBug(checker, name,
-/*SuppressOnSink=*/true) {}
-
-  const char *getDescription() const override { return ""; }
-
-  bool isLeak() const override { return true; }
-};
-
-} // end namespace retaincountchecker
-} // end namespace ento
-} // end namespace clang
-
 void RefVal::print(raw_ostream ) const {
   if (!T.isNull())
 Out << "Tracked " << T.getAsString() << " | ";
@@ -414,20 +351,6 @@ void RetainCountChecker::checkPostCall(c
   checkSummary(*Summ, Call, C);
 }
 
-RefCountBug *
-RetainCountChecker::getLeakWithinFunctionBug(const LangOptions ) const {
-  if (!leakWithinFunction)
-leakWithinFunction.reset(new Leak(this, "Leak"));
-  return leakWithinFunction.get();
-}
-
-RefCountBug *
-RetainCountChecker::getLeakAtReturnBug(const LangOptions ) const {
-  if (!leakAtReturn)
-leakAtReturn.reset(new Leak(this, "Leak of returned object"));
-  return leakAtReturn.get();
-}
-
 /// GetReturnType - Used to get the return type of a message expression or
 ///  function call with the intention of affixing that type to a tracked 
symbol.
 ///  While the return type can be queried directly from RetEx, when
@@ -879,6 +802,20 @@ ProgramStateRef RetainCountChecker::upda
   return setRefBinding(state, sym, V);
 }
 
+const RefCountBug &
+RetainCountChecker::errorKindToBugKind(RefVal::Kind ErrorKind) const {
+  switch (ErrorKind) {
+case RefVal::ErrorUseAfterRelease:
+  return useAfterRelease;
+case RefVal::ErrorReleaseNotOwned:
+  return releaseNotOwned;
+case RefVal::ErrorDeallocNotOwned:
+  return deallocNotOwned;
+default:
+  llvm_unreachable("Unhandled error.");
+ 

r351509 - [analyzer] [RetainCountChecker] Produce a correct message when OSTypeAlloc is used

2019-01-17 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 17 19:12:48 2019
New Revision: 351509

URL: http://llvm.org/viewvc/llvm-project?rev=351509=rev
Log:
[analyzer] [RetainCountChecker] Produce a correct message when OSTypeAlloc is 
used

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/test/Analysis/os_object_base.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=351509=351508=351509=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Jan 17 19:12:48 2019
@@ -132,6 +132,32 @@ static Optional findArgIdxOfSy
   return None;
 }
 
+Optional findMetaClassAlloc(const Expr *Callee) {
+  if (const auto *ME = dyn_cast(Callee)) {
+if (ME->getMemberDecl()->getNameAsString() != "alloc")
+  return None;
+const Expr *This = ME->getBase()->IgnoreParenImpCasts();
+if (const auto *DRE = dyn_cast(This)) {
+  const ValueDecl *VD = DRE->getDecl();
+  if (VD->getNameAsString() != "metaClass")
+return None;
+
+  if (const auto *RD = dyn_cast(VD->getDeclContext()))
+return RD->getNameAsString();
+
+}
+  }
+  return None;
+}
+
+std::string findAllocatedObjectName(const Stmt *S,
+QualType QT) {
+  if (const auto *CE = dyn_cast(S))
+if (auto Out = findMetaClassAlloc(CE->getCallee()))
+  return *Out;
+  return getPrettyTypeName(QT);
+}
+
 static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
const LocationContext *LCtx,
const RefVal , SymbolRef ,
@@ -189,7 +215,7 @@ static void generateDiagnosticsForCallLi
 os << "a Core Foundation object of type '"
<< Sym->getType().getAsString() << "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::OS) {
-os << "an OSObject of type '" << getPrettyTypeName(Sym->getType())
+os << "an OSObject of type '" << findAllocatedObjectName(S, Sym->getType())
<< "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::Generalized) {
 os << "an object of type '" << Sym->getType().getAsString()

Modified: cfe/trunk/test/Analysis/os_object_base.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/os_object_base.h?rev=351509=351508=351509=diff
==
--- cfe/trunk/test/Analysis/os_object_base.h (original)
+++ cfe/trunk/test/Analysis/os_object_base.h Thu Jan 17 19:12:48 2019
@@ -47,7 +47,7 @@ struct OSObject : public OSMetaClassBase
 };
 
 struct OSMetaClass : public OSMetaClassBase {
-  virtual OSObject * alloc();
+  virtual OSObject * alloc() const;
   virtual ~OSMetaClass(){}
 };
 

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=351509=351508=351509=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Jan 17 19:12:48 2019
@@ -627,3 +627,10 @@ void test_smart_ptr_no_leak() {
   }
   obj->release();
 }
+
+void test_ostypealloc_correct_diagnostic_name() {
+  OSArray *arr = OSTypeAlloc(OSArray); // expected-note{{Call to method 
'OSMetaClass::alloc' returns an OSObject of type 'OSArray' with a +1 retain 
count}}
+  arr->retain(); // expected-note{{Reference count incremented. The object now 
has a +2 retain count}}
+  arr->release(); // expected-note{{Reference count decremented. The object 
now has a +1 retain count}}
+} // expected-note{{Object leaked: object allocated and stored into 'arr' is 
not referenced later in this execution path and has a retain count of +1}}
+  // expected-warning@-1{{Potential leak of an object stored into 'arr'}}


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


r351510 - [analyzer] Extend BugType constructor to accept "SuppressOnSink" as a parameter

2019-01-17 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 17 19:13:01 2019
New Revision: 351510

URL: http://llvm.org/viewvc/llvm-project?rev=351510=rev
Log:
[analyzer] Extend BugType constructor to accept "SuppressOnSink" as a parameter

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h?rev=351510=351509=351510=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h Thu Jan 
17 19:13:01 2019
@@ -38,12 +38,14 @@ private:
   virtual void anchor();
 
 public:
-  BugType(CheckName Check, StringRef Name, StringRef Cat)
+  BugType(CheckName Check, StringRef Name, StringRef Cat,
+  bool SuppressOnSink=false)
   : Check(Check), Name(Name), Category(Cat), Checker(nullptr),
-SuppressOnSink(false) {}
-  BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat)
+SuppressOnSink(SuppressOnSink) {}
+  BugType(const CheckerBase *Checker, StringRef Name, StringRef Cat,
+  bool SuppressOnSink=false)
   : Check(Checker->getCheckName()), Name(Name), Category(Cat),
-Checker(Checker), SuppressOnSink(false) {}
+Checker(Checker), SuppressOnSink(SuppressOnSink) {}
   virtual ~BugType() = default;
 
   StringRef getName() const { return Name; }
@@ -64,7 +66,6 @@ public:
   ///  type should be suppressed if the end node of the report is 
post-dominated
   ///  by a sink node.
   bool isSuppressOnSink() const { return SuppressOnSink; }
-  void setSuppressOnSink(bool x) { SuppressOnSink = x; }
 };
 
 class BuiltinBug : public BugType {

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp?rev=351510=351509=351510=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp Thu Jan 17 
19:13:01 2019
@@ -399,14 +399,14 @@ bool isZero(ProgramStateRef State, const
 
 IteratorChecker::IteratorChecker() {
   OutOfRangeBugType.reset(
-  new BugType(this, "Iterator out of range", "Misuse of STL APIs"));
-  OutOfRangeBugType->setSuppressOnSink(true);
+  new BugType(this, "Iterator out of range", "Misuse of STL APIs",
+  /*SuppressOnSink=*/true));
   MismatchedBugType.reset(
-  new BugType(this, "Iterator(s) mismatched", "Misuse of STL APIs"));
-  MismatchedBugType->setSuppressOnSink(true);
+  new BugType(this, "Iterator(s) mismatched", "Misuse of STL APIs",
+  /*SuppressOnSink=*/true));
   InvalidatedBugType.reset(
-  new BugType(this, "Iterator invalidated", "Misuse of STL APIs"));
-  InvalidatedBugType->setSuppressOnSink(true);
+  new BugType(this, "Iterator invalidated", "Misuse of STL APIs",
+  /*SuppressOnSink=*/true));
 }
 
 void IteratorChecker::checkPreCall(const CallEvent ,

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=351510=351509=351510=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Thu Jan 17 19:13:01 
2019
@@ -2301,14 +2301,14 @@ void MallocChecker::reportLeak(SymbolRef
 
   assert(N);
   if (!BT_Leak[*CheckKind]) {
-BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory 
leak",
-  categories::MemoryError));
 // Leaks should not be reported if they are post-dominated by a sink:
 // (1) Sinks are higher importance bugs.
 // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
 // with __noreturn functions such as assert() or exit(). We choose not
 // to report leaks on such paths.
-BT_Leak[*CheckKind]->setSuppressOnSink(true);
+BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory 
leak",
+  categories::MemoryError,
+  

r351508 - [analyzer] [RetainCountChecker] Smart pointer support.

2019-01-17 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 17 19:12:35 2019
New Revision: 351508

URL: http://llvm.org/viewvc/llvm-project?rev=351508=rev
Log:
[analyzer] [RetainCountChecker] Smart pointer support.

rdar://47323216

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

Added:
cfe/trunk/test/Analysis/os_object_base.h
cfe/trunk/test/Analysis/os_smart_ptr.h
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp
cfe/trunk/test/Analysis/test-separate-retaincount.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=351508=351507=351508=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
17 19:12:35 2019
@@ -685,6 +685,10 @@ public:
   Optional canEval(const CallExpr *CE, const FunctionDecl *FD,
 bool );
 
+  /// \return Whether the type corresponds to a known smart pointer
+  /// implementation (that is, everything about it is inlineable).
+  static bool isKnownSmartPointer(QualType QT);
+
   bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
 
   const RetainSummary *getSummary(const CallEvent ,

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351508=351507=351508=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Jan 17 19:12:35 2019
@@ -529,6 +529,13 @@ void RetainCountChecker::processSummaryO
   C.addTransition(state);
 }
 
+static bool isSmartPtrField(const MemRegion *MR) {
+  const auto *TR = dyn_cast(
+cast(MR)->getSuperRegion());
+  return TR && RetainSummaryManager::isKnownSmartPointer(TR->getValueType());
+}
+
+
 /// A value escapes in these possible cases:
 ///
 /// - binding to something that is not a memory region.
@@ -536,10 +543,15 @@ void RetainCountChecker::processSummaryO
 /// - binding to a variable that has a destructor attached using CleanupAttr
 ///
 /// We do not currently model what happens when a symbol is
-/// assigned to a struct field, so be conservative here and let the symbol go.
+/// assigned to a struct field, unless it is a known smart pointer
+/// implementation, about which we know that it is inlined.
 /// FIXME: This could definitely be improved upon.
 static bool shouldEscapeRegion(const MemRegion *R) {
+  if (isSmartPtrField(R))
+return false;
+
   const auto *VR = dyn_cast(R);
+
   if (!R->hasStackStorage() || !VR)
 return true;
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=351508=351507=351508=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Jan 17 
19:12:35 2019
@@ -146,7 +146,7 @@ static bool isSubclass(const Decl *D,
 }
 
 static bool isOSObjectSubclass(const Decl *D) {
-  return isSubclass(D, "OSObject");
+  return isSubclass(D, "OSMetaClassBase");
 }
 
 static bool isOSObjectDynamicCast(StringRef S) {
@@ -199,6 +199,20 @@ static bool isOSObjectRelated(const CXXM
   return false;
 }
 
+bool
+RetainSummaryManager::isKnownSmartPointer(QualType QT) {
+  QT = QT.getCanonicalType();
+  const auto *RD = QT->getAsCXXRecordDecl();
+  if (!RD)
+return false;
+  const IdentifierInfo *II = RD->getIdentifier();
+  if (II && II->getName() == "smart_ptr")
+if (const auto *ND = dyn_cast(RD->getDeclContext()))
+  if (ND->getNameAsString() == "os")
+return true;
+  return false;
+}
+
 const RetainSummary *
 RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD,
 StringRef FName, QualType RetTy) {

Added: cfe/trunk/test/Analysis/os_object_base.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/os_object_base.h?rev=351508=auto
==
--- cfe/trunk/test/Analysis/os_object_base.h (added)
+++ cfe/trunk/test/Analysis/os_object_base.h Thu Jan 17 19:12:35 2019
@@ -0,0 +1,54 @@
+#ifndef _OS_BASE_H
+#define _OS_BASE_H
+

r351394 - [analyzer] Another RetainCountChecker cleanup

2019-01-16 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Jan 16 15:21:38 2019
New Revision: 351394

URL: http://llvm.org/viewvc/llvm-project?rev=351394=rev
Log:
[analyzer] Another RetainCountChecker cleanup

This is not NFC strictly speaking, since it unifies CleanupAttr handling,
so that out parameters now also understand it.

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351394=351393=351394=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Wed Jan 16 15:21:38 2019
@@ -529,12 +529,24 @@ void RetainCountChecker::processSummaryO
   C.addTransition(state);
 }
 
+/// A value escapes in these possible cases:
+///
+/// - binding to something that is not a memory region.
+/// - binding to a memregion that does not have stack storage
+/// - binding to a variable that has a destructor attached using CleanupAttr
+///
+/// We do not currently model what happens when a symbol is
+/// assigned to a struct field, so be conservative here and let the symbol go.
+/// FIXME: This could definitely be improved upon.
 static bool shouldEscapeRegion(const MemRegion *R) {
-
-  // We do not currently model what happens when a symbol is
-  // assigned to a struct field, so be conservative here and let the symbol
-  // go. TODO: This could definitely be improved upon.
-  return !R->hasStackStorage() || !isa(R);
+  const auto *VR = dyn_cast(R);
+  if (!R->hasStackStorage() || !VR)
+return true;
+
+  const VarDecl *VD = VR->getDecl();
+  if (!VD->hasAttr())
+return false; // CleanupAttr attaches destructors, which cause escaping.
+  return true;
 }
 
 static SmallVector
@@ -1145,39 +1157,15 @@ ExplodedNode * RetainCountChecker::check
 
 void RetainCountChecker::checkBind(SVal loc, SVal val, const Stmt *S,
CheckerContext ) const {
-  // Are we storing to something that causes the value to "escape"?
-  bool escapes = true;
-
-  // A value escapes in three possible cases (this may change):
-  //
-  // (1) we are binding to something that is not a memory region.
-  // (2) we are binding to a memregion that does not have stack storage
   ProgramStateRef state = C.getState();
+  const MemRegion *MR = loc.getAsRegion();
 
-  if (auto regionLoc = loc.getAs()) {
-escapes = shouldEscapeRegion(regionLoc->getRegion());
-  }
-
-  // If we are storing the value into an auto function scope variable annotated
-  // with (__attribute__((cleanup))), stop tracking the value to avoid leak
-  // false positives.
-  if (const auto *LVR = dyn_cast_or_null(loc.getAsRegion())) {
-const VarDecl *VD = LVR->getDecl();
-if (VD->hasAttr()) {
-  escapes = true;
-}
-  }
-
-  // If our store can represent the binding and we aren't storing to something
-  // that doesn't have local storage then just return and have the simulation
-  // state continue as is.
-  if (!escapes)
-  return;
-
-  // Otherwise, find all symbols referenced by 'val' that we are tracking
+  // Find all symbols referenced by 'val' that we are tracking
   // and stop tracking them.
-  state = state->scanReachableSymbols(val).getState();
-  C.addTransition(state);
+  if (MR && shouldEscapeRegion(MR)) {
+state = state->scanReachableSymbols(val).getState();
+C.addTransition(state);
+  }
 }
 
 ProgramStateRef RetainCountChecker::evalAssume(ProgramStateRef state,
@@ -1196,14 +1184,14 @@ ProgramStateRef RetainCountChecker::eval
 
   bool changed = false;
   RefBindingsTy::Factory  = state->get_context();
+  ConstraintManager  = state->getConstraintManager();
 
-  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+  for (auto  : B) {
 // Check if the symbol is null stop tracking the symbol.
-ConstraintManager  = state->getConstraintManager();
-ConditionTruthVal AllocFailed = CMgr.isNull(state, I.getKey());
+ConditionTruthVal AllocFailed = CMgr.isNull(state, I.first);
 if (AllocFailed.isConstrainedTrue()) {
   changed = true;
-  B = RefBFactory.remove(B, I.getKey());
+  B = RefBFactory.remove(B, I.first);
 }
   }
 
@@ -1424,9 +1412,9 @@ void RetainCountChecker::checkEndFunctio
 return;
   }
 
-  for (RefBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+  for (auto  : B) {
 state = handleAutoreleaseCounts(state, Pred, /*Tag=*/nullptr, Ctx,
-I->first, I->second);
+I.first, I.second);
 if (!state)
   return;
 

r351393 - [analyzer] [NFC] Yet another minor cleanup of RetainCountChecker

2019-01-16 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Jan 16 15:21:15 2019
New Revision: 351393

URL: http://llvm.org/viewvc/llvm-project?rev=351393=rev
Log:
[analyzer] [NFC] Yet another minor cleanup of RetainCountChecker

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

Modified:

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

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

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=351393=351392=351393=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Wed Jan 16 15:21:15 2019
@@ -29,13 +29,13 @@ const RefVal *getRefBinding(ProgramState
   return State->get(Sym);
 }
 
-ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
+static ProgramStateRef setRefBinding(ProgramStateRef State, SymbolRef Sym,
  RefVal Val) {
   assert(Sym != nullptr);
   return State->set(Sym, Val);
 }
 
-ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
+static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
   return State->remove(Sym);
 }
 
@@ -196,7 +196,7 @@ public:
   ProgramStateRef getState() const { return state; }
 
   bool VisitSymbol(SymbolRef sym) override {
-state = state->remove(sym);
+state = removeRefBinding(state, sym);
 return true;
   }
 };
@@ -1213,25 +1213,21 @@ ProgramStateRef RetainCountChecker::eval
   return state;
 }
 
-ProgramStateRef
-RetainCountChecker::checkRegionChanges(ProgramStateRef state,
-   const InvalidatedSymbols *invalidated,
-   ArrayRef 
ExplicitRegions,
-   ArrayRef Regions,
-   const LocationContext *LCtx,
-   const CallEvent *Call) const {
+ProgramStateRef RetainCountChecker::checkRegionChanges(
+ProgramStateRef state, const InvalidatedSymbols *invalidated,
+ArrayRef ExplicitRegions,
+ArrayRef Regions, const LocationContext *LCtx,
+const CallEvent *Call) const {
   if (!invalidated)
 return state;
 
   llvm::SmallPtrSet WhitelistedSymbols;
-  for (ArrayRef::iterator I = ExplicitRegions.begin(),
-   E = ExplicitRegions.end(); I != E; ++I) {
-if (const SymbolicRegion *SR = (*I)->StripCasts()->getAs())
+
+  for (const MemRegion *I : ExplicitRegions)
+if (const SymbolicRegion *SR = I->StripCasts()->getAs())
   WhitelistedSymbols.insert(SR->getSymbol());
-  }
 
-  for (SymbolRef sym :
-   llvm::make_range(invalidated->begin(), invalidated->end())) {
+  for (SymbolRef sym : *invalidated) {
 if (WhitelistedSymbols.count(sym))
   continue;
 // Remove any existing reference-count binding.
@@ -1356,18 +1352,15 @@ RetainCountChecker::processLeaks(Program
  ExplodedNode *Pred) const {
   // Generate an intermediate node representing the leak point.
   ExplodedNode *N = Ctx.addTransition(state, Pred);
+  const LangOptions  = Ctx.getASTContext().getLangOpts();
 
   if (N) {
-for (SmallVectorImpl::iterator
- I = Leaked.begin(), E = Leaked.end(); I != E; ++I) {
-
-  const LangOptions  = Ctx.getASTContext().getLangOpts();
+for (SymbolRef L : Leaked) {
   RefCountBug *BT = Pred ? getLeakWithinFunctionBug(LOpts)
   : getLeakAtReturnBug(LOpts);
   assert(BT && "BugType not initialized.");
 
-  Ctx.emitReport(
-  llvm::make_unique(*BT, LOpts, N, *I, Ctx));
+  Ctx.emitReport(llvm::make_unique(*BT, LOpts, N, L, Ctx));
 }
   }
 
@@ -1459,7 +1452,6 @@ void RetainCountChecker::checkDeadSymbol
   ExplodedNode *Pred = C.getPredecessor();
 
   ProgramStateRef state = C.getState();
-  RefBindingsTy B = state->get();
   SmallVector Leaked;
 
   // Update counts from autorelease pools
@@ -1492,12 +1484,10 @@ void RetainCountChecker::checkDeadSymbol
   // Now generate a new node that nukes the old bindings.
   // The only bindings left at this point are the leaked symbols.
   RefBindingsTy::Factory  = state->get_context();
-  B = state->get();
+  RefBindingsTy B = state->get();
 
-  for (SmallVectorImpl::iterator I = Leaked.begin(),
-E = Leaked.end();
-   I != E; ++I)
-B = F.remove(B, *I);
+  for (SymbolRef L : Leaked)
+B = F.remove(B, L);
 
   state = state->set(B);
   C.addTransition(state, Pred);

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
URL: 

r351097 - [analyzer] [PR39792] false positive on strcpy targeting struct members

2019-01-14 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Mon Jan 14 10:54:48 2019
New Revision: 351097

URL: http://llvm.org/viewvc/llvm-project?rev=351097=rev
Log:
[analyzer] [PR39792] false positive on strcpy targeting struct members

Patch by Pierre van Houtryve.

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
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=351097=351096=351097=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp Mon Jan 
14 10:54:48 2019
@@ -651,14 +651,14 @@ void WalkAST::checkCall_strcpy(const Cal
 
   const auto *Target = CE->getArg(0)->IgnoreImpCasts(),
  *Source = CE->getArg(1)->IgnoreImpCasts();
-  if (const auto *DeclRef = dyn_cast(Target))
-if (const auto *Array = dyn_cast(DeclRef->getType())) {
-  uint64_t ArraySize = BR.getContext().getTypeSize(Array) / 8;
-  if (const auto *String = dyn_cast(Source)) {
-if (ArraySize >= String->getLength() + 1)
-  return;
-  }
+
+  if (const auto *Array = dyn_cast(Target->getType())) {
+uint64_t ArraySize = BR.getContext().getTypeSize(Array) / 8;
+if (const auto *String = dyn_cast(Source)) {
+  if (ArraySize >= String->getLength() + 1)
+return;
 }
+  }
 
   // Issue a warning.
   PathDiagnosticLocation CELoc =

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=351097=351096=351097=diff
==
--- cfe/trunk/test/Analysis/security-syntax-checks.m (original)
+++ cfe/trunk/test/Analysis/security-syntax-checks.m Mon Jan 14 10:54:48 2019
@@ -177,6 +177,11 @@ void test_strcpy_safe() {
   strcpy(x, "abcd");
 }
 
+void test_strcpy_safe_2() {
+  struct {char s1[100];} s;
+  strcpy(s.s1, "hello");
+}
+
 //===--===
 // strcat()
 //===--===


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


r351096 - [analyzer] [NFC] Remove unused undefined method.

2019-01-14 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Mon Jan 14 10:54:35 2019
New Revision: 351096

URL: http://llvm.org/viewvc/llvm-project?rev=351096=rev
Log:
[analyzer] [NFC] Remove unused undefined method.

Wow, at no point the linker or compiler complaints about that!

Modified:

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

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h?rev=351096=351095=351096=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
Mon Jan 14 10:54:35 2019
@@ -342,8 +342,6 @@ public:
 
   void processObjCLiterals(CheckerContext , const Expr *Ex) const;
 
-  const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const;
-
   ProgramStateRef handleSymbolDeath(ProgramStateRef state,
 SymbolRef sid, RefVal V,
 SmallVectorImpl ) const;


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


r350982 - [analyzer] Support for OSObjects out parameters in RetainCountChecker

2019-01-11 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Jan 11 15:35:17 2019
New Revision: 350982

URL: http://llvm.org/viewvc/llvm-project?rev=350982=rev
Log:
[analyzer] Support for OSObjects out parameters in RetainCountChecker

rdar://46357478
rdar://47121327

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/Inputs/expected-plists/retain-release.m.objc.plist
cfe/trunk/test/Analysis/Inputs/expected-plists/retain-release.m.objcpp.plist
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350982=350981=350982=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Fri Jan 
11 15:35:17 2019
@@ -77,13 +77,21 @@ enum ArgEffectKind {
   IncRef,
 
   /// The argument is a pointer to a retain-counted object; on exit, the new
-  /// value of the pointer is a +0 value or NULL.
+  /// value of the pointer is a +0 value.
   UnretainedOutParameter,
 
   /// The argument is a pointer to a retain-counted object; on exit, the new
-  /// value of the pointer is a +1 value or NULL.
+  /// value of the pointer is a +1 value.
   RetainedOutParameter,
 
+  /// The argument is a pointer to a retain-counted object; on exit, the new
+  /// value of the pointer is a +1 value iff the return code is zero.
+  RetainedOutParameterOnZero,
+
+  /// The argument is a pointer to a retain-counted object; on exit, the new
+  /// value of the pointer is a +1 value iff the return code is non-zero.
+  RetainedOutParameterOnNonZero,
+
   /// The argument is treated as potentially escaping, meaning that
   /// even when its reference count hits 0 it should be treated as still
   /// possibly being alive as someone else *may* be holding onto the object.

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=350982=350981=350982=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Fri Jan 11 15:35:17 2019
@@ -529,38 +529,92 @@ void RetainCountChecker::processSummaryO
   C.addTransition(state);
 }
 
-static ProgramStateRef updateOutParameter(ProgramStateRef State,
-  SVal ArgVal,
-  ArgEffectKind Effect) {
-  auto *ArgRegion = dyn_cast_or_null(ArgVal.getAsRegion());
-  if (!ArgRegion)
-return State;
-
-  QualType PointeeTy = ArgRegion->getValueType();
-  if (!coreFoundation::isCFObjectRef(PointeeTy))
-return State;
-
-  SVal PointeeVal = State->getSVal(ArgRegion);
-  SymbolRef Pointee = PointeeVal.getAsLocSymbol();
-  if (!Pointee)
-return State;
-
-  switch (Effect) {
-  case UnretainedOutParameter:
-State = setRefBinding(State, Pointee,
-  RefVal::makeNotOwned(ObjKind::CF, PointeeTy));
-break;
-  case RetainedOutParameter:
-// Do nothing. Retained out parameters will either point to a +1 reference
-// or NULL, but the way you check for failure differs depending on the API.
-// Consequently, we don't have a good way to track them yet.
-break;
+static bool shouldEscapeRegion(const MemRegion *R) {
 
-  default:
-llvm_unreachable("only for out parameters");
+  // We do not currently model what happens when a symbol is
+  // assigned to a struct field, so be conservative here and let the symbol
+  // go. TODO: This could definitely be improved upon.
+  return !R->hasStackStorage() || !isa(R);
+}
+
+static SmallVector
+updateOutParameters(ProgramStateRef State, const RetainSummary ,
+const CallEvent ) {
+
+  SVal L = CE.getReturnValue();
+
+  // Splitting is required to support out parameters,
+  // as out parameters might be created only on the "success" branch.
+  // We want to avoid eagerly splitting unless out parameters are actually
+  // needed.
+  bool SplitNecessary = false;
+  for (auto  : Summ.getArgEffects())
+if (P.second.getKind() == RetainedOutParameterOnNonZero ||
+P.second.getKind() == RetainedOutParameterOnZero)
+  SplitNecessary = true;
+
+  ProgramStateRef AssumeNonZeroReturn = State;
+ 

r350981 - [analyzer] Introduce a convenience method for getting a CallEvent from an arbitrary Stmt

2019-01-11 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Jan 11 15:35:04 2019
New Revision: 350981

URL: http://llvm.org/viewvc/llvm-project?rev=350981=rev
Log:
[analyzer] Introduce a convenience method for getting a CallEvent from an 
arbitrary Stmt

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=350981=350980=350981=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Fri 
Jan 11 15:35:04 2019
@@ -1138,9 +1138,16 @@ class CallEventManager {
 public:
   CallEventManager(llvm::BumpPtrAllocator ) : Alloc(alloc) {}
 
+  /// Gets an outside caller given a callee context.
   CallEventRef<>
   getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
 
+  /// Gets a call event for a function call, Objective-C method call,
+  /// or a 'new' call.
+  CallEventRef<>
+  getCall(const Stmt *S, ProgramStateRef State,
+  const LocationContext *LC);
+
   CallEventRef<>
   getSimpleCall(const CallExpr *E, ProgramStateRef State,
 const LocationContext *LCtx);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=350981=350980=350981=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Fri Jan 11 15:35:04 2019
@@ -1369,28 +1369,23 @@ CallEventManager::getCaller(const StackF
   const Stmt *CallSite = CalleeCtx->getCallSite();
 
   if (CallSite) {
-if (const CallExpr *CE = dyn_cast(CallSite))
-  return getSimpleCall(CE, State, CallerCtx);
+if (CallEventRef<> Out = getCall(CallSite, State, CallerCtx))
+  return Out;
 
-switch (CallSite->getStmtClass()) {
-case Stmt::CXXConstructExprClass:
-case Stmt::CXXTemporaryObjectExprClass: {
-  SValBuilder  = State->getStateManager().getSValBuilder();
-  const auto *Ctor = cast(CalleeCtx->getDecl());
-  Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
-  SVal ThisVal = State->getSVal(ThisPtr);
-
-  return getCXXConstructorCall(cast(CallSite),
-   ThisVal.getAsRegion(), State, CallerCtx);
-}
-case Stmt::CXXNewExprClass:
-  return getCXXAllocatorCall(cast(CallSite), State, CallerCtx);
-case Stmt::ObjCMessageExprClass:
-  return getObjCMethodCall(cast(CallSite),
-   State, CallerCtx);
-default:
-  llvm_unreachable("This is not an inlineable statement.");
-}
+Stmt::StmtClass SC = CallSite->getStmtClass();
+
+// All other cases are handled by getCall.
+assert(SC == Stmt::CXXConstructExprClass ||
+   SC == Stmt::CXXTemporaryObjectExprClass &&
+   "This is not an inlineable statement");
+
+SValBuilder  = State->getStateManager().getSValBuilder();
+const auto *Ctor = cast(CalleeCtx->getDecl());
+Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
+SVal ThisVal = State->getSVal(ThisPtr);
+
+return getCXXConstructorCall(cast(CallSite),
+ ThisVal.getAsRegion(), State, CallerCtx);
   }
 
   // Fall back to the CFG. The only thing we haven't handled yet is
@@ -1417,3 +1412,16 @@ CallEventManager::getCaller(const StackF
   E.getAs().hasValue(), State,
   CallerCtx);
 }
+
+CallEventRef<> CallEventManager::getCall(const Stmt *S, ProgramStateRef State,
+ const LocationContext *LC) {
+  if (const auto *CE = dyn_cast(S)) {
+return getSimpleCall(CE, State, LC);
+  } else if (const auto *NE = dyn_cast(S)) {
+return getCXXAllocatorCall(NE, State, LC);
+  } else if (const auto *ME = dyn_cast(S)) {
+return getObjCMethodCall(ME, State, LC);
+  } else {
+return nullptr;
+  }
+}


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


r350942 - [attributes] Extend os_returns_(not_?)_retained attributes to parameters

2019-01-11 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Jan 11 10:02:08 2019
New Revision: 350942

URL: http://llvm.org/viewvc/llvm-project?rev=350942=rev
Log:
[attributes] Extend os_returns_(not_?)_retained attributes to parameters

When applied to out-parameters, the attributes specify the expected lifetime of 
the written-into object.

Additionally, introduce OSReturnsRetainedOn(Non)Zero attributes, which
specify that an ownership transfer happens depending on a return code.

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

Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test
cfe/trunk/test/Sema/attr-osobject.cpp
cfe/trunk/test/Sema/attr-osobject.mm

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=350942=350941=350942=diff
==
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Fri Jan 11 10:02:08 2019
@@ -841,13 +841,25 @@ def OSConsumed : InheritableParamAttr {
 
 def OSReturnsRetained : InheritableAttr {
   let Spellings = [Clang<"os_returns_retained">];
-  let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
+  let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>;
   let Documentation = [RetainBehaviorDocs];
 }
 
 def OSReturnsNotRetained : InheritableAttr {
   let Spellings = [Clang<"os_returns_not_retained">];
-  let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
+  let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty, ParmVar]>;
+  let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsRetainedOnZero : InheritableAttr {
+  let Spellings = [Clang<"os_returns_retained_on_zero">];
+  let Subjects = SubjectList<[ParmVar]>;
+  let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsRetainedOnNonZero : InheritableAttr {
+  let Spellings = [Clang<"os_returns_retained_on_non_zero">];
+  let Subjects = SubjectList<[ParmVar]>;
   let Documentation = [RetainBehaviorDocs];
 }
 

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=350942=350941=350942=diff
==
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Fri Jan 11 10:02:08 2019
@@ -888,6 +888,21 @@ Similar to ``__attribute__((ns_consumes_
 ``__attribute__((os_consumes_this))`` specifies that the method call consumes
 the reference to "this" (e.g., when attaching it to a different object supplied
 as a parameter).
+Out parameters (parameters the function is meant to write into,
+either via pointers-to-pointers or references-to-pointers)
+may be annotated with ``__attribute__((os_returns_retained))``
+or ``__attribute__((os_returns_not_retained))`` which specifies that the object
+written into the out parameter should (or respectively should not) be released
+after use.
+Since often out parameters may or may not be written depending on the exit
+code of the function,
+annotations ``__attribute__((os_returns_retained_on_zero))``
+and ``__attribute__((os_returns_retained_on_non_zero))`` specify that
+an out parameter at ``+1`` is written if and only if the function returns a 
zero
+(respectively non-zero) error code.
+Observe that return-code-dependent out parameter annotations are only
+available for retained out parameters, as non-retained object do not have to be
+released by the callee.
 These attributes are only used by the Clang Static Analyzer.
 
 The family of attributes ``X_returns_X_retained`` can be added to functions,

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=350942=350941=350942=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jan 11 10:02:08 
2019
@@ -3425,7 +3425,7 @@ def err_ns_attribute_wrong_parameter_typ
   "%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">;
 def warn_ns_attribute_wrong_parameter_type : Warning<
   "%0 attribute only applies to "
-  "%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">,
+  "%select{Objective-C 
object|pointer|pointer-to-CF-pointer|pointer/reference-to-OSObject-pointer}1 
parameters">,
   InGroup;
 def warn_objc_requires_super_protocol : Warning<
   "%0 attribute cannot be applied to %select{methods in protocols|dealloc}1">,

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: 

r350870 - [analyzer] [hotfix] Fix the tests

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:28:10 2019
New Revision: 350870

URL: http://llvm.org/viewvc/llvm-project?rev=350870=rev
Log:
[analyzer] [hotfix] Fix the tests

The error must have crept during the cherry-pick.

Modified:

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

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=350870=350869=350870=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Jan 10 10:28:10 2019
@@ -156,23 +156,25 @@ static void generateDiagnosticsForCallLi
 }
   }
 
+   os << " returns ";
+
   if (CurrV.getObjKind() == ObjKind::CF) {
-os << " a Core Foundation object of type '"
+os << "a Core Foundation object of type '"
<< Sym->getType().getAsString() << "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::OS) {
-os << " an OSObject of type '" << getPrettyTypeName(Sym->getType())
+os << "an OSObject of type '" << getPrettyTypeName(Sym->getType())
<< "' with a ";
   } else if (CurrV.getObjKind() == ObjKind::Generalized) {
-os << " an object of type '" << Sym->getType().getAsString()
+os << "an object of type '" << Sym->getType().getAsString()
<< "' with a ";
   } else {
 assert(CurrV.getObjKind() == ObjKind::ObjC);
 QualType T = Sym->getType();
 if (!isa(T)) {
-  os << " returns an Objective-C object with a ";
+  os << "an Objective-C object with a ";
 } else {
   const ObjCObjectPointerType *PT = cast(T);
-  os << " returns an instance of " << PT->getPointeeType().getAsString()
+  os << "an instance of " << PT->getPointeeType().getAsString()
  << " with a ";
 }
   }


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


r350869 - [analyzer] Update the category name for RetainCountChecker reports

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:16:25 2019
New Revision: 350869

URL: http://llvm.org/viewvc/llvm-project?rev=350869=rev
Log:
[analyzer] Update the category name for RetainCountChecker reports

..now that it includes OSObjects

rdar://46509986

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

Modified:

cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
cfe/trunk/test/Analysis/Inputs/expected-plists/edges-new.mm.plist
cfe/trunk/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
cfe/trunk/test/Analysis/Inputs/expected-plists/objc-radar17039661.m.plist

cfe/trunk/test/Analysis/Inputs/expected-plists/plist-output-alternate.m.plist
cfe/trunk/test/Analysis/Inputs/expected-plists/plist-output.m.plist

cfe/trunk/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
cfe/trunk/test/Analysis/inlining/Inputs/expected-plists/path-notes.m.plist

Modified: 
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h?rev=350869=350868=350869=diff
==
--- 
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h 
(original)
+++ 
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h 
Thu Jan 10 10:16:25 2019
@@ -16,7 +16,7 @@ namespace clang {
 namespace categories {
   extern const char * const CoreFoundationObjectiveC;
   extern const char * const LogicError;
-  extern const char * const MemoryCoreFoundationObjectiveC;
+  extern const char * const MemoryRefCount;
   extern const char * const MemoryError;
   extern const char * const UnixAPI;
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp?rev=350869=350868=350869=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp Thu Jan 10 
10:16:25 2019
@@ -757,15 +757,15 @@ ObjCDeallocChecker::ObjCDeallocChecker()
 
   MissingReleaseBugType.reset(
   new BugType(this, "Missing ivar release (leak)",
-  categories::MemoryCoreFoundationObjectiveC));
+  categories::MemoryRefCount));
 
   ExtraReleaseBugType.reset(
   new BugType(this, "Extra ivar release",
-  categories::MemoryCoreFoundationObjectiveC));
+  categories::MemoryRefCount));
 
   MistakenDeallocBugType.reset(
   new BugType(this, "Mistaken dealloc",
-  categories::MemoryCoreFoundationObjectiveC));
+  categories::MemoryRefCount));
 }
 
 void ObjCDeallocChecker::initIdentifierInfoAndSelectors(

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=350869=350868=350869=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Jan 10 10:16:25 2019
@@ -39,19 +39,19 @@ ProgramStateRef removeRefBinding(Program
   return State->remove(Sym);
 }
 
-class UseAfterRelease : public CFRefBug {
+class UseAfterRelease : public RefCountBug {
 public:
   UseAfterRelease(const CheckerBase *checker)
-  : CFRefBug(checker, "Use-after-release") {}
+  : RefCountBug(checker, "Use-after-release") {}
 
   const char *getDescription() const override {
 return "Reference-counted object is used after it is released";
   }
 };
 
-class BadRelease : public CFRefBug {
+class BadRelease : public RefCountBug {
 public:
-  BadRelease(const CheckerBase *checker) : CFRefBug(checker, "Bad release") {}
+  BadRelease(const CheckerBase *checker) : RefCountBug(checker, "Bad release") 
{}
 
   const char *getDescription() const override {
 return "Incorrect decrement of the reference count of an object that is "
@@ -59,30 +59,30 @@ public:
   }
 };
 
-class DeallocNotOwned : public CFRefBug {
+class DeallocNotOwned : public RefCountBug {
 public:

r350868 - [analyzer] [NFC] [RetainCountChecker] Remove dead unused map

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:16:10 2019
New Revision: 350868

URL: http://llvm.org/viewvc/llvm-project?rev=350868=rev
Log:
[analyzer] [NFC] [RetainCountChecker] Remove dead unused map

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

Modified:

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

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h?rev=350868=350867=350868=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
Thu Jan 10 10:16:10 2019
@@ -256,11 +256,6 @@ class RetainCountChecker
   mutable std::unique_ptr overAutorelease, returnNotOwnedForOwned;
   mutable std::unique_ptr leakWithinFunction, leakAtReturn;
 
-  typedef llvm::DenseMap 
SymbolTagMap;
-
-  // This map is only used to ensure proper deletion of any allocated tags.
-  mutable SymbolTagMap DeadSymbolTags;
-
   mutable std::unique_ptr Summaries;
 public:
   static constexpr const char *DeallocTagDescription = "DeallocSent";
@@ -273,7 +268,6 @@ public:
 
   RetainCountChecker() {}
 
-  ~RetainCountChecker() override { DeleteContainerSeconds(DeadSymbolTags); }
 
   CFRefBug *getLeakWithinFunctionBug(const LangOptions ) const;
 


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


r350866 - [analyzer] [NFC] Reverse the argument order for "diff" in tests

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:15:44 2019
New Revision: 350866

URL: http://llvm.org/viewvc/llvm-project?rev=350866=rev
Log:
[analyzer] [NFC] Reverse the argument order for "diff" in tests

The current argument order has "expected" and "actual" the wrong way around,
so that the diff shows the change from expected to actual, not from actual to 
expected.

Namely, if the expected diagnostics contains the string "foo", but the analyzer 
emits "bar",
we really want to see:

```
- foo
+ bar
```

not

```
- bar
+ foo
```

since adapting to most changes would require applying that diff to the expected 
output.

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

Modified:
cfe/trunk/test/Analysis/NewDelete-path-notes.cpp
cfe/trunk/test/Analysis/conditional-path-notes.c
cfe/trunk/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
cfe/trunk/test/Analysis/copypaste/plist-diagnostics.cpp
cfe/trunk/test/Analysis/cxx-for-range.cpp

cfe/trunk/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-diagnostics-taint-test.c.sarif

cfe/trunk/test/Analysis/diagnostics/Inputs/expected-sarif/sarif-multi-diagnostic-test.c.sarif
cfe/trunk/test/Analysis/diagnostics/deref-track-symbolic-region.c
cfe/trunk/test/Analysis/diagnostics/report-issues-within-main-file.cpp
cfe/trunk/test/Analysis/diagnostics/sarif-diagnostics-taint-test.c
cfe/trunk/test/Analysis/diagnostics/sarif-multi-diagnostic-test.c
cfe/trunk/test/Analysis/diagnostics/undef-value-caller.c
cfe/trunk/test/Analysis/diagnostics/undef-value-param.c
cfe/trunk/test/Analysis/diagnostics/undef-value-param.m
cfe/trunk/test/Analysis/edges-new.mm
cfe/trunk/test/Analysis/generics.m
cfe/trunk/test/Analysis/inline-plist.c
cfe/trunk/test/Analysis/inline-unique-reports.c
cfe/trunk/test/Analysis/inlining/eager-reclamation-path-notes.c
cfe/trunk/test/Analysis/inlining/eager-reclamation-path-notes.cpp
cfe/trunk/test/Analysis/inlining/path-notes.c
cfe/trunk/test/Analysis/inlining/path-notes.cpp
cfe/trunk/test/Analysis/inlining/path-notes.m
cfe/trunk/test/Analysis/lit.local.cfg
cfe/trunk/test/Analysis/method-call-path-notes.cpp
cfe/trunk/test/Analysis/model-file.cpp
cfe/trunk/test/Analysis/null-deref-path-notes.m
cfe/trunk/test/Analysis/nullability-notes.m
cfe/trunk/test/Analysis/objc-arc.m
cfe/trunk/test/Analysis/plist-macros-with-expansion.cpp
cfe/trunk/test/Analysis/plist-macros.cpp
cfe/trunk/test/Analysis/plist-output-alternate.m
cfe/trunk/test/Analysis/plist-output.m
cfe/trunk/test/Analysis/retain-release-path-notes.m
cfe/trunk/test/Analysis/unix-fns.c

Modified: cfe/trunk/test/Analysis/NewDelete-path-notes.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/NewDelete-path-notes.cpp?rev=350866=350865=350866=diff
==
--- cfe/trunk/test/Analysis/NewDelete-path-notes.cpp (original)
+++ cfe/trunk/test/Analysis/NewDelete-path-notes.cpp Thu Jan 10 10:15:44 2019
@@ -1,7 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc 
-analyzer-output=text -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc 
-analyzer-output=text -analyzer-config c++-allocator-inlining=true -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc 
-analyzer-output=plist %s -o %t.plist
-// RUN: cat %t.plist | %diff_plist 
%S/Inputs/expected-plists/NewDelete-path-notes.cpp.plist
+// RUN: cat %t.plist | %diff_plist 
%S/Inputs/expected-plists/NewDelete-path-notes.cpp.plist -
 
 void test() {
   int *p = new int;

Modified: cfe/trunk/test/Analysis/conditional-path-notes.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/conditional-path-notes.c?rev=350866=350865=350866=diff
==
--- cfe/trunk/test/Analysis/conditional-path-notes.c (original)
+++ cfe/trunk/test/Analysis/conditional-path-notes.c Thu Jan 10 10:15:44 2019
@@ -1,6 +1,6 @@
 // RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference 
-analyzer-output=text -verify
 // RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference 
-analyzer-output=plist -o %t
-// RUN: cat %t | %diff_plist 
%S/Inputs/expected-plists/conditional-path-notes.c.plist
+// RUN: cat %t | %diff_plist 
%S/Inputs/expected-plists/conditional-path-notes.c.plist -
 
 void testCondOp(int *p) {
   int *x = p ? p : p;

Modified: 
cfe/trunk/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp?rev=350866=350865=350866=diff
==
--- cfe/trunk/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp 
(original)
+++ 

r350864 - [analyzer] [RetainCountChecker] [NFC] Remove SummaryLog

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:15:17 2019
New Revision: 350864

URL: http://llvm.org/viewvc/llvm-project?rev=350864=rev
Log:
[analyzer] [RetainCountChecker] [NFC] Remove SummaryLog

The complicated machinery for passing the summary log around is actually
only used for one thing! To figure out whether the "dealloc" message was
sent.

Since I have tried to extend it for other uses and failed (it's actually
very hard to use), I think it's much better to simply use a tag and
remove the summary log altogether.

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

Modified:

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=350864=350863=350864=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Jan 10 10:15:17 2019
@@ -414,42 +414,6 @@ void RetainCountChecker::checkPostCall(c
   checkSummary(*Summ, Call, C);
 }
 
-void RetainCountChecker::checkEndAnalysis(ExplodedGraph , BugReporter ,
-  ExprEngine ) const {
-  // FIXME: This is a hack to make sure the summary log gets cleared between
-  // analyses of different code bodies.
-  //
-  // Why is this necessary? Because a checker's lifetime is tied to a
-  // translation unit, but an ExplodedGraph's lifetime is just a code body.
-  // Once in a blue moon, a new ExplodedNode will have the same address as an
-  // old one with an associated summary, and the bug report visitor gets very
-  // confused. (To make things worse, the summary lifetime is currently also
-  // tied to a code body, so we get a crash instead of incorrect results.)
-  //
-  // Why is this a bad solution? Because if the lifetime of the ExplodedGraph
-  // changes, things will start going wrong again. Really the lifetime of this
-  // log needs to be tied to either the specific nodes in it or the entire
-  // ExplodedGraph, not to a specific part of the code being analyzed.
-  //
-  // (Also, having stateful local data means that the same checker can't be
-  // used from multiple threads, but a lot of checkers have incorrect
-  // assumptions about that anyway. So that wasn't a priority at the time of
-  // this fix.)
-  //
-  // This happens at the end of analysis, but bug reports are emitted /after/
-  // this point. So we can't just clear the summary log now. Instead, we mark
-  // that the next time we access the summary log, it should be cleared.
-
-  // If we never reset the summary log during /this/ code body analysis,
-  // there were no new summaries. There might still have been summaries from
-  // the /last/ analysis, so clear them out to make sure the bug report
-  // visitors don't get confused.
-  if (ShouldResetSummaryLog)
-SummaryLog.clear();
-
-  ShouldResetSummaryLog = !SummaryLog.empty();
-}
-
 CFRefBug *
 RetainCountChecker::getLeakWithinFunctionBug(const LangOptions ) const {
   if (!leakWithinFunction)
@@ -609,6 +573,11 @@ void RetainCountChecker::checkSummary(co
   SourceRange ErrorRange;
   SymbolRef ErrorSym = nullptr;
 
+  // Helper tag for providing diagnostics: indicate whether dealloc was sent
+  // at this location.
+  static CheckerProgramPointTag DeallocSentTag(this, DeallocTagDescription);
+  bool DeallocSent = false;
+
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
 SVal V = CallOrMsg.getArgSVal(idx);
 
@@ -627,6 +596,8 @@ void RetainCountChecker::checkSummary(co
   ErrorRange = CallOrMsg.getArgSourceRange(idx);
   ErrorSym = Sym;
   break;
+} else if (Effect.getKind() == Dealloc) {
+  DeallocSent = true;
 }
   }
 }
@@ -644,6 +615,8 @@ void RetainCountChecker::checkSummary(co
   if (hasErr) {
 ErrorRange = MsgInvocation->getOriginExpr()->getReceiverRange();
 ErrorSym = Sym;
+  } else if (Summ.getReceiverEffect().getKind() == Dealloc) {
+DeallocSent = true;
   }
 }
   }
@@ -688,24 +661,10 @@ void RetainCountChecker::checkSummary(co
   state = setRefBinding(state, Sym, *updatedRefVal);
   }
 
-  // This check is actually necessary; otherwise the statement builder thinks
-  // we've hit a previously-found path.
-  // Normally addTransition takes care of this, but we want the node pointer.
-  ExplodedNode *NewNode;
-  if (state == 

r350865 - [analyzer] [NFC] Reduce redundancy in RetainSummaryManager by using a function

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:15:30 2019
New Revision: 350865

URL: http://llvm.org/viewvc/llvm-project?rev=350865=rev
Log:
[analyzer] [NFC] Reduce redundancy in RetainSummaryManager by using a function

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

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350865=350864=350865=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:15:30 2019
@@ -641,10 +641,9 @@ class RetainSummaryManager {
   /// Apply the annotation of {@code pd} in function {@code FD}
   /// to the resulting summary stored in out-parameter {@code Template}.
   /// \return whether an annotation was applied.
-  bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
-unsigned parm_idx,
-const FunctionDecl *FD,
-RetainSummaryTemplate );
+  bool applyParamAnnotationEffect(const ParmVarDecl *pd, unsigned parm_idx,
+  const NamedDecl *FD,
+  RetainSummaryTemplate );
 
 public:
   RetainSummaryManager(ASTContext ,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=350865=350864=350865=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Jan 10 
10:15:30 2019
@@ -811,8 +811,8 @@ RetainSummaryManager::getRetEffectFromAn
   return None;
 }
 
-bool RetainSummaryManager::applyFunctionParamAnnotationEffect(
-const ParmVarDecl *pd, unsigned parm_idx, const FunctionDecl *FD,
+bool RetainSummaryManager::applyParamAnnotationEffect(
+const ParmVarDecl *pd, unsigned parm_idx, const NamedDecl *FD,
 RetainSummaryTemplate ) {
   QualType QT = pd->getType();
   if (auto K =
@@ -832,7 +832,7 @@ bool RetainSummaryManager::applyFunction
 if (const auto *MD = dyn_cast(FD)) {
   for (const auto *OD : MD->overridden_methods()) {
 const ParmVarDecl *OP = OD->parameters()[parm_idx];
-if (applyFunctionParamAnnotationEffect(OP, parm_idx, OD, Template))
+if (applyParamAnnotationEffect(OP, parm_idx, OD, Template))
   return true;
   }
 }
@@ -853,10 +853,8 @@ RetainSummaryManager::updateSummaryFromA
   // Effects on the parameters.
   unsigned parm_idx = 0;
   for (auto pi = FD->param_begin(),
- pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
-const ParmVarDecl *pd = *pi;
-applyFunctionParamAnnotationEffect(pd, parm_idx, FD, Template);
-  }
+ pe = FD->param_end(); pi != pe; ++pi, ++parm_idx)
+applyParamAnnotationEffect(*pi, parm_idx, FD, Template);
 
   QualType RetTy = FD->getReturnType();
   if (Optional RetE = getRetEffectFromAnnotations(RetTy, FD))
@@ -882,19 +880,9 @@ RetainSummaryManager::updateSummaryFromA
   // Effects on the parameters.
   unsigned parm_idx = 0;
   for (auto pi = MD->param_begin(), pe = MD->param_end(); pi != pe;
-   ++pi, ++parm_idx) {
-const ParmVarDecl *pd = *pi;
-QualType QT = pd->getType();
-if (auto K =
-hasAnyEnabledAttrOf(
-pd, QT)) {
-  Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
-} else if (auto K = hasAnyEnabledAttrOf(pd, QT)) {
-  Template->addArg(AF, parm_idx, ArgEffect(RetainedOutParameter, *K));
-} else if (auto K = hasAnyEnabledAttrOf(pd, QT)) 
{
-  Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
-}
-  }
+   ++pi, ++parm_idx)
+applyParamAnnotationEffect(*pi, parm_idx, MD, Template);
+
   QualType RetTy = MD->getReturnType();
   if (Optional RetE = getRetEffectFromAnnotations(RetTy, MD))
 Template->setRetEffect(*RetE);


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


r350862 - [analyzer] [RetainCountChecker] [NFC] Refactor the way attributes are handled

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:14:51 2019
New Revision: 350862

URL: http://llvm.org/viewvc/llvm-project?rev=350862=rev
Log:
[analyzer] [RetainCountChecker] [NFC] Refactor the way attributes are handled

Make sure all checks for attributes go through a centralized function,
which checks whether attribute handling is enabled, and performs
validation.  The type of the attribute is returned.

Sadly, metaprogramming is required as attributes have no sensible static
getters.

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

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350862=350861=350862=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:14:51 2019
@@ -741,16 +741,18 @@ public:
 
   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
 
-  /// \return True if the declaration has an attribute {@code T},
-  /// AND we are tracking that attribute. False otherwise.
+  /// Determine whether a declaration {@code D} of correspondent type (return
+  /// type for functions/methods) {@code QT} has any of the given attributes,
+  /// provided they pass necessary validation checks AND tracking the given
+  /// attribute is enabled.
+  /// Returns the object kind corresponding to the present attribute, or None,
+  /// if none of the specified attributes are present.
+  /// Crashes if passed an attribute which is not explicitly handled.
   template 
-  bool hasEnabledAttr(const Decl *D) {
-return isAttrEnabled() && D->hasAttr();
-  }
+  Optional hasAnyEnabledAttrOf(const Decl *D, QualType QT);
 
-  /// Check whether we are tracking properties specified by the attributes.
-  template 
-  bool isAttrEnabled();
+  template 
+  Optional hasAnyEnabledAttrOf(const Decl *D, QualType QT);
 
   friend class RetainSummaryTemplate;
 };

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=350862=350861=350862=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Jan 10 
10:14:51 2019
@@ -36,17 +36,79 @@ constexpr static bool isOneOf() {
   return std::is_same::value || isOneOf();
 }
 
-template  bool RetainSummaryManager::isAttrEnabled() {
+namespace {
+
+struct GeneralizedReturnsRetainedAttr {
+  static bool classof(const Attr *A) {
+if (auto AA = dyn_cast(A))
+  return AA->getAnnotation() == "rc_ownership_returns_retained";
+return false;
+  }
+};
+
+struct GeneralizedReturnsNotRetainedAttr {
+  static bool classof(const Attr *A) {
+if (auto AA = dyn_cast(A))
+  return AA->getAnnotation() == "rc_ownership_returns_not_retained";
+return false;
+  }
+};
+
+struct GeneralizedConsumedAttr {
+  static bool classof(const Attr *A) {
+if (auto AA = dyn_cast(A))
+  return AA->getAnnotation() == "rc_ownership_consumed";
+return false;
+  }
+};
+
+}
+
+template 
+Optional RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
+QualType QT) {
+  ObjKind K;
   if (isOneOf()) {
-return TrackObjCAndCFObjects;
+  CFReturnsNotRetainedAttr>()) {
+if (!TrackObjCAndCFObjects)
+  return None;
+
+K = ObjKind::CF;
+  } else if (isOneOf()) {
+
+if (!TrackObjCAndCFObjects)
+  return None;
+
+if (isOneOf() &&
+!cocoa::isCocoaObjectRef(QT))
+  return None;
+K = ObjKind::ObjC;
   } else if (isOneOf()) {
-return TrackOSObjects;
+if (!TrackOSObjects)
+  return None;
+K = ObjKind::OS;
+  } else if (isOneOf()) {
+K = ObjKind::Generalized;
+  } else {
+llvm_unreachable("Unexpected attribute");
   }
-  llvm_unreachable("Unexpected attribute passed");
+  if (D->hasAttr())
+return K;
+  return None;
+}
+
+template 
+Optional RetainSummaryManager::hasAnyEnabledAttrOf(const Decl *D,
+QualType QT) {
+  if (auto Out = hasAnyEnabledAttrOf(D, QT))
+return Out;
+  return hasAnyEnabledAttrOf(D, QT);
 }
 
 const RetainSummary *
@@ -727,33 +789,18 @@ RetainSummaryManager::getCFSummaryGetRul
 Optional
 RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,
   const Decl *D) {
-  if (TrackObjCAndCFObjects && cocoa::isCocoaObjectRef(RetTy)) {
-if (D->hasAttr())
-  

r350863 - [analyzer] [RetainCountChecker] [NFC] Another minor cleanup

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:15:04 2019
New Revision: 350863

URL: http://llvm.org/viewvc/llvm-project?rev=350863=rev
Log:
[analyzer] [RetainCountChecker] [NFC] Another minor cleanup

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

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350863=350862=350863=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:15:04 2019
@@ -38,17 +38,20 @@ namespace ento {
 
 /// Determines the object kind of a tracked object.
 enum class ObjKind {
-  /// Indicates that the tracked object is a CF object.  This is
-  /// important between GC and non-GC code.
+  /// Indicates that the tracked object is a CF object.
   CF,
+
   /// Indicates that the tracked object is an Objective-C object.
   ObjC,
+
   /// Indicates that the tracked object could be a CF or Objective-C object.
   AnyObj,
+
   /// Indicates that the tracked object is a generalized object.
   Generalized,
 
-  /// A descendant of OSObject.
+  /// Indicates that the tracking object is a descendant of a
+  /// referenced-counted OSObject, used in the Darwin kernel.
   OS
 };
 
@@ -60,20 +63,17 @@ enum ArgEffectKind {
   /// the referenced object.
   Autorelease,
 
-  /// The argument is treated as if an -dealloc message had been sent to
-  /// the referenced object.
+  /// The argument is treated as if the referenced object was deallocated.
   Dealloc,
 
-  /// The argument has its reference count decreased by 1.  This is as
-  /// if CFRelease has been called on the argument.
+  /// The argument has its reference count decreased by 1.
   DecRef,
 
   /// The argument has its reference count decreased by 1 to model
   /// a transferred bridge cast under ARC.
   DecRefBridgedTransferred,
 
-  /// The argument has its reference count increased by 1.  This is as
-  /// if CFRetain has been called on the argument.
+  /// The argument has its reference count increased by 1.
   IncRef,
 
   /// The argument is a pointer to a retain-counted object; on exit, the new
@@ -139,18 +139,19 @@ public:
 /// Indicates that no retain count information is tracked for
 /// the return value.
 NoRet,
+
 /// Indicates that the returned value is an owned (+1) symbol.
 OwnedSymbol,
+
 /// Indicates that the returned value is an object with retain count
 /// semantics but that it is not owned (+0).  This is the default
 /// for getters, etc.
 NotOwnedSymbol,
-/// Indicates that the object is not owned and controlled by the
-/// Garbage collector.
-GCNotOwnedSymbol,
+
 /// Indicates that the return value is an owned object when the
 /// receiver is also a tracked object.
 OwnedWhenTrackedReceiver,
+
 // Treat this function as returning a non-tracked symbol even if
 // the function has been inlined. This is used where the call
 // site summary is more precise than the summary indirectly produced
@@ -158,7 +159,6 @@ public:
 NoRetHard
   };
 
-
 private:
   Kind K;
   ObjKind O;
@@ -192,9 +192,6 @@ public:
   static RetEffect MakeNotOwned(ObjKind o) {
 return RetEffect(NotOwnedSymbol, o);
   }
-  static RetEffect MakeGCNotOwned() {
-return RetEffect(GCNotOwnedSymbol, ObjKind::ObjC);
-  }
   static RetEffect MakeNoRet() {
 return RetEffect(NoRet);
   }
@@ -372,6 +369,7 @@ public:
   ArgEffect getReceiverEffect() const { return Receiver; }
 
   /// \return the effect on the "this" receiver of the method call.
+  /// This is only meaningful if the summary applies to CXXMethodDecl*.
   ArgEffect getThisEffect() const { return This; }
 
   /// Set the effect of the method on "this".

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=350863=350862=350863=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Jan 10 
10:15:04 2019
@@ -38,6 +38,7 @@ constexpr static bool isOneOf() {
 
 namespace {
 
+/// Fake attribute class for RC* attributes.
 struct GeneralizedReturnsRetainedAttr {
   static bool classof(const Attr *A) {
 if (auto AA = dyn_cast(A))


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


r350860 - [analyzer] [RetainCountChecker] Remove obsolete "MakeCollectable" enum value

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:14:25 2019
New Revision: 350860

URL: http://llvm.org/viewvc/llvm-project?rev=350860=rev
Log:
[analyzer] [RetainCountChecker] Remove obsolete "MakeCollectable" enum value

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

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

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350860=350859=350860=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:14:25 2019
@@ -76,10 +76,6 @@ enum ArgEffectKind {
   /// if CFRetain has been called on the argument.
   IncRef,
 
-  /// The argument acts as if has been passed to CFMakeCollectable, which
-  /// transfers the object to the Garbage Collector under GC.
-  MakeCollectable,
-
   /// The argument is a pointer to a retain-counted object; on exit, the new
   /// value of the pointer is a +0 value or NULL.
   UnretainedOutParameter,

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=350860=350859=350860=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Jan 10 10:14:25 2019
@@ -730,8 +730,6 @@ ProgramStateRef RetainCountChecker::upda
   break;
 }
   }
-  if (AE.getKind() == MakeCollectable)
-AE = AE.withKind(DoNothing);
 
   // Handle all use-after-releases.
   if (V.getKind() == RefVal::Released) {
@@ -741,9 +739,6 @@ ProgramStateRef RetainCountChecker::upda
   }
 
   switch (AE.getKind()) {
-case MakeCollectable:
-  llvm_unreachable("MakeCollectable already converted");
-
 case UnretainedOutParameter:
 case RetainedOutParameter:
   llvm_unreachable("Applies to pointer-to-pointer parameters, which should 
"

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=350860=350859=350860=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Jan 10 
10:14:25 2019
@@ -457,7 +457,6 @@ static ArgEffect getStopTrackingHardEqui
   case Autorelease:
   case DecRefBridgedTransferred:
   case IncRef:
-  case MakeCollectable:
   case UnretainedOutParameter:
   case RetainedOutParameter:
   case MayEscape:
@@ -665,7 +664,7 @@ RetainSummaryManager::getUnarySummary(co
   case cfretain: Effect = Effect.withKind(IncRef); break;
   case cfrelease: Effect = Effect.withKind(DecRef); break;
   case cfautorelease: Effect = Effect.withKind(Autorelease); break;
-  case cfmakecollectable: Effect = Effect.withKind(MakeCollectable); break;
+  case cfmakecollectable: Effect = Effect.withKind(DoNothing); break;
   }
 
   ScratchArgs = AF.add(ScratchArgs, 0, Effect);


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


r350861 - [analyzer] [RetainCountChecker] Remove redundant enum UnarySummaryKind

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:14:38 2019
New Revision: 350861

URL: http://llvm.org/viewvc/llvm-project?rev=350861=rev
Log:
[analyzer] [RetainCountChecker] Remove redundant enum UnarySummaryKind

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

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350861=350860=350861=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:14:38 2019
@@ -537,10 +537,8 @@ class RetainSummaryManager {
   /// Free the OS object.
   const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
 
-  enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
-
   const RetainSummary *getUnarySummary(const FunctionType* FT,
-   UnaryFuncKind func);
+   ArgEffectKind AE);
 
   const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
   const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=350861=350860=350861=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Jan 10 
10:14:38 2019
@@ -194,7 +194,7 @@ const RetainSummary *RetainSummaryManage
   } else if(FName == "NSMakeCollectable") {
 // Handle: id NSMakeCollectable(CFTypeRef)
 AllowAnnotations = false;
-return RetTy->isObjCIdType() ? getUnarySummary(FT, cfmakecollectable)
+return RetTy->isObjCIdType() ? getUnarySummary(FT, DoNothing)
  : getPersistentStopSummary();
   } else if (FName == "CMBufferQueueDequeueAndRetain" ||
  FName == "CMBufferQueueDequeueIfDataReadyAndRetain") {
@@ -307,16 +307,16 @@ const RetainSummary *RetainSummaryManage
 // We want to ignore such annotation.
 AllowAnnotations = false;
 
-return getUnarySummary(FT, cfretain);
+return getUnarySummary(FT, IncRef);
   } else if (isAutorelease(FD, FName)) {
 // The headers use cf_consumed, but we can fully model CFAutorelease
 // ourselves.
 AllowAnnotations = false;
 
-return getUnarySummary(FT, cfautorelease);
+return getUnarySummary(FT, Autorelease);
   } else if (isMakeCollectable(FName)) {
 AllowAnnotations = false;
-return getUnarySummary(FT, cfmakecollectable);
+return getUnarySummary(FT, DoNothing);
   } else {
 return getCFCreateGetRuleSummary(FD);
   }
@@ -326,7 +326,7 @@ const RetainSummary *RetainSummaryManage
 if (cocoa::isRefType(RetTy, "CG", FName) ||
 cocoa::isRefType(RetTy, "CV", FName)) {
   if (isRetain(FD, FName))
-return getUnarySummary(FT, cfretain);
+return getUnarySummary(FT, IncRef);
   else
 return getCFCreateGetRuleSummary(FD);
 }
@@ -350,7 +350,7 @@ const RetainSummary *RetainSummaryManage
 FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
 
 if (isRelease(FD, FName))
-  return getUnarySummary(FT, cfrelease);
+  return getUnarySummary(FT, DecRef);
 else {
   assert(ScratchArgs.isEmpty());
   // Remaining CoreFoundation and CoreGraphics functions.
@@ -644,11 +644,9 @@ RetainSummaryManager::canEval(const Call
   return None;
 }
 
-// TODO: UnaryFuncKind is a very funny enum, it really should not exist:
-// just pass the needed effect directly!
 const RetainSummary *
 RetainSummaryManager::getUnarySummary(const FunctionType* FT,
-  UnaryFuncKind func) {
+  ArgEffectKind AE) {
 
   // Unary functions have no arg effects by definition.
   ArgEffects ScratchArgs(AF.getEmptyMap());
@@ -659,13 +657,7 @@ RetainSummaryManager::getUnarySummary(co
   if (!FTP || FTP->getNumParams() != 1)
 return getPersistentStopSummary();
 
-  ArgEffect Effect(DoNothing, ObjKind::CF);
-  switch (func) {
-  case cfretain: Effect = Effect.withKind(IncRef); break;
-  case cfrelease: Effect = Effect.withKind(DecRef); break;
-  case cfautorelease: Effect = Effect.withKind(Autorelease); break;
-  case cfmakecollectable: Effect = Effect.withKind(DoNothing); break;
-  }
+  ArgEffect Effect(AE, ObjKind::CF);
 
   ScratchArgs = AF.add(ScratchArgs, 0, Effect);
   return 

r350859 - [analyzer] [RetainCountChecker] [NFC] Remove redundant enum items *Msg, as the object type is already communicated by a separate field

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:14:12 2019
New Revision: 350859

URL: http://llvm.org/viewvc/llvm-project?rev=350859=rev
Log:
[analyzer] [RetainCountChecker] [NFC] Remove redundant enum items *Msg, as the 
object type is already communicated by a separate field

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350859=350858=350859=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:14:12 2019
@@ -68,21 +68,11 @@ enum ArgEffectKind {
   /// if CFRelease has been called on the argument.
   DecRef,
 
-  /// The argument has its reference count decreased by 1.  This is as
-  /// if a -release message has been sent to the argument.  This differs
-  /// in behavior from DecRef when ARC is enabled.
-  DecRefMsg,
-
   /// The argument has its reference count decreased by 1 to model
   /// a transferred bridge cast under ARC.
   DecRefBridgedTransferred,
 
   /// The argument has its reference count increased by 1.  This is as
-  /// if a -retain message has been sent to the argument.  This differs
-  /// in behavior from IncRef when ARC is enabled.
-  IncRefMsg,
-
-  /// The argument has its reference count increased by 1.  This is as
   /// if CFRetain has been called on the argument.
   IncRef,
 
@@ -122,13 +112,6 @@ enum ArgEffectKind {
   /// count of the argument and all typestate tracking on that argument
   /// should cease.
   DecRefAndStopTrackingHard,
-
-  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
-  ///
-  /// The models the effect that the called function decrements the reference
-  /// count of the argument and all typestate tracking on that argument
-  /// should cease.
-  DecRefMsgAndStopTrackingHard
 };
 
 /// An ArgEffect summarizes the retain count behavior on an argument or 
receiver

Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=350859=350858=350859=diff
==
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Thu Jan 10 10:14:12 2019
@@ -1484,14 +1484,15 @@ void ObjCMigrateASTConsumer::AddCFAnnota
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
 const ParmVarDecl *pd = *pi;
 ArgEffect AE = AEArgs[i];
-if (AE.getKind() == DecRef && !pd->hasAttr() &&
+if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF &&
+!pd->hasAttr() &&
 NSAPIObj->isMacroDefined("CF_CONSUMED")) {
   edit::Commit commit(*Editor);
   commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
   Editor->commit(commit);
-}
-else if (AE.getKind() == DecRefMsg && !pd->hasAttr() &&
- NSAPIObj->isMacroDefined("NS_CONSUMED")) {
+} else if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::ObjC &&
+   !pd->hasAttr() &&
+   NSAPIObj->isMacroDefined("NS_CONSUMED")) {
   edit::Commit commit(*Editor);
   commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
   Editor->commit(commit);
@@ -1536,8 +1537,8 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
 const ParmVarDecl *pd = *pi;
 ArgEffect AE = AEArgs[i];
-if (AE.getKind() == DecRef /*CFConsumed annotated*/ ||
-AE.getKind() == IncRef) {
+if ((AE.getKind() == DecRef /*CFConsumed annotated*/ ||
+ AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) {
   if (AE.getKind() == DecRef && !pd->hasAttr())
 ArgCFAudited = true;
   else if (AE.getKind() == IncRef)
@@ -1610,7 +1611,9 @@ void ObjCMigrateASTConsumer::AddCFAnnota
pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
 const ParmVarDecl *pd = *pi;
 ArgEffect AE = AEArgs[i];
-if (AE.getKind() == DecRef && !pd->hasAttr() &&
+if (AE.getKind() == DecRef
+&& AE.getObjKind() == ObjKind::CF
+&& !pd->hasAttr() &&
 NSAPIObj->isMacroDefined("CF_CONSUMED")) {
   edit::Commit commit(*Editor);
   commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
@@ -1633,7 +1636,7 @@ void ObjCMigrateASTConsumer::migrateAddM
MethodDecl->hasAttr() ||
MethodDecl->hasAttr());
 
-  if 

r350858 - [analyzer] [NFC] Track object type with ArgEffect in RetainCountChecker.

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:13:59 2019
New Revision: 350858

URL: http://llvm.org/viewvc/llvm-project?rev=350858=rev
Log:
[analyzer] [NFC] Track object type with ArgEffect in RetainCountChecker.

This would be needed in the future.

https://reviews.llvm.org/D56040

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350858=350857=350858=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:13:59 2019
@@ -52,9 +52,7 @@ enum class ObjKind {
   OS
 };
 
-/// An ArgEffect summarizes the retain count behavior on an argument or 
receiver
-/// to a function or method.
-enum ArgEffect {
+enum ArgEffectKind {
   /// There is no effect.
   DoNothing,
 
@@ -133,6 +131,27 @@ enum ArgEffect {
   DecRefMsgAndStopTrackingHard
 };
 
+/// An ArgEffect summarizes the retain count behavior on an argument or 
receiver
+/// to a function or method.
+class ArgEffect {
+  ArgEffectKind K;
+  ObjKind O;
+public:
+  explicit ArgEffect(ArgEffectKind K = DoNothing, ObjKind O = ObjKind::AnyObj)
+  : K(K), O(O) {}
+
+  ArgEffectKind getKind() const { return K; }
+  ObjKind getObjKind() const { return O; }
+
+  ArgEffect withKind(ArgEffectKind NewK) {
+return ArgEffect(NewK, O);
+  }
+
+  bool operator==(const ArgEffect ) const {
+return K == Other.K && O == Other.O;
+  }
+};
+
 /// RetEffect summarizes a call's retain/release behavior with respect
 /// to its return value.
 class RetEffect {
@@ -218,7 +237,9 @@ class CallEffects {
   RetEffect Ret;
   ArgEffect Receiver;
 
-  CallEffects(const RetEffect ) : Ret(R) {}
+  CallEffects(const RetEffect ,
+  ArgEffect Receiver = ArgEffect(DoNothing, ObjKind::AnyObj))
+  : Ret(R), Receiver(Receiver) {}
 
 public:
   /// Returns the argument effects for a call.
@@ -263,7 +284,8 @@ namespace llvm {
 
 template <> struct FoldingSetTrait {
 static inline void Profile(const ArgEffect X, FoldingSetNodeID ) {
-  ID.AddInteger((unsigned) X);
+  ID.AddInteger((unsigned) X.getKind());
+  ID.AddInteger((unsigned) X.getObjKind());
 }
 };
 template <> struct FoldingSetTrait {
@@ -377,8 +399,8 @@ public:
   void setThisEffect(ArgEffect e) { This = e; }
 
   bool isNoop() const {
-return Ret == RetEffect::MakeNoRet() && Receiver == DoNothing
-  && DefaultArgEffect == MayEscape && This == DoNothing
+return Ret == RetEffect::MakeNoRet() && Receiver.getKind() == DoNothing
+  && DefaultArgEffect.getKind() == MayEscape && This.getKind() == DoNothing
   && Args.isEmpty();
   }
 
@@ -547,32 +569,31 @@ class RetainSummaryManager {
 
   const RetainSummary *getPersistentSummary(const RetainSummary );
 
-  const RetainSummary *getPersistentSummary(RetEffect RetEff,
-ArgEffects ScratchArgs,
-ArgEffect ReceiverEff = DoNothing,
-ArgEffect DefaultEff = MayEscape,
-ArgEffect ThisEff = DoNothing) {
-RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff,
-   ThisEff);
+  const RetainSummary *
+  getPersistentSummary(RetEffect RetEff, ArgEffects ScratchArgs,
+   ArgEffect ReceiverEff = ArgEffect(DoNothing),
+   ArgEffect DefaultEff = ArgEffect(MayEscape),
+   ArgEffect ThisEff = ArgEffect(DoNothing)) {
+RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff, ThisEff);
 return getPersistentSummary(Summ);
   }
 
   const RetainSummary *getDoNothingSummary() {
 return getPersistentSummary(RetEffect::MakeNoRet(),
 ArgEffects(AF.getEmptyMap()),
-DoNothing, DoNothing);
+ArgEffect(DoNothing), ArgEffect(DoNothing));
   }
 
   const RetainSummary *getDefaultSummary() {
 return getPersistentSummary(RetEffect::MakeNoRet(),
 ArgEffects(AF.getEmptyMap()),
-DoNothing, MayEscape);
+ArgEffect(DoNothing), ArgEffect(MayEscape));
   }
 
   const RetainSummary *getPersistentStopSummary() {
-return 

r350857 - [analyzer] [NFC] Move ObjKind into a separate top-level enum in RetainSummaryManager.

2019-01-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Jan 10 10:13:46 2019
New Revision: 350857

URL: http://llvm.org/viewvc/llvm-project?rev=350857=rev
Log:
[analyzer] [NFC] Move ObjKind into a separate top-level enum in 
RetainSummaryManager.

Allows using it in future outside of RetEffect.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/ARCMigrate/ObjCMT.cpp

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350857=350856=350857=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Jan 
10 10:13:46 2019
@@ -36,6 +36,22 @@ using namespace ento;
 namespace clang {
 namespace ento {
 
+/// Determines the object kind of a tracked object.
+enum class ObjKind {
+  /// Indicates that the tracked object is a CF object.  This is
+  /// important between GC and non-GC code.
+  CF,
+  /// Indicates that the tracked object is an Objective-C object.
+  ObjC,
+  /// Indicates that the tracked object could be a CF or Objective-C object.
+  AnyObj,
+  /// Indicates that the tracked object is a generalized object.
+  Generalized,
+
+  /// A descendant of OSObject.
+  OS
+};
+
 /// An ArgEffect summarizes the retain count behavior on an argument or 
receiver
 /// to a function or method.
 enum ArgEffect {
@@ -144,27 +160,12 @@ public:
 NoRetHard
   };
 
-  /// Determines the object kind of a tracked object.
-  enum ObjKind {
-/// Indicates that the tracked object is a CF object.  This is
-/// important between GC and non-GC code.
-CF,
-/// Indicates that the tracked object is an Objective-C object.
-ObjC,
-/// Indicates that the tracked object could be a CF or Objective-C object.
-AnyObj,
-/// Indicates that the tracked object is a generalized object.
-Generalized,
-
-/// A descendant of OSObject.
-OS
-  };
 
 private:
   Kind K;
   ObjKind O;
 
-  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
+  RetEffect(Kind k, ObjKind o = ObjKind::AnyObj) : K(k), O(o) {}
 
 public:
   Kind getKind() const { return K; }
@@ -184,7 +185,7 @@ public:
   }
 
   static RetEffect MakeOwnedWhenTrackedReceiver() {
-return RetEffect(OwnedWhenTrackedReceiver, ObjC);
+return RetEffect(OwnedWhenTrackedReceiver, ObjKind::ObjC);
   }
 
   static RetEffect MakeOwned(ObjKind o) {
@@ -194,7 +195,7 @@ public:
 return RetEffect(NotOwnedSymbol, o);
   }
   static RetEffect MakeGCNotOwned() {
-return RetEffect(GCNotOwnedSymbol, ObjC);
+return RetEffect(GCNotOwnedSymbol, ObjKind::ObjC);
   }
   static RetEffect MakeNoRet() {
 return RetEffect(NoRet);
@@ -659,9 +660,9 @@ public:
  TrackObjCAndCFObjects(trackObjCAndCFObjects),
  TrackOSObjects(trackOSObjects),
  AF(BPAlloc),
- ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
-   : RetEffect::MakeOwned(RetEffect::ObjC)),
- ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
+ ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
+   : RetEffect::MakeOwned(ObjKind::ObjC)),
+ ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(ObjKind::ObjC)
: RetEffect::MakeOwnedWhenTrackedReceiver()) {
 InitializeClassMethodSummaries();
 InitializeMethodSummaries();

Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=350857=350856=350857=diff
==
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Thu Jan 10 10:13:46 2019
@@ -1460,14 +1460,14 @@ void ObjCMigrateASTConsumer::AddCFAnnota
   if (!ResultAnnotated) {
 RetEffect Ret = CE.getReturnValue();
 const char *AnnotationString = nullptr;
-if (Ret.getObjKind() == RetEffect::CF) {
+if (Ret.getObjKind() == ObjKind::CF) {
   if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
 AnnotationString = " CF_RETURNS_RETAINED";
   else if (Ret.notOwned() &&
NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
 AnnotationString = " CF_RETURNS_NOT_RETAINED";
 }
-else if (Ret.getObjKind() == RetEffect::ObjC) {
+else if (Ret.getObjKind() == ObjKind::ObjC) {
   

r350057 - [analyzer] [NFC] Clean up the mess of constructing argument effects in RetainCountChecker

2018-12-24 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Mon Dec 24 10:45:18 2018
New Revision: 350057

URL: http://llvm.org/viewvc/llvm-project?rev=350057=rev
Log:
[analyzer] [NFC] Clean up the mess of constructing argument effects in 
RetainCountChecker

Previously, argument effects were stored in a method variable, which was
effectively global.
The global state was reset at each (hopefully) entrance point to the
summary construction,
and every function could modify it.

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

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=350057=350056=350057=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Mon Dec 
24 10:45:18 2018
@@ -508,9 +508,6 @@ class RetainSummaryManager {
   /// AF - A factory for ArgEffects objects.
   ArgEffects::Factory AF;
 
-  /// ScratchArgs - A holding buffer for construct ArgEffects.
-  ArgEffects ScratchArgs;
-
   /// ObjCAllocRetE - Default return effect for methods returning Objective-C
   ///  objects.
   RetEffect ObjCAllocRetE;
@@ -523,10 +520,6 @@ class RetainSummaryManager {
   /// effects.
   llvm::FoldingSet SimpleSummaries;
 
-  /// getArgEffects - Returns a persistent ArgEffects object based on the
-  ///  data in ScratchArgs.
-  ArgEffects getArgEffects();
-
   /// Create an OS object at +1.
   const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD);
 
@@ -554,25 +547,30 @@ class RetainSummaryManager {
   const RetainSummary *getPersistentSummary(const RetainSummary );
 
   const RetainSummary *getPersistentSummary(RetEffect RetEff,
+ArgEffects ScratchArgs,
 ArgEffect ReceiverEff = DoNothing,
 ArgEffect DefaultEff = MayEscape,
 ArgEffect ThisEff = DoNothing) {
-RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff,
+RetainSummary Summ(ScratchArgs, RetEff, DefaultEff, ReceiverEff,
ThisEff);
 return getPersistentSummary(Summ);
   }
 
   const RetainSummary *getDoNothingSummary() {
-return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+return getPersistentSummary(RetEffect::MakeNoRet(),
+ArgEffects(AF.getEmptyMap()),
+DoNothing, DoNothing);
   }
 
   const RetainSummary *getDefaultSummary() {
 return getPersistentSummary(RetEffect::MakeNoRet(),
+ArgEffects(AF.getEmptyMap()),
 DoNothing, MayEscape);
   }
 
   const RetainSummary *getPersistentStopSummary() {
 return getPersistentSummary(RetEffect::MakeNoRet(),
+ArgEffects(AF.getEmptyMap()),
 StopTracking, StopTracking);
   }
 
@@ -649,7 +647,6 @@ class RetainSummaryManager {
   bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
 unsigned parm_idx,
 const FunctionDecl *FD,
-ArgEffects::Factory ,
 RetainSummaryTemplate );
 
 public:
@@ -661,7 +658,7 @@ public:
  ARCEnabled(usesARC),
  TrackObjCAndCFObjects(trackObjCAndCFObjects),
  TrackOSObjects(trackOSObjects),
- AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),
+ AF(BPAlloc),
  ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
: RetEffect::MakeOwned(RetEffect::ObjC)),
  ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=350057=350056=350057=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Mon Dec 24 
10:45:18 2018
@@ -49,12 +49,6 @@ template  bool RetainSummaryMan
   llvm_unreachable("Unexpected attribute passed");
 }
 
-ArgEffects RetainSummaryManager::getArgEffects() {
-  ArgEffects AE = ScratchArgs;
-  ScratchArgs = AF.getEmptyMap();
-  return AE;
-}
-
 const RetainSummary *
 RetainSummaryManager::getPersistentSummary(const RetainSummary ) {
   // Unique "simple" summaries -- those without ArgEffects.
@@ -190,11 +184,9 @@ const 

r349943 - [analyzer] Tests quickfix.

2018-12-21 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Dec 21 11:40:44 2018
New Revision: 349943

URL: http://llvm.org/viewvc/llvm-project?rev=349943=rev
Log:
[analyzer] Tests quickfix.

Modified:
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=349943=349942=349943=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Fri Dec 21 11:40:44 2018
@@ -143,7 +143,7 @@ void test_escaping_into_voidstar() {
 void test_escape_has_source() {
   OSObject *obj = new OSObject;
   if (obj)
-escape_with_source((MYTYPE)obj);
+escape_with_source(obj);
   return;
 }
 


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


r349938 - [analyzer] Correct the summary violation diagnostics for the retain count checker

2018-12-21 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Dec 21 11:13:28 2018
New Revision: 349938

URL: http://llvm.org/viewvc/llvm-project?rev=349938=rev
Log:
[analyzer] Correct the summary violation diagnostics for the retain count 
checker

It should be in the past tense.

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=349938=349937=349938=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Fri Dec 21 11:13:28 2018
@@ -285,7 +285,7 @@ annotateConsumedSummaryMismatch(const Ex
 os << "Parameter '";
 PVD->getNameForDiagnostic(os, PVD->getASTContext().getPrintingPolicy(),
   /*Qualified=*/false);
-os << "' is marked as consuming, but the function does not consume "
+os << "' is marked as consuming, but the function did not consume "
<< "the reference\n";
   }
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=349938=349937=349938=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Fri Dec 21 11:13:28 2018
@@ -99,7 +99,7 @@ bool os_consume_violation_two_args(OS_CO
 escape(obj);
 return true;
   }
-  return false; // expected-note{{Parameter 'obj' is marked as consuming, but 
the function does not consume the reference}}
+  return false; // expected-note{{Parameter 'obj' is marked as consuming, but 
the function did not consume the reference}}
 }
 
 bool os_consume_violation(OS_CONSUME OSObject *obj) {
@@ -108,7 +108,7 @@ bool os_consume_violation(OS_CONSUME OSO
 escape(obj);
 return true;
   }
-  return false; // expected-note{{Parameter 'obj' is marked as consuming, but 
the function does not consume the reference}}
+  return false; // expected-note{{Parameter 'obj' is marked as consuming, but 
the function did not consume the reference}}
 }
 
 void os_consume_ok(OS_CONSUME OSObject *obj) {


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


r349939 - Revert "Revert rL349876 from cfe/trunk: [analyzer] Perform escaping in RetainCountChecker on type mismatch even for inlined functions"

2018-12-21 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Dec 21 11:13:40 2018
New Revision: 349939

URL: http://llvm.org/viewvc/llvm-project?rev=349939=rev
Log:
Revert "Revert rL349876 from cfe/trunk: [analyzer] Perform escaping in 
RetainCountChecker on type mismatch even for inlined functions"

This reverts commit b44b33f6e020a2c369da2b0c1d53cd52975f2526.

Revert the revert with the fix.

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=349939=349938=349939=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Fri Dec 21 11:13:40 2018
@@ -502,6 +502,25 @@ static Optional refValFromRetEff
   return None;
 }
 
+static bool isPointerToObject(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull())
+if (PT->getAsCXXRecordDecl())
+  return true;
+  return false;
+}
+
+/// Whether the tracked value should be escaped on a given call.
+/// OSObjects are escaped when passed to void * / etc.
+static bool shouldEscapeArgumentOnCall(const CallEvent , unsigned ArgIdx,
+   const RefVal *TrackedValue) {
+  if (TrackedValue->getObjKind() != RetEffect::OS)
+return false;
+  if (ArgIdx >= CE.parameters().size())
+return false;
+  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
+}
+
 // We don't always get the exact modeling of the function with regards to the
 // retain count checker even when the function is inlined. For example, we need
 // to stop tracking the symbols which were marked with StopTrackingHard.
@@ -512,11 +531,16 @@ void RetainCountChecker::processSummaryO
 
   // Evaluate the effect of the arguments.
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
-if (Summ.getArg(idx) == StopTrackingHard) {
-  SVal V = CallOrMsg.getArgSVal(idx);
-  if (SymbolRef Sym = V.getAsLocSymbol()) {
+SVal V = CallOrMsg.getArgSVal(idx);
+
+if (SymbolRef Sym = V.getAsLocSymbol()) {
+  bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
+  if (const RefVal *T = getRefBinding(state, Sym))
+if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
+  ShouldRemoveBinding = true;
+
+  if (ShouldRemoveBinding)
 state = removeRefBinding(state, Sym);
-  }
 }
   }
 
@@ -574,25 +598,6 @@ static ProgramStateRef updateOutParamete
   return State;
 }
 
-static bool isPointerToObject(QualType QT) {
-  QualType PT = QT->getPointeeType();
-  if (!PT.isNull())
-if (PT->getAsCXXRecordDecl())
-  return true;
-  return false;
-}
-
-/// Whether the tracked value should be escaped on a given call.
-/// OSObjects are escaped when passed to void * / etc.
-static bool shouldEscapeArgumentOnCall(const CallEvent , unsigned ArgIdx,
-   const RefVal *TrackedValue) {
-  if (TrackedValue->getObjKind() != RetEffect::OS)
-return false;
-  if (ArgIdx >= CE.parameters().size())
-return false;
-  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
-}
-
 void RetainCountChecker::checkSummary(const RetainSummary ,
   const CallEvent ,
   CheckerContext ) const {

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=349939=349938=349939=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Fri Dec 21 11:13:40 2018
@@ -91,6 +91,7 @@ struct OSMetaClassBase {
 };
 
 void escape(void *);
+void escape_with_source(void *p) {}
 bool coin();
 
 bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
@@ -139,6 +140,13 @@ void test_escaping_into_voidstar() {
   escape(obj);
 }
 
+void test_escape_has_source() {
+  OSObject *obj = new OSObject;
+  if (obj)
+escape_with_source((MYTYPE)obj);
+  return;
+}
+
 void test_no_infinite_check_recursion(MyArray *arr) {
   OSObject *input = new OSObject;
   OSObject *o = arr->generateObject(input);


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


r349876 - [analyzer] Perform escaping in RetainCountChecker on type mismatch even for inlined functions

2018-12-20 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Dec 20 18:16:36 2018
New Revision: 349876

URL: http://llvm.org/viewvc/llvm-project?rev=349876=rev
Log:
[analyzer] Perform escaping in RetainCountChecker on type mismatch even for 
inlined functions

The fix done in D55465 did not previously apply when the function was inlined.

rdar://46889541

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=349876=349875=349876=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Dec 20 18:16:36 2018
@@ -502,6 +502,25 @@ static Optional refValFromRetEff
   return None;
 }
 
+static bool isPointerToObject(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull())
+if (PT->getAsCXXRecordDecl())
+  return true;
+  return false;
+}
+
+/// Whether the tracked value should be escaped on a given call.
+/// OSObjects are escaped when passed to void * / etc.
+static bool shouldEscapeArgumentOnCall(const CallEvent , unsigned ArgIdx,
+   const RefVal *TrackedValue) {
+  if (TrackedValue->getObjKind() != RetEffect::OS)
+return false;
+  if (ArgIdx >= CE.parameters().size())
+return false;
+  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
+}
+
 // We don't always get the exact modeling of the function with regards to the
 // retain count checker even when the function is inlined. For example, we need
 // to stop tracking the symbols which were marked with StopTrackingHard.
@@ -512,11 +531,16 @@ void RetainCountChecker::processSummaryO
 
   // Evaluate the effect of the arguments.
   for (unsigned idx = 0, e = CallOrMsg.getNumArgs(); idx != e; ++idx) {
-if (Summ.getArg(idx) == StopTrackingHard) {
-  SVal V = CallOrMsg.getArgSVal(idx);
-  if (SymbolRef Sym = V.getAsLocSymbol()) {
+SVal V = CallOrMsg.getArgSVal(idx);
+
+if (SymbolRef Sym = V.getAsLocSymbol()) {
+  bool ShouldRemoveBinding = Summ.getArg(idx) == StopTrackingHard;
+  if (const RefVal *T = getRefBinding(state, Sym))
+if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
+  ShouldRemoveBinding = true;
+
+  if (ShouldRemoveBinding)
 state = removeRefBinding(state, Sym);
-  }
 }
   }
 
@@ -574,25 +598,6 @@ static ProgramStateRef updateOutParamete
   return State;
 }
 
-static bool isPointerToObject(QualType QT) {
-  QualType PT = QT->getPointeeType();
-  if (!PT.isNull())
-if (PT->getAsCXXRecordDecl())
-  return true;
-  return false;
-}
-
-/// Whether the tracked value should be escaped on a given call.
-/// OSObjects are escaped when passed to void * / etc.
-static bool shouldEscapeArgumentOnCall(const CallEvent , unsigned ArgIdx,
-   const RefVal *TrackedValue) {
-  if (TrackedValue->getObjKind() != RetEffect::OS)
-return false;
-  if (ArgIdx >= CE.parameters().size())
-return false;
-  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
-}
-
 void RetainCountChecker::checkSummary(const RetainSummary ,
   const CallEvent ,
   CheckerContext ) const {

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=349876=349875=349876=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Dec 20 18:16:36 2018
@@ -90,7 +90,10 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+typedef unsigned long MYTYPE;
+
 void escape(void *);
+void escape_with_source(MYTYPE p) {}
 bool coin();
 
 bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
@@ -139,6 +142,13 @@ void test_escaping_into_voidstar() {
   escape(obj);
 }
 
+void test_escape_has_source() {
+  OSObject *obj = new OSObject;
+  if (obj)
+escape_with_source((MYTYPE)obj);
+  return;
+}
+
 void test_no_infinite_check_recursion(MyArray *arr) {
   OSObject *input = new OSObject;
   OSObject *o = arr->generateObject(input);


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


r349875 - [analyzer] Fix a bug in RetainCountDiagnostics while printing a note on mismatched summary in inlined functions

2018-12-20 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Dec 20 18:16:23 2018
New Revision: 349875

URL: http://llvm.org/viewvc/llvm-project?rev=349875=rev
Log:
[analyzer] Fix a bug in RetainCountDiagnostics while printing a note on 
mismatched summary in inlined functions

Previously, we were not printing a note at all if at least one of the 
parameters was not annotated.

rdar://46888422

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=349875=349874=349875=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Dec 20 18:16:23 2018
@@ -268,7 +268,7 @@ annotateConsumedSummaryMismatch(const Ex
 const ParmVarDecl *PVD = Parameters[I];
 
 if (!PVD->hasAttr())
-  return nullptr;
+  continue;
 
 if (SymbolRef SR = Call->getArgSVal(I).getAsLocSymbol()) {
   const RefVal *CountBeforeCall = getRefBinding(CN->getState(), SR);
@@ -311,10 +311,9 @@ CFRefReportVisitor::VisitNode(const Expl
   BugReporterContext , BugReport ) {
   const SourceManager  = BRC.getSourceManager();
   CallEventManager  = BRC.getStateManager().getCallEventManager();
-  if (auto CE = N->getLocationAs()) {
+  if (auto CE = N->getLocationAs())
 if (auto PD = annotateConsumedSummaryMismatch(N, *CE, SM, CEMgr))
   return PD;
-  }
 
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=349875=349874=349875=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Dec 20 18:16:23 2018
@@ -93,6 +93,15 @@ struct OSMetaClassBase {
 void escape(void *);
 bool coin();
 
+bool os_consume_violation_two_args(OS_CONSUME OSObject *obj, bool extra) {
+  if (coin()) { // expected-note{{Assuming the condition is false}}
+// expected-note@-1{{Taking false branch}}
+escape(obj);
+return true;
+  }
+  return false; // expected-note{{Parameter 'obj' is marked as consuming, but 
the function does not consume the reference}}
+}
+
 bool os_consume_violation(OS_CONSUME OSObject *obj) {
   if (coin()) { // expected-note{{Assuming the condition is false}}
 // expected-note@-1{{Taking false branch}}
@@ -113,6 +122,13 @@ void use_os_consume_violation() {
 } // expected-note{{Object leaked: object allocated and stored into 'obj' is 
not referenced later in this execution path and has a retain count of +1}}
   // expected-warning@-1{{Potential leak of an object stored into 'obj'}}
 
+void use_os_consume_violation_two_args() {
+  OSObject *obj = new OSObject; // expected-note{{Operator 'new' returns an 
OSObject of type OSObject with a +1 retain count}}
+  os_consume_violation_two_args(obj, coin()); // expected-note{{Calling 
'os_consume_violation_two_args'}}
+ // expected-note@-1{{Returning from 
'os_consume_violation_two_args'}}
+} // expected-note{{Object leaked: object allocated and stored into 'obj' is 
not referenced later in this execution path and has a retain count of +1}}
+  // expected-warning@-1{{Potential leak of an object stored into 'obj'}}
+
 void use_os_consume_ok() {
   OSObject *obj = new OSObject;
   os_consume_ok(obj);


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


r349863 - Revert "Revert "[driver] [analyzer] Fix a backward compatibility issue after r348038.""

2018-12-20 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Dec 20 16:26:19 2018
New Revision: 349863

URL: http://llvm.org/viewvc/llvm-project?rev=349863=rev
Log:
Revert "Revert "[driver] [analyzer] Fix a backward compatibility issue after 
r348038.""

This reverts commit 144927939587b790c0536f4ff08245043fc8d733.

Fixes the bug in the original commit.

Added:
cfe/trunk/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
Modified:
cfe/trunk/lib/Driver/ToolChains/Clang.cpp
cfe/trunk/test/Analysis/invalid-analyzer-config-value.c

Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Clang.cpp?rev=349863=349862=349863=diff
==
--- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Thu Dec 20 16:26:19 2018
@@ -2360,9 +2360,6 @@ static void RenderAnalyzerOptions(const
   // Treat blocks as analysis entry points.
   CmdArgs.push_back("-analyzer-opt-analyze-nested-blocks");
 
-  // Enable compatilibily mode to avoid analyzer-config related errors.
-  CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
-
   // Add default argument set.
   if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
 CmdArgs.push_back("-analyzer-checker=core");
@@ -3738,6 +3735,13 @@ void Clang::ConstructJob(Compilation ,
   if (isa(JA))
 RenderAnalyzerOptions(Args, CmdArgs, Triple, Input);
 
+  // Enable compatilibily mode to avoid analyzer-config related errors.
+  // Since we can't access frontend flags through hasArg, let's manually 
iterate
+  // through them.
+  for (auto Arg : Args.filtered(options::OPT_Xclang))
+if (StringRef(Arg->getValue()) == "-analyzer-config")
+  CmdArgs.push_back("-analyzer-config-compatibility-mode=true");
+
   CheckCodeGenerationOptions(D, Args);
 
   unsigned FunctionAlignment = ParseFunctionAlignment(TC, Args);

Added: cfe/trunk/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c?rev=349863=auto
==
--- cfe/trunk/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c (added)
+++ cfe/trunk/test/Analysis/invalid-a-na-ly-zer-con-fig-value.c Thu Dec 20 
16:26:19 2018
@@ -0,0 +1,80 @@
+// Same as invalid-analyzer-config-value.c but without -analyzer-config
+// in the file name, so that argument string pattern matching
+// didn't accidentally match it.
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config notes-as-events=yesplease \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-BOOL-INPUT
+
+// CHECK-BOOL-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-BOOL-INPUT-SAME:'notes-as-events', that expects a boolean 
value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config notes-as-events=yesplease
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config max-inlinable-size=400km/h \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UINT-INPUT
+
+// CHECK-UINT-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-UINT-INPUT-SAME:'max-inlinable-size', that expects an unsigned
+// CHECK-UINT-INPUT-SAME:value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config max-inlinable-size=400km/h
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config ctu-dir=0123012301230123 \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-FILENAME-INPUT
+
+// CHECK-FILENAME-INPUT: (frontend): invalid input for analyzer-config option
+// CHECK-FILENAME-INPUT-SAME:'ctu-dir', that expects a filename
+// CHECK-FILENAME-INPUT-SAME:value
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config ctu-dir=0123012301230123
+
+
+// RUN: not %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config no-false-positives=true \
+// RUN:   2>&1 | FileCheck %s -check-prefix=CHECK-UNKNOWN-CFG
+
+// CHECK-UNKNOWN-CFG: (frontend): unknown analyzer-config 'no-false-positives'
+
+// RUN: %clang_analyze_cc1 -verify %s \
+// RUN:   -analyzer-checker=core \
+// RUN:   -analyzer-config-compatibility-mode=true \
+// RUN:   -analyzer-config no-false-positives=true
+
+
+// Test the driver properly using "analyzer-config-compatibility-mode=true",
+// no longer causing an error on input error.
+// RUN: %clang --analyze %s
+
+// RUN: not %clang --analyze %s \
+// RUN:   -Xclang 

r348821 - [analyzer] Hack for backwards compatibility for options for RetainCountChecker.

2018-12-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Mon Dec 10 17:13:58 2018
New Revision: 348821

URL: http://llvm.org/viewvc/llvm-project?rev=348821=rev
Log:
[analyzer] Hack for backwards compatibility for options for RetainCountChecker.

To be removed once the clients update.

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/test-separate-retaincount.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=348821=348820=348821=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Mon Dec 10 17:13:58 2018
@@ -1530,7 +1530,19 @@ void ento::registerRetainCountChecker(Ch
   Chk->TrackObjCAndCFObjects = true;
 }
 
+// FIXME: remove this, hack for backwards compatibility:
+// it should be possible to enable the NS/CF retain count checker as
+// osx.cocoa.RetainCount, and it should be possible to disable
+// osx.OSObjectRetainCount using osx.cocoa.RetainCount:CheckOSObject=false.
+static bool hasPrevCheckOSObjectOptionDisabled(AnalyzerOptions ) {
+  auto I = Options.Config.find("osx.cocoa.RetainCount:CheckOSObject");
+  if (I != Options.Config.end())
+return I->getValue() == "false";
+  return false;
+}
+
 void ento::registerOSObjectRetainCountChecker(CheckerManager ) {
   auto *Chk = Mgr.registerChecker();
-  Chk->TrackOSObjects = true;
+  if (!hasPrevCheckOSObjectOptionDisabled(Mgr.getAnalyzerOptions()))
+Chk->TrackOSObjects = true;
 }

Modified: cfe/trunk/test/Analysis/test-separate-retaincount.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/test-separate-retaincount.cpp?rev=348821=348820=348821=diff
==
--- cfe/trunk/test/Analysis/test-separate-retaincount.cpp (original)
+++ cfe/trunk/test/Analysis/test-separate-retaincount.cpp Mon Dec 10 17:13:58 
2018
@@ -1,5 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx 
-analyzer-disable-checker osx.cocoa.RetainCount -DNO_CF_OBJECT -verify %s
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx 
-analyzer-disable-checker osx.OSObjectRetainCount -DNO_OS_OBJECT -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config 
"osx.cocoa.RetainCount:CheckOSObject=false" -DNO_OS_OBJECT -verify %s
 
 typedef const void * CFTypeRef;
 extern CFTypeRef CFRetain(CFTypeRef cf);


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


r348822 - [analyzer] Remove memoization from RunLoopAutoreleaseLeakChecker

2018-12-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Mon Dec 10 17:14:17 2018
New Revision: 348822

URL: http://llvm.org/viewvc/llvm-project?rev=348822=rev
Log:
[analyzer] Remove memoization from RunLoopAutoreleaseLeakChecker

Memoization dose not seem to be necessary, as other statement visitors
run just fine without it,
and in fact seems to be causing memory corruptions.
Just removing it instead of investigating the root cause.

rdar://45945002

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

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

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp?rev=348822=348821=348822=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp Mon 
Dec 10 17:14:17 2018
@@ -58,13 +58,12 @@ public:
 
 } // end anonymous namespace
 
-
-using TriBoolTy = Optional;
-using MemoizationMapTy = llvm::DenseMap>;
-
-static TriBoolTy
-seenBeforeRec(const Stmt *Parent, const Stmt *A, const Stmt *B,
-  MemoizationMapTy ) {
+/// \return Whether {@code A} occurs before {@code B} in traversal of
+/// {@code Parent}.
+/// Conceptually a very incomplete/unsound approximation of happens-before
+/// relationship (A is likely to be evaluated before B),
+/// but useful enough in this case.
+static bool seenBefore(const Stmt *Parent, const Stmt *A, const Stmt *B) {
   for (const Stmt *C : Parent->children()) {
 if (!C) continue;
 
@@ -74,26 +73,9 @@ seenBeforeRec(const Stmt *Parent, const
 if (C == B)
   return false;
 
-Optional  = Memoization[C];
-if (!Cached)
-  Cached = seenBeforeRec(C, A, B, Memoization);
-
-if (Cached->hasValue())
-  return Cached->getValue();
+return seenBefore(C, A, B);
   }
-
-  return None;
-}
-
-/// \return Whether {@code A} occurs before {@code B} in traversal of
-/// {@code Parent}.
-/// Conceptually a very incomplete/unsound approximation of happens-before
-/// relationship (A is likely to be evaluated before B),
-/// but useful enough in this case.
-static bool seenBefore(const Stmt *Parent, const Stmt *A, const Stmt *B) {
-  MemoizationMapTy Memoization;
-  TriBoolTy Val = seenBeforeRec(Parent, A, B, Memoization);
-  return Val.getValue();
+  return false;
 }
 
 static void emitDiagnostics(BoundNodes ,


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


r348820 - [analyzer] Display a diagnostics when an inlined function violates its os_consumed summary

2018-12-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Mon Dec 10 17:13:40 2018
New Revision: 348820

URL: http://llvm.org/viewvc/llvm-project?rev=348820=rev
Log:
[analyzer] Display a diagnostics when an inlined function violates its 
os_consumed summary

This is currently a diagnostics, but might be upgraded to an error in the 
future,
especially if we introduce os_return_on_success attributes.

rdar://46359592

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=348820=348819=348820=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Mon Dec 10 17:13:40 2018
@@ -113,13 +113,11 @@ static bool shouldGenerateNote(llvm::raw
   return true;
 }
 
-static void generateDiagnosticsForCallLike(
-  ProgramStateRef CurrSt,
-  const LocationContext *LCtx,
-  const RefVal ,
-  SymbolRef ,
-  const Stmt *S,
-  llvm::raw_string_ostream ) {
+static void generateDiagnosticsForCallLike(ProgramStateRef CurrSt,
+   const LocationContext *LCtx,
+   const RefVal , SymbolRef ,
+   const Stmt *S,
+   llvm::raw_string_ostream ) {
   if (const CallExpr *CE = dyn_cast(S)) {
 // Get the name of the callee (if it is available)
 // from the tracked SVal.
@@ -137,8 +135,8 @@ static void generateDiagnosticsForCallLi
 } else {
   os << "function call";
 }
-  } else if (isa(S)){
-os << "Operator new";
+  } else if (isa(S)) {
+os << "Operator 'new'";
   } else {
 assert(isa(S));
 CallEventManager  = CurrSt->getStateManager().getCallEventManager();
@@ -230,9 +228,94 @@ public:
 } // end namespace ento
 } // end namespace clang
 
+
+/// Find the first node with the parent stack frame.
+static const ExplodedNode *getCalleeNode(const ExplodedNode *Pred) {
+  const StackFrameContext *SC = Pred->getStackFrame();
+  if (SC->inTopFrame())
+return nullptr;
+  const StackFrameContext *PC = SC->getParent()->getStackFrame();
+  if (!PC)
+return nullptr;
+
+  const ExplodedNode *N = Pred;
+  while (N && N->getStackFrame() != PC) {
+N = N->getFirstPred();
+  }
+  return N;
+}
+
+
+/// Insert a diagnostic piece at function exit
+/// if a function parameter is annotated as "os_consumed",
+/// but it does not actually consume the reference.
+static std::shared_ptr
+annotateConsumedSummaryMismatch(const ExplodedNode *N,
+CallExitBegin ,
+const SourceManager ,
+CallEventManager ) {
+
+  const ExplodedNode *CN = getCalleeNode(N);
+  if (!CN)
+return nullptr;
+
+  CallEventRef<> Call = CEMgr.getCaller(N->getStackFrame(), N->getState());
+
+  std::string sbuf;
+  llvm::raw_string_ostream os(sbuf);
+  ArrayRef Parameters = Call->parameters();
+  for (unsigned I=0; I < Call->getNumArgs() && I < Parameters.size(); ++I) {
+const ParmVarDecl *PVD = Parameters[I];
+
+if (!PVD->hasAttr())
+  return nullptr;
+
+if (SymbolRef SR = Call->getArgSVal(I).getAsLocSymbol()) {
+  const RefVal *CountBeforeCall = getRefBinding(CN->getState(), SR);
+  const RefVal *CountAtExit = getRefBinding(N->getState(), SR);
+
+  if (!CountBeforeCall || !CountAtExit)
+continue;
+
+  unsigned CountBefore = CountBeforeCall->getCount();
+  unsigned CountAfter = CountAtExit->getCount();
+
+  bool AsExpected = CountBefore > 0 && CountAfter == CountBefore - 1;
+  if (!AsExpected) {
+os << "Parameter '";
+PVD->getNameForDiagnostic(os, PVD->getASTContext().getPrintingPolicy(),
+  /*Qualified=*/false);
+os << "' is marked as consuming, but the function does not consume "
+   << "the reference\n";
+  }
+}
+  }
+
+  if (os.str().empty())
+return nullptr;
+
+  // FIXME: remove the code duplication with NoStoreFuncVisitor.
+  PathDiagnosticLocation L;
+  if (const ReturnStmt *RS = CallExitLoc.getReturnStmt()) {
+L = PathDiagnosticLocation::createBegin(RS, SM, N->getLocationContext());
+  } else {
+L = PathDiagnosticLocation(
+Call->getRuntimeDefinition().getDecl()->getSourceRange().getEnd(), SM);
+  }
+
+  return std::make_shared(L, os.str());
+}
+
 std::shared_ptr
 CFRefReportVisitor::VisitNode(const ExplodedNode *N,
   BugReporterContext , BugReport ) {
+  

r348819 - [analyzer] Resolve another bug where the name of the leaked object was not printed properly

2018-12-10 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Mon Dec 10 17:13:20 2018
New Revision: 348819

URL: http://llvm.org/viewvc/llvm-project?rev=348819=rev
Log:
[analyzer] Resolve another bug where the name of the leaked object was not 
printed properly

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=348819=348818=348819=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Mon Dec 10 17:13:20 2018
@@ -405,11 +405,11 @@ static AllocationInfo GetAllocationSite(
 
 if (FB) {
   const MemRegion *R = FB.getRegion();
-  const VarRegion *VR = R->getBaseRegion()->getAs();
   // Do not show local variables belonging to a function other than
   // where the error is reported.
-  if (!VR || VR->getStackFrame() == LeakContext->getStackFrame())
-FirstBinding = R;
+  if (auto MR = dyn_cast(R->getMemorySpace()))
+if (MR->getStackFrame() == LeakContext->getStackFrame())
+  FirstBinding = R;
 }
 
 // AllocationNode is the last node in which the symbol was tracked.

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=348819=348818=348819=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Mon Dec 10 17:13:20 2018
@@ -153,8 +153,8 @@ void check_free_use_after_free() {
 
 unsigned int check_leak_explicit_new() {
   OSArray *arr = new OSArray; // expected-note{{Operator new returns an 
OSObject of type OSArray with a +1 retain count}}
-  return arr->getCount(); // expected-note{{Object leaked: allocated object of 
type OSArray is not referenced later in this execution path and has a retain 
count of +1}}
-  // expected-warning@-1{{Potential leak of an object 
of type OSArray}}
+  return arr->getCount(); // expected-note{{Object leaked: object allocated 
and stored into 'arr' is not referenced later in this execution path and has a 
retain count of +1}}
+  // expected-warning@-1{{Potential leak of an object 
stored into 'arr'}}
 }
 
 unsigned int check_leak_factory() {


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


r348675 - Stop tracking retain count of OSObject after escape to void * / other primitive types

2018-12-07 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Dec  7 17:18:40 2018
New Revision: 348675

URL: http://llvm.org/viewvc/llvm-project?rev=348675=rev
Log:
Stop tracking retain count of OSObject after escape to void * / other primitive 
types

Escaping to void * / uint64_t / others non-OSObject * should stop tracking,
as such functions can have heterogeneous semantics depending on context,
and can not always be annotated.

rdar://46439133

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=348675=348674=348675=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Fri Dec  7 17:18:40 2018
@@ -574,6 +574,25 @@ static ProgramStateRef updateOutParamete
   return State;
 }
 
+static bool isPointerToObject(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull())
+if (PT->getAsCXXRecordDecl())
+  return true;
+  return false;
+}
+
+/// Whether the tracked value should be escaped on a given call.
+/// OSObjects are escaped when passed to void * / etc.
+static bool shouldEscapeArgumentOnCall(const CallEvent , unsigned ArgIdx,
+   const RefVal *TrackedValue) {
+  if (TrackedValue->getObjKind() != RetEffect::OS)
+return false;
+  if (ArgIdx >= CE.parameters().size())
+return false;
+  return !isPointerToObject(CE.parameters()[ArgIdx]->getType());
+}
+
 void RetainCountChecker::checkSummary(const RetainSummary ,
   const CallEvent ,
   CheckerContext ) const {
@@ -592,6 +611,10 @@ void RetainCountChecker::checkSummary(co
   state = updateOutParameter(state, V, Effect);
 } else if (SymbolRef Sym = V.getAsLocSymbol()) {
   if (const RefVal *T = getRefBinding(state, Sym)) {
+
+if (shouldEscapeArgumentOnCall(CallOrMsg, idx, T))
+  Effect = StopTrackingHard;
+
 state = updateSymbol(state, Sym, *T, Effect, hasErr, C);
 if (hasErr) {
   ErrorRange = CallOrMsg.getArgSourceRange(idx);

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=348675=348674=348675=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Fri Dec  7 17:18:40 2018
@@ -89,6 +89,13 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+void escape(void *);
+
+void test_escaping_into_voidstar() {
+  OSObject *obj = new OSObject;
+  escape(obj);
+}
+
 void test_no_infinite_check_recursion(MyArray *arr) {
   OSObject *input = new OSObject;
   OSObject *o = arr->generateObject(input);


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


r348638 - [analyzer] Move out tracking retain count for OSObjects into a separate checker

2018-12-07 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Dec  7 12:21:51 2018
New Revision: 348638

URL: http://llvm.org/viewvc/llvm-project?rev=348638=rev
Log:
[analyzer] Move out tracking retain count for OSObjects into a separate checker

Allow enabling and disabling tracking of ObjC/CF objects
separately from tracking of OS objects.

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

Added:
cfe/trunk/test/Analysis/test-separate-retaincount.cpp
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

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=348638=348637=348638=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Fri Dec  7 
12:21:51 2018
@@ -520,6 +520,9 @@ def MacOSKeychainAPIChecker : Checker<"S
 def ObjCPropertyChecker : Checker<"ObjCProperty">,
   HelpText<"Check for proper uses of Objective-C properties">;
 
+def OSObjectRetainCountChecker : Checker<"OSObjectRetainCount">,
+  HelpText<"Check for leaks and improper reference count management for 
OSObject">;
+
 } // end "osx"
 
 let ParentPackage = Cocoa in {

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=348638=348637=348638=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Fri Dec  
7 12:21:51 2018
@@ -469,6 +469,8 @@ public:
   }
 };
 
+class RetainSummaryTemplate;
+
 class RetainSummaryManager {
   typedef llvm::DenseMap
   FuncSummariesTy;
@@ -483,7 +485,10 @@ class RetainSummaryManager {
   /// Records whether or not the analyzed code runs in ARC mode.
   const bool ARCEnabled;
 
-  /// Track sublcasses of OSObject
+  /// Track Objective-C and CoreFoundation objects.
+  const bool TrackObjCAndCFObjects;
+
+  /// Track sublcasses of OSObject.
   const bool TrackOSObjects;
 
   /// FuncSummaries - A map from FunctionDecls to summaries.
@@ -626,13 +631,36 @@ class RetainSummaryManager {
   const RetainSummary * generateSummary(const FunctionDecl *FD,
 bool );
 
+  /// Return a summary for OSObject, or nullptr if not found.
+  const RetainSummary *getSummaryForOSObject(const FunctionDecl *FD,
+ StringRef FName, QualType RetTy);
+
+  /// Return a summary for Objective-C or CF object, or nullptr if not found.
+  const RetainSummary *getSummaryForObjCOrCFObject(
+const FunctionDecl *FD,
+StringRef FName,
+QualType RetTy,
+const FunctionType *FT,
+bool );
+
+  /// Apply the annotation of {@code pd} in function {@code FD}
+  /// to the resulting summary stored in out-parameter {@code Template}.
+  /// \return whether an annotation was applied.
+  bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
+unsigned parm_idx,
+const FunctionDecl *FD,
+ArgEffects::Factory ,
+RetainSummaryTemplate );
+
 public:
   RetainSummaryManager(ASTContext ,
bool usesARC,
-   bool trackOSObject)
+   bool trackObjCAndCFObjects,
+   bool trackOSObjects)
: Ctx(ctx),
  ARCEnabled(usesARC),
- TrackOSObjects(trackOSObject),
+ TrackObjCAndCFObjects(trackObjCAndCFObjects),
+ TrackOSObjects(trackOSObjects),
  AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),
  ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
: RetEffect::MakeOwned(RetEffect::ObjC)),
@@ -709,6 +737,7 @@ public:
   void updateSummaryFromAnnotations(const RetainSummary *,
 const FunctionDecl *FD);
 
+
   void updateSummaryForCall(const RetainSummary *,
 const CallEvent );
 
@@ -716,9 +745,21 @@ public:
 
   RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
 
+  /// \return True if the declaration has an attribute {@code T},
+  /// AND we are tracking that attribute. False otherwise.
+  template 
+  bool hasEnabledAttr(const Decl 

r348637 - [analyzer] RetainCountChecker: remove untested, unused, incorrect option IncludeAllocationLine

2018-12-07 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Dec  7 12:21:37 2018
New Revision: 348637

URL: http://llvm.org/viewvc/llvm-project?rev=348637=rev
Log:
[analyzer] RetainCountChecker: remove untested, unused, incorrect option 
IncludeAllocationLine

The option has no tests, is not used anywhere, and is actually
incorrect: it prints the line number without the reference to a file,
which can be outright incorrect.

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

Modified:

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=348637=348636=348637=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Fri Dec  7 12:21:37 2018
@@ -1059,8 +1059,7 @@ ExplodedNode * RetainCountChecker::check
 if (N) {
   const LangOptions  = C.getASTContext().getLangOpts();
   auto R = llvm::make_unique(
-  *getLeakAtReturnBug(LOpts), LOpts, SummaryLog, N, Sym, C,
-  IncludeAllocationLine);
+  *getLeakAtReturnBug(LOpts), LOpts, SummaryLog, N, Sym, C);
   C.emitReport(std::move(R));
 }
 return N;
@@ -1346,7 +1345,7 @@ RetainCountChecker::processLeaks(Program
   assert(BT && "BugType not initialized.");
 
   Ctx.emitReport(llvm::make_unique(
-  *BT, LOpts, SummaryLog, N, *I, Ctx, IncludeAllocationLine));
+  *BT, LOpts, SummaryLog, N, *I, Ctx));
 }
   }
 
@@ -1508,8 +1507,6 @@ void ento::registerRetainCountChecker(Ch
 
   AnalyzerOptions  = Mgr.getAnalyzerOptions();
 
-  Chk->IncludeAllocationLine = Options.getCheckerBooleanOption(
-   "leak-diagnostics-reference-allocation", false, 
Chk);
   Chk->ShouldCheckOSObjectRetainCount = Options.getCheckerBooleanOption(
 "CheckOSObject", true, 
Chk);
 }

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=348637=348636=348637=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Fri Dec  7 12:21:37 2018
@@ -634,8 +634,7 @@ void CFRefLeakReport::deriveAllocLocatio
   UniqueingDecl = AllocNode->getLocationContext()->getDecl();
 }
 
-void CFRefLeakReport::createDescription(CheckerContext ,
-bool IncludeAllocationLine) {
+void CFRefLeakReport::createDescription(CheckerContext ) {
   assert(Location.isValid() && UniqueingDecl && UniqueingLocation.isValid());
   Description.clear();
   llvm::raw_string_ostream os(Description);
@@ -644,10 +643,6 @@ void CFRefLeakReport::createDescription(
   Optional RegionDescription = describeRegion(AllocBinding);
   if (RegionDescription) {
 os << " stored into '" << *RegionDescription << '\'';
-if (IncludeAllocationLine) {
-  FullSourceLoc SL(AllocStmt->getBeginLoc(), Ctx.getSourceManager());
-  os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
-}
   } else {
 
 // If we can't figure out the name, just supply the type information.
@@ -658,15 +653,14 @@ void CFRefLeakReport::createDescription(
 CFRefLeakReport::CFRefLeakReport(CFRefBug , const LangOptions ,
  const SummaryLogTy ,
  ExplodedNode *n, SymbolRef sym,
- CheckerContext ,
- bool IncludeAllocationLine)
+ CheckerContext )
   : CFRefReport(D, LOpts, Log, n, sym, false) {
 
   deriveAllocLocation(Ctx, sym);
   if (!AllocBinding)
 deriveParamLocation(Ctx, sym);
 
-  createDescription(Ctx, IncludeAllocationLine);
+  createDescription(Ctx);
 
   addVisitor(llvm::make_unique(sym, Log));
 }

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h?rev=348637=348636=348637=diff
==
--- 

r348533 - [analyzer] Rely on os_consumes_this attribute to signify that the method call consumes a reference for "this"

2018-12-06 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Dec  6 14:07:12 2018
New Revision: 348533

URL: http://llvm.org/viewvc/llvm-project?rev=348533=rev
Log:
[analyzer] Rely on os_consumes_this attribute to signify that the method call 
consumes a reference for "this"

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=348533=348532=348533=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Dec  
6 14:07:12 2018
@@ -369,8 +369,12 @@ public:
   ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.
   ArgEffect getReceiverEffect() const { return Receiver; }
 
+  /// \return the effect on the "this" receiver of the method call.
   ArgEffect getThisEffect() const { return This; }
 
+  /// Set the effect of the method on "this".
+  void setThisEffect(ArgEffect e) { This = e; }
+
   bool isNoop() const {
 return Ret == RetEffect::MakeNoRet() && Receiver == DoNothing
   && DefaultArgEffect == MayEscape && This == DoNothing

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=348533=348532=348533=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Dec  6 
14:07:12 2018
@@ -759,6 +759,9 @@ RetainSummaryManager::updateSummaryFromA
   QualType RetTy = FD->getReturnType();
   if (Optional RetE = getRetEffectFromAnnotations(RetTy, FD))
 Template->setRetEffect(*RetE);
+
+  if (FD->hasAttr())
+Template->setThisEffect(DecRef);
 }
 
 void

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=348533=348532=348533=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Dec  6 14:07:12 2018
@@ -5,6 +5,7 @@ struct OSMetaClass;
 #define OS_CONSUME __attribute__((os_consumed))
 #define OS_RETURNS_RETAINED __attribute__((os_returns_retained))
 #define OS_RETURNS_NOT_RETAINED __attribute__((os_returns_not_retained))
+#define OS_CONSUMES_THIS __attribute__((os_consumes_this))
 
 #define OSTypeID(type)   (type::metaClass)
 
@@ -49,6 +50,11 @@ struct OSArray : public OSObject {
 
   virtual void consumeReference(OS_CONSUME OSArray *other);
 
+  void putIntoArray(OSArray *array) OS_CONSUMES_THIS;
+
+  template 
+  void putIntoT(T *owner) OS_CONSUMES_THIS;
+
   static OSArray *generateArrayHasCode() {
 return new OSArray;
   }
@@ -112,6 +118,16 @@ unsigned int check_attribute_indirect_pr
   return 0;
 }
 
+void check_consumes_this(OSArray *owner) {
+  OSArray *arr = new OSArray;
+  arr->putIntoArray(owner);
+}
+
+void check_consumes_this_with_template(OSArray *owner) {
+  OSArray *arr = new OSArray;
+  arr->putIntoT(owner);
+}
+
 void check_free_no_error() {
   OSArray *arr = OSArray::withCapacity(10);
   arr->retain();


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


r348532 - [attributes] Add an attribute os_consumes_this, with similar semantics to ns_consumes_self

2018-12-06 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Dec  6 14:06:59 2018
New Revision: 348532

URL: http://llvm.org/viewvc/llvm-project?rev=348532=rev
Log:
[attributes] Add an attribute os_consumes_this, with similar semantics to 
ns_consumes_self

The attribute specifies that the call of the C++ method consumes a
reference to "this".

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

Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/Sema/attr-osobject.cpp

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=348532=348531=348532=diff
==
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Dec  6 14:06:59 2018
@@ -90,6 +90,10 @@ def NonBitField : SubsetSubjectisBitField()}],
 "non-bit-field non-static data members">;
 
+def NonStaticCXXMethod : SubsetSubjectisStatic()}],
+   "non-static member functions">;
+
 def NonStaticNonConstCXXMethod
 : SubsetSubjectisStatic() && !S->isConst()}],
@@ -846,6 +850,12 @@ def OSReturnsNotRetained : InheritableAt
   let Documentation = [RetainBehaviorDocs];
 }
 
+def OSConsumesThis : InheritableAttr {
+  let Spellings = [Clang<"os_consumes_this">];
+  let Subjects = SubjectList<[NonStaticCXXMethod]>;
+  let Documentation = [RetainBehaviorDocs];
+}
+
 def Cleanup : InheritableAttr {
   let Spellings = [GCC<"cleanup">];
   let Args = [FunctionArgument<"FunctionDecl">];
@@ -1649,13 +1659,13 @@ def NSReturnsAutoreleased : InheritableA
 def NSConsumesSelf : InheritableAttr {
   let Spellings = [Clang<"ns_consumes_self">];
   let Subjects = SubjectList<[ObjCMethod]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def NSConsumed : InheritableParamAttr {
   let Spellings = [Clang<"ns_consumed">];
   let Subjects = SubjectList<[ParmVar]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def ObjCException : InheritableAttr {

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=348532=348531=348532=diff
==
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Thu Dec  6 14:06:59 2018
@@ -862,6 +862,9 @@ is responsible for freeing it.
 Similiarly, the annotation ``__attribute__((ns_returns_not_retained))``
 specifies that the object is returned at ``+0`` and the ownership remains with
 the callee.
+The annotation ``__attribute__((ns_consumes_self))`` specifies that
+the Objective-C method call consumes the reference to ``self``, e.g. by
+attaching it to a supplied parameter.
 Additionally, parameters can have an annotation
 ``__attribute__((ns_consumed))``, which specifies that passing an owned object
 as that parameter effectively transfers the ownership, and the caller is no
@@ -881,7 +884,11 @@ the same attribute family is present:
 ``__attribute__((os_returns_not_retained))``,
 ``__attribute__((os_returns_retained))`` and ``__attribute__((os_consumed))``,
 with the same respective semantics.
-These attributes are also used by the Clang Static Analyzer.
+Similar to ``__attribute__((ns_consumes_self))``,
+``__attribute__((os_consumes_this))`` specifies that the method call consumes
+the reference to "this" (e.g., when attaching it to a different object supplied
+as a parameter).
+These attributes are only used by the Clang Static Analyzer.
 
 The family of attributes ``X_returns_X_retained`` can be added to functions,
 C++ methods, and Objective-C methods and properties.

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=348532=348531=348532=diff
==
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Dec  6 14:06:59 2018
@@ -6408,6 +6408,9 @@ static void ProcessDeclAttribute(Sema 
   case ParsedAttr::AT_NSConsumesSelf:
 handleSimpleAttribute(S, D, AL);
 break;
+  case ParsedAttr::AT_OSConsumesThis:
+handleSimpleAttribute(S, D, AL);
+break;
   case ParsedAttr::AT_NSReturnsAutoreleased:
   case ParsedAttr::AT_NSReturnsNotRetained:
   case ParsedAttr::AT_NSReturnsRetained:

Modified: cfe/trunk/test/Sema/attr-osobject.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-osobject.cpp?rev=348532=348531=348532=diff
==
--- cfe/trunk/test/Sema/attr-osobject.cpp (original)
+++ cfe/trunk/test/Sema/attr-osobject.cpp Thu Dec  6 14:06:59 

r348531 - [analyzer] Fix an infinite recursion bug while checking parent methods in RetainCountChecker

2018-12-06 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Dec  6 14:06:44 2018
New Revision: 348531

URL: http://llvm.org/viewvc/llvm-project?rev=348531=rev
Log:
[analyzer] Fix an infinite recursion bug while checking parent methods in 
RetainCountChecker

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=348531=348530=348531=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Dec  6 
14:06:44 2018
@@ -730,7 +730,7 @@ bool applyFunctionParamAnnotationEffect(
 if (const auto *MD = dyn_cast(FD)) {
   for (const auto *OD : MD->overridden_methods()) {
 const ParmVarDecl *OP = OD->parameters()[parm_idx];
-if (applyFunctionParamAnnotationEffect(OP, parm_idx, MD, AF, Template))
+if (applyFunctionParamAnnotationEffect(OP, parm_idx, OD, AF, Template))
   return true;
   }
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=348531=348530=348531=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Dec  6 14:06:44 2018
@@ -45,6 +45,8 @@ struct OSArray : public OSObject {
 
   OSObject *identity() override;
 
+  virtual OSObject *generateObject(OSObject *input);
+
   virtual void consumeReference(OS_CONSUME OSArray *other);
 
   static OSArray *generateArrayHasCode() {
@@ -68,6 +70,8 @@ struct MyArray : public OSArray {
   void consumeReference(OSArray *other) override;
 
   OSObject *identity() override;
+
+  OSObject *generateObject(OSObject *input) override;
 };
 
 struct OtherStruct {
@@ -79,6 +83,14 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+void test_no_infinite_check_recursion(MyArray *arr) {
+  OSObject *input = new OSObject;
+  OSObject *o = arr->generateObject(input);
+  o->release();
+  input->release();
+}
+
+
 void check_param_attribute_propagation(MyArray *parent) {
   OSArray *arr = new OSArray;
   parent->consumeReference(arr);


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


r348443 - [attributes] Add more tests for os_returns_retained

2018-12-05 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Dec  5 17:21:38 2018
New Revision: 348443

URL: http://llvm.org/viewvc/llvm-project?rev=348443=rev
Log:
[attributes] Add more tests for os_returns_retained

Modified:
cfe/trunk/test/Sema/attr-osobject.mm

Modified: cfe/trunk/test/Sema/attr-osobject.mm
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-osobject.mm?rev=348443=348442=348443=diff
==
--- cfe/trunk/test/Sema/attr-osobject.mm (original)
+++ cfe/trunk/test/Sema/attr-osobject.mm Wed Dec  5 17:21:38 2018
@@ -1,6 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks %s
 
 struct S {};
 
@@ -9,3 +7,9 @@ struct S {};
   - (S*) generateS __attribute__((os_returns_retained));
   - (void) takeS:(S*) __attribute__((os_consumed)) s;
 @end
+
+typedef __attribute__((os_returns_retained)) id (^blockType)(); // 
expected-warning{{'os_returns_retained' attribute only applies to functions, 
Objective-C methods, and Objective-C properties}}
+
+__auto_type b = ^ id (id filter)  __attribute__((os_returns_retained))  { // 
expected-warning{{'os_returns_retained' attribute only applies to functions, 
Objective-C methods, and Objective-C properties}}
+  return filter;
+};


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


r348396 - [analyzer] Attribute for RetainCountChecker for OSObject should propagate with inheritance

2018-12-05 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Dec  5 10:34:54 2018
New Revision: 348396

URL: http://llvm.org/viewvc/llvm-project?rev=348396=rev
Log:
[analyzer] Attribute for RetainCountChecker for OSObject should propagate with 
inheritance

rdar://46388388

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=348396=348395=348396=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Wed Dec  5 
10:34:54 2018
@@ -686,9 +686,59 @@ RetainSummaryManager::getRetEffectFromAn
 return RetEffect::MakeNotOwned(RetEffect::Generalized);
   }
 
+  if (const auto *MD = dyn_cast(D))
+for (const auto *PD : MD->overridden_methods())
+  if (auto RE = getRetEffectFromAnnotations(RetTy, PD))
+return RE;
+
   return None;
 }
 
+/// Apply the annotation of {@code pd} in function {@code FD}
+/// to the resulting summary stored in out-parameter {@code Template}.
+/// Return whether an annotation was applied.
+bool applyFunctionParamAnnotationEffect(const ParmVarDecl *pd,
+unsigned parm_idx,
+const FunctionDecl *FD,
+ArgEffects::Factory ,
+RetainSummaryTemplate ) {
+  if (pd->hasAttr()) {
+Template->addArg(AF, parm_idx, DecRefMsg);
+return true;
+  } else if (pd->hasAttr() || pd->hasAttr() ||
+ hasRCAnnotation(pd, "rc_ownership_consumed")) {
+Template->addArg(AF, parm_idx, DecRef);
+return true;
+  } else if (pd->hasAttr() ||
+ hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
+QualType PointeeTy = pd->getType()->getPointeeType();
+if (!PointeeTy.isNull()) {
+  if (coreFoundation::isCFObjectRef(PointeeTy)) {
+Template->addArg(AF, parm_idx, RetainedOutParameter);
+return true;
+  }
+}
+  } else if (pd->hasAttr()) {
+QualType PointeeTy = pd->getType()->getPointeeType();
+if (!PointeeTy.isNull()) {
+  if (coreFoundation::isCFObjectRef(PointeeTy)) {
+Template->addArg(AF, parm_idx, UnretainedOutParameter);
+return true;
+  }
+}
+  } else {
+if (const auto *MD = dyn_cast(FD)) {
+  for (const auto *OD : MD->overridden_methods()) {
+const ParmVarDecl *OP = OD->parameters()[parm_idx];
+if (applyFunctionParamAnnotationEffect(OP, parm_idx, MD, AF, Template))
+  return true;
+  }
+}
+  }
+
+  return false;
+}
+
 void
 RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *,
const FunctionDecl *FD) {
@@ -703,24 +753,7 @@ RetainSummaryManager::updateSummaryFromA
   for (auto pi = FD->param_begin(),
  pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
 const ParmVarDecl *pd = *pi;
-if (pd->hasAttr()) {
-  Template->addArg(AF, parm_idx, DecRefMsg);
-} else if (pd->hasAttr() ||
- pd->hasAttr() ||
- hasRCAnnotation(pd, "rc_ownership_consumed")) {
-  Template->addArg(AF, parm_idx, DecRef);
-} else if (pd->hasAttr() ||
- hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
-  QualType PointeeTy = pd->getType()->getPointeeType();
-  if (!PointeeTy.isNull())
-if (coreFoundation::isCFObjectRef(PointeeTy))
-  Template->addArg(AF, parm_idx, RetainedOutParameter);
-} else if (pd->hasAttr()) {
-  QualType PointeeTy = pd->getType()->getPointeeType();
-  if (!PointeeTy.isNull())
-if (coreFoundation::isCFObjectRef(PointeeTy))
-  Template->addArg(AF, parm_idx, UnretainedOutParameter);
-}
+applyFunctionParamAnnotationEffect(pd, parm_idx, FD, AF, Template);
   }
 
   QualType RetTy = FD->getReturnType();

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=348396=348395=348396=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Wed Dec  5 10:34:54 2018
@@ -21,12 +21,13 @@ struct OSObject {
 
   unsigned int foo() { return 42; }
 
+  virtual OS_RETURNS_NOT_RETAINED OSObject *identity();
+
   static OSObject *generateObject(int);
 
   static OSObject *getObject();
   static OSObject *GetObject();
 
-
   static void * operator new(size_t size);
 
   static const OSMetaClass * const metaClass;
@@ -40,6 +41,12 @@ struct 

Re: [cfe-dev] r347339 - [clang][Parse] Diagnose useless null statements / empty init-statements

2018-12-05 Thread George Karpenkov via cfe-commits
These are the cases I get:

#define unexpected(a) { kprintf("unexpected %s:%d\n", __FILE__, __LINE__); a; }

and

#if 0
#define DEBG(fmt, args...)  { IOLog(fmt, ## args); kprintf(fmt, ## args); }
#else
#define DEBG(fmt, args...)  {}
#endif

Now calls

`DEBG(‘x’);` and `unexpected(‘msg’);`

cause the warning to be fired.
Of course, semicolon could be omitted, but the fact that the macro has braces 
is sort of an implementation detail.

Greg Parker has pointed out it’s possible to rewrite the macros using the “do { 
… } while (0)”,
but that is a lot of macros to change, and the resulting code would be arguably 
less readable.

> On Dec 5, 2018, at 5:10 AM, Aaron Ballman  wrote:
> 
> On Wed, Dec 5, 2018 at 1:40 AM Roman Lebedev  > wrote:
>> 
>> It is a problem in practice for us since we have projects which enable 
>> all available warnings and also enable “-Werror”.
>> Hm, they have asked for -Weverything and they got it. Seems to be
>> working as intended.
>> When in previous discussions elsewhere i have talked about
>> -Weverything, i was always
>> been told that it isn't supposed to be used like that (admittedly, i
>> *do* use it like that :)).
>> 
>> Could you explain how is this different from any other warning that is
>> considered pointless by the project?
>> Why not simply disable it?

You are right, it could be disabled. It’s just for this warning the noise vs. 
usefulness ratio seemed pretty low.

>> 
> Would you be okay with the warning if it was only diagnosed when the
> source location of the semi-colon is not immediately preceded by a
> macro expansion location? e.g.,
> 
> EMPTY_EXPANSION(12); // Not diagnosed
> EMPTY_EXPANSION; // Not diagnosed
> ; // Diagnosed
 This could work provided that all empty space preceding the semicolon is 
 ignored (as the macro could be separated by space(s) or newline(s).
 I’m not sure the complexity would be worth it, as I haven’t seen bugs 
 arising from extra semicolons and empty statements,
 but it would take care of my use case.
 
>>> 
>>> Or rather when the *previous* semicolon is coming from a macro.
>> I don't like this. clang is already wa-a-ay too forgiving about
>> macros, it almost ignores almost every warning in macros.
>> It was an *intentional* decision to still warn on useless ';' after
>> non-empty macros.
> 
> I think I'm confused now. This is a test case:
> 
> NULLMACRO(v7); // OK. This could be either GOODMACRO() or
> BETTERMACRO() situation, so we can't know we can drop it.
> 
> So empty macro expansions should be ignored as I expected... so what
> is being diagnosed? George, can you provide a more clear example that
> demonstrates the issue?
> 
> To be clear, I do *not* think this is a situation we should spend
> effort supporting (assuming "all available warnings" really means
> -Weverything and not something else):
> 
>> It is a problem in practice for us since we have projects which enable all 
>> available warnings and also enable “-Werror”.
> 
> However, if we are diagnosing *empty* macro expansions followed by a
> semi-colon, I think that would be unacceptably chatty and is worth
> fixing on its own merits.
> 
> ~Aaron
> 
>> 
> ~Aaron
> 
>> Regards,
>> George
>> Roman.
>> 
>>> On Nov 20, 2018, at 10:59 AM, Roman Lebedev via cfe-commits 
>>>  wrote:
>>> 
>>> Author: lebedevri
>>> Date: Tue Nov 20 10:59:05 2018
>>> New Revision: 347339
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=347339=rev
>>> Log:
>>> [clang][Parse] Diagnose useless null statements / empty init-statements
>>> 
>>> Summary:
>>> clang has `-Wextra-semi` (D43162), which is not dictated by the 
>>> currently selected standard.
>>> While that is great, there is at least one more source of need-less 
>>> semis - 'null statements'.
>>> Sometimes, they are needed:
>>> ```
>>> for(int x = 0; continueToDoWork(x); x++)
>>> ; // Ugly code, but the semi is needed here.
>>> ```
>>> 
>>> But sometimes they are just there for no reason:
>>> ```
>>> switch(X) {
>>> case 0:
>>> return -2345;
>>> case 5:
>>> return 0;
>>> default:
>>> return 42;
>>> }; // <- oops
>>> 
>>> ;;; <- PS, still not diagnosed. Clearly this is junk.
>>> ```
>>> 
>>> Additionally:
>>> ```
>>> if(; // <- empty init-statement
>>>  true)
>>> ;
>>> 
>>> switch (; // empty init-statement
>>>   x) {
>>> ...
>>> }
>>> 
>>> for (; // <- empty init-statement
>>>int y : S())
>>> ;
>>> }
>>> 
>>> As usual, things may or may not go sideways in the presence of macros.
>>> While evaluating this diag on my codebase of interest, it was 
>>> unsurprisingly
>>> discovered that Google Test macros are *very* prone to this.
>>> And it seems many issues are deep within 

[clang-tools-extra] r348328 - [clang-query] Continue if compilation command not found for some files

2018-12-04 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Dec  4 18:02:40 2018
New Revision: 348328

URL: http://llvm.org/viewvc/llvm-project?rev=348328=rev
Log:
[clang-query] Continue if compilation command not found for some files

When searching for a code pattern in an entire project with a
compilation database it's tempting to run

```
clang-query **.cpp
```

And yet, that often breaks because some files are just not in the
compilation database: tests, sample code, etc..
clang-query should not stop when encountering such cases.

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

Modified:
clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp

Modified: clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp?rev=348328=348327=348328=diff
==
--- clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp (original)
+++ clang-tools-extra/trunk/clang-query/tool/ClangQuery.cpp Tue Dec  4 18:02:40 
2018
@@ -100,8 +100,19 @@ int main(int argc, const char **argv) {
   ClangTool Tool(OptionsParser.getCompilations(),
  OptionsParser.getSourcePathList());
   std::vector> ASTs;
-  if (Tool.buildASTs(ASTs) != 0)
+  int Status = Tool.buildASTs(ASTs);
+  int ASTStatus = 0;
+  if (Status == 1) {
+// Building ASTs failed.
 return 1;
+  } else if (Status == 2) {
+ASTStatus |= 1;
+llvm::errs() << "Failed to build AST for some of the files, "
+ << "results may be incomplete."
+ << "\n";
+  } else {
+assert(Status == 0 && "Unexpected status returned");
+  }
 
   QuerySession QS(ASTs);
 
@@ -134,5 +145,5 @@ int main(int argc, const char **argv) {
 }
   }
 
-  return 0;
+  return ASTStatus;
 }


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


Re: r347339 - [clang][Parse] Diagnose useless null statements / empty init-statements

2018-12-04 Thread George Karpenkov via cfe-commits


> On Dec 4, 2018, at 4:47 PM, Aaron Ballman  wrote:
> 
> On Tue, Dec 4, 2018 at 7:35 PM George Karpenkov  wrote:
>> 
>> Hi Roman,
>> 
>> I’m against this new warning.
>> 
>> A very common idiom is defining a “DEBUG” macro to be a no-op in release, 
>> and a logging function otherwise.
>> The new introduced warning warns on all such cases (e.g. 
>> 'DEBUG(“mystring”);')
> 
> Yeah, that's not good.
> 
>> As noted in the review, Clang warnings should generally not be used to 
>> diagnose style issues — and an extra semicolon does not seem to be a common 
>> bug source.
>> 
>> It is a problem in practice for us since we have projects which enable all 
>> available warnings and also enable “-Werror”.
> 
> Would you be okay with the warning if it was only diagnosed when the
> source location of the semi-colon is not immediately preceded by a
> macro expansion location? e.g.,
> 
> EMPTY_EXPANSION(12); // Not diagnosed
> EMPTY_EXPANSION; // Not diagnosed
> ; // Diagnosed

This could work provided that all empty space preceding the semicolon is 
ignored (as the macro could be separated by space(s) or newline(s).
I’m not sure the complexity would be worth it, as I haven’t seen bugs arising 
from extra semicolons and empty statements,
but it would take care of my use case.

> 
> ~Aaron
> 
>> 
>> Regards,
>> George
>> 
>> 
>>> On Nov 20, 2018, at 10:59 AM, Roman Lebedev via cfe-commits 
>>>  wrote:
>>> 
>>> Author: lebedevri
>>> Date: Tue Nov 20 10:59:05 2018
>>> New Revision: 347339
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=347339=rev
>>> Log:
>>> [clang][Parse] Diagnose useless null statements / empty init-statements
>>> 
>>> Summary:
>>> clang has `-Wextra-semi` (D43162), which is not dictated by the currently 
>>> selected standard.
>>> While that is great, there is at least one more source of need-less semis - 
>>> 'null statements'.
>>> Sometimes, they are needed:
>>> ```
>>> for(int x = 0; continueToDoWork(x); x++)
>>> ; // Ugly code, but the semi is needed here.
>>> ```
>>> 
>>> But sometimes they are just there for no reason:
>>> ```
>>> switch(X) {
>>> case 0:
>>> return -2345;
>>> case 5:
>>> return 0;
>>> default:
>>> return 42;
>>> }; // <- oops
>>> 
>>> ;;; <- PS, still not diagnosed. Clearly this is junk.
>>> ```
>>> 
>>> Additionally:
>>> ```
>>> if(; // <- empty init-statement
>>>  true)
>>> ;
>>> 
>>> switch (; // empty init-statement
>>>   x) {
>>> ...
>>> }
>>> 
>>> for (; // <- empty init-statement
>>>int y : S())
>>> ;
>>> }
>>> 
>>> As usual, things may or may not go sideways in the presence of macros.
>>> While evaluating this diag on my codebase of interest, it was unsurprisingly
>>> discovered that Google Test macros are *very* prone to this.
>>> And it seems many issues are deep within the GTest itself, not
>>> in the snippets passed from the codebase that uses GTest.
>>> 
>>> So after some thought, i decided not do issue a diagnostic if the semi
>>> is within *any* macro, be it either from the normal header, or system 
>>> header.
>>> 
>>> Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=39111 | PR39111 ]]
>>> 
>>> Reviewers: rsmith, aaron.ballman, efriedma
>>> 
>>> Reviewed By: aaron.ballman
>>> 
>>> Subscribers: cfe-commits
>>> 
>>> Differential Revision: https://reviews.llvm.org/D52695
>>> 
>>> Added:
>>>   
>>> cfe/trunk/test/Parser/extra-semi-resulting-in-nullstmt-in-init-statement.cpp
>>>   cfe/trunk/test/Parser/extra-semi-resulting-in-nullstmt.cpp
>>> Modified:
>>>   cfe/trunk/docs/ReleaseNotes.rst
>>>   cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>>>   cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>>>   cfe/trunk/include/clang/Parse/Parser.h
>>>   cfe/trunk/lib/Parse/ParseExprCXX.cpp
>>>   cfe/trunk/lib/Parse/ParseStmt.cpp
>>> 
>>> Modified: cfe/trunk/docs/ReleaseNotes.rst
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=347339=347338=347339=diff
>>> ==
>>> --- cfe/trunk/docs/ReleaseNotes.rst (original)
>>> +++ cfe/trunk/docs/ReleaseNotes.rst Tue Nov 20 10:59:05 2018
>>> @@ -55,6 +55,63 @@ Major New Features
>>> Improvements to Clang's diagnostics
>>> ^^^
>>> 
>>> +- ``-Wextra-semi-stmt`` is a new diagnostic that diagnoses extra 
>>> semicolons,
>>> +  much like ``-Wextra-semi``. This new diagnostic diagnoses all 
>>> *unnecessary*
>>> +  null statements (expression statements without an expression), unless: 
>>> the
>>> +  semicolon directly follows a macro that was expanded to nothing or if the
>>> +  semicolon is within the macro itself. This applies to macros defined in 
>>> system
>>> +  headers as well as user-defined macros.
>>> +
>>> +  .. code-block:: c++
>>> +
>>> +  #define MACRO(x) int x;
>>> +  #define NULLMACRO(varname)
>>> +
>>> +  void test() {
>>> +; // <- warning: ';' with no preceding expression is a null 
>>> statement
>>> +
>>> +while (true)
>>> 

Re: r346041 - Diagnose parameter names that shadow the names of inherited fields under -Wshadow-field.

2018-12-04 Thread George Karpenkov via cfe-commits


> On Dec 4, 2018, at 4:48 PM, Aaron Ballman  wrote:
> 
> On Tue, Dec 4, 2018 at 7:17 PM George Karpenkov  wrote:
>> 
>> Hi Aaron,
>> 
>> Should such changes be reviewed?
> 
> This was reviewed in D52421.
> 
>> In particular, it introduces tons of warnings in XNU (which are painful due 
>> to -Werror).
>> I expect similar issues in many other our projects.
>> 
>> While in principle correct,
>> wouldn’t it make more sense to only warn on function definitions and not 
>> declarations?
> 
> Absolutely! I'll make that change, thank you for the suggestion.

OK thanks!

> 
> ~Aaron
> 
>> 
>> This would avoid:
>> 
>> - A gigantic avalanche of warnings when compiling a project,
>> as the warning would be duplicated for every TU including the problematic 
>> header
>> - A warning on declaration without a body is  useful: nothing can collide 
>> there,
>> and the actual definition might use a different name.
>> 
>> George
>> 
>>> On Nov 2, 2018, at 2:04 PM, Aaron Ballman via cfe-commits 
>>>  wrote:
>>> 
>>> Author: aaronballman
>>> Date: Fri Nov  2 14:04:44 2018
>>> New Revision: 346041
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=346041=rev
>>> Log:
>>> Diagnose parameter names that shadow the names of inherited fields under 
>>> -Wshadow-field.
>>> 
>>> This addresses PR34120. Note, unlike GCC, we take into account the 
>>> accessibility of the field when deciding whether to warn or not.
>>> 
>>> Modified:
>>>   cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>>   cfe/trunk/include/clang/Sema/Sema.h
>>>   cfe/trunk/lib/Sema/SemaDecl.cpp
>>>   cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>>>   cfe/trunk/test/SemaCXX/warn-shadow.cpp
>>> 
>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=346041=346040=346041=diff
>>> ==
>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Nov  2 
>>> 14:04:44 2018
>>> @@ -9467,16 +9467,15 @@ def warn_block_literal_qualifiers_on_omi
>>>  InGroup;
>>> 
>>> def ext_warn_gnu_final : ExtWarn<
>>> -  "__final is a GNU extension, consider using C++11 final">,
>>> -  InGroup;
>>> -
>>> -def warn_shadow_field :
>>> -  Warning<"non-static data member %0 of %1 shadows member inherited from "
>>> -  "type %2">,
>>> -  InGroup, DefaultIgnore;
>>> -def note_shadow_field : Note<"declared here">;
>>> -
>>> -def err_multiversion_required_in_redecl : Error<
>>> +  "__final is a GNU extension, consider using C++11 final">,
>>> +  InGroup;
>>> +
>>> +def warn_shadow_field : Warning<
>>> +  "%select{parameter|non-static data member}3 %0 %select{|of %1 }3shadows "
>>> +  "member inherited from type %2">, InGroup, DefaultIgnore;
>>> +def note_shadow_field : Note<"declared here">;
>>> +
>>> +def err_multiversion_required_in_redecl : Error<
>>>  "function declaration is missing %select{'target'|'cpu_specific' or "
>>>  "'cpu_dispatch'}0 attribute in a multiversioned function">;
>>> def note_multiversioning_caused_here : Note<
>>> 
>>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=346041=346040=346041=diff
>>> ==
>>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>>> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Nov  2 14:04:44 2018
>>> @@ -10588,7 +10588,8 @@ private:
>>>  /// Check if there is a field shadowing.
>>>  void CheckShadowInheritedFields(const SourceLocation ,
>>>  DeclarationName FieldName,
>>> -  const CXXRecordDecl *RD);
>>> +  const CXXRecordDecl *RD,
>>> +  bool DeclIsField = true);
>>> 
>>>  /// Check if the given expression contains 'break' or 'continue'
>>>  /// statement that produces control flow different from GCC.
>>> 
>>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=346041=346040=346041=diff
>>> ==
>>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Nov  2 14:04:44 2018
>>> @@ -12366,6 +12366,13 @@ Decl *Sema::ActOnParamDeclarator(Scope *
>>>D.setInvalidType(true);
>>>  }
>>>}
>>> +
>>> +if (LangOpts.CPlusPlus) {
>>> +  DeclarationNameInfo DNI = GetNameForDeclarator(D);
>>> +  if (auto *RD = dyn_cast(CurContext))
>>> +CheckShadowInheritedFields(DNI.getLoc(), DNI.getName(), RD,
>>> +   /*DeclIsField*/ false);
>>> +}
>>>  }
>>> 
>>>  // Temporarily put parameter variables in the translation unit, not
>>> 
>>> Modified: 

Re: r347339 - [clang][Parse] Diagnose useless null statements / empty init-statements

2018-12-04 Thread George Karpenkov via cfe-commits
Hi Roman,

I’m against this new warning.

A very common idiom is defining a “DEBUG” macro to be a no-op in release, and a 
logging function otherwise.
The new introduced warning warns on all such cases (e.g. 'DEBUG(“mystring”);')

As noted in the review, Clang warnings should generally not be used to diagnose 
style issues — and an extra semicolon does not seem to be a common bug source.

It is a problem in practice for us since we have projects which enable all 
available warnings and also enable “-Werror”.

Regards,
George


> On Nov 20, 2018, at 10:59 AM, Roman Lebedev via cfe-commits 
>  wrote:
> 
> Author: lebedevri
> Date: Tue Nov 20 10:59:05 2018
> New Revision: 347339
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=347339=rev
> Log:
> [clang][Parse] Diagnose useless null statements / empty init-statements
> 
> Summary:
> clang has `-Wextra-semi` (D43162), which is not dictated by the currently 
> selected standard.
> While that is great, there is at least one more source of need-less semis - 
> 'null statements'.
> Sometimes, they are needed:
> ```
> for(int x = 0; continueToDoWork(x); x++)
>  ; // Ugly code, but the semi is needed here.
> ```
> 
> But sometimes they are just there for no reason:
> ```
> switch(X) {
> case 0:
>  return -2345;
> case 5:
>  return 0;
> default:
>  return 42;
> }; // <- oops
> 
> ;;; <- PS, still not diagnosed. Clearly this is junk.
> ```
> 
> Additionally:
> ```
> if(; // <- empty init-statement
>   true)
>  ;
> 
> switch (; // empty init-statement
>x) {
>  ...
> }
> 
> for (; // <- empty init-statement
> int y : S())
>  ;
> }
> 
> As usual, things may or may not go sideways in the presence of macros.
> While evaluating this diag on my codebase of interest, it was unsurprisingly
> discovered that Google Test macros are *very* prone to this.
> And it seems many issues are deep within the GTest itself, not
> in the snippets passed from the codebase that uses GTest.
> 
> So after some thought, i decided not do issue a diagnostic if the semi
> is within *any* macro, be it either from the normal header, or system header.
> 
> Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=39111 | PR39111 ]]
> 
> Reviewers: rsmith, aaron.ballman, efriedma
> 
> Reviewed By: aaron.ballman
> 
> Subscribers: cfe-commits
> 
> Differential Revision: https://reviews.llvm.org/D52695
> 
> Added:
>
> cfe/trunk/test/Parser/extra-semi-resulting-in-nullstmt-in-init-statement.cpp
>cfe/trunk/test/Parser/extra-semi-resulting-in-nullstmt.cpp
> Modified:
>cfe/trunk/docs/ReleaseNotes.rst
>cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>cfe/trunk/include/clang/Parse/Parser.h
>cfe/trunk/lib/Parse/ParseExprCXX.cpp
>cfe/trunk/lib/Parse/ParseStmt.cpp
> 
> Modified: cfe/trunk/docs/ReleaseNotes.rst
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=347339=347338=347339=diff
> ==
> --- cfe/trunk/docs/ReleaseNotes.rst (original)
> +++ cfe/trunk/docs/ReleaseNotes.rst Tue Nov 20 10:59:05 2018
> @@ -55,6 +55,63 @@ Major New Features
> Improvements to Clang's diagnostics
> ^^^
> 
> +- ``-Wextra-semi-stmt`` is a new diagnostic that diagnoses extra semicolons,
> +  much like ``-Wextra-semi``. This new diagnostic diagnoses all *unnecessary*
> +  null statements (expression statements without an expression), unless: the
> +  semicolon directly follows a macro that was expanded to nothing or if the
> +  semicolon is within the macro itself. This applies to macros defined in 
> system
> +  headers as well as user-defined macros.
> +
> +  .. code-block:: c++
> +
> +  #define MACRO(x) int x;
> +  #define NULLMACRO(varname)
> +
> +  void test() {
> +; // <- warning: ';' with no preceding expression is a null statement
> +
> +while (true)
> +  ; // OK, it is needed.
> +
> +switch (my_enum) {
> +case E1:
> +  // stuff
> +  break;
> +case E2:
> +  ; // OK, it is needed.
> +}
> +
> +MACRO(v0;) // Extra semicolon, but within macro, so ignored.
> +
> +MACRO(v1); // <- warning: ';' with no preceding expression is a null 
> statement
> +
> +NULLMACRO(v2); // ignored, NULLMACRO expanded to nothing.
> +  }
> +
> +- ``-Wempty-init-stmt`` is a new diagnostic that diagnoses empty 
> init-statements
> +  of ``if``, ``switch``, ``range-based for``, unless: the semicolon directly
> +  follows a macro that was expanded to nothing or if the semicolon is within 
> the
> +  macro itself (both macros from system headers, and normal macros). This
> +  diagnostic is in the ``-Wextra-semi-stmt`` group and is enabled in
> +  ``-Wextra``.
> +
> +  .. code-block:: c++
> +
> +  void test() {
> +if(; // <- warning: init-statement of 'if' is a null statement
> +   true)

Re: r346041 - Diagnose parameter names that shadow the names of inherited fields under -Wshadow-field.

2018-12-04 Thread George Karpenkov via cfe-commits
Hi Aaron,

Should such changes be reviewed?
In particular, it introduces tons of warnings in XNU (which are painful due to 
-Werror).
I expect similar issues in many other our projects.

While in principle correct,
wouldn’t it make more sense to only warn on function definitions and not 
declarations?

This would avoid:

 - A gigantic avalanche of warnings when compiling a project,
as the warning would be duplicated for every TU including the problematic header
 - A warning on declaration without a body is  useful: nothing can collide 
there,
and the actual definition might use a different name.

George

> On Nov 2, 2018, at 2:04 PM, Aaron Ballman via cfe-commits 
>  wrote:
> 
> Author: aaronballman
> Date: Fri Nov  2 14:04:44 2018
> New Revision: 346041
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=346041=rev
> Log:
> Diagnose parameter names that shadow the names of inherited fields under 
> -Wshadow-field.
> 
> This addresses PR34120. Note, unlike GCC, we take into account the 
> accessibility of the field when deciding whether to warn or not.
> 
> Modified:
>cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>cfe/trunk/include/clang/Sema/Sema.h
>cfe/trunk/lib/Sema/SemaDecl.cpp
>cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>cfe/trunk/test/SemaCXX/warn-shadow.cpp
> 
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=346041=346040=346041=diff
> ==
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Nov  2 14:04:44 
> 2018
> @@ -9467,16 +9467,15 @@ def warn_block_literal_qualifiers_on_omi
>   InGroup;
> 
> def ext_warn_gnu_final : ExtWarn<
> -  "__final is a GNU extension, consider using C++11 final">,
> -  InGroup;
> -
> -def warn_shadow_field :
> -  Warning<"non-static data member %0 of %1 shadows member inherited from "
> -  "type %2">,
> -  InGroup, DefaultIgnore;
> -def note_shadow_field : Note<"declared here">;
> -
> -def err_multiversion_required_in_redecl : Error<
> +  "__final is a GNU extension, consider using C++11 final">,
> +  InGroup;
> +
> +def warn_shadow_field : Warning<
> +  "%select{parameter|non-static data member}3 %0 %select{|of %1 }3shadows "
> +  "member inherited from type %2">, InGroup, DefaultIgnore;
> +def note_shadow_field : Note<"declared here">;
> +
> +def err_multiversion_required_in_redecl : Error<
>   "function declaration is missing %select{'target'|'cpu_specific' or "
>   "'cpu_dispatch'}0 attribute in a multiversioned function">;
> def note_multiversioning_caused_here : Note<
> 
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=346041=346040=346041=diff
> ==
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Nov  2 14:04:44 2018
> @@ -10588,7 +10588,8 @@ private:
>   /// Check if there is a field shadowing.
>   void CheckShadowInheritedFields(const SourceLocation ,
>   DeclarationName FieldName,
> -  const CXXRecordDecl *RD);
> +  const CXXRecordDecl *RD,
> +  bool DeclIsField = true);
> 
>   /// Check if the given expression contains 'break' or 'continue'
>   /// statement that produces control flow different from GCC.
> 
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=346041=346040=346041=diff
> ==
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Nov  2 14:04:44 2018
> @@ -12366,6 +12366,13 @@ Decl *Sema::ActOnParamDeclarator(Scope *
> D.setInvalidType(true);
>   }
> }
> +
> +if (LangOpts.CPlusPlus) {
> +  DeclarationNameInfo DNI = GetNameForDeclarator(D);
> +  if (auto *RD = dyn_cast(CurContext))
> +CheckShadowInheritedFields(DNI.getLoc(), DNI.getName(), RD,
> +   /*DeclIsField*/ false);
> +}
>   }
> 
>   // Temporarily put parameter variables in the translation unit, not
> 
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=346041=346040=346041=diff
> ==
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Nov  2 14:04:44 2018
> @@ -2832,13 +2832,14 @@ static const ParsedAttr *getMSPropertyAt
>   return nullptr;
> }
> 
> -// Check if there is a field shadowing.
> -void 

Re: [PATCH] D55076: [analyzer] RetainCountChecker: recognize that OSObject can be created directly using an operator "new"

2018-11-30 Thread George Karpenkov via cfe-commits
Pushed the fix. Again, sorry for the trouble.

> On Nov 30, 2018, at 11:34 AM, George Karpenkov via cfe-commits 
>  wrote:
> 
> Good idea about using the mailing list, thanks, I’ll do that!
> 
>> On Nov 30, 2018, at 11:30 AM, Aaron Ballman  wrote:
>> 
>> On Fri, Nov 30, 2018 at 2:26 PM George Karpenkov  
>> wrote:
>>> 
>>> Thanks I’ll take a look.
>>> 
>>> BTW when reverting could you use “git revert” or mention manually the 
>>> phabricator revision being reverted,
>>> and apply reverts atomically?
>>> I (and many others) work exclusively using a git monorepo, so I don’t even 
>>> have a straightforward way to lookup what "r347951” is.
>> 
>> Given that I work exclusively in svn, I won't be using git revert. :-)
>> I can add the phab revision to the commit log when possible, but I
>> expect to continue to use svn revisions until the git transition takes
>> place. FWIW, you can use the mailing lists to look up what r347951
>> (such as 
>> http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20181126/252804.html).
>> Sorry for the troubles, though!
>> 
>> ~Aaron
>> 
>>> 
>>> Thanks!
>>> 
>>>> On Nov 30, 2018, at 11:20 AM, Aaron Ballman  wrote:
>>>> 
>>>> On Fri, Nov 30, 2018 at 2:19 PM George Karpenkov  
>>>> wrote:
>>>>> 
>>>>> Thanks and sorry about the trouble. I’ll recommit with size_t.
>>>> 
>>>> No worries, it happens! FYI, I also had to commit r348023 as part of
>>>> the reverts.
>>>> 
>>>> ~Aaron
>>>>> 
>>>>> On Nov 30, 2018, at 10:56 AM, Aaron Ballman  
>>>>> wrote:
>>>>> 
>>>>> On Fri, Nov 30, 2018 at 9:37 AM Artem Dergachev via Phabricator via
>>>>> cfe-commits  wrote:
>>>>> 
>>>>> 
>>>>> NoQ added inline comments.
>>>>> 
>>>>> 
>>>>> 
>>>>> Comment at: clang/test/Analysis/osobject-retain-release.cpp:27
>>>>> +
>>>>> +  static void * operator new(unsigned long size);
>>>>> +
>>>>> 
>>>>> NoQ wrote:
>>>>> 
>>>>> I think we should use `size_t` as much as possible, because this may 
>>>>> otherwise have weird consequences on platforms on which `size_t` is not 
>>>>> defined as `unsigned long`. Not sure if this checker is ran on such 
>>>>> platforms. But the test doesn't have the triple specified, so it runs 
>>>>> under the host triple, which may be arbitrary and cause problems on 
>>>>> buildbots.
>>>>> 
>>>>> I.e.,
>>>>> 
>>>>> ```
>>>>> typedef __typeof(sizeof(int)) size_t;
>>>>> // use size_t
>>>>> ```
>>>>> 
>>>>> http://lab.llvm.org:8011/builders/clang-cmake-armv8-lld/builds/440/steps/ninja%20check%202/logs/FAIL%3A%20Clang%3A%3Aosobject-retain-release.cpp
>>>>> 
>>>>> 
>>>>> I reverted r347949 through r347951 in r348020 to get the bots back to 
>>>>> green.
>>>>> 
>>>>> ~Aaron
>>>>> 
>>>>> 
>>>>> 
>>>>> Repository:
>>>>> rC Clang
>>>>> 
>>>>> CHANGES SINCE LAST ACTION
>>>>> https://reviews.llvm.org/D55076/new/
>>>>> 
>>>>> https://reviews.llvm.org/D55076
>>>>> 
>>>>> 
>>>>> 
>>>>> ___
>>>>> cfe-commits mailing list
>>>>> cfe-commits@lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>> 
>>>>> 
>>> 
> 
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

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


r348030 - Revert "Reverting r347949-r347951 because they broke the test bots."

2018-11-30 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Nov 30 12:43:42 2018
New Revision: 348030

URL: http://llvm.org/viewvc/llvm-project?rev=348030=rev
Log:
Revert "Reverting r347949-r347951 because they broke the test bots."

This reverts commit 5bad6129c012fbf186eb055be49344e790448ecc.

Hopefully fixing the issue which was breaking the bots.

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=348030=348029=348030=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Fri Nov 
30 12:43:42 2018
@@ -530,6 +530,8 @@ class RetainSummaryManager {
   /// Decrement the reference count on OS object.
   const RetainSummary *getOSSummaryReleaseRule(const FunctionDecl *FD);
 
+  /// Free the OS object.
+  const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
 
   enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=348030=348029=348030=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Fri Nov 30 
12:43:42 2018
@@ -124,10 +124,8 @@ RetainSummaryManager::generateSummary(co
   }
 
   const IdentifierInfo *II = FD->getIdentifier();
-  if (!II)
-return getDefaultSummary();
 
-  StringRef FName = II->getName();
+  StringRef FName = II ? II->getName() : "";
 
   // Strip away preceding '_'.  Doing this here will effect all the checks
   // down below.
@@ -304,6 +302,12 @@ RetainSummaryManager::generateSummary(co
 
   if (FName == "retain")
 return getOSSummaryRetainRule(FD);
+
+  if (FName == "free")
+return getOSSummaryFreeRule(FD);
+
+  if (MD->getOverloadedOperator() == OO_New)
+return getOSSummaryCreateRule(MD);
 }
   }
 
@@ -480,20 +484,14 @@ RetainSummaryManager::getSummary(const C
   const RetainSummary *Summ;
   switch (Call.getKind()) {
   case CE_Function:
-Summ = getFunctionSummary(cast(Call).getDecl());
-break;
   case CE_CXXMember:
-Summ = getFunctionSummary(cast(Call).getDecl());
-break;
   case CE_CXXMemberOperator:
-Summ = getFunctionSummary(cast(Call).getDecl());
-break;
   case CE_CXXConstructor:
-Summ = getFunctionSummary(cast(Call).getDecl());
+  case CE_CXXAllocator:
+Summ = getFunctionSummary(cast_or_null(Call.getDecl()));
 break;
   case CE_Block:
   case CE_CXXDestructor:
-  case CE_CXXAllocator:
 // FIXME: These calls are currently unsupported.
 return getPersistentStopSummary();
   case CE_ObjCMessage: {
@@ -619,6 +617,14 @@ RetainSummaryManager::getOSSummaryReleas
 }
 
 const RetainSummary *
+RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
+  return getPersistentSummary(RetEffect::MakeNoRet(),
+  /*ReceiverEff=*/DoNothing,
+  /*DefaultEff=*/DoNothing,
+  /*ThisEff=*/Dealloc);
+}
+
+const RetainSummary *
 RetainSummaryManager::getOSSummaryCreateRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeOwned(RetEffect::OS));
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=348030=348029=348030=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Fri Nov 30 12:43:42 2018
@@ -11,9 +11,12 @@ struct OSMetaClass;
 #define OSDynamicCast(type, inst)   \
 ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
 
+using size_t = decltype(sizeof(int));
+
 struct OSObject {
   virtual void retain();
   virtual void release() {};
+  virtual void free();
   virtual ~OSObject(){}
 
   unsigned int foo() { return 42; }
@@ -23,6 +26,9 @@ struct OSObject {
   static OSObject *getObject();
   static OSObject *GetObject();
 
+
+  static void * operator new(size_t size);
+
   static const OSMetaClass * const metaClass;
 };
 
@@ -62,6 +68,34 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+void check_free_no_error() {
+  OSArray *arr = OSArray::withCapacity(10);
+  arr->retain();
+  

Re: [PATCH] D55076: [analyzer] RetainCountChecker: recognize that OSObject can be created directly using an operator "new"

2018-11-30 Thread George Karpenkov via cfe-commits
Good idea about using the mailing list, thanks, I’ll do that!

> On Nov 30, 2018, at 11:30 AM, Aaron Ballman  wrote:
> 
> On Fri, Nov 30, 2018 at 2:26 PM George Karpenkov  wrote:
>> 
>> Thanks I’ll take a look.
>> 
>> BTW when reverting could you use “git revert” or mention manually the 
>> phabricator revision being reverted,
>> and apply reverts atomically?
>> I (and many others) work exclusively using a git monorepo, so I don’t even 
>> have a straightforward way to lookup what "r347951” is.
> 
> Given that I work exclusively in svn, I won't be using git revert. :-)
> I can add the phab revision to the commit log when possible, but I
> expect to continue to use svn revisions until the git transition takes
> place. FWIW, you can use the mailing lists to look up what r347951
> (such as 
> http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20181126/252804.html).
> Sorry for the troubles, though!
> 
> ~Aaron
> 
>> 
>> Thanks!
>> 
>>> On Nov 30, 2018, at 11:20 AM, Aaron Ballman  wrote:
>>> 
>>> On Fri, Nov 30, 2018 at 2:19 PM George Karpenkov  
>>> wrote:
 
 Thanks and sorry about the trouble. I’ll recommit with size_t.
>>> 
>>> No worries, it happens! FYI, I also had to commit r348023 as part of
>>> the reverts.
>>> 
>>> ~Aaron
 
 On Nov 30, 2018, at 10:56 AM, Aaron Ballman  wrote:
 
 On Fri, Nov 30, 2018 at 9:37 AM Artem Dergachev via Phabricator via
 cfe-commits  wrote:
 
 
 NoQ added inline comments.
 
 
 
 Comment at: clang/test/Analysis/osobject-retain-release.cpp:27
 +
 +  static void * operator new(unsigned long size);
 +
 
 NoQ wrote:
 
 I think we should use `size_t` as much as possible, because this may 
 otherwise have weird consequences on platforms on which `size_t` is not 
 defined as `unsigned long`. Not sure if this checker is ran on such 
 platforms. But the test doesn't have the triple specified, so it runs 
 under the host triple, which may be arbitrary and cause problems on 
 buildbots.
 
 I.e.,
 
 ```
 typedef __typeof(sizeof(int)) size_t;
 // use size_t
 ```
 
 http://lab.llvm.org:8011/builders/clang-cmake-armv8-lld/builds/440/steps/ninja%20check%202/logs/FAIL%3A%20Clang%3A%3Aosobject-retain-release.cpp
 
 
 I reverted r347949 through r347951 in r348020 to get the bots back to 
 green.
 
 ~Aaron
 
 
 
 Repository:
 rC Clang
 
 CHANGES SINCE LAST ACTION
 https://reviews.llvm.org/D55076/new/
 
 https://reviews.llvm.org/D55076
 
 
 
 ___
 cfe-commits mailing list
 cfe-commits@lists.llvm.org
 http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
 
 
>> 

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


Re: [PATCH] D55076: [analyzer] RetainCountChecker: recognize that OSObject can be created directly using an operator "new"

2018-11-30 Thread George Karpenkov via cfe-commits
Thanks I’ll take a look.

BTW when reverting could you use “git revert” or mention manually the 
phabricator revision being reverted,
and apply reverts atomically?
I (and many others) work exclusively using a git monorepo, so I don’t even have 
a straightforward way to lookup what "r347951” is.

Thanks!

> On Nov 30, 2018, at 11:20 AM, Aaron Ballman  wrote:
> 
> On Fri, Nov 30, 2018 at 2:19 PM George Karpenkov  wrote:
>> 
>> Thanks and sorry about the trouble. I’ll recommit with size_t.
> 
> No worries, it happens! FYI, I also had to commit r348023 as part of
> the reverts.
> 
> ~Aaron
>> 
>> On Nov 30, 2018, at 10:56 AM, Aaron Ballman  wrote:
>> 
>> On Fri, Nov 30, 2018 at 9:37 AM Artem Dergachev via Phabricator via
>> cfe-commits  wrote:
>> 
>> 
>> NoQ added inline comments.
>> 
>> 
>> 
>> Comment at: clang/test/Analysis/osobject-retain-release.cpp:27
>> +
>> +  static void * operator new(unsigned long size);
>> +
>> 
>> NoQ wrote:
>> 
>> I think we should use `size_t` as much as possible, because this may 
>> otherwise have weird consequences on platforms on which `size_t` is not 
>> defined as `unsigned long`. Not sure if this checker is ran on such 
>> platforms. But the test doesn't have the triple specified, so it runs under 
>> the host triple, which may be arbitrary and cause problems on buildbots.
>> 
>> I.e.,
>> 
>> ```
>> typedef __typeof(sizeof(int)) size_t;
>> // use size_t
>> ```
>> 
>> http://lab.llvm.org:8011/builders/clang-cmake-armv8-lld/builds/440/steps/ninja%20check%202/logs/FAIL%3A%20Clang%3A%3Aosobject-retain-release.cpp
>> 
>> 
>> I reverted r347949 through r347951 in r348020 to get the bots back to green.
>> 
>> ~Aaron
>> 
>> 
>> 
>> Repository:
>> rC Clang
>> 
>> CHANGES SINCE LAST ACTION
>> https://reviews.llvm.org/D55076/new/
>> 
>> https://reviews.llvm.org/D55076
>> 
>> 
>> 
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>> 
>> 

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


Re: [PATCH] D55076: [analyzer] RetainCountChecker: recognize that OSObject can be created directly using an operator "new"

2018-11-30 Thread George Karpenkov via cfe-commits
Thanks and sorry about the trouble. I’ll recommit with size_t.

> On Nov 30, 2018, at 10:56 AM, Aaron Ballman  wrote:
> 
> On Fri, Nov 30, 2018 at 9:37 AM Artem Dergachev via Phabricator via
> cfe-commits mailto:cfe-commits@lists.llvm.org>> 
> wrote:
>> 
>> NoQ added inline comments.
>> 
>> 
>> 
>> Comment at: clang/test/Analysis/osobject-retain-release.cpp:27
>> +
>> +  static void * operator new(unsigned long size);
>> +
>> 
>> NoQ wrote:
>>> I think we should use `size_t` as much as possible, because this may 
>>> otherwise have weird consequences on platforms on which `size_t` is not 
>>> defined as `unsigned long`. Not sure if this checker is ran on such 
>>> platforms. But the test doesn't have the triple specified, so it runs under 
>>> the host triple, which may be arbitrary and cause problems on buildbots.
>>> 
>>> I.e.,
>>> 
>>> ```
>>> typedef __typeof(sizeof(int)) size_t;
>>> // use size_t
>>> ```
>> http://lab.llvm.org:8011/builders/clang-cmake-armv8-lld/builds/440/steps/ninja%20check%202/logs/FAIL%3A%20Clang%3A%3Aosobject-retain-release.cpp
> 
> I reverted r347949 through r347951 in r348020 to get the bots back to green.
> 
> ~Aaron
> 
>> 
>> 
>> Repository:
>>  rC Clang
>> 
>> CHANGES SINCE LAST ACTION
>>  https://reviews.llvm.org/D55076/new/ 
>> 
>> https://reviews.llvm.org/D55076 
>> 
>> 
>> 
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org 
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits 
>> 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r347950 - [analyzer] RetainCountChecker for OSObject model the "free" call

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:19:16 2018
New Revision: 347950

URL: http://llvm.org/viewvc/llvm-project?rev=347950=rev
Log:
[analyzer] RetainCountChecker for OSObject model the "free" call

The "free" call frees the object immediately, ignoring the reference count.
Sadly, it is actually used in a few places, so we need to model it.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=347950=347949=347950=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Nov 
29 18:19:16 2018
@@ -530,6 +530,8 @@ class RetainSummaryManager {
   /// Decrement the reference count on OS object.
   const RetainSummary *getOSSummaryReleaseRule(const FunctionDecl *FD);
 
+  /// Free the OS object.
+  const RetainSummary *getOSSummaryFreeRule(const FunctionDecl *FD);
 
   enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=347950=347949=347950=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Nov 29 
18:19:16 2018
@@ -303,6 +303,9 @@ RetainSummaryManager::generateSummary(co
   if (FName == "retain")
 return getOSSummaryRetainRule(FD);
 
+  if (FName == "free")
+return getOSSummaryFreeRule(FD);
+
   if (MD->getOverloadedOperator() == OO_New)
 return getOSSummaryCreateRule(MD);
 }
@@ -622,6 +625,14 @@ RetainSummaryManager::getOSSummaryReleas
 }
 
 const RetainSummary *
+RetainSummaryManager::getOSSummaryFreeRule(const FunctionDecl *FD) {
+  return getPersistentSummary(RetEffect::MakeNoRet(),
+  /*ReceiverEff=*/DoNothing,
+  /*DefaultEff=*/DoNothing,
+  /*ThisEff=*/Dealloc);
+}
+
+const RetainSummary *
 RetainSummaryManager::getOSSummaryCreateRule(const FunctionDecl *FD) {
   return getPersistentSummary(RetEffect::MakeOwned(RetEffect::OS));
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=347950=347949=347950=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Nov 29 18:19:16 2018
@@ -14,6 +14,7 @@ struct OSMetaClass;
 struct OSObject {
   virtual void retain();
   virtual void release() {};
+  virtual void free();
   virtual ~OSObject(){}
 
   unsigned int foo() { return 42; }
@@ -65,6 +66,22 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+void check_free_no_error() {
+  OSArray *arr = OSArray::withCapacity(10);
+  arr->retain();
+  arr->retain();
+  arr->retain();
+  arr->free();
+}
+
+void check_free_use_after_free() {
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'OSArray::withCapacity' returns an OSObject of type struct OSArray * with a +1 
retain count}}
+  arr->retain(); // expected-note{{Reference count incremented. The object now 
has a +2 retain count}}
+  arr->free(); // expected-note{{Object released}}
+  arr->retain(); // expected-warning{{Reference-counted object is used after 
it is released}}
+ // expected-note@-1{{Reference-counted object is used after 
it is released}}
+}
+
 unsigned int check_leak_explicit_new() {
   OSArray *arr = new OSArray; // expected-note{{Operator new returns an 
OSObject of type struct OSArray * with a +1 retain count}}
   return arr->getCount(); // expected-note{{Object leaked: allocated object of 
type struct OSArray * is not referenced later in this execution path and has a 
retain count of +1}}


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


r347945 - [analyzer] For OSObject, trust that functions starting with Get

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:18:10 2018
New Revision: 347945

URL: http://llvm.org/viewvc/llvm-project?rev=347945=rev
Log:
[analyzer] For OSObject, trust that functions starting with Get

(uppercase) are also getters.

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=347945=347944=347945=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Nov 29 
18:18:10 2018
@@ -241,7 +241,9 @@ RetainSummaryManager::generateSummary(co
 
 // All objects returned with functions *not* starting with
 // get, or iterators, are returned at +1.
-if (!II->getName().startswith("get") || isOSIteratorSubclass(PD)) {
+if ((!II->getName().startswith("get") &&
+ !II->getName().startswith("Get")) ||
+isOSIteratorSubclass(PD)) {
   return getOSSummaryCreateRule(FD);
 } else {
   return getOSSummaryGetRule(FD);

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=347945=347944=347945=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Nov 29 18:18:10 2018
@@ -20,6 +20,9 @@ struct OSObject {
 
   static OSObject *generateObject(int);
 
+  static OSObject *getObject();
+  static OSObject *GetObject();
+
   static const OSMetaClass * const metaClass;
 };
 
@@ -55,6 +58,14 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+void check_get_object() {
+  OSObject::getObject();
+}
+
+void check_Get_object() {
+  OSObject::GetObject();
+}
+
 void check_custom_iterator_rule(OSArray *arr) {
   OSIterator *it = arr->getIterator();
   it->release();


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


r347949 - [analyzer] RetainCountChecker: recognize that OSObject can be created directly using an operator "new"

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:19:03 2018
New Revision: 347949

URL: http://llvm.org/viewvc/llvm-project?rev=347949=rev
Log:
[analyzer] RetainCountChecker: recognize that OSObject can be created directly 
using an operator "new"

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=347949=347948=347949=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Nov 29 18:19:03 2018
@@ -137,6 +137,8 @@ static void generateDiagnosticsForCallLi
 } else {
   os << "function call";
 }
+  } else if (const auto *NE = dyn_cast(S)){
+os << "Operator new";
   } else {
 assert(isa(S));
 CallEventManager  = CurrSt->getStateManager().getCallEventManager();

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=347949=347948=347949=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Nov 29 
18:19:03 2018
@@ -124,10 +124,8 @@ RetainSummaryManager::generateSummary(co
   }
 
   const IdentifierInfo *II = FD->getIdentifier();
-  if (!II)
-return getDefaultSummary();
 
-  StringRef FName = II->getName();
+  StringRef FName = II ? II->getName() : "";
 
   // Strip away preceding '_'.  Doing this here will effect all the checks
   // down below.
@@ -304,6 +302,9 @@ RetainSummaryManager::generateSummary(co
 
   if (FName == "retain")
 return getOSSummaryRetainRule(FD);
+
+  if (MD->getOverloadedOperator() == OO_New)
+return getOSSummaryCreateRule(MD);
 }
   }
 
@@ -491,9 +492,11 @@ RetainSummaryManager::getSummary(const C
   case CE_CXXConstructor:
 Summ = getFunctionSummary(cast(Call).getDecl());
 break;
+  case CE_CXXAllocator:
+Summ = getFunctionSummary(cast(Call).getDecl());
+break;
   case CE_Block:
   case CE_CXXDestructor:
-  case CE_CXXAllocator:
 // FIXME: These calls are currently unsupported.
 return getPersistentStopSummary();
   case CE_ObjCMessage: {

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=347949=347948=347949=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Nov 29 18:19:03 2018
@@ -23,6 +23,9 @@ struct OSObject {
   static OSObject *getObject();
   static OSObject *GetObject();
 
+
+  static void * operator new(unsigned long size);
+
   static const OSMetaClass * const metaClass;
 };
 
@@ -62,6 +65,18 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+unsigned int check_leak_explicit_new() {
+  OSArray *arr = new OSArray; // expected-note{{Operator new returns an 
OSObject of type struct OSArray * with a +1 retain count}}
+  return arr->getCount(); // expected-note{{Object leaked: allocated object of 
type struct OSArray * is not referenced later in this execution path and has a 
retain count of +1}}
+  // expected-warning@-1{{Potential leak of an object 
of type struct OSArray *}}
+}
+
+unsigned int check_leak_factory() {
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'OSArray::withCapacity' returns an OSObject of type struct OSArray * with a +1 
retain count}}
+  return arr->getCount(); // expected-note{{Object leaked: object allocated 
and stored into 'arr' is not referenced later in this execution path and has a 
retain count of +1}}
+  // expected-warning@-1{{Potential leak of an object 
stored into 'arr'}}
+}
+
 void check_get_object() {
   OSObject::getObject();
 }


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


r347941 - [analyzer] [NFC] Test dumping trimmed graph

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:17:18 2018
New Revision: 347941

URL: http://llvm.org/viewvc/llvm-project?rev=347941=rev
Log:
[analyzer] [NFC] Test dumping trimmed graph

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

Modified:
cfe/trunk/test/Analysis/dump_egraph.c

Modified: cfe/trunk/test/Analysis/dump_egraph.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dump_egraph.c?rev=347941=347940=347941=diff
==
--- cfe/trunk/test/Analysis/dump_egraph.c (original)
+++ cfe/trunk/test/Analysis/dump_egraph.c Thu Nov 29 18:17:18 2018
@@ -1,5 +1,6 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-dump-egraph=%t.dot 
%s
 // RUN: cat %t.dot | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-dump-egraph=%t.dot 
-trim-egraph %s
 // REQUIRES: asserts
 
 int getJ();


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


r347947 - [attributes] Add a family of OS_CONSUMED, OS_RETURNS and OS_RETURNS_RETAINED attributes

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:18:37 2018
New Revision: 347947

URL: http://llvm.org/viewvc/llvm-project?rev=347947=rev
Log:
[attributes] Add a family of OS_CONSUMED, OS_RETURNS and OS_RETURNS_RETAINED 
attributes

The addition adds three attributes for communicating ownership,
analogous to existing NS_ and CF_ attributes.
The attributes are meant to be used for communicating ownership of all
objects in XNU (Darwin kernel) and all of the kernel modules.
The ownership model there is very similar, but still different from the
Foundation model, so we think that introducing a new family of
attributes is appropriate.

The addition required a sizeable refactoring of the existing code for
CF_ and NS_ ownership attributes, due to tight coupling and the fact
that differentiating between the types was previously done using a
boolean.

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

Added:
cfe/trunk/test/Sema/attr-osobject.cpp
cfe/trunk/test/Sema/attr-osobject.mm
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=347947=347946=347947=diff
==
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Nov 29 18:18:37 2018
@@ -812,19 +812,38 @@ def CFUnknownTransfer : InheritableAttr
 def CFReturnsRetained : InheritableAttr {
   let Spellings = [Clang<"cf_returns_retained">];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def CFReturnsNotRetained : InheritableAttr {
   let Spellings = [Clang<"cf_returns_not_retained">];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def CFConsumed : InheritableParamAttr {
   let Spellings = [Clang<"cf_consumed">];
   let Subjects = SubjectList<[ParmVar]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
+}
+
+// OSObject-based attributes.
+def OSConsumed : InheritableParamAttr {
+  let Spellings = [Clang<"os_consumed">];
+  let Subjects = SubjectList<[ParmVar]>;
+  let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsRetained : InheritableAttr {
+  let Spellings = [Clang<"os_returns_retained">];
+  let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
+  let Documentation = [RetainBehaviorDocs];
+}
+
+def OSReturnsNotRetained : InheritableAttr {
+  let Spellings = [Clang<"os_returns_not_retained">];
+  let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def Cleanup : InheritableAttr {
@@ -1612,19 +1631,19 @@ def ObjCBridgeRelated : InheritableAttr
 def NSReturnsRetained : DeclOrTypeAttr {
   let Spellings = [Clang<"ns_returns_retained">];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def NSReturnsNotRetained : InheritableAttr {
   let Spellings = [Clang<"ns_returns_not_retained">];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def NSReturnsAutoreleased : InheritableAttr {
   let Spellings = [Clang<"ns_returns_autoreleased">];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
-  let Documentation = [Undocumented];
+  let Documentation = [RetainBehaviorDocs];
 }
 
 def NSConsumesSelf : InheritableAttr {

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=347947=347946=347947=diff
==
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Thu Nov 29 18:18:37 2018
@@ -847,6 +847,51 @@ Query for this feature with ``__has_attr
   }];
 }
 
+def RetainBehaviorDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The behavior of a function with respect to reference counting for Foundation
+(Objective-C), CoreFoundation (C) and OSObject (C++) is determined by a naming
+convention (e.g. functions starting with "get" are assumed to return at
+``+0``).
+
+It can be overriden using a family of the following attributes.  In
+Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to
+a function communicates that the object is returned at 

r347943 - [analyzer] Add the type of the leaked object to the diagnostic message

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:17:44 2018
New Revision: 347943

URL: http://llvm.org/viewvc/llvm-project?rev=347943=rev
Log:
[analyzer] Add the type of the leaked object to the diagnostic message

If the object is a temporary, and there is no variable it binds to,
let's at least print out the object name in order to help differentiate
it from other temporaries.

rdar://45175098

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

Modified:

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/test/Analysis/Inputs/expected-plists/objc-arc.m.plist

cfe/trunk/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
cfe/trunk/test/Analysis/objc-radar17039661.m
cfe/trunk/test/Analysis/osobject-retain-release.cpp
cfe/trunk/test/Analysis/retain-release-path-notes.m
cfe/trunk/test/Analysis/retaincountchecker-compoundregion.m

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=347943=347942=347943=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Nov 29 18:17:44 2018
@@ -28,6 +28,17 @@ static bool isNumericLiteralExpression(c
  isa(E);
 }
 
+/// If type represents a pointer to CXXRecordDecl,
+/// and is not a typedef, return the decl name.
+/// Otherwise, return the serialization of type.
+static StringRef getPrettyTypeName(QualType QT) {
+  QualType PT = QT->getPointeeType();
+  if (!PT.isNull() && !QT->getAs())
+if (const auto *RD = PT->getAsCXXRecordDecl())
+  return RD->getName();
+  return QT.getAsString();
+}
+
 /// Write information about the type state change to {@code os},
 /// return whether the note should be generated.
 static bool shouldGenerateNote(llvm::raw_string_ostream ,
@@ -193,7 +204,7 @@ CFRefReportVisitor::VisitNode(const Expl
<< Sym->getType().getAsString() << " with a ";
   } else if (CurrV.getObjKind() == RetEffect::OS) {
 os << " returns an OSObject of type "
-   << Sym->getType().getAsString() << " with a ";
+   << getPrettyTypeName(Sym->getType()) << " with a ";
   } else if (CurrV.getObjKind() == RetEffect::Generalized) {
 os << " returns an object of type " << Sym->getType().getAsString()
<< " with a ";
@@ -432,7 +443,7 @@ CFRefLeakReportVisitor::getEndPath(BugRe
   if (RegionDescription) {
 os << "object allocated and stored into '" << *RegionDescription << '\'';
   } else {
-os << "allocated object";
+os << "allocated object of type " << getPrettyTypeName(Sym->getType());
   }
 
   // Get the retain count.
@@ -472,10 +483,10 @@ CFRefLeakReportVisitor::getEndPath(BugRe
   " Foundation";
   }
 }
-  }
-  else
+  } else {
 os << " is not referenced later in this execution path and has a retain "
   "count of +" << RV->getCount();
+  }
 
   return std::make_shared(L, os.str());
 }
@@ -555,6 +566,10 @@ void CFRefLeakReport::createDescription(
   FullSourceLoc SL(AllocStmt->getBeginLoc(), Ctx.getSourceManager());
   os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
 }
+  } else {
+
+// If we can't figure out the name, just supply the type information.
+os << " of type " << getPrettyTypeName(Sym->getType());
   }
 }
 

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h?rev=347943=347942=347943=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
 Thu Nov 29 18:17:44 2018
@@ -141,12 +141,14 @@ public:
 };
 
 class CFRefReport : public BugReport {
+protected:
+  SymbolRef Sym;
 
 public:
   CFRefReport(CFRefBug , const LangOptions ,
   const SummaryLogTy , ExplodedNode *n, SymbolRef sym,
   bool registerVisitor = true)
-: BugReport(D, D.getDescription(), n) {
+: BugReport(D, D.getDescription(), n), Sym(sym) {
 if (registerVisitor)
   addVisitor(llvm::make_unique(sym, Log));
   }

Modified: cfe/trunk/test/Analysis/Inputs/expected-plists/objc-arc.m.plist
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/expected-plists/objc-arc.m.plist?rev=347943=347942=347943=diff

r347940 - [analyzer] [NFC] Some miscellaneous clean ups and documentation fixes.

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:17:05 2018
New Revision: 347940

URL: http://llvm.org/viewvc/llvm-project?rev=347940=rev
Log:
[analyzer] [NFC] Some miscellaneous clean ups and documentation fixes.

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

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

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

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h?rev=347940=347939=347940=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h Thu Nov 
29 18:17:05 2018
@@ -260,12 +260,12 @@ public:
   public:
 virtual ~BindingsHandler();
 
+/// \return whether the iteration should continue.
 virtual bool HandleBinding(StoreManager& SMgr, Store store,
const MemRegion *region, SVal val) = 0;
   };
 
-  class FindUniqueBinding :
-  public BindingsHandler {
+  class FindUniqueBinding : public BindingsHandler {
 SymbolRef Sym;
 const MemRegion* Binding = nullptr;
 bool First = true;

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=347940=347939=347940=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Nov 29 18:17:05 2018
@@ -28,6 +28,80 @@ static bool isNumericLiteralExpression(c
  isa(E);
 }
 
+/// Write information about the type state change to {@code os},
+/// return whether the note should be generated.
+static bool shouldGenerateNote(llvm::raw_string_ostream ,
+   const RefVal *PrevT, const RefVal ,
+   SmallVector ) {
+  // Get the previous type state.
+  RefVal PrevV = *PrevT;
+
+  // Specially handle -dealloc.
+  if (std::find(AEffects.begin(), AEffects.end(), Dealloc) != AEffects.end()) {
+// Determine if the object's reference count was pushed to zero.
+assert(!PrevV.hasSameState(CurrV) && "The state should have changed.");
+// We may not have transitioned to 'release' if we hit an error.
+// This case is handled elsewhere.
+if (CurrV.getKind() == RefVal::Released) {
+  assert(CurrV.getCombinedCounts() == 0);
+  os << "Object released by directly sending the '-dealloc' message";
+  return true;
+}
+  }
+
+  // Determine if the typestate has changed.
+  if (!PrevV.hasSameState(CurrV))
+switch (CurrV.getKind()) {
+case RefVal::Owned:
+case RefVal::NotOwned:
+  if (PrevV.getCount() == CurrV.getCount()) {
+// Did an autorelease message get sent?
+if (PrevV.getAutoreleaseCount() == CurrV.getAutoreleaseCount())
+  return false;
+
+assert(PrevV.getAutoreleaseCount() < CurrV.getAutoreleaseCount());
+os << "Object autoreleased";
+return true;
+  }
+
+  if (PrevV.getCount() > CurrV.getCount())
+os << "Reference count decremented.";
+  else
+os << "Reference count incremented.";
+
+  if (unsigned Count = CurrV.getCount())
+os << " The object now has a +" << Count << " retain count.";
+
+  return true;
+
+case RefVal::Released:
+  if (CurrV.getIvarAccessHistory() ==
+  RefVal::IvarAccessHistory::ReleasedAfterDirectAccess &&
+  CurrV.getIvarAccessHistory() != PrevV.getIvarAccessHistory()) {
+os << "Strong instance variable relinquished. ";
+  }
+  os << "Object released.";
+  return true;
+
+case RefVal::ReturnedOwned:
+  // Autoreleases can be applied after marking a node ReturnedOwned.
+  if (CurrV.getAutoreleaseCount())
+return false;
+
+  os << "Object returned to caller as an owning reference (single "
+"retain count transferred to caller)";
+  return true;
+
+case RefVal::ReturnedNotOwned:
+  os << "Object returned to caller with a +0 retain count";
+  return true;
+
+default:
+  return false;
+}
+  return true;
+}
+
 std::shared_ptr
 CFRefReportVisitor::VisitNode(const ExplodedNode *N,
   BugReporterContext , BugReport ) {
@@ -64,11 +138,9 @@ CFRefReportVisitor::VisitNode(const Expl
 
 if (isa(S)) {
   os << "NSArray literal is an object with a +0 retain count";
-}
-else if (isa(S)) {
+} else if (isa(S)) {
   os << "NSDictionary literal is an object with a +0 

r347944 - [analyzer] Print a fully qualified name for functions in RetainCountChecker diagnostics

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:17:57 2018
New Revision: 347944

URL: http://llvm.org/viewvc/llvm-project?rev=347944=rev
Log:
[analyzer] Print a fully qualified name for functions in RetainCountChecker 
diagnostics

Attempt to get a fully qualified name from AST if an SVal corresponding
to the object is not available.

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=347944=347943=347944=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Nov 29 18:17:57 2018
@@ -173,10 +173,19 @@ CFRefReportVisitor::VisitNode(const Expl
   os << "Object loaded from instance variable";
 } else {
   if (const CallExpr *CE = dyn_cast(S)) {
-// Get the name of the callee (if it is available).
+// Get the name of the callee (if it is available)
+// from the tracked SVal.
 SVal X = CurrSt->getSValAsScalarOrLoc(CE->getCallee(), LCtx);
-if (const FunctionDecl *FD = X.getAsFunctionDecl()) {
-  os << "Call to function '" << *FD << '\'';
+const FunctionDecl *FD = X.getAsFunctionDecl();
+
+// If failed, try to get it from AST.
+if (!FD)
+  FD = dyn_cast(CE->getCalleeDecl());
+
+if (const auto *MD = dyn_cast(CE->getCalleeDecl())) {
+  os << "Call to method '" << MD->getQualifiedNameAsString() << '\'';
+} else if (FD) {
+  os << "Call to function '" << FD->getQualifiedNameAsString() << '\'';
 } else {
   os << "function call";
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=347944=347943=347944=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Nov 29 18:17:57 2018
@@ -60,14 +60,19 @@ void check_custom_iterator_rule(OSArray
   it->release();
 }
 
+void check_iterator_leak(OSArray *arr) {
+  arr->getIterator(); // expected-note{{Call to method 'OSArray::getIterator' 
returns an OSObject of type struct OSIterator * with a +1 retain count}}
+} // expected-note{{Object leaked: allocated object of type struct OSIterator 
* is not referenced later}}
+  // expected-warning@-1{{Potential leak of an object of type struct 
OSIterator *}}n this execution path and has a retain count of +1}}
+
 void check_no_invalidation() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 
'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain 
count}}
   OtherStruct::doNothingToArray(arr);
 } // expected-warning{{Potential leak of an object stored into 'arr'}}
   // expected-note@-1{{Object leaked}}
 
 void check_no_invalidation_other_struct() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 
'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain 
count}}
   OtherStruct other(arr); // expected-warning{{Potential leak}}
   // expected-note@-1{{Object leaked}}
 }
@@ -94,8 +99,8 @@ struct ArrayOwner : public OSObject {
 };
 
 OSArray *generateArray() {
-  return OSArray::withCapacity(10); // expected-note{{Call to function 
'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
-// expected-note@-1{{Call to function 
'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+  return OSArray::withCapacity(10); // expected-note{{Call to method 
'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
+// expected-note@-1{{Call to method 
'withCapacity' returns an OSObject of type OSArray with a +1 retain count}}
 }
 
 unsigned int check_leak_good_error_message() {
@@ -164,7 +169,7 @@ unsigned int check_dynamic_cast_no_null_
 }
 
 void check_dynamic_cast_null_branch(OSObject *obj) {
-  OSArray *arr1 = OSArray::withCapacity(10); // expected-note{{Call to 
function 

r347951 - [analyzer] Fixes after rebase.

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:19:29 2018
New Revision: 347951

URL: http://llvm.org/viewvc/llvm-project?rev=347951=rev
Log:
[analyzer] Fixes after rebase.

Modified:
cfe/trunk/test/Analysis/osobject-retain-release.cpp
cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=347951=347950=347951=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Nov 29 18:19:29 2018
@@ -75,7 +75,7 @@ void check_free_no_error() {
 }
 
 void check_free_use_after_free() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'OSArray::withCapacity' returns an OSObject of type struct OSArray * with a +1 
retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 
'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain 
count}}
   arr->retain(); // expected-note{{Reference count incremented. The object now 
has a +2 retain count}}
   arr->free(); // expected-note{{Object released}}
   arr->retain(); // expected-warning{{Reference-counted object is used after 
it is released}}
@@ -83,13 +83,13 @@ void check_free_use_after_free() {
 }
 
 unsigned int check_leak_explicit_new() {
-  OSArray *arr = new OSArray; // expected-note{{Operator new returns an 
OSObject of type struct OSArray * with a +1 retain count}}
-  return arr->getCount(); // expected-note{{Object leaked: allocated object of 
type struct OSArray * is not referenced later in this execution path and has a 
retain count of +1}}
-  // expected-warning@-1{{Potential leak of an object 
of type struct OSArray *}}
+  OSArray *arr = new OSArray; // expected-note{{Operator new returns an 
OSObject of type OSArray with a +1 retain count}}
+  return arr->getCount(); // expected-note{{Object leaked: allocated object of 
type OSArray is not referenced later in this execution path and has a retain 
count of +1}}
+  // expected-warning@-1{{Potential leak of an object 
of type OSArray}}
 }
 
 unsigned int check_leak_factory() {
-  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'OSArray::withCapacity' returns an OSObject of type struct OSArray * with a +1 
retain count}}
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to method 
'OSArray::withCapacity' returns an OSObject of type OSArray with a +1 retain 
count}}
   return arr->getCount(); // expected-note{{Object leaked: object allocated 
and stored into 'arr' is not referenced later in this execution path and has a 
retain count of +1}}
   // expected-warning@-1{{Potential leak of an object 
stored into 'arr'}}
 }

Modified: cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test?rev=347951=347950=347951=diff
==
--- cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test 
(original)
+++ cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test Thu Nov 
29 18:19:29 2018
@@ -2,7 +2,7 @@
 
 // The number of supported attributes should never go down!
 
-// CHECK: #pragma clang attribute supports 132 attributes:
+// CHECK: #pragma clang attribute supports 133 attributes:
 // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@@ -86,8 +86,8 @@
 // CHECK-NEXT: NoThrow (SubjectMatchRule_function)
 // CHECK-NEXT: NotTailCalled (SubjectMatchRule_function)
 // CHECK-NEXT: OSConsumed (SubjectMatchRule_variable_is_parameter)
-// CHECK-NEXT: OSReturnsNotRetained (SubjectMatchRule_function, 
SubjectMatchRule_objc_method)
-// CHECK-NEXT: OSReturnsRetained (SubjectMatchRule_function, 
SubjectMatchRule_objc_method)
+// CHECK-NEXT: OSReturnsNotRetained (SubjectMatchRule_function, 
SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
+// CHECK-NEXT: OSReturnsRetained (SubjectMatchRule_function, 
SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
 // CHECK-NEXT: ObjCBoxable (SubjectMatchRule_record)
 // CHECK-NEXT: ObjCBridge (SubjectMatchRule_record, 
SubjectMatchRule_type_alias)
 // CHECK-NEXT: ObjCBridgeMutable (SubjectMatchRule_record)


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


r347946 - [analyzer] [NFC] Minor refactoring of RetainCountDiagnostics

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:18:23 2018
New Revision: 347946

URL: http://llvm.org/viewvc/llvm-project?rev=347946=rev
Log:
[analyzer] [NFC] Minor refactoring of RetainCountDiagnostics

Move visitors to the implementation file, move a complicated logic into
a function.

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

Modified:

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

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=347946=347945=347946=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Nov 29 18:18:23 2018
@@ -39,6 +39,69 @@ ProgramStateRef removeRefBinding(Program
   return State->remove(Sym);
 }
 
+class UseAfterRelease : public CFRefBug {
+public:
+  UseAfterRelease(const CheckerBase *checker)
+  : CFRefBug(checker, "Use-after-release") {}
+
+  const char *getDescription() const override {
+return "Reference-counted object is used after it is released";
+  }
+};
+
+class BadRelease : public CFRefBug {
+public:
+  BadRelease(const CheckerBase *checker) : CFRefBug(checker, "Bad release") {}
+
+  const char *getDescription() const override {
+return "Incorrect decrement of the reference count of an object that is "
+   "not owned at this point by the caller";
+  }
+};
+
+class DeallocNotOwned : public CFRefBug {
+public:
+  DeallocNotOwned(const CheckerBase *checker)
+  : CFRefBug(checker, "-dealloc sent to non-exclusively owned object") {}
+
+  const char *getDescription() const override {
+return "-dealloc sent to object that may be referenced elsewhere";
+  }
+};
+
+class OverAutorelease : public CFRefBug {
+public:
+  OverAutorelease(const CheckerBase *checker)
+  : CFRefBug(checker, "Object autoreleased too many times") {}
+
+  const char *getDescription() const override {
+return "Object autoreleased too many times";
+  }
+};
+
+class ReturnedNotOwnedForOwned : public CFRefBug {
+public:
+  ReturnedNotOwnedForOwned(const CheckerBase *checker)
+  : CFRefBug(checker, "Method should return an owned object") {}
+
+  const char *getDescription() const override {
+return "Object with a +0 retain count returned to caller where a +1 "
+   "(owning) retain count is expected";
+  }
+};
+
+class Leak : public CFRefBug {
+public:
+  Leak(const CheckerBase *checker, StringRef name) : CFRefBug(checker, name) {
+// Leaks should not be reported if they are post-dominated by a sink.
+setSuppressOnSink(true);
+  }
+
+  const char *getDescription() const override { return ""; }
+
+  bool isLeak() const override { return true; }
+};
+
 } // end namespace retaincountchecker
 } // end namespace ento
 } // end namespace clang
@@ -350,6 +413,56 @@ void RetainCountChecker::checkPostCall(c
   checkSummary(*Summ, Call, C);
 }
 
+void RetainCountChecker::checkEndAnalysis(ExplodedGraph , BugReporter ,
+  ExprEngine ) const {
+  // FIXME: This is a hack to make sure the summary log gets cleared between
+  // analyses of different code bodies.
+  //
+  // Why is this necessary? Because a checker's lifetime is tied to a
+  // translation unit, but an ExplodedGraph's lifetime is just a code body.
+  // Once in a blue moon, a new ExplodedNode will have the same address as an
+  // old one with an associated summary, and the bug report visitor gets very
+  // confused. (To make things worse, the summary lifetime is currently also
+  // tied to a code body, so we get a crash instead of incorrect results.)
+  //
+  // Why is this a bad solution? Because if the lifetime of the ExplodedGraph
+  // changes, things will start going wrong again. Really the lifetime of this
+  // log needs to be tied to either the specific nodes in it or the entire
+  // ExplodedGraph, not to a specific part of the code being analyzed.
+  //
+  // (Also, having stateful local data means that the same checker can't be
+  // used from multiple threads, but a lot of checkers have incorrect
+  // assumptions about that anyway. So that wasn't a priority at the time of
+  // this fix.)
+  //
+  // This happens at the end of analysis, but bug reports are emitted /after/
+  // this point. So we can't just clear the summary log now. Instead, we mark
+  // that the next time we access the summary log, it should be 

r347948 - [analyzer] Switch retain count checker for OSObject to use OS_* attributes

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:18:50 2018
New Revision: 347948

URL: http://llvm.org/viewvc/llvm-project?rev=347948=rev
Log:
[analyzer] Switch retain count checker for OSObject to use OS_* attributes

Instead of generalized reference counting annotations.

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=347948=347947=347948=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Nov 29 18:18:50 2018
@@ -526,7 +526,8 @@ CFRefLeakReportVisitor::getEndPath(BugRe
   os << "that is annotated as CF_RETURNS_NOT_RETAINED";
 } else if (D->hasAttr()) {
   os << "that is annotated as NS_RETURNS_NOT_RETAINED";
-  // TODO: once the patch is ready, insert a case for 
OS_RETURNS_NOT_RETAINED
+} else if (D->hasAttr()) {
+  os << "that is annotated as OS_RETURNS_NOT_RETAINED";
 } else {
   if (const ObjCMethodDecl *MD = dyn_cast(D)) {
 if (BRC.getASTContext().getLangOpts().ObjCAutoRefCount) {

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=347948=347947=347948=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Nov 29 
18:18:50 2018
@@ -664,15 +664,21 @@ RetainSummaryManager::getRetEffectFromAn
 return None;
   }
 
-  if (D->hasAttr())
+  if (D->hasAttr()) {
 return RetEffect::MakeOwned(RetEffect::CF);
-  else if (hasRCAnnotation(D, "rc_ownership_returns_retained"))
+  } else if (D->hasAttr()) {
+return RetEffect::MakeOwned(RetEffect::OS);
+  } else if (hasRCAnnotation(D, "rc_ownership_returns_retained")) {
 return RetEffect::MakeOwned(RetEffect::Generalized);
+  }
 
-  if (D->hasAttr())
+  if (D->hasAttr()) {
 return RetEffect::MakeNotOwned(RetEffect::CF);
-  else if (hasRCAnnotation(D, "rc_ownership_returns_not_retained"))
+  } else if (D->hasAttr()) {
+return RetEffect::MakeNotOwned(RetEffect::OS);
+  } else if (hasRCAnnotation(D, "rc_ownership_returns_not_retained")) {
 return RetEffect::MakeNotOwned(RetEffect::Generalized);
+  }
 
   return None;
 }
@@ -688,15 +694,16 @@ RetainSummaryManager::updateSummaryFromA
 
   // Effects on the parameters.
   unsigned parm_idx = 0;
-  for (FunctionDecl::param_const_iterator pi = FD->param_begin(),
+  for (auto pi = FD->param_begin(),
  pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {
 const ParmVarDecl *pd = *pi;
-if (pd->hasAttr())
+if (pd->hasAttr()) {
   Template->addArg(AF, parm_idx, DecRefMsg);
-else if (pd->hasAttr() ||
- hasRCAnnotation(pd, "rc_ownership_consumed"))
+} else if (pd->hasAttr() ||
+ pd->hasAttr() ||
+ hasRCAnnotation(pd, "rc_ownership_consumed")) {
   Template->addArg(AF, parm_idx, DecRef);
-else if (pd->hasAttr() ||
+} else if (pd->hasAttr() ||
  hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
   QualType PointeeTy = pd->getType()->getPointeeType();
   if (!PointeeTy.isNull())
@@ -734,9 +741,9 @@ RetainSummaryManager::updateSummaryFromA
  pi=MD->param_begin(), pe=MD->param_end();
pi != pe; ++pi, ++parm_idx) {
 const ParmVarDecl *pd = *pi;
-if (pd->hasAttr())
+if (pd->hasAttr()) {
   Template->addArg(AF, parm_idx, DecRefMsg);
-else if (pd->hasAttr()) {
+} else if (pd->hasAttr() || pd->hasAttr()) 
{
   Template->addArg(AF, parm_idx, DecRef);
 } else if (pd->hasAttr()) {
   QualType PointeeTy = pd->getType()->getPointeeType();

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=347948=347947=347948=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Nov 29 18:18:50 2018
@@ -2,9 +2,9 @@
 
 struct OSMetaClass;
 
-#define OS_CONSUME __attribute__((annotate("rc_ownership_consumed")))
-#define OS_RETURNS_RETAINED 
__attribute__((annotate("rc_ownership_returns_retained")))
-#define OS_RETURNS_NOT_RETAINED 

r347942 - [analyzer] Reference leaked object by name, even if it was created in an inlined function.

2018-11-29 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Nov 29 18:17:31 2018
New Revision: 347942

URL: http://llvm.org/viewvc/llvm-project?rev=347942=rev
Log:
[analyzer] Reference leaked object by name, even if it was created in an 
inlined function.

rdar://45532181

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

Modified:

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

cfe/trunk/test/Analysis/Inputs/expected-plists/retain-release-path-notes.m.plist
cfe/trunk/test/Analysis/osobject-retain-release.cpp
cfe/trunk/test/Analysis/retain-release-path-notes.m

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp?rev=347942=347941=347942=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 (original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp
 Thu Nov 29 18:17:31 2018
@@ -306,9 +306,8 @@ struct AllocationInfo {
 };
 } // end anonymous namespace
 
-static AllocationInfo
-GetAllocationSite(ProgramStateManager& StateMgr, const ExplodedNode *N,
-  SymbolRef Sym) {
+static AllocationInfo GetAllocationSite(ProgramStateManager ,
+const ExplodedNode *N, SymbolRef Sym) {
   const ExplodedNode *AllocationNode = N;
   const ExplodedNode *AllocationNodeInCurrentOrParentContext = N;
   const MemRegion *FirstBinding = nullptr;
@@ -353,9 +352,9 @@ GetAllocationSite(ProgramStateManager& S
 // Find the last init that was called on the given symbol and store the
 // init method's location context.
 if (!InitMethodContext)
-  if (Optional CEP = N->getLocation().getAs()) {
+  if (auto CEP = N->getLocation().getAs()) {
 const Stmt *CE = CEP->getCallExpr();
-if (const ObjCMessageExpr *ME = dyn_cast_or_null(CE)) 
{
+if (const auto *ME = dyn_cast_or_null(CE)) {
   const Stmt *RecExpr = ME->getInstanceReceiver();
   if (RecExpr) {
 SVal RecV = St->getSVal(RecExpr, NContext);
@@ -365,7 +364,7 @@ GetAllocationSite(ProgramStateManager& S
 }
   }
 
-N = N->pred_empty() ? nullptr : *(N->pred_begin());
+N = N->getFirstPred();
   }
 
   // If we are reporting a leak of the object that was allocated with alloc,
@@ -382,9 +381,11 @@ GetAllocationSite(ProgramStateManager& S
   // If allocation happened in a function different from the leak node context,
   // do not report the binding.
   assert(N && "Could not find allocation node");
-  if (N->getLocationContext() != LeakContext) {
+
+  if (AllocationNodeInCurrentOrParentContext &&
+  AllocationNodeInCurrentOrParentContext->getLocationContext() !=
+  LeakContext)
 FirstBinding = nullptr;
-  }
 
   return AllocationInfo(AllocationNodeInCurrentOrParentContext,
 FirstBinding,
@@ -409,8 +410,7 @@ CFRefLeakReportVisitor::getEndPath(BugRe
   // We are reporting a leak.  Walk up the graph to get to the first node where
   // the symbol appeared, and also get the first VarDecl that tracked object
   // is stored to.
-  AllocationInfo AllocI =
-GetAllocationSite(BRC.getStateManager(), EndN, Sym);
+  AllocationInfo AllocI = GetAllocationSite(BRC.getStateManager(), EndN, Sym);
 
   const MemRegion* FirstBinding = AllocI.R;
   BR.markInteresting(AllocI.InterestingMethodContext);
@@ -448,11 +448,12 @@ CFRefLeakReportVisitor::getEndPath(BugRe
 os << (isa(D) ? " is returned from a method "
   : " is returned from a function ");
 
-if (D->hasAttr())
+if (D->hasAttr()) {
   os << "that is annotated as CF_RETURNS_NOT_RETAINED";
-else if (D->hasAttr())
+} else if (D->hasAttr()) {
   os << "that is annotated as NS_RETURNS_NOT_RETAINED";
-else {
+  // TODO: once the patch is ready, insert a case for 
OS_RETURNS_NOT_RETAINED
+} else {
   if (const ObjCMethodDecl *MD = dyn_cast(D)) {
 if (BRC.getASTContext().getLangOpts().ObjCAutoRefCount) {
   os << "managed by Automatic Reference Counting";
@@ -497,7 +498,8 @@ void CFRefLeakReport::deriveParamLocatio
   }
 }
 
-void CFRefLeakReport::deriveAllocLocation(CheckerContext ,SymbolRef sym) {
+void CFRefLeakReport::deriveAllocLocation(CheckerContext ,
+  SymbolRef sym) {
   // Most bug reports are cached at the location where they occurred.
   // With leaks, we want to unique them by the location where they were
   // allocated, and only report a single path.  To do this, we need to find
@@ -511,7 +513,7 @@ void CFRefLeakReport::deriveAllocLocatio
   const SourceManager& SMgr = Ctx.getSourceManager();
 
   AllocationInfo AllocI =
-GetAllocationSite(Ctx.getStateManager(), 

Re: [cfe-dev] Dumping AST information to other formats

2018-11-29 Thread George Karpenkov via cfe-commits
Hi Aaron,

You might find useful the recent work we have done on stable identifiers for 
AST:
now Stmt and Decl classes have a “getID” method,
which returns an identifier stable across different runs (at least on the same 
architecture, probably not the same for different ones).

George

> On Nov 27, 2018, at 6:22 AM, Aaron Ballman via cfe-dev 
>  wrote:
> 
> On Tue, Nov 27, 2018 at 4:50 AM Stephen Kelly via cfe-commits
> mailto:cfe-commits@lists.llvm.org>> wrote:
>> 
>> On 26/11/2018 19:20, Aaron Ballman via cfe-commits wrote:
>>> Once upon a time, there was -ast-print-xml. This -cc1 option was
>>> dropped because it was frequently out of sync with the AST data. It is
>>> right to ask: why would JSON, etc be any different? This is still an
>>> open question, but a goal of this implementation will be to ensure
>>> it's easier to maintain as the AST evolves. However, this feature is
>>> intended to output a safe subset of AST information, so I don't think
>>> this feature will require any more burden to support than -ast-dump
>>> already requires (which is extremely limited).
>> 
>>> I wanted to see if there were concerns or implementation ideas the
>>> community wanted to share before beginning the implementation phase of
>>> this feature.
>> 
>> Hi Aaron,
>> 
>> As you know, I've already done some work in this area.
>> 
>> I split the ASTDumper.cpp into multiple classes so that the traversal of
>> the AST is separate to the printing of it to the output stream. You can
>> see the proof of concept here:
>> 
>>  https://github.com/steveire/clang/commits/extract-AST-dumping
>> 
>> though it is not ready for a real review. I just extracted it to a
>> branch for the purpose of this mailing list reply.
>> 
>> In my branch there are two implementations of outputter - one detailed
>> and one 'simplified' AST. You can see the difference here:
>> 
>>  http://ec2-52-14-16-249.us-east-2.compute.amazonaws.com:10240/z/JuAvs8
>> 
>> Because the traversal is in a separate class, it should be possible to
>> port ASTMatchFinder.cpp to use it, which will eliminate the class of
>> bugs that arise due to ASTMatchFinder.cpp currently using RAV. Here is
>> one such bug:
>> 
>>  https://bugs.llvm.org/show_bug.cgi?id=37629
>> 
>> but there are others for example relating to getting to a
>> CXXConstructorDecl from a CXXCtorInitializer, so it is a class of bug
>> rather than a single bug.
>> 
>> Because the traversal is in a separate class, you should be able to also
>> implement it for different output formats without a significant
>> maintenance burden.
>> 
>> Using this approach, the output formats will not get out of sync and
>> fall to the same fate as the XML output feature.
>> 
>> Let me know if you're interested.
> 
> Thank you for passing this along -- it's actually somewhat aligned
> with what I was envisioning. I very much like splitting out the
> traversal and the printing mechanisms.
> 
> Would you like to be included on the review thread when I submit a patch?
> 
> ~Aaron
> ___
> cfe-dev mailing list
> cfe-...@lists.llvm.org 
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev 
> 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r345099 - [analyzer] Trust summaries for OSObject::retain and OSObject::release

2018-11-26 Thread George Karpenkov via cfe-commits
The error is indeed strange.
The body is declared as

  LazyDeclStmtPtr Body;

where

using LazyDeclStmtPtr =
LazyOffsetPtr;

where

template
struct LazyOffsetPtr {
  mutable uint64_t Ptr = 0;
(…)
  explicit operator bool() const { return Ptr != 0; }
(…)
}

so it does not seem like it can be uninitialized.
Sadly on macOS I don’t have either valgrind or msan,
so I can’t reproduce the failure.
Do you think you could debug further?
Is “Body” indeed uninitialized at use time? (e.g. if you print it..)
A stacktrace from a debug build should be helpful.

Thanks,
George

> On Nov 26, 2018, at 12:03 AM, Mikael Holmén  
> wrote:
> 
> Hi again,
> 
> Do you have any opinion about the below valgrind complaint that starts 
> appearing with this patch?
> 
> valgrind still complains on it on current trunk.
> 
> I see it when compiling with clang 3.6.0. I've also tried gcc 5.4.0 but 
> then I don't get it.
> 
> Regards,
> Mikael
> 
> On 11/21/18 8:33 AM, Mikael Holmén via cfe-commits wrote:
>> Hi George,
>> 
>> I noticed that valgrind started complaining in one case with this patch.
>> 
>> I've no idea if it's really due to something in the patch or if it's
>> something old that surfaced or if it's a false flag.
>> 
>> Anyway, with this patch the following
>> 
>>   valgrind clang-tidy -checks='-*,clang-analyzer-*' 'memcpy.c' -- -O0
>> 
>> gives me
>> 
>> ==18829== Memcheck, a memory error detector
>> ==18829== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
>> ==18829== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
>> ==18829== Command: build-all/bin/clang-tidy -checks=-*,clang-analyzer-*
>> memcpy.c -- -O0
>> ==18829==
>> ==18829== Conditional jump or move depends on uninitialised value(s)
>> ==18829==at 0xE580DF:
>> clang::ento::RetainSummaryManager::canEval(clang::CallExpr const*,
>> clang::FunctionDecl const*, bool&) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xD034AA:
>> clang::ento::retaincountchecker::RetainCountChecker::evalCall(clang::CallExpr
>> const*, clang::ento::CheckerContext&) const (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xDCBCD7:
>> clang::ento::CheckerManager::runCheckersForEvalCall(clang::ento::ExplodedNodeSet&,
>> clang::ento::ExplodedNodeSet const&, clang::ento::CallEvent const&,
>> clang::ento::ExprEngine&) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xE033D5:
>> clang::ento::ExprEngine::evalCall(clang::ento::ExplodedNodeSet&,
>> clang::ento::ExplodedNode*, clang::ento::CallEvent const&) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xE03165:
>> clang::ento::ExprEngine::VisitCallExpr(clang::CallExpr const*,
>> clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xDE3D9A: clang::ento::ExprEngine::Visit(clang::Stmt
>> const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xDDEFD1:
>> clang::ento::ExprEngine::ProcessStmt(clang::Stmt const*,
>> clang::ento::ExplodedNode*) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xDDEBBC:
>> clang::ento::ExprEngine::processCFGElement(clang::CFGElement,
>> clang::ento::ExplodedNode*, unsigned int,
>> clang::ento::NodeBuilderContext*) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xDD3154:
>> clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned
>> int, clang::ento::ExplodedNode*) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xDD24D3:
>> clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*,
>> unsigned int, llvm::IntrusiveRefCntPtr)
>> (in /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xB8E90E: (anonymous
>> namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int,
>> clang::ento::ExprEngine::InliningModes, llvm::DenseSet> const*, llvm::DenseMapInfo >*) (in
>> /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==by 0xB89943: (anonymous
>> namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&)
>> (in /data/repo/llvm-patch/build-all/bin/clang-tidy)
>> ==18829==
>> 
>> The call to
>> 
>>  const FunctionDecl* FDD = FD->getDefinition();
>> 
>> in RetainSummaryManager::canEval eventually ends up in
>> 
>&

r346028 - [analyzer] Fixup of the module build after https://reviews.llvm.org/D53277

2018-11-02 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Fri Nov  2 11:28:52 2018
New Revision: 346028

URL: http://llvm.org/viewvc/llvm-project?rev=346028=rev
Log:
[analyzer] Fixup of the module build after https://reviews.llvm.org/D53277

Adds AnalyzerOptions.def to the list of textual headers.

Modified:
cfe/trunk/include/clang/module.modulemap

Modified: cfe/trunk/include/clang/module.modulemap
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/module.modulemap?rev=346028=346027=346028=diff
==
--- cfe/trunk/include/clang/module.modulemap (original)
+++ cfe/trunk/include/clang/module.modulemap Fri Nov  2 11:28:52 2018
@@ -128,6 +128,7 @@ module Clang_StaticAnalyzer_Core {
   umbrella "StaticAnalyzer/Core"
 
   textual header "StaticAnalyzer/Core/Analyses.def"
+  textual header "StaticAnalyzer/Core/AnalyzerOptions.def"
   textual header "StaticAnalyzer/Core/PathSensitive/SVals.def"
   textual header "StaticAnalyzer/Core/PathSensitive/Symbols.def"
   textual header "StaticAnalyzer/Core/PathSensitive/Regions.def"


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


r345747 - [analyzer] Re-add custom OSIterator rule for RetainCountChecker

2018-10-31 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Oct 31 10:38:46 2018
New Revision: 345747

URL: http://llvm.org/viewvc/llvm-project?rev=345747=rev
Log:
[analyzer] Re-add custom OSIterator rule for RetainCountChecker

Turns out the rule is quite ubiquitous.

Revert of https://reviews.llvm.org/D53628

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345747=345746=345747=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Wed Oct 31 
10:38:46 2018
@@ -69,6 +69,10 @@ static bool isOSObjectDynamicCast(String
   return S == "safeMetaCast";
 }
 
+static bool isOSIteratorSubclass(const Decl *D) {
+  return isSubclass(D, "OSIterator");
+}
+
 static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation) {
   for (const auto *Ann : D->specific_attrs()) {
 if (Ann->getAnnotation() == rcAnnotation)
@@ -235,11 +239,12 @@ RetainSummaryManager::generateSummary(co
 if (isOSObjectDynamicCast(II->getName()))
   return getDefaultSummary();
 
-// All objects returned with functions starting with "get" are getters.
-if (II->getName().startswith("get")) {
-  return getOSSummaryGetRule(FD);
-} else {
+// All objects returned with functions *not* starting with
+// get, or iterators, are returned at +1.
+if (!II->getName().startswith("get") || isOSIteratorSubclass(PD)) {
   return getOSSummaryCreateRule(FD);
+} else {
+  return getOSSummaryGetRule(FD);
 }
   }
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345747=345746=345747=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Wed Oct 31 10:38:46 2018
@@ -23,6 +23,9 @@ struct OSObject {
   static const OSMetaClass * const metaClass;
 };
 
+struct OSIterator : public OSObject {
+};
+
 struct OSArray : public OSObject {
   unsigned int getCount();
 
@@ -33,6 +36,8 @@ struct OSArray : public OSObject {
 return nullptr;
   }
 
+  OSIterator * getIterator();
+
   static OS_RETURNS_NOT_RETAINED OSArray *MaskedGetter();
   static OS_RETURNS_RETAINED OSArray *getOoopsActuallyCreate();
 
@@ -49,6 +54,11 @@ struct OSMetaClassBase {
   static OSObject *safeMetaCast(const OSObject *inst, const OSMetaClass *meta);
 };
 
+void check_custom_iterator_rule(OSArray *arr) {
+  OSIterator *it = arr->getIterator();
+  it->release();
+}
+
 void check_no_invalidation() {
   OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain 
count}}
   OtherStruct::doNothingToArray(arr);


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


r345746 - [analyzer] RetainCountChecker: for now, do not trust the summaries of inlined code

2018-10-31 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Oct 31 10:38:29 2018
New Revision: 345746

URL: http://llvm.org/viewvc/llvm-project?rev=345746=rev
Log:
[analyzer] RetainCountChecker: for now, do not trust the summaries of inlined 
code

Trusting summaries of inlined code would require a more thorough work,
as the current approach was causing too many false positives, as the new
example in test.  The culprit lies in the fact that we currently escape
all variables written into a field (but not passed off to unknown
functions!), which can result in inconsistent behavior.

rdar://45655344

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=345746=345745=345746=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Wed Oct 31 10:38:29 2018
@@ -420,13 +420,6 @@ void RetainCountChecker::processSummaryO
   RetEffect RE = Summ.getRetEffect();
 
   if (SymbolRef Sym = CallOrMsg.getReturnValue().getAsSymbol()) {
-if (const auto *MCall = dyn_cast()) {
-  if (Optional updatedRefVal =
-  refValFromRetEffect(RE, MCall->getResultType())) {
-state = setRefBinding(state, Sym, *updatedRefVal);
-  }
-}
-
 if (RE.getKind() == RetEffect::NoRetHard)
   state = removeRefBinding(state, Sym);
   }
@@ -1103,9 +1096,8 @@ RetainCountChecker::checkRegionChanges(P
   WhitelistedSymbols.insert(SR->getSymbol());
   }
 
-  for (InvalidatedSymbols::const_iterator I=invalidated->begin(),
-   E = invalidated->end(); I!=E; ++I) {
-SymbolRef sym = *I;
+  for (SymbolRef sym :
+   llvm::make_range(invalidated->begin(), invalidated->end())) {
 if (WhitelistedSymbols.count(sym))
   continue;
 // Remove any existing reference-count binding.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345746=345745=345746=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Wed Oct 31 
10:38:29 2018
@@ -101,10 +101,11 @@ static bool isOSObjectRelated(const CXXM
 return true;
 
   for (ParmVarDecl *Param : MD->parameters()) {
-QualType PT = Param->getType();
-if (CXXRecordDecl *RD = PT->getPointeeType()->getAsCXXRecordDecl())
-  if (isOSObjectSubclass(RD))
-return true;
+QualType PT = Param->getType()->getPointeeType();
+if (!PT.isNull())
+  if (CXXRecordDecl *RD = PT->getAsCXXRecordDecl())
+if (isOSObjectSubclass(RD))
+  return true;
   }
 
   return false;

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345746=345745=345746=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Wed Oct 31 10:38:29 2018
@@ -2,10 +2,9 @@
 
 struct OSMetaClass;
 
-#define TRUSTED 
__attribute__((annotate("rc_ownership_trusted_implementation")))
-#define OS_CONSUME TRUSTED __attribute__((annotate("rc_ownership_consumed")))
-#define OS_RETURNS_RETAINED TRUSTED 
__attribute__((annotate("rc_ownership_returns_retained")))
-#define OS_RETURNS_NOT_RETAINED TRUSTED 
__attribute__((annotate("rc_ownership_returns_not_retained")))
+#define OS_CONSUME __attribute__((annotate("rc_ownership_consumed")))
+#define OS_RETURNS_RETAINED 
__attribute__((annotate("rc_ownership_returns_retained")))
+#define OS_RETURNS_NOT_RETAINED 
__attribute__((annotate("rc_ownership_returns_not_retained")))
 
 #define OSTypeID(type)   (type::metaClass)
 
@@ -62,6 +61,37 @@ void check_no_invalidation_other_struct(
   // expected-note@-1{{Object leaked}}
 }
 
+struct ArrayOwner : public OSObject {
+  OSArray *arr;
+  ArrayOwner(OSArray *arr) : arr(arr) {}
+
+  static ArrayOwner* create(OSArray *arr) {
+return new ArrayOwner(arr);
+  }
+
+  OSArray *getArray() {
+return arr;
+  }
+
+  OSArray *createArray() {
+return OSArray::withCapacity(10);
+  }
+
+  OSArray *createArraySourceUnknown();
+
+  OSArray *getArraySourceUnknown();
+};
+
+void check_confusing_getters() {
+  OSArray *arr = 

r345745 - [analyzer] Enable retain count checking for OSObject by defa

2018-10-31 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Wed Oct 31 10:38:12 2018
New Revision: 345745

URL: http://llvm.org/viewvc/llvm-project?rev=345745=rev
Log:
[analyzer] Enable retain count checking for OSObject by defa

The FP rate seems to be good enough now.

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h?rev=345745=345744=345745=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h 
Wed Oct 31 10:38:12 2018
@@ -282,7 +282,7 @@ public:
   ~RetainCountChecker() override { DeleteContainerSeconds(DeadSymbolTags); }
 
   bool shouldCheckOSObjectRetainCount() const {
-return Options.getBooleanOption("CheckOSObject", false, this);
+return Options.getBooleanOption("CheckOSObject", true, this);
   }
 
   void checkEndAnalysis(ExplodedGraph , BugReporter ,

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345745=345744=345745=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Wed Oct 31 10:38:12 2018
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyze 
-analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config 
osx.cocoa.RetainCount:CheckOSObject=true -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyze 
-analyzer-checker=core,osx.cocoa.RetainCount -analyzer-output=text -verify %s
 
 struct OSMetaClass;
 


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


r345341 - [analyzer] Fix a bug in "collapsed" graph viewer

2018-10-25 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Oct 25 16:38:58 2018
New Revision: 345341

URL: http://llvm.org/viewvc/llvm-project?rev=345341=rev
Log:
[analyzer] Fix a bug in "collapsed" graph viewer

Nodes which have only one predecessor and only one successor can not
always be hidden, even if all states are the same.
An additional condition is needed: the predecessor may have only one successor.
This can be seen on this example:

```
  A
 / \
B   C
 \ /
  D
```

Nodes B and C can not be hidden even if all nodes in the graph have the
same state.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp

Modified: 
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h?rev=345341=345340=345341=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h 
Thu Oct 25 16:38:58 2018
@@ -210,10 +210,14 @@ public:
 return const_cast(this)->getFirstPred();
   }
 
-  const ExplodedNode *getFirstSucc() const {
+  ExplodedNode *getFirstSucc() {
 return succ_empty() ? nullptr : *(succ_begin());
   }
 
+  const ExplodedNode *getFirstSucc() const {
+return const_cast(this)->getFirstSucc();
+  }
+
   // Iterators over successor and predecessor vertices.
   using succ_iterator = ExplodedNode * const *;
   using const_succ_iterator = const ExplodedNode * const *;
@@ -243,8 +247,10 @@ public:
   int64_t getID(ExplodedGraph *G) const;
 
   /// The node is trivial if it has only one successor, only one predecessor,
+  /// it's predecessor has only one successor,
   /// and its program state is the same as the program state of the previous
   /// node.
+  /// Trivial nodes may be skipped while printing exploded graph.
   bool isTrivial() const;
 
 private:
@@ -460,7 +466,6 @@ public:
 // GraphTraits
 
 namespace llvm {
-
   template <> struct GraphTraits {
 using GraphTy = clang::ento::ExplodedGraph *;
 using NodeRef = clang::ento::ExplodedNode *;
@@ -471,17 +476,19 @@ namespace llvm {
   return *G->roots_begin();
 }
 
+static bool predecessorOfTrivial(NodeRef N) {
+  return N->succ_size() == 1 && N->getFirstSucc()->isTrivial();
+}
+
 static ChildIteratorType child_begin(NodeRef N) {
-  if (N->succ_size() == 1 && (*N->succ_begin())->isTrivial()) {
+  if (predecessorOfTrivial(N))
 return child_begin(*N->succ_begin());
-  }
   return N->succ_begin();
 }
 
 static ChildIteratorType child_end(NodeRef N) {
-  if (N->succ_size() == 1 && (*N->succ_begin())->isTrivial()) {
-return child_end(*N->succ_begin());
-  }
+  if (predecessorOfTrivial(N))
+return child_end(N->getFirstSucc());
   return N->succ_end();
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp?rev=345341=345340=345341=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExplodedGraph.cpp Thu Oct 25 16:38:58 2018
@@ -292,7 +292,8 @@ int64_t ExplodedNode::getID(ExplodedGrap
 
 bool ExplodedNode::isTrivial() const {
   return pred_size() == 1 && succ_size() == 1 &&
- (*pred_begin())->getState()->getID() == getState()->getID();
+ getFirstPred()->getState()->getID() == getState()->getID() &&
+ getFirstPred()->succ_size() == 1;
 }
 
 ExplodedNode *ExplodedGraph::getNode(const ProgramPoint ,


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


r345338 - [analyzer] Correct modelling of OSDynamicCast: eagerly state split

2018-10-25 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Oct 25 16:38:07 2018
New Revision: 345338

URL: http://llvm.org/viewvc/llvm-project?rev=345338=rev
Log:
[analyzer] Correct modelling of OSDynamicCast: eagerly state split

Previously, OSDynamicCast was modeled as an identity.

This is not correct: the output of OSDynamicCast may be zero even if the
input was not zero (if the class is not of desired type), and thus the
modeling led to false positives.

Instead, we are doing eager state split:
in one branch, the returned value is identical to the input parameter,
and in the other branch, the returned value is zero.

This patch required a substantial refactoring of canEval infrastructure,
as now it can return different function summaries, and not just true/false.

rdar://45497400

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

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

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=345338=345337=345338=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Oct 
25 16:38:07 2018
@@ -636,9 +636,19 @@ public:
 InitializeMethodSummaries();
   }
 
-  bool canEval(const CallExpr *CE,
-   const FunctionDecl *FD,
-   bool );
+  enum class BehaviorSummary {
+// Function does not return.
+NoOp,
+
+// Function returns the first argument.
+Identity,
+
+// Function either returns zero, or the input parameter.
+IdentityOrZero
+  };
+
+  Optional canEval(const CallExpr *CE, const FunctionDecl *FD,
+bool );
 
   bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
 

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=345338=345337=345338=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Thu Oct 25 16:38:07 2018
@@ -774,14 +774,17 @@ bool RetainCountChecker::evalCall(const
 
   const LocationContext *LCtx = C.getLocationContext();
 
+  using BehaviorSummary = RetainSummaryManager::BehaviorSummary;
+  Optional BSmr =
+  SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation);
+
   // See if it's one of the specific functions we know how to eval.
-  if (!SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation))
+  if (!BSmr)
 return false;
 
   // Bind the return value.
-  // For now, all the functions which we can evaluate and which take
-  // at least one argument are identities.
-  if (CE->getNumArgs() >= 1) {
+  if (BSmr == BehaviorSummary::Identity ||
+  BSmr == BehaviorSummary::IdentityOrZero) {
 SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
 
 // If the receiver is unknown or the function has
@@ -793,7 +796,24 @@ bool RetainCountChecker::evalCall(const
   RetVal =
   SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
 }
-state = state->BindExpr(CE, LCtx, RetVal, false);
+state = state->BindExpr(CE, LCtx, RetVal, /*Invalidate=*/false);
+
+if (BSmr == BehaviorSummary::IdentityOrZero) {
+  // Add a branch where the output is zero.
+  ProgramStateRef NullOutputState = C.getState();
+
+  // Assume that output is zero on the other branch.
+  NullOutputState = NullOutputState->BindExpr(
+  CE, LCtx, C.getSValBuilder().makeNull(), /*Invalidate=*/false);
+
+  C.addTransition(NullOutputState);
+
+  // And on the original branch assume that both input and
+  // output are non-zero.
+  if (auto L = RetVal.getAs())
+state = state->assume(*L, /*Assumption=*/true);
+
+}
   }
 
   C.addTransition(state);

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345338=345337=345338=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Oct 25 
16:38:07 2018
@@ -65,6 +65,10 @@ static bool isOSObjectSubclass(const Dec
   return isSubclass(D, "OSObject");
 }
 
+static 

r345340 - [analyzer] [RetainCountChecker] Do not invalidate references passed to constructors and operators

2018-10-25 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Oct 25 16:38:41 2018
New Revision: 345340

URL: http://llvm.org/viewvc/llvm-project?rev=345340=rev
Log:
[analyzer] [RetainCountChecker] Do not invalidate references passed to 
constructors and operators

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h?rev=345340=345339=345340=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/RetainSummaryManager.h Thu Oct 
25 16:38:41 2018
@@ -139,7 +139,7 @@ public:
 OwnedWhenTrackedReceiver,
 // Treat this function as returning a non-tracked symbol even if
 // the function has been inlined. This is used where the call
-// site summary is more presise than the summary indirectly produced
+// site summary is more precise than the summary indirectly produced
 // by inlining the function
 NoRetHard
   };

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345340=345339=345340=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Oct 25 
16:38:41 2018
@@ -478,8 +478,12 @@ RetainSummaryManager::getSummary(const C
 Summ = getFunctionSummary(cast(Call).getDecl());
 break;
   case CE_CXXMemberOperator:
-  case CE_Block:
+Summ = getFunctionSummary(cast(Call).getDecl());
+break;
   case CE_CXXConstructor:
+Summ = getFunctionSummary(cast(Call).getDecl());
+break;
+  case CE_Block:
   case CE_CXXDestructor:
   case CE_CXXAllocator:
 // FIXME: These calls are currently unsupported.

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345340=345339=345340=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Thu Oct 25 16:38:41 2018
@@ -43,6 +43,7 @@ struct OSArray : public OSObject {
 
 struct OtherStruct {
   static void doNothingToArray(OSArray *array);
+  OtherStruct(OSArray *arr);
 };
 
 struct OSMetaClassBase {
@@ -55,6 +56,12 @@ void check_no_invalidation() {
 } // expected-warning{{Potential leak of an object stored into 'arr'}}
   // expected-note@-1{{Object leaked}}
 
+void check_no_invalidation_other_struct() {
+  OSArray *arr = OSArray::withCapacity(10); // expected-note{{Call to function 
'withCapacity' returns an OSObject of type struct OSArray * with a +1 retain 
count}}
+  OtherStruct other(arr); // expected-warning{{Potential leak}}
+  // expected-note@-1{{Object leaked}}
+}
+
 void check_rc_consumed() {
   OSArray *arr = OSArray::withCapacity(10);
   OSArray::consumeArray(arr);


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


r345339 - [analyzer] Remove custom rule for OSIterator in RetainCountChecker

2018-10-25 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Thu Oct 25 16:38:24 2018
New Revision: 345339

URL: http://llvm.org/viewvc/llvm-project?rev=345339=rev
Log:
[analyzer] Remove custom rule for OSIterator in RetainCountChecker

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

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

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345339=345338=345339=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Thu Oct 25 
16:38:24 2018
@@ -69,10 +69,6 @@ static bool isOSObjectDynamicCast(String
   return S == "safeMetaCast";
 }
 
-static bool isOSIteratorSubclass(const Decl *D) {
-  return isSubclass(D, "OSIterator");
-}
-
 static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation) {
   for (const auto *Ann : D->specific_attrs()) {
 if (Ann->getAnnotation() == rcAnnotation)
@@ -240,10 +236,6 @@ RetainSummaryManager::generateSummary(co
 
 // All objects returned with functions starting with "get" are getters.
 if (II->getName().startswith("get")) {
-
-  // ...except for iterators.
-  if (isOSIteratorSubclass(PD))
-return getOSSummaryCreateRule(FD);
   return getOSSummaryGetRule(FD);
 } else {
   return getOSSummaryCreateRule(FD);


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


r345101 - [analyzer] [NFC] Change scanReachableSymbols to use ranges

2018-10-23 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Oct 23 16:12:12 2018
New Revision: 345101

URL: http://llvm.org/viewvc/llvm-project?rev=345101=rev
Log:
[analyzer] [NFC] Change scanReachableSymbols to use ranges

Remove unused overload. Clean up some usages.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

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

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=345101=345100=345101=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h 
Tue Oct 23 16:12:12 2018
@@ -348,6 +348,8 @@ public:
   /// a value of such type.
   SVal getSValAsScalarOrLoc(const MemRegion *R) const;
 
+  using region_iterator = const MemRegion **;
+
   /// Visits the symbols reachable from the given SVal using the provided
   /// SymbolVisitor.
   ///
@@ -357,24 +359,14 @@ public:
   /// \sa ScanReachableSymbols
   bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const;
 
-  /// Visits the symbols reachable from the SVals in the given range
-  /// using the provided SymbolVisitor.
-  bool scanReachableSymbols(const SVal *I, const SVal *E,
-SymbolVisitor ) const;
-
   /// Visits the symbols reachable from the regions in the given
   /// MemRegions range using the provided SymbolVisitor.
-  bool scanReachableSymbols(const MemRegion * const *I,
-const MemRegion * const *E,
+  bool scanReachableSymbols(llvm::iterator_range Reachable,
 SymbolVisitor ) const;
 
   template  CB scanReachableSymbols(SVal val) const;
-  template  CB scanReachableSymbols(const SVal *beg,
- const SVal *end) const;
-
   template  CB
-  scanReachableSymbols(const MemRegion * const *beg,
-   const MemRegion * const *end) const;
+  scanReachableSymbols(llvm::iterator_range Reachable) const;
 
   /// Create a new state in which the statement is marked as tainted.
   LLVM_NODISCARD ProgramStateRef
@@ -883,17 +875,10 @@ CB ProgramState::scanReachableSymbols(SV
 }
 
 template 
-CB ProgramState::scanReachableSymbols(const SVal *beg, const SVal *end) const {
-  CB cb(this);
-  scanReachableSymbols(beg, end, cb);
-  return cb;
-}
-
-template 
-CB ProgramState::scanReachableSymbols(const MemRegion * const *beg,
- const MemRegion * const *end) const {
+CB ProgramState::scanReachableSymbols(
+llvm::iterator_range Reachable) const {
   CB cb(this);
-  scanReachableSymbols(beg, end, cb);
+  scanReachableSymbols(Reachable, cb);
   return cb;
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=345101=345100=345101=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Oct 23 16:12:12 
2018
@@ -2539,8 +2539,7 @@ void MallocChecker::checkPostStmt(const
   }
 
   state =
-state->scanReachableSymbols(Regions.data(),
-Regions.data() + 
Regions.size()).getState();
+state->scanReachableSymbols(Regions).getState();
   C.addTransition(state);
 }
 

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=345101=345100=345101=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Tue Oct 23 16:12:12 2018
@@ -175,9 +175,7 @@ void RetainCountChecker::checkPostStmt(c
 Regions.push_back(VR);
   }
 
-  state =
-state->scanReachableSymbols(Regions.data(),
-Regions.data() + 
Regions.size()).getState();
+  state = 
state->scanReachableSymbols(Regions).getState();
   C.addTransition(state);
 }
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=345101=345100=345101=diff
==
--- 

r345100 - [analyzer] Do not stop tracking CXX methods touching OSObject.

2018-10-23 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Oct 23 16:11:50 2018
New Revision: 345100

URL: http://llvm.org/viewvc/llvm-project?rev=345100=rev
Log:
[analyzer] Do not stop tracking CXX methods touching OSObject.

Trust generalized annotations for OSObject.

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=345100=345099=345100=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Tue Oct 23 16:11:50 2018
@@ -45,7 +45,7 @@ ProgramStateRef removeRefBinding(Program
 
 void RefVal::print(raw_ostream ) const {
   if (!T.isNull())
-Out << "Tracked " << T.getAsString() << '/';
+Out << "Tracked " << T.getAsString() << " | ";
 
   switch (getKind()) {
 default: llvm_unreachable("Invalid RefVal kind");

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345100=345099=345100=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Tue Oct 23 
16:11:50 2018
@@ -8,8 +8,8 @@
 
//===--===//
 //
 //  This file defines summaries implementation for retain counting, which
-//  implements a reference count checker for Core Foundation and Cocoa
-//  on (Mac OS X).
+//  implements a reference count checker for Core Foundation, Cocoa
+//  and OSObject (on Mac OS X).
 //
 
//===--===//
 
@@ -94,6 +94,22 @@ static bool isMakeCollectable(StringRef
   return FName.contains_lower("MakeCollectable");
 }
 
+/// A function is OSObject related if it is declared on a subclass
+/// of OSObject, or any of the parameters is a subclass of an OSObject.
+static bool isOSObjectRelated(const CXXMethodDecl *MD) {
+  if (isOSObjectSubclass(MD->getParent()))
+return true;
+
+  for (ParmVarDecl *Param : MD->parameters()) {
+QualType PT = Param->getType();
+if (CXXRecordDecl *RD = PT->getPointeeType()->getAsCXXRecordDecl())
+  if (isOSObjectSubclass(RD))
+return true;
+  }
+
+  return false;
+}
+
 const RetainSummary *
 RetainSummaryManager::generateSummary(const FunctionDecl *FD,
   bool ) {
@@ -322,12 +338,10 @@ RetainSummaryManager::generateSummary(co
 }
   }
 
-  if (isa(FD)) {
-
-// Stop tracking arguments passed to C++ methods, as those might be
-// wrapping smart pointers.
-return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, 
StopTracking,
-DoNothing);
+  if (const auto *MD = dyn_cast(FD)) {
+if (!(TrackOSObjects && isOSObjectRelated(MD)))
+  return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, 
StopTracking,
+  DoNothing);
   }
 
   return getDefaultSummary();
@@ -642,6 +656,8 @@ RetainSummaryManager::getRetEffectFromAn
 
   if (D->hasAttr())
 return RetEffect::MakeNotOwned(RetEffect::CF);
+  else if (hasRCAnnotation(D, "rc_ownership_returns_not_retained"))
+return RetEffect::MakeNotOwned(RetEffect::Generalized);
 
   return None;
 }

Modified: cfe/trunk/test/Analysis/osobject-retain-release.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/osobject-retain-release.cpp?rev=345100=345099=345100=diff
==
--- cfe/trunk/test/Analysis/osobject-retain-release.cpp (original)
+++ cfe/trunk/test/Analysis/osobject-retain-release.cpp Tue Oct 23 16:11:50 2018
@@ -2,6 +2,11 @@
 
 struct OSMetaClass;
 
+#define TRUSTED 
__attribute__((annotate("rc_ownership_trusted_implementation")))
+#define OS_CONSUME TRUSTED __attribute__((annotate("rc_ownership_consumed")))
+#define OS_RETURNS_RETAINED TRUSTED 
__attribute__((annotate("rc_ownership_returns_retained")))
+#define OS_RETURNS_NOT_RETAINED TRUSTED 
__attribute__((annotate("rc_ownership_returns_not_retained")))
+
 #define OSTypeID(type)   (type::metaClass)
 
 #define OSDynamicCast(type, inst)   \
@@ -21,14 +26,53 @@ struct OSArray : public OSObject {
   unsigned int getCount();
 
   static OSArray *withCapacity(unsigned int capacity);
+  static void consumeArray(OS_CONSUME OSArray * 

r345099 - [analyzer] Trust summaries for OSObject::retain and OSObject::release

2018-10-23 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Oct 23 16:11:30 2018
New Revision: 345099

URL: http://llvm.org/viewvc/llvm-project?rev=345099=rev
Log:
[analyzer] Trust summaries for OSObject::retain and OSObject::release

Refactor the way in which summaries are consumed for safeMetaCast

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

Modified:

cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
cfe/trunk/test/Analysis/osobject-retain-release.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp?rev=345099=345098=345099=diff
==
--- 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
(original)
+++ 
cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp 
Tue Oct 23 16:11:30 2018
@@ -776,31 +776,27 @@ bool RetainCountChecker::evalCall(const
 
   const LocationContext *LCtx = C.getLocationContext();
 
-  // Process OSDynamicCast: should just return the first argument.
-  // For now, tresting the cast as a no-op, and disregarding the case where
-  // the output becomes null due to the type mismatch.
-  if (FD->getNameAsString() == "safeMetaCast") {
-state = state->BindExpr(CE, LCtx, 
-state->getSVal(CE->getArg(0), LCtx));
-C.addTransition(state);
-return true;
-  }
-
   // See if it's one of the specific functions we know how to eval.
   if (!SmrMgr.canEval(CE, FD, hasTrustedImplementationAnnotation))
 return false;
 
   // Bind the return value.
-  SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
-  if (RetVal.isUnknown() ||
-  (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
+  // For now, all the functions which we can evaluate and which take
+  // at least one argument are identities.
+  if (CE->getNumArgs() >= 1) {
+SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
+
 // If the receiver is unknown or the function has
 // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
 // return value.
-SValBuilder  = C.getSValBuilder();
-RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
+if (RetVal.isUnknown() ||
+(hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
+  SValBuilder  = C.getSValBuilder();
+  RetVal =
+  SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
+}
+state = state->BindExpr(CE, LCtx, RetVal, false);
   }
-  state = state->BindExpr(CE, LCtx, RetVal, false);
 
   C.addTransition(state);
   return true;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp?rev=345099=345098=345099=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp Tue Oct 23 
16:11:30 2018
@@ -102,9 +102,6 @@ RetainSummaryManager::generateSummary(co
 return getPersistentStopSummary();
   }
 
-  // [PR 3337] Use 'getAs' to strip away any typedefs on the
-  // function's type.
-  const FunctionType *FT = FD->getType()->getAs();
   const IdentifierInfo *II = FD->getIdentifier();
   if (!II)
 return getDefaultSummary();
@@ -115,7 +112,8 @@ RetainSummaryManager::generateSummary(co
   // down below.
   FName = FName.substr(FName.find_first_not_of('_'));
 
-  // Inspect the result type.
+  // Inspect the result type. Strip away any typedefs.
+  const auto *FT = FD->getType()->getAs();
   QualType RetTy = FT->getReturnType();
   std::string RetTyName = RetTy.getAsString();
 
@@ -506,12 +504,6 @@ bool RetainSummaryManager::isTrustedRefe
 bool RetainSummaryManager::canEval(const CallExpr *CE,
const FunctionDecl *FD,
bool ) {
-  // For now, we're only handling the functions that return aliases of their
-  // arguments: CFRetain (and its families).
-  // Eventually we should add other functions we can model entirely,
-  // such as CFRelease, which don't invalidate their arguments or globals.
-  if (CE->getNumArgs() != 1)
-return false;
 
   IdentifierInfo *II = FD->getIdentifier();
   if (!II)
@@ -533,6 +525,13 @@ bool RetainSummaryManager::canEval(const
   return isRetain(FD, FName) || isAutorelease(FD, FName) ||
  isMakeCollectable(FName);
 
+// Process OSDynamicCast: should just return the first argument.
+// For now, treating the cast as a no-op, and disregarding the case where
+// the output becomes null due to the type mismatch.
+if (TrackOSObjects && FName == 

r345064 - [analyzer] Rename trackNullOrUndefValue to trackExpressionValue

2018-10-23 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Oct 23 11:24:53 2018
New Revision: 345064

URL: http://llvm.org/viewvc/llvm-project?rev=345064=rev
Log:
[analyzer] Rename trackNullOrUndefValue to trackExpressionValue

trackNullOrUndefValue is a long and confusing name,
and it does not actually reflect what the function is doing.
Give a function a new name, with a relatively clear semantics.

Also remove some dead code.

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

Modified:

cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Modified: 
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h?rev=345064=345063=345064=diff
==
--- 
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h 
(original)
+++ 
cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h 
Tue Oct 23 11:24:53 2018
@@ -345,12 +345,11 @@ public:
 
 namespace bugreporter {
 
-/// Attempts to add visitors to trace a null or undefined value back to its
-/// point of origin, whether it is a symbol constrained to null or an explicit
-/// assignment.
+/// Attempts to add visitors to track expression value back to its point of
+/// origin.
 ///
 /// \param N A node "downstream" from the evaluation of the statement.
-/// \param S The statement whose value is null or undefined.
+/// \param E The expression value which we are tracking
 /// \param R The bug report to which visitors should be attached.
 /// \param EnableNullFPSuppression Whether we should employ false positive
 /// suppression (inlined defensive checks, returned null).
@@ -358,13 +357,10 @@ namespace bugreporter {
 /// \return Whether or not the function was able to add visitors for this
 /// statement. Note that returning \c true does not actually imply
 /// that any visitors were added.
-bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport ,
-   bool EnableNullFPSuppression = true);
+bool trackExpressionValue(const ExplodedNode *N, const Expr *E, BugReport ,
+  bool EnableNullFPSuppression = true);
 
 const Expr *getDerefExpr(const Stmt *S);
-const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetRetValExpr(const ExplodedNode *N);
-bool isDeclRefExprToReference(const Expr *E);
 
 } // namespace bugreporter
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp?rev=345064=345063=345064=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp Tue Oct 
23 11:24:53 2018
@@ -214,7 +214,7 @@ void NilArgChecker::generateBugReport(Ex
 
   auto R = llvm::make_unique(*BT, Msg, N);
   R->addRange(Range);
-  bugreporter::trackNullOrUndefValue(N, E, *R);
+  bugreporter::trackExpressionValue(N, E, *R);
   C.emitReport(std::move(R));
 }
 
@@ -578,7 +578,7 @@ void CFRetainReleaseChecker::checkPreCal
 
 auto report = llvm::make_unique(BT, OS.str(), N);
 report->addRange(Call.getArgSourceRange(0));
-bugreporter::trackNullOrUndefValue(N, Call.getArgExpr(0), *report);
+bugreporter::trackExpressionValue(N, Call.getArgExpr(0), *report);
 C.emitReport(std::move(report));
 return;
   }

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CStringChecker.cpp?rev=345064=345063=345064=diff

  1   2   3   4   5   >