https://github.com/gamesh411 updated 
https://github.com/llvm/llvm-project/pull/188709

From fe7730879969ebd71ea569605a81cc97ffab1f19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <[email protected]>
Date: Tue, 24 Mar 2026 12:05:52 +0100
Subject: [PATCH 1/2] [analyzer][NFC] Reorganize bstring.cpp tests

This change eliminates preprocessor-based suppression of test cases, and
moves special cases to separate test files.
---
 .../test/Analysis/bstring-oob-suppressed.cpp  |  92 ++++++++++++++++
 clang/test/Analysis/bstring-uninit-only.cpp   |  23 ++++
 clang/test/Analysis/bstring.cpp               | 100 +-----------------
 3 files changed, 120 insertions(+), 95 deletions(-)
 create mode 100644 clang/test/Analysis/bstring-oob-suppressed.cpp
 create mode 100644 clang/test/Analysis/bstring-uninit-only.cpp

diff --git a/clang/test/Analysis/bstring-oob-suppressed.cpp 
b/clang/test/Analysis/bstring-oob-suppressed.cpp
new file mode 100644
index 0000000000000..8eb9ad7a08dff
--- /dev/null
+++ b/clang/test/Analysis/bstring-oob-suppressed.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:     -analyzer-checker=core \
+// RUN:     -analyzer-checker=unix.cstring \
+// RUN:     -analyzer-checker=unix.Malloc \
+// RUN:     -analyzer-checker=debug.ExprInspection \
+// RUN:     -analyzer-config eagerly-assume=false \
+// RUN:     -analyzer-checker=alpha.unix.cstring.BufferOverlap \
+// RUN:     -analyzer-checker=unix.cstring.NotNullTerminated \
+// RUN:     -verify %s
+
+// These tests exercise memset calls that go out-of-bounds. They are separated
+// from bstring.cpp because they require OutOfBounds to be disabled: with
+// OutOfBounds enabled, the analysis sinks at the OOB memset and the subsequent
+// clang_analyzer_eval calls are not reached.
+//
+// FIXME: These tests document the analyzer's current behavior when OutOfBounds
+// is disabled and OOB memset calls don't terminate the path. Once the
+// OutOfBounds checker is stable enough to always terminate execution at OOB
+// errors (regardless of whether the checker frontend is enabled), these tests
+// should be revisited: the clang_analyzer_eval calls after the OOB memset
+// would become unreachable.
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+void clang_analyzer_eval(int);
+void *memset(void *dest, int ch, std::size_t count);
+
+namespace memset_non_pod {
+class Base {
+public:
+  int b_mem;
+  Base() : b_mem(1) {}
+};
+
+class Derived : public Base {
+public:
+  int d_mem;
+  Derived() : d_mem(2) {}
+};
+
+void memset2_inheritance_field() {
+  Derived d;
+  // FIXME: OOB memset on a derived field with sizeof(Derived).
+  // Current behavior: the not-set part is treated as UNKNOWN.
+  memset(&d.d_mem, 0, sizeof(Derived));
+  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
+}
+
+void memset3_inheritance_field() {
+  Derived d;
+  // FIXME: memset on the base field with sizeof(Derived). This doesn't
+  // actually write past the object's extent, but it's UB because the memset
+  // accesses the object through a pointer to a member, violating aliasing
+  // rules. Current behavior: the field is treated as correctly set to 0.
+  memset(&d.b_mem, 0, sizeof(Derived));
+  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
+}
+
+class BaseVirtual {
+public:
+  int b_mem;
+  virtual int get() { return 1; }
+};
+
+class DerivedVirtual : public BaseVirtual {
+public:
+  int d_mem;
+};
+
+void memset8_virtual_inheritance_field() {
+  DerivedVirtual d;
+  // FIXME: Same as memset3, but the base has a virtual function. In typical
+  // implementations &d.b_mem differs from &d because the vtable pointer
+  // precedes the first member, so this may also write past the object's
+  // extent.
+  memset(&d.b_mem, 0, sizeof(Derived));
+  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
+}
+} // namespace memset_non_pod
+
+void memset1_new_array() {
+  int *array = new int[10];
+  memset(array, 0, 10 * sizeof(int));
+  clang_analyzer_eval(array[2] == 0); // expected-warning{{TRUE}}
+  // FIXME: OOB memset on a heap array. The analysis continues past it.
+  memset(array + 1, 'a', 10 * sizeof(9));
+  clang_analyzer_eval(array[2] == 0); // expected-warning{{UNKNOWN}}
+  delete[] array;
+}
diff --git a/clang/test/Analysis/bstring-uninit-only.cpp 
b/clang/test/Analysis/bstring-uninit-only.cpp
new file mode 100644
index 0000000000000..fa78ccc2f4c26
--- /dev/null
+++ b/clang/test/Analysis/bstring-uninit-only.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:     -analyzer-checker=core \
+// RUN:     -analyzer-checker=unix.cstring \
+// RUN:     -analyzer-checker=unix.Malloc \
+// RUN:     -analyzer-checker=debug.ExprInspection \
+// RUN:     -analyzer-config eagerly-assume=false \
+// RUN:     -analyzer-checker=alpha.unix.cstring.UninitializedRead \
+// RUN:     -verify %s
+
+// This test verifies that UninitializedRead produces warnings even when
+// OutOfBounds is disabled. Previously, CheckBufferAccess would early-return
+// before reaching checkInit() when OutOfBounds was disabled, suppressing
+// UninitializedRead as a side effect.
+
+#include "Inputs/system-header-simulator-cxx.h"
+#include "Inputs/system-header-simulator-for-malloc.h"
+
+void memmove_uninit_without_outofbound() {
+  int src[4];
+  int dst[4];
+  memmove(dst, src, sizeof(src)); // expected-warning{{The first element of 
the 2nd argument is undefined}}
+                                  // expected-note@-1{{Other elements might 
also be undefined}}
+}
diff --git a/clang/test/Analysis/bstring.cpp b/clang/test/Analysis/bstring.cpp
index 732b36a92ac5a..dabd53d48cb4b 100644
--- a/clang/test/Analysis/bstring.cpp
+++ b/clang/test/Analysis/bstring.cpp
@@ -3,28 +3,14 @@
 // DEFINE:     -analyzer-checker=unix.cstring \
 // DEFINE:     -analyzer-checker=unix.Malloc \
 // DEFINE:     -analyzer-checker=debug.ExprInspection \
