[clang] 73716ba - [analyzer][NFC] Add tests for D132236

Tomasz Kamiński via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 3 06:43:37 PDT 2022


Author: Tomasz Kamiński
Date: 2022-10-03T15:42:38+02:00
New Revision: 73716baa30ebc75783d2902e12accea35dec193a

URL: https://github.com/llvm/llvm-project/commit/73716baa30ebc75783d2902e12accea35dec193a
DIFF: https://github.com/llvm/llvm-project/commit/73716baa30ebc75783d2902e12accea35dec193a.diff

LOG: [analyzer][NFC] Add tests for D132236

D132236 would have introduced regressions in the symbol lifetime
handling. However, the testsuite did not catch this, so here we have
some tests, which would have break if D132236 had landed.

This patch addresses the comment https://reviews.llvm.org/D132236#3753238

Co-authored-by: Balazs Benics <balazs.benics at sonarsource.com>

Reviewed By: martong

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

Added: 
    clang/test/Analysis/symbol-reaper-lambda.cpp

Modified: 
    clang/test/Analysis/NewDeleteLeaks.cpp
    clang/test/Analysis/trivial-copy-struct.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Analysis/NewDeleteLeaks.cpp b/clang/test/Analysis/NewDeleteLeaks.cpp
index 19a6aff7833be..b2bad7e76fad0 100644
--- a/clang/test/Analysis/NewDeleteLeaks.cpp
+++ b/clang/test/Analysis/NewDeleteLeaks.cpp
@@ -192,3 +192,29 @@ void use_ret() {
 // expected-note at -1 {{Potential leak of memory pointed to by 'v'}}
 
 } // namespace refkind_from_unoallocated_to_allocated
+
+// Check that memory leak is reported against a symbol if the last place it's
+// mentioned is a base region of a lazy compound value, as the program cannot
+// possibly free that memory.
+namespace symbol_reaper_lifetime {
+struct Nested {
+  int buf[2];
+};
+struct Wrapping {
+  Nested data;
+};
+
+Nested allocateWrappingAndReturnNested() {
+  // expected-note at +1 {{Memory is allocated}}
+  Wrapping const* p = new Wrapping();
+  // expected-warning at +2 {{Potential leak of memory pointed to by 'p'}}
+  // expected-note at +1    {{Potential leak of memory pointed to by 'p'}}
+  return p->data;
+}
+
+void caller() {
+  // expected-note at +1 {{Calling 'allocateWrappingAndReturnNested'}}
+  Nested n = allocateWrappingAndReturnNested();
+  (void)n;
+} // no-warning: No potential memory leak here, because that's been already reported.
+} // namespace symbol_reaper_lifetime

diff  --git a/clang/test/Analysis/symbol-reaper-lambda.cpp b/clang/test/Analysis/symbol-reaper-lambda.cpp
new file mode 100644
index 0000000000000..c63562b4d430b
--- /dev/null
+++ b/clang/test/Analysis/symbol-reaper-lambda.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+// expected-no-diagnostics
+
+template <typename... Ts>
+void escape(Ts&...);
+struct Dummy {};
+
+int strange(Dummy param) {
+  Dummy local_pre_lambda;
+  int ref_captured = 0;
+
+  // LambdaExpr is modeled as lazyCompoundVal of tempRegion, that contains
+  // all captures. In this instance, this region contains a pointer/reference
+  // to ref_captured variable.
+  auto fn = [&] {
+    escape(param, local_pre_lambda);
+    return ref_captured; // no-warning: The value is not garbage.
+  };
+
+  int local_defined_after_lambda; // Unused, but necessary! Important that it's before the call.
+
+  // The ref_captured binding should not be pruned at this point, as it is still
+  // accessed via reference captured in operator() of fn.
+  return fn();
+}
+

diff  --git a/clang/test/Analysis/trivial-copy-struct.cpp b/clang/test/Analysis/trivial-copy-struct.cpp
index b9a2b1d9b201d..cd9cfde3ee9dc 100644
--- a/clang/test/Analysis/trivial-copy-struct.cpp
+++ b/clang/test/Analysis/trivial-copy-struct.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 template <typename T> void clang_analyzer_dump(T);
+template <typename T> void clang_analyzer_value(T);
 void clang_analyzer_warnIfReached();
 
 struct Node { int* ptr; };
@@ -34,3 +35,25 @@ void copy_on_heap(Node* n1) {
   (void)(n1->ptr);
   (void)(n2->ptr);
 }
+
+struct List {
+  List* next;
+  int value;
+  int padding;
+};
+
+void deadCode(List orig) {
+  List c = orig;
+  clang_analyzer_dump(c.value);
+  // expected-warning-re at -1 {{reg_${{[0-9]+}}<int orig.value>}}
+  if (c.value == 42)
+    return;
+  clang_analyzer_value(c.value);
+  // expected-warning at -1 {{32s:{ [-2147483648, 2147483647] }}}
+  // The symbol was garbage collected too early, hence we lose the constraints.
+  if (c.value != 42)
+    return;
+
+  // Dead code should be unreachable
+  clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
+}


        


More information about the cfe-commits mailing list