frederic-tingaud-sonarsource updated this revision to Diff 428044.
frederic-tingaud-sonarsource added a comment.

Fix formatting


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

https://reviews.llvm.org/D124845

Files:
  clang/include/clang/Analysis/ConstructionContext.h
  clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
  clang/lib/StaticAnalyzer/Core/CallEvent.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  clang/test/Analysis/cxxnewexpr-callback-inline.cpp
  clang/test/Analysis/cxxnewexpr-callback-noinline.cpp
  clang/test/Analysis/cxxnewexpr-callback.cpp
  clang/test/Analysis/dtor.cpp

Index: clang/test/Analysis/dtor.cpp
===================================================================
--- clang/test/Analysis/dtor.cpp
+++ clang/test/Analysis/dtor.cpp
@@ -570,3 +570,32 @@
   // no-crash
 }
 } // namespace dtor_over_loc_concrete_int
+
+// Test overriden new/delete operators
+struct CustomOperators {
+  void *operator new(size_t count) {
+    return malloc(count);
+  }
+
+  void operator delete(void *addr) {
+    free(addr);
+  }
+
+private:
+  int i;
+};
+
+void compliant() {
+  auto *a = new CustomOperators();
+  delete a;
+}
+
+void overrideLeak() {
+  auto *a = new CustomOperators();
+} // expected-warning{{Potential leak of memory pointed to by 'a'}}
+
+void overrideDoubleDelete() {
+  auto *a = new CustomOperators();
+  delete a;
+  delete a; // expected-warning@581 {{Attempt to free released memory}}
+}
Index: clang/test/Analysis/cxxnewexpr-callback.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/cxxnewexpr-callback.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config c++-allocator-inlining=true,debug.AnalysisOrder:PreStmtCXXNewExpr=true,debug.AnalysisOrder:PostStmtCXXNewExpr=true,debug.AnalysisOrder:PreCall=true,debug.AnalysisOrder:PostCall=true,debug.AnalysisOrder:NewAllocator=true %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-INLINE
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config c++-allocator-inlining=false,debug.AnalysisOrder:PreStmtCXXNewExpr=true,debug.AnalysisOrder:PostStmtCXXNewExpr=true,debug.AnalysisOrder:PreCall=true,debug.AnalysisOrder:PostCall=true,debug.AnalysisOrder:NewAllocator=true %s 2>&1 | FileCheck %s  --check-prefixes=CHECK,CHECK-NO-INLINE
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+namespace std {
+void *malloc(size_t);
+void free(void *);
+} // namespace std
+
+void *operator new(size_t size) { return std::malloc(size); }
+void operator delete(void *ptr) { std::free(ptr); }
+
+struct S {
+  S() {}
+  ~S() {}
+};
+
+void foo();
+
+void test() {
+  S *s = new S();
+  foo();
+  delete s;
+}
+
+/*
+void test() {
+  S *s = new S();
+// CHECK-INLINE:      PreCall (operator new)
+// CHECK-INLINE-NEXT: PreCall (std::malloc)
+// CHECK-INLINE-NEXT: PostCall (std::malloc)
+// CHECK-INLINE-NEXT: PostCall (operator new)
+// CHECK-INLINE-NEXT: NewAllocator
+// CHECK-NO-INLINE: PreCall (S::S)
+// CHECK-INLINE-NEXT: PreCall (S::S)
+// CHECK-NEXT: PostCall (S::S)
+// CHECK-NEXT: PreStmt<CXXNewExpr>
+// CHECK-NEXT: PostStmt<CXXNewExpr>
+  foo();
+// CHECK-NEXT: PreCall (foo)
+// CHECK-NEXT: PostCall (foo)
+  delete s;
+// CHECK-NEXT: PreCall (S::~S)
+// CHECK-NEXT: PostCall (S::~S)
+// CHECK-NEXT: PreCall (operator delete)
+// CHECK-INLINE-NEXT: PreCall (std::free)
+// CHECK-INLINE-NEXT: PostCall (std::free)
+// CHECK-NEXT: PostCall (operator delete)
+}
+
+void operator delete(void *ptr) {
+  std::free(ptr);
+// CHECK-NO-INLINE-NEXT: PreCall (std::free)
+// CHECK-NO-INLINE-NEXT: PostCall (std::free)
+}
+
+void *operator new(size_t size) {
+  return std::malloc(size);
+// CHECK-NO-INLINE-NEXT: PreCall (std::malloc)
+// CHECK-NO-INLINE-NEXT: PostCall (std::malloc)
+}
+*/
Index: clang/test/Analysis/cxxnewexpr-callback-noinline.cpp
===================================================================
--- clang/test/Analysis/cxxnewexpr-callback-noinline.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config c++-allocator-inlining=false,debug.AnalysisOrder:PreStmtCXXNewExpr=true,debug.AnalysisOrder:PostStmtCXXNewExpr=true,debug.AnalysisOrder:PreCall=true,debug.AnalysisOrder:PostCall=true,debug.AnalysisOrder:NewAllocator=true %s 2>&1 | FileCheck %s
-
-#include "Inputs/system-header-simulator-cxx.h"
-
-namespace std {
-  void *malloc(size_t);
-}
-
-void *operator new(size_t size) { return std::malloc(size); }
-
-struct S {
-  S() {}
-};
-
-void foo();
-
-void test() {
-  S *s = new S();
-  foo();
-}
-
-// CHECK:      PreCall (S::S)
-// CHECK-NEXT: PostCall (S::S)
-// CHECK-NEXT: PreStmt<CXXNewExpr>
-// CHECK-NEXT: PostStmt<CXXNewExpr>
-// CHECK-NEXT: PreCall (foo)
-// CHECK-NEXT: PostCall (foo)
-// CHECK-NEXT: PreCall (std::malloc)
-// CHECK-NEXT: PostCall (std::malloc)
Index: clang/test/Analysis/cxxnewexpr-callback-inline.cpp
===================================================================
--- clang/test/Analysis/cxxnewexpr-callback-inline.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config c++-allocator-inlining=true,debug.AnalysisOrder:PreStmtCXXNewExpr=true,debug.AnalysisOrder:PostStmtCXXNewExpr=true,debug.AnalysisOrder:PreCall=true,debug.AnalysisOrder:PostCall=true,debug.AnalysisOrder:NewAllocator=true %s 2>&1 | FileCheck %s
-
-#include "Inputs/system-header-simulator-cxx.h"
-
-namespace std {
-  void *malloc(size_t);
-}
-
-void *operator new(size_t size) { return std::malloc(size); }
-
-struct S {
-  S() {}
-};
-
-void foo();
-
-void test() {
-  S *s = new S();
-  foo();
-}
-
-// CHECK:      PreCall (operator new)
-// CHECK-NEXT: PreCall (std::malloc)
-// CHECK-NEXT: PostCall (std::malloc)
-// CHECK-NEXT: PostCall (operator new)
-// CHECK-NEXT: NewAllocator
-// CHECK-NEXT: PreCall (S::S)
-// CHECK-NEXT: PostCall (S::S)
-// CHECK-NEXT: PreStmt<CXXNewExpr>
-// CHECK-NEXT: PostStmt<CXXNewExpr>
-// CHECK-NEXT: PreCall (foo)
-// CHECK-NEXT: PostCall (foo)
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -945,8 +945,17 @@
 
   ExplodedNodeSet DstPreCall;
   getCheckerManager().runCheckersForPreCall(DstPreCall, Pred, *Call, *this);