+// DEFINE:     -analyzer-checker=alpha.unix.cstring \
 // DEFINE:     -analyzer-config eagerly-assume=false \
 // DEFINE:     -verify %s
 
-// RUN: %{analyzer} \
-// RUN:     -analyzer-checker=alpha.unix.cstring
-
-// RUN: %{analyzer} -DUSE_BUILTINS \
-// RUN:     -analyzer-checker=alpha.unix.cstring
-
-// RUN: %{analyzer} -DVARIANT \
-// RUN:     -analyzer-checker=alpha.unix.cstring
-
-// RUN: %{analyzer} -DUSE_BUILTINS -DVARIANT \
-// RUN:     -analyzer-checker=alpha.unix.cstring
-
-// RUN: %{analyzer} -DSUPPRESS_OUT_OF_BOUND \
-// RUN:     -analyzer-checker=alpha.unix.cstring.BufferOverlap \
-// RUN:     -analyzer-checker=unix.cstring.NotNullTerminated
-
-// RUN: %{analyzer} \
-// RUN:   -DUNINIT_WITHOUT_OUTOFBOUND \
-// RUN:   -analyzer-checker=alpha.unix.cstring.UninitializedRead
+// RUN: %{analyzer}
+// RUN: %{analyzer} -DUSE_BUILTINS
+// RUN: %{analyzer} -DVARIANT
+// RUN: %{analyzer} -DUSE_BUILTINS -DVARIANT
 
 #include "Inputs/system-header-simulator-cxx.h"
 #include "Inputs/system-header-simulator-for-malloc.h"
@@ -122,33 +108,6 @@ void memset1_inheritance() {
   clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
 }
 
