This revision was automatically updated to reflect the committed changes.
Closed by commit rGe94192198f8a: [analyzer] Add support for 
ObjCIndirectCopyRestoreExpr. (authored by Paul Pelzl <ppe...@apple.com>, 
committed by dergachev.a).
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81071/new/

https://reviews.llvm.org/D81071

Files:
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/Analysis/objc-indirect-copy-restore.m

Index: clang/test/Analysis/objc-indirect-copy-restore.m
===================================================================
--- /dev/null
+++ clang/test/Analysis/objc-indirect-copy-restore.m
@@ -0,0 +1,67 @@
+// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(int);
+void clang_analyzer_warnIfReached();
+
+extern void __assert_fail (__const char *__assertion, __const char *__file,
+    unsigned int __line, __const char *__function)
+     __attribute__ ((__noreturn__));
+
+#define assert(expr) \
+  ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
+
+
+@protocol NSObject
++ (nonnull instancetype)alloc;
+- (nonnull instancetype)init;
+@end
+@interface NSObject <NSObject> {}
+@end
+
+@interface NSError : NSObject {
+@public
+  int x;
+}
+@end
+
+
+@interface SomeClass : NSObject
++ (int)doSomethingWithError:(NSError *__autoreleasing *)error;
+@end
+
+@implementation SomeClass
++ (int)doSomethingWithError:(NSError *__autoreleasing *)error {
+    if (error) {
+        NSError *e = [[NSError alloc] init];
+        assert(e);
+        e->x = 5;
+        *error = e;
+        clang_analyzer_eval(*error != 0); // expected-warning{{TRUE}}
+    }
+    return 0;
+}
+@end
+
+void testStrongOutParam(void) {
+  NSError *error;
+  clang_analyzer_eval(error != 0); // expected-warning{{FALSE}}
+  int ok = [SomeClass doSomethingWithError:&error];
+  clang_analyzer_eval(ok);         // expected-warning{{FALSE}}
+  clang_analyzer_eval(error != 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(error->x == 5); // expected-warning{{TRUE}}
+}
+
+void testAutoreleasingOutParam(void) {
+  NSError *__autoreleasing error;
+  clang_analyzer_eval(error != 0); // expected-warning{{FALSE}}
+  int ok = [SomeClass doSomethingWithError:&error];
+  clang_analyzer_eval(ok);         // expected-warning{{FALSE}}
+  clang_analyzer_eval(error != 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(error->x == 5); // expected-warning{{TRUE}}
+}
+
+void testNilOutParam(void) {
+    int ok = [SomeClass doSomethingWithError:(void *)0];
+    clang_analyzer_eval(ok);  // expected-warning{{FALSE}}
+}
+
Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1210,7 +1210,6 @@
 
   switch (S->getStmtClass()) {
     // C++, OpenMP and ARC stuff we don't support yet.
-    case Expr::ObjCIndirectCopyRestoreExprClass:
     case Stmt::CXXDependentScopeMemberExprClass:
     case Stmt::CXXTryStmtClass:
     case Stmt::CXXTypeidExprClass:
@@ -1870,6 +1869,21 @@
       Bldr.addNodes(Dst);
       break;
     }
+
+    case Expr::ObjCIndirectCopyRestoreExprClass: {
+      // ObjCIndirectCopyRestoreExpr implies passing a temporary for
+      // correctness of lifetime management.  Due to limited analysis
+      // of ARC, this is implemented as direct arg passing.
+      Bldr.takeNodes(Pred);
+      ProgramStateRef state = Pred->getState();
+      const auto *OIE = cast<ObjCIndirectCopyRestoreExpr>(S);
+      const Expr *E = OIE->getSubExpr();
+      SVal V = state->getSVal(E, Pred->getLocationContext());
+      Bldr.generateNode(S, Pred,
+              state->BindExpr(S, Pred->getLocationContext(), V));
+      Bldr.addNodes(Dst);
+      break;
+    }
   }
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to