+  ExplodedNodeSet DstPostCall;
 
-  getCheckerManager().runCheckersForPostCall(Dst, DstPreCall, *Call, *this);
+  if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) {
+    StmtNodeBuilder Bldr(DstPreCall, DstPostCall, *currBldrCtx);
+    for (ExplodedNode *I : DstPreCall) {
+      defaultEvalCall(Bldr, I, *Call);
+    }
+  } else {
+    DstPostCall = DstPreCall;
+  }
+  getCheckerManager().runCheckersForPostCall(Dst, DstPostCall, *Call, *this);
 }
 
 void ExprEngine::VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
Index: clang/lib/StaticAnalyzer/Core/CallEvent.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -1408,6 +1408,8 @@
     return getSimpleCall(CE, State, LC);
   } else if (const auto *NE = dyn_cast<CXXNewExpr>(S)) {
     return getCXXAllocatorCall(NE, State, LC);
+  } else if (const auto *DE = dyn_cast<CXXDeleteExpr>(S)) {
+    return getCXXDeallocatorCall(DE, State, LC);
   } else if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
     return getObjCMethodCall(ME, State, LC);
   } else {
Index: clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -1276,7 +1276,7 @@
   getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
 
   /// Gets a call event for a function call, Objective-C method call,
-  /// or a 'new' call.
+  /// a 'new', or a 'delete' call.
   CallEventRef<>
   getCall(const Stmt *S, ProgramStateRef State,
           const LocationContext *LC);
Index: clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
===================================================================
--- clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -128,7 +128,8 @@
                 true)
 
 ANALYZER_OPTION(bool, MayInlineCXXAllocator, "c++-allocator-inlining",
-                "Whether or not allocator call may be considered for inlining.",
+                "Whether or not allocator and deallocator calls may be "
+                "considered for inlining.",
                 true)
 
 ANALYZER_OPTION(
Index: clang/include/clang/Analysis/ConstructionContext.h
===================================================================
--- clang/include/clang/Analysis/ConstructionContext.h
+++ clang/include/clang/Analysis/ConstructionContext.h
@@ -120,7 +120,8 @@
   ConstructionContextItem(const Expr *E, unsigned Index)
       : Data(E), Kind(ArgumentKind), Index(Index) {
     assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) ||
-           isa<CXXInheritedCtorInitExpr>(E) || isa<ObjCMessageExpr>(E));
+           isa<CXXDeleteExpr>(E) || isa<CXXInheritedCtorInitExpr>(E) ||
+           isa<ObjCMessageExpr>(E));
   }
 
   ConstructionContextItem(const CXXCtorInitializer *Init)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to