-#ifdef SUPPRESS_OUT_OF_BOUND
-void memset2_inheritance_field() {
-  Derived d;
-  // FIXME: This example wrongly calls `memset` on the derived field, with the
-  // size parameter that has the size of the whole derived class. The analysis
-  // should stop at that point as this is UB.
-  // This test asserts the current behavior of treating the not set part as
-  // UNKNOWN.
-  memset(&d.d_mem, 0, sizeof(Derived));
-  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
-  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
-}
-
-void memset3_inheritance_field() {
-  Derived d;
-  // FIXME: Here we are setting the field of the base with the size of the
-  // Derived class. By the letter of the standard this is UB, but practically
-  // this only touches memory it is supposed to with the above class
-  // definitions. If we were to be strict the analysis should stop here.
-  // This test asserts the current behavior of nevertheless treating the
-  // wrongly set field as correctly set to 0.
-  memset(&d.b_mem, 0, sizeof(Derived));
-  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}}
-  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
-}
-#endif
-
 void memset4_array_nonpod_object() {
   Derived array[10];
   clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}}
@@ -195,53 +154,4 @@ void memset7_placement_new() {
   clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}}
 }
 
-class BaseVirtual {
-public:
-  int b_mem;
-  virtual int get() { return 1; }
-};
-
-class DerivedVirtual : public BaseVirtual {
-public:
-  int d_mem;
-};
-
-#ifdef SUPPRESS_OUT_OF_BOUND
-void memset8_virtual_inheritance_field() {
-  DerivedVirtual d;
-  // FIXME: This example wrongly calls `memset` on the derived field, with the
-  // size parameter that has the size of the whole derived class. The analysis
-  // should stop at that point as this is UB. The situation is further
-  // complicated by the fact the base base a virtual function.
-  // This test asserts the current behavior of treating the not set part as
-  // UNKNOWN.
-  memset(&d.b_mem, 0, sizeof(Derived));
-  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
-  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
-}
-#endif
 } // namespace memset_non_pod
-
-#ifdef SUPPRESS_OUT_OF_BOUND
-void memset1_new_array() {
-  int *array = new int[10];
-  memset(array, 0, 10 * sizeof(int));
-  clang_analyzer_eval(array[2] == 0); // expected-warning{{TRUE}}
-  // FIXME: The analyzer should stop analysis after memset. Maybe the intent of
-  // this test was to test for this as a desired behaviour, but it shouldn't 
be.
-  // Going out-of-bounds with memset is a fatal error, even if we decide not to
-  // report it.
-  memset(array + 1, 'a', 10 * sizeof(9));
-  clang_analyzer_eval(array[2] == 0); // expected-warning{{UNKNOWN}}
-  delete[] array;
-}
-#endif
-
-#ifdef UNINIT_WITHOUT_OUTOFBOUND
-void memmove_uninit_without_outofbound() {
-  int src[4];
-  int dst[4];
-  memmove(dst, src, sizeof(src)); // expected-warning{{The first element of 
the 2nd argument is undefined}}
-                                  // expected-note@-1{{Other elements might 
also be undefined}}
-}
-#endif

From fea51fb0fc88e4242cf16b64dc0bbfb234ec5321 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Endre=20F=C3=BCl=C3=B6p?= <[email protected]>
Date: Mon, 30 Mar 2026 16:14:23 +0200
Subject: [PATCH 2/2] use multi-prefix verify instead of file splitting

This eliminates all preprocessor-based test suppression (SUPPRESS_OUT_OF_BOUND
and UNINIT_WITHOUT_OUTOFBOUND) without introducing new files.

Three verify prefix groups are used:
- 'oob': expectations only checked when OutOfBounds is enabled (sinks)
- 'no-oob': expectations only checked when OutOfBounds is disabled
- 'uninit': expectations only checked when UninitializedRead is enabled
---
 .../test/Analysis/bstring-oob-suppressed.cpp  |  92 ---------------
 clang/test/Analysis/bstring-uninit-only.cpp   |  23 ----
 clang/test/Analysis/bstring.cpp               | 109 ++++++++++++++++--
 3 files changed, 101 insertions(+), 123 deletions(-)
 delete mode 100644 clang/test/Analysis/bstring-oob-suppressed.cpp
 delete mode 100644 clang/test/Analysis/bstring-uninit-only.cpp

