Skip to content

Commit 172c16a

Browse files
committed
Improve test
1 parent 7a4cab0 commit 172c16a

File tree

2 files changed

+75
-26
lines changed

2 files changed

+75
-26
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
10+
// REQUIRES: asan
11+
12+
// Check that libc++ honors when __SANITIZER_DISABLE_CONTAINER_OVERFLOW__ is set
13+
// and disables the container overflow checks.
14+
15+
// ADDITIONAL_COMPILE_FLAGS: -D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__
16+
17+
#include <deque>
18+
#include <string>
19+
#include <vector>
20+
21+
// This check is somewhat weak because it would pass if we renamed the libc++-internal
22+
// macro and forgot to update this test. But it doesn't hurt to check it in addition to
23+
// the tests below.
24+
#if _LIBCPP_ENABLE_ASAN_CONTAINER_CHECKS
25+
# error "Container overflow checks should be disabled in libc++"
26+
#endif
27+
28+
void vector() {
29+
std::vector<int> v;
30+
v.reserve(100);
31+
int* data = v.data();
32+
33+
// This is illegal with respect to std::vector, but legal from the core language perspective since
34+
// we do own that allocated memory and `int` is an implicit lifetime type. If container overflow
35+
// checks are enabled, this would fail.
36+
data[4] = 42;
37+
}
38+
39+
// For std::string, we must use a custom char_traits class to reliably test this behavior. Since
40+
// std::string is externally instantiated in the built library, __SANITIZER_DISABLE_CONTAINER_OVERFLOW__
41+
// will not be honored for any function that happens to be in the built library. Using a custom
42+
// char_traits class ensures that this doesn't get in the way.
43+
struct my_char_traits : std::char_traits<char> {};
44+
45+
void string() {
46+
std::basic_string<char, my_char_traits> s;
47+
s.reserve(100);
48+
char* data = s.data();
49+
data[4] = 'x';
50+
}
51+
52+
void deque() {
53+
std::deque<int> d;
54+
d.push_back(1);
55+
d.push_back(2);
56+
d.push_back(3);
57+
int* last_element = &d[2];
58+
d.pop_back();
59+
60+
// This reference is technically invalidated according to the library. However since
61+
// we know std::deque is implemented using segments of a fairly large size and we know
62+
// the non-erased elements are not invalidated by pop_front() (per the Standard), we can
63+
// rely on the fact that the last element still exists in memory that is owned by the
64+
// std::deque.
65+
//
66+
// If container overflow checks were enabled, this would obviously fail.
67+
*last_element = 42;
68+
}
69+
70+
int main(int, char**) {
71+
vector();
72+
string();
73+
deque();
74+
return 0;
75+
}

libcxx/test/extensions/libcxx/asan/disable_container_overflow_checks.sh.cpp

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)