diff --git a/clang/test/Analysis/bstring-oob-suppressed.cpp 
b/clang/test/Analysis/bstring-oob-suppressed.cpp
deleted file mode 100644
index 8eb9ad7a08dff..0000000000000
--- a/clang/test/Analysis/bstring-oob-suppressed.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-// RUN: %clang_analyze_cc1 \
-// RUN:     -analyzer-checker=core \
-// RUN:     -analyzer-checker=unix.cstring \
-// RUN:     -analyzer-checker=unix.Malloc \
-// RUN:     -analyzer-checker=debug.ExprInspection \
-// RUN:     -analyzer-config eagerly-assume=false \
-// RUN:     -analyzer-checker=alpha.unix.cstring.BufferOverlap \
-// RUN:     -analyzer-checker=unix.cstring.NotNullTerminated \
-// RUN:     -verify %s
-
-// These tests exercise memset calls that go out-of-bounds. They are separated
-// from bstring.cpp because they require OutOfBounds to be disabled: with
-// OutOfBounds enabled, the analysis sinks at the OOB memset and the subsequent
-// clang_analyzer_eval calls are not reached.
-//
-// FIXME: These tests document the analyzer's current behavior when OutOfBounds
-// is disabled and OOB memset calls don't terminate the path. Once the
-// OutOfBounds checker is stable enough to always terminate execution at OOB
-// errors (regardless of whether the checker frontend is enabled), these tests
-// should be revisited: the clang_analyzer_eval calls after the OOB memset
-// would become unreachable.
-
-#include "Inputs/system-header-simulator-cxx.h"
-
-void clang_analyzer_eval(int);
-void *memset(void *dest, int ch, std::size_t count);
-
-namespace memset_non_pod {
-class Base {
-public:
-  int b_mem;
-  Base() : b_mem(1) {}
-};
-
-class Derived : public Base {
-public:
-  int d_mem;
-  Derived() : d_mem(2) {}
-};
-
-void memset2_inheritance_field() {
-  Derived d;
-  // FIXME: OOB memset on a derived field with sizeof(Derived).
-  // Current behavior: the not-set part is treated as UNKNOWN.
-  memset(&d.d_mem, 0, sizeof(Derived));
-  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
-  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
-}
-
-void memset3_inheritance_field() {
-  Derived d;
-  // FIXME: memset on the base field with sizeof(Derived). This doesn't
-  // actually write past the object's extent, but it's UB because the memset
-  // accesses the object through a pointer to a member, violating aliasing
-  // rules. Current behavior: the field is treated as correctly set to 0.
-  memset(&d.b_mem, 0, sizeof(Derived));
-  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}}
-  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
-}
-
-class BaseVirtual {
-public:
-  int b_mem;
-  virtual int get() { return 1; }
-};
-
-class DerivedVirtual : public BaseVirtual {
-public:
-  int d_mem;
-};
-
-void memset8_virtual_inheritance_field() {
-  DerivedVirtual d;
-  // FIXME: Same as memset3, but the base has a virtual function. In typical
-  // implementations &d.b_mem differs from &d because the vtable pointer
-  // precedes the first member, so this may also write past the object's
-  // extent.
-  memset(&d.b_mem, 0, sizeof(Derived));
-  clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
-  clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
-}
-} // namespace memset_non_pod
-
-void memset1_new_array() {
-  int *array = new int[10];
-  memset(array, 0, 10 * sizeof(int));
-  clang_analyzer_eval(array[2] == 0); // expected-warning{{TRUE}}
-  // FIXME: OOB memset on a heap array. The analysis continues past it.
-  memset(array + 1, 'a', 10 * sizeof(9));
-  clang_analyzer_eval(array[2] == 0); // expected-warning{{UNKNOWN}}
-  delete[] array;
-}
diff --git a/clang/test/Analysis/bstring-uninit-only.cpp 
b/clang/test/Analysis/bstring-uninit-only.cpp
deleted file mode 100644
index fa78ccc2f4c26..0000000000000
--- a/clang/test/Analysis/bstring-uninit-only.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: %clang_analyze_cc1 \
-// RUN:     -analyzer-checker=core \
-// RUN:     -analyzer-checker=unix.cstring \
-// RUN:     -analyzer-checker=unix.Malloc \
-// RUN:     -analyzer-checker=debug.ExprInspection \
-// RUN:     -analyzer-config eagerly-assume=false \
-// RUN:     -analyzer-checker=alpha.unix.cstring.UninitializedRead \
-// RUN:     -verify %s
-
-// This test verifies that UninitializedRead produces warnings even when
-// OutOfBounds is disabled. Previously, CheckBufferAccess would early-return
-// before reaching checkInit() when OutOfBounds was disabled, suppressing
-// UninitializedRead as a side effect.
-
-#include "Inputs/system-header-simulator-cxx.h"
-#include "Inputs/system-header-simulator-for-malloc.h"
-
-void memmove_uninit_without_outofbound() {
-  int src[4];
-  int dst[4];
-  memmove(dst, src, sizeof(src)); // expected-warning{{The first element of 
the 2nd argument is undefined}}
-                                  // expected-note@-1{{Other elements might 
also be undefined}}
-}
diff --git a/clang/test/Analysis/bstring.cpp b/clang/test/Analysis/bstring.cpp
index dabd53d48cb4b..9f044c6453739 100644
--- a/clang/test/Analysis/bstring.cpp
+++ b/clang/test/Analysis/bstring.cpp
@@ -3,14 +3,29 @@
 // DEFINE:     -analyzer-checker=unix.cstring \
 // DEFINE:     -analyzer-checker=unix.Malloc \
 // DEFINE:     -analyzer-checker=debug.ExprInspection \
-// DEFINE:     -analyzer-checker=alpha.unix.cstring \
-// DEFINE:     -analyzer-config eagerly-assume=false \
-// DEFINE:     -verify %s
-
-// RUN: %{analyzer}
-// RUN: %{analyzer} -DUSE_BUILTINS
-// RUN: %{analyzer} -DVARIANT
-// RUN: %{analyzer} -DUSE_BUILTINS -DVARIANT
+// DEFINE:     -analyzer-config eagerly-assume=false
+
+// All alpha.unix.cstring subcheckers enabled (OutOfBounds sinks at OOB 
memset).
+// RUN: %{analyzer} -analyzer-checker=alpha.unix.cstring \
+// RUN:     -verify=expected,oob,uninit %s
+// RUN: %{analyzer} -analyzer-checker=alpha.unix.cstring \
+// RUN:     -DUSE_BUILTINS -verify=expected,oob,uninit %s
+// RUN: %{analyzer} -analyzer-checker=alpha.unix.cstring \
+// RUN:     -DVARIANT -verify=expected,oob,uninit %s
+// RUN: %{analyzer} -analyzer-checker=alpha.unix.cstring \
+// RUN:     -DUSE_BUILTINS -DVARIANT -verify=expected,oob,uninit %s
+
+// OutOfBounds disabled: OOB memset doesn't sink, analysis continues.
+// RUN: %{analyzer} \
+// RUN:     -analyzer-checker=alpha.unix.cstring.BufferOverlap \
+// RUN:     -analyzer-checker=unix.cstring.NotNullTerminated \
+// RUN:     -verify=expected,no-oob %s
+
+// UninitializedRead enabled without OutOfBounds: verifies that
+// UninitializedRead works independently of OutOfBounds.
+// RUN: %{analyzer} \
+// RUN:     -analyzer-checker=alpha.unix.cstring.UninitializedRead \
+// RUN:     -verify=expected,no-oob,uninit %s
 
 #include "Inputs/system-header-simulator-cxx.h"
 #include "Inputs/system-header-simulator-for-malloc.h"
@@ -108,6 +123,33 @@ void memset1_inheritance() {
   clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
 }
 
+void memset2_inheritance_field() {
+  Derived d;
+  // FIXME: OOB memset on a derived field with sizeof(Derived).
+  // Current behavior: with 'oob' the analysis sinks; with 'no-oob' it
+  // continues and the evals produce UNKNOWN.
+  // Expected behavior: the OOB error is fatal regardless of whether the
+  // OutOfBounds checker frontend is enabled, so the evals should be 
unreachable
+  // in all configurations. The 'no-oob' expectations below should be removed.
+  memset(&d.d_mem, 0, sizeof(Derived)); // oob-warning{{overflows the 
destination buffer}}
+  clang_analyzer_eval(d.b_mem == 0); // no-oob-warning{{UNKNOWN}}
+  clang_analyzer_eval(d.d_mem == 0); // no-oob-warning{{UNKNOWN}}
+}
+
+void memset3_inheritance_field() {
+  Derived d;
+  // FIXME: memset on the base field with sizeof(Derived). By the letter of
+  // the standard this is UB, but practically this only touches memory it is
+  // supposed to with the above class definitions.
+  // Current behavior: with 'oob' the analysis sinks. With 'no-oob' the fields 
are
+  // treated as correctly set to 0.
+  // Expected behavior: same as memset2. The OOB error should be fatal in all
+  // configurations and the 'no-oob' expectations should be removed.
+  memset(&d.b_mem, 0, sizeof(Derived)); // oob-warning{{overflows the 
destination buffer}}
+  clang_analyzer_eval(d.b_mem == 0); // no-oob-warning{{TRUE}}
+  clang_analyzer_eval(d.d_mem == 0); // no-oob-warning{{TRUE}}
+}
+
 void memset4_array_nonpod_object() {
   Derived array[10];
   clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}}
@@ -154,4 +196,55 @@ void memset7_placement_new() {
   clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}}
 }
 
+class BaseVirtual {
+public:
+  int b_mem;
+  virtual int get() { return 1; }
+};
+
+class DerivedVirtual : public BaseVirtual {
+public:
+  int d_mem;
+};
+
+void memset8_virtual_inheritance_field() {
+  DerivedVirtual d;
+  // FIXME: Same as memset3, but the base has a virtual function. In typical
+  // implementations &d.b_mem differs from &d because the vtable pointer
+  // precedes the first member, so this may also write past the object's
+  // extent.
+  // Current behavior: with 'oob' the analysis sinks. With 'no-oob' the fields
+  // are treated as UNKNOWN.
+  // Expected behavior: same as memset2. The OOB error should be fatal in all
+  // configurations and the 'no-oob' expectations should be removed.
+  memset(&d.b_mem, 0, sizeof(Derived)); // oob-warning{{overflows the 
destination buffer}}
+  clang_analyzer_eval(d.b_mem == 0); // no-oob-warning{{UNKNOWN}}
+  clang_analyzer_eval(d.d_mem == 0); // no-oob-warning{{UNKNOWN}}
+}
+
 } // namespace memset_non_pod
+
+void memset1_new_array() {
+  int *array = new int[10];
+  memset(array, 0, 10 * sizeof(int));
+  clang_analyzer_eval(array[2] == 0); // expected-warning{{TRUE}}
+  // FIXME: OOB memset on a heap array.
+  // Current behavior: with 'oob' the analysis sinks. With 'no-oob' it
+  // continues and the eval produces UNKNOWN.
+  // Expected behavior: same as memset2. The OOB error should be fatal in all
+  // configurations and the 'no-oob' expectation should be removed.
+  memset(array + 1, 'a', 10 * sizeof(9)); // oob-warning{{overflows the 
destination buffer}}
+  clang_analyzer_eval(array[2] == 0); // no-oob-warning{{UNKNOWN}}
+  delete[] array;
+}
+
+void memmove_uninit_without_outofbound() {
+  int src[4];
+  int dst[4];
+  // This test verifies that UninitializedRead produces warnings even when
+  // OutOfBounds is disabled. Previously, CheckBufferAccess would early-return
+  // before reaching checkInit() when OutOfBounds was disabled, suppressing
+  // UninitializedRead as a side effect.
+  memmove(dst, src, sizeof(src)); // uninit-warning{{The first element of the 
2nd argument is undefined}}
+                                  // uninit-note@-1{{Other elements might also 
be undefined}}
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to