blob: fbe1d2f9ffedc0bd1d4648e484f226089d4ed67f [file] [log] [blame]
[email protected]44106182012-04-06 03:53:021// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]0716cba2009-12-17 12:37:582// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]c2a18492011-10-05 13:22:504//
5// This file contains intentional memory errors, some of which may lead to
6// crashes if the test is ran without special memory testing tools. We use these
7// errors to verify the sanity of the tools.
[email protected]0716cba2009-12-17 12:37:588
avi9b6f42932015-12-26 22:15:149#include <stddef.h>
10
[email protected]f49ecd8f2011-05-10 18:03:3411#include "base/atomicops.h"
Scott Violet44165792018-02-22 02:08:0812#include "base/cfi_buildflags.h"
[email protected]b4b34792014-06-14 08:29:3713#include "base/debug/asan_invalid_access.h"
14#include "base/debug/profiler.h"
[email protected]495cad92013-07-18 08:12:4015#include "base/message_loop/message_loop.h"
[email protected]ee857512010-05-14 08:24:4216#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
[email protected]34b99632011-01-01 01:01:0617#include "base/threading/thread.h"
avi9b6f42932015-12-26 22:15:1418#include "build/build_config.h"
[email protected]0716cba2009-12-17 12:37:5819#include "testing/gtest/include/gtest/gtest.h"
20
[email protected]ce072a72010-12-31 20:02:1621namespace base {
22
[email protected]0716cba2009-12-17 12:37:5823namespace {
24
[email protected]f49ecd8f2011-05-10 18:03:3425const base::subtle::Atomic32 kMagicValue = 42;
[email protected]0716cba2009-12-17 12:37:5826
[email protected]c2a18492011-10-05 13:22:5027// Helper for memory accesses that can potentially corrupt memory or cause a
28// crash during a native run.
[email protected]aee2f332014-03-27 15:08:0429#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
[email protected]9a4f6182012-10-24 14:11:0230#if defined(OS_IOS)
31// EXPECT_DEATH is not supported on IOS.
32#define HARMFUL_ACCESS(action,error_regexp) do { action; } while (0)
[email protected]b4b34792014-06-14 08:29:3733#elif defined(SYZYASAN)
34// We won't get a meaningful error message because we're not running under the
35// SyzyASan logger, but we can at least make sure that the error has been
36// generated in the SyzyASan runtime.
37#define HARMFUL_ACCESS(action,unused) \
38if (debug::IsBinaryInstrumented()) { EXPECT_DEATH(action, \
39 "AsanRuntime::OnError"); }
[email protected]9a4f6182012-10-24 14:11:0240#else
[email protected]c2a18492011-10-05 13:22:5041#define HARMFUL_ACCESS(action,error_regexp) EXPECT_DEATH(action,error_regexp)
[email protected]b4b34792014-06-14 08:29:3742#endif // !OS_IOS && !SYZYASAN
[email protected]c2a18492011-10-05 13:22:5043#else
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:2144#define HARMFUL_ACCESS(action, error_regexp)
45#define HARMFUL_ACCESS_IS_NOOP
[email protected]c2a18492011-10-05 13:22:5046#endif
47
[email protected]1e51a962014-01-16 05:31:4148void DoReadUninitializedValue(char *ptr) {
[email protected]43dea192012-05-16 08:42:0849 // Comparison with 64 is to prevent clang from optimizing away the
[email protected]83a13b22011-09-18 16:39:1250 // jump -- valgrind only catches jumps and conditional moves, but clang uses
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:2151 // the borrow flag if the condition is just `*ptr == '\0'`. We no longer
52 // support valgrind, but this constant should be fine to keep as-is.
[email protected]43dea192012-05-16 08:42:0853 if (*ptr == 64) {
[email protected]1e51a962014-01-16 05:31:4154 VLOG(1) << "Uninit condition is true";
[email protected]adf7d802010-09-23 09:12:3755 } else {
[email protected]1e51a962014-01-16 05:31:4156 VLOG(1) << "Uninit condition is false";
[email protected]adf7d802010-09-23 09:12:3757 }
58}
59
[email protected]1e51a962014-01-16 05:31:4160void ReadUninitializedValue(char *ptr) {
61#if defined(MEMORY_SANITIZER)
62 EXPECT_DEATH(DoReadUninitializedValue(ptr),
63 "use-of-uninitialized-value");
64#else
65 DoReadUninitializedValue(ptr);
66#endif
67}
68
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:2169#ifndef HARMFUL_ACCESS_IS_NOOP
[email protected]9ded9912010-03-26 12:54:4470void ReadValueOutOfArrayBoundsLeft(char *ptr) {
[email protected]45b9eba2010-10-18 23:57:4971 char c = ptr[-2];
72 VLOG(1) << "Reading a byte out of bounds: " << c;
[email protected]9ded9912010-03-26 12:54:4473}
74
75void ReadValueOutOfArrayBoundsRight(char *ptr, size_t size) {
[email protected]45b9eba2010-10-18 23:57:4976 char c = ptr[size + 1];
77 VLOG(1) << "Reading a byte out of bounds: " << c;
[email protected]9ded9912010-03-26 12:54:4478}
79
[email protected]9ded9912010-03-26 12:54:4480void WriteValueOutOfArrayBoundsLeft(char *ptr) {
[email protected]f49ecd8f2011-05-10 18:03:3481 ptr[-1] = kMagicValue;
[email protected]9ded9912010-03-26 12:54:4482}
83
[email protected]9ded9912010-03-26 12:54:4484void WriteValueOutOfArrayBoundsRight(char *ptr, size_t size) {
[email protected]f49ecd8f2011-05-10 18:03:3485 ptr[size] = kMagicValue;
[email protected]9ded9912010-03-26 12:54:4486}
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:2187#endif // HARMFUL_ACCESS_IS_NOOP
[email protected]9ded9912010-03-26 12:54:4488
89void MakeSomeErrors(char *ptr, size_t size) {
[email protected]adf7d802010-09-23 09:12:3790 ReadUninitializedValue(ptr);
[email protected]e260ebc2013-12-18 05:31:3391
[email protected]c2a18492011-10-05 13:22:5092 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsLeft(ptr),
[email protected]e260ebc2013-12-18 05:31:3393 "2 bytes to the left");
[email protected]c2a18492011-10-05 13:22:5094 HARMFUL_ACCESS(ReadValueOutOfArrayBoundsRight(ptr, size),
[email protected]e260ebc2013-12-18 05:31:3395 "1 bytes to the right");
[email protected]c2a18492011-10-05 13:22:5096 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsLeft(ptr),
[email protected]e260ebc2013-12-18 05:31:3397 "1 bytes to the left");
[email protected]c2a18492011-10-05 13:22:5098 HARMFUL_ACCESS(WriteValueOutOfArrayBoundsRight(ptr, size),
[email protected]e260ebc2013-12-18 05:31:3399 "0 bytes to the right");
[email protected]9ded9912010-03-26 12:54:44100}
101
[email protected]66d051bb2010-10-14 08:25:54102} // namespace
103
104// A memory leak detector should report an error in this test.
105TEST(ToolsSanityTest, MemoryLeak) {
[email protected]6bfad0e2011-11-01 11:08:09106 // Without the |volatile|, clang optimizes away the next two lines.
107 int* volatile leak = new int[256]; // Leak some memory intentionally.
[email protected]66d051bb2010-10-14 08:25:54108 leak[4] = 1; // Make sure the allocated memory is used.
109}
110
[email protected]3da8c162014-03-28 17:35:10111#if (defined(ADDRESS_SANITIZER) && defined(OS_IOS)) || defined(SYZYASAN)
[email protected]9a4f6182012-10-24 14:11:02112// Because iOS doesn't support death tests, each of the following tests will
[email protected]3da8c162014-03-28 17:35:10113// crash the whole program under Asan. On Windows Asan is based on SyzyAsan; the
114// error report mechanism is different than with Asan so these tests will fail.
[email protected]9a4f6182012-10-24 14:11:02115#define MAYBE_AccessesToNewMemory DISABLED_AccessesToNewMemory
116#define MAYBE_AccessesToMallocMemory DISABLED_AccessesToMallocMemory
[email protected]2d4e0132014-05-14 11:50:37117#else
118#define MAYBE_AccessesToNewMemory AccessesToNewMemory
119#define MAYBE_AccessesToMallocMemory AccessesToMallocMemory
[email protected]de0c7ed52014-07-18 02:40:40120#endif // (defined(ADDRESS_SANITIZER) && defined(OS_IOS)) || defined(SYZYASAN)
[email protected]f5162802014-05-14 16:04:30121
122// The following tests pass with Clang r170392, but not r172454, which
123// makes AddressSanitizer detect errors in them. We disable these tests under
124// AddressSanitizer until we fully switch to Clang r172454. After that the
125// tests should be put back under the (defined(OS_IOS) || defined(OS_WIN))
126// clause above.
127// See also http://crbug.com/172614.
128#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
[email protected]2d4e0132014-05-14 11:50:37129#define MAYBE_SingleElementDeletedWithBraces \
130 DISABLED_SingleElementDeletedWithBraces
[email protected]f5162802014-05-14 16:04:30131#define MAYBE_ArrayDeletedWithoutBraces DISABLED_ArrayDeletedWithoutBraces
[email protected]de0c7ed52014-07-18 02:40:40132#else
133#define MAYBE_ArrayDeletedWithoutBraces ArrayDeletedWithoutBraces
134#define MAYBE_SingleElementDeletedWithBraces SingleElementDeletedWithBraces
135#endif // defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
136
[email protected]9a4f6182012-10-24 14:11:02137TEST(ToolsSanityTest, MAYBE_AccessesToNewMemory) {
[email protected]9ded9912010-03-26 12:54:44138 char *foo = new char[10];
139 MakeSomeErrors(foo, 10);
140 delete [] foo;
[email protected]c2a18492011-10-05 13:22:50141 // Use after delete.
142 HARMFUL_ACCESS(foo[5] = 0, "heap-use-after-free");
[email protected]9ded9912010-03-26 12:54:44143}
144
[email protected]9a4f6182012-10-24 14:11:02145TEST(ToolsSanityTest, MAYBE_AccessesToMallocMemory) {
[email protected]9ded9912010-03-26 12:54:44146 char *foo = reinterpret_cast<char*>(malloc(10));
147 MakeSomeErrors(foo, 10);
148 free(foo);
[email protected]c2a18492011-10-05 13:22:50149 // Use after free.
150 HARMFUL_ACCESS(foo[5] = 0, "heap-use-after-free");
[email protected]9ded9912010-03-26 12:54:44151}
152
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21153#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
154
hanscd4cce32015-05-19 17:03:14155static int* allocateArray() {
156 // Clang warns about the mismatched new[]/delete if they occur in the same
157 // function.
158 return new int[10];
159}
160
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21161// This test may corrupt memory if not compiled with AddressSanitizer.
[email protected]9a4f6182012-10-24 14:11:02162TEST(ToolsSanityTest, MAYBE_ArrayDeletedWithoutBraces) {
[email protected]014b0b062011-09-18 16:30:12163 // Without the |volatile|, clang optimizes away the next two lines.
hanscd4cce32015-05-19 17:03:14164 int* volatile foo = allocateArray();
[email protected]f5162802014-05-14 16:04:30165 delete foo;
[email protected]9ded9912010-03-26 12:54:44166}
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21167#endif
[email protected]9ded9912010-03-26 12:54:44168
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21169#if defined(ADDRESS_SANITIZER)
hanscd4cce32015-05-19 17:03:14170static int* allocateScalar() {
171 // Clang warns about the mismatched new/delete[] if they occur in the same
172 // function.
173 return new int;
174}
175
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21176// This test may corrupt memory if not compiled with AddressSanitizer.
[email protected]9a4f6182012-10-24 14:11:02177TEST(ToolsSanityTest, MAYBE_SingleElementDeletedWithBraces) {
[email protected]014b0b062011-09-18 16:30:12178 // Without the |volatile|, clang optimizes away the next two lines.
hanscd4cce32015-05-19 17:03:14179 int* volatile foo = allocateScalar();
[email protected]928ca1d2011-09-30 18:52:04180 (void) foo;
[email protected]f5162802014-05-14 16:04:30181 delete [] foo;
[email protected]9ded9912010-03-26 12:54:44182}
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21183#endif
[email protected]9ded9912010-03-26 12:54:44184
[email protected]aee2f332014-03-27 15:08:04185#if defined(ADDRESS_SANITIZER) || defined(SYZYASAN)
[email protected]b4b34792014-06-14 08:29:37186
[email protected]9b147ae2011-11-08 09:28:49187TEST(ToolsSanityTest, DISABLED_AddressSanitizerNullDerefCrashTest) {
[email protected]6fcbc62f2011-10-12 17:18:24188 // Intentionally crash to make sure AddressSanitizer is running.
189 // This test should not be ran on bots.
190 int* volatile zero = NULL;
191 *zero = 0;
192}
[email protected]9b147ae2011-11-08 09:28:49193
194TEST(ToolsSanityTest, DISABLED_AddressSanitizerLocalOOBCrashTest) {
195 // Intentionally crash to make sure AddressSanitizer is instrumenting
196 // the local variables.
197 // This test should not be ran on bots.
198 int array[5];
199 // Work around the OOB warning reported by Clang.
200 int* volatile access = &array[5];
201 *access = 43;
202}
203
204namespace {
205int g_asan_test_global_array[10];
206} // namespace
207
208TEST(ToolsSanityTest, DISABLED_AddressSanitizerGlobalOOBCrashTest) {
209 // Intentionally crash to make sure AddressSanitizer is instrumenting
210 // the global variables.
211 // This test should not be ran on bots.
212
213 // Work around the OOB warning reported by Clang.
214 int* volatile access = g_asan_test_global_array - 1;
215 *access = 43;
216}
217
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21218#ifndef HARMFUL_ACCESS_IS_NOOP
[email protected]b4b34792014-06-14 08:29:37219TEST(ToolsSanityTest, AsanHeapOverflow) {
220 HARMFUL_ACCESS(debug::AsanHeapOverflow() ,"to the right");
221}
222
223TEST(ToolsSanityTest, AsanHeapUnderflow) {
224 HARMFUL_ACCESS(debug::AsanHeapUnderflow(), "to the left");
225}
226
227TEST(ToolsSanityTest, AsanHeapUseAfterFree) {
228 HARMFUL_ACCESS(debug::AsanHeapUseAfterFree(), "heap-use-after-free");
229}
230
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21231#if defined(SYZYASAN) && defined(COMPILER_MSVC)
[email protected]b4b34792014-06-14 08:29:37232TEST(ToolsSanityTest, AsanCorruptHeapBlock) {
233 HARMFUL_ACCESS(debug::AsanCorruptHeapBlock(), "");
234}
235
236TEST(ToolsSanityTest, AsanCorruptHeap) {
237 // This test will kill the process by raising an exception, there's no
238 // particular string to look for in the stack trace.
239 EXPECT_DEATH(debug::AsanCorruptHeap(), "");
240}
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21241#endif // SYZYASAN && COMPILER_MSVC
242#endif // !HARMFUL_ACCESS_IS_NOOP
[email protected]b4b34792014-06-14 08:29:37243
244#endif // ADDRESS_SANITIZER || SYZYASAN
[email protected]f49ecd8f2011-05-10 18:03:34245
246namespace {
247
248// We use caps here just to ensure that the method name doesn't interfere with
249// the wildcarded suppressions.
250class TOOLS_SANITY_TEST_CONCURRENT_THREAD : public PlatformThread::Delegate {
251 public:
252 explicit TOOLS_SANITY_TEST_CONCURRENT_THREAD(bool *value) : value_(value) {}
Chris Watkinsbb7211c2017-11-29 07:16:38253 ~TOOLS_SANITY_TEST_CONCURRENT_THREAD() override = default;
dcheng56488182014-10-21 10:54:51254 void ThreadMain() override {
[email protected]f49ecd8f2011-05-10 18:03:34255 *value_ = true;
256
257 // Sleep for a few milliseconds so the two threads are more likely to live
258 // simultaneously. Otherwise we may miss the report due to mutex
259 // lock/unlock's inside thread creation code in pure-happens-before mode...
[email protected]a1b75b942011-12-31 22:53:51260 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
[email protected]f49ecd8f2011-05-10 18:03:34261 }
262 private:
263 bool *value_;
264};
265
266class ReleaseStoreThread : public PlatformThread::Delegate {
267 public:
268 explicit ReleaseStoreThread(base::subtle::Atomic32 *value) : value_(value) {}
Chris Watkinsbb7211c2017-11-29 07:16:38269 ~ReleaseStoreThread() override = default;
dcheng56488182014-10-21 10:54:51270 void ThreadMain() override {
[email protected]f49ecd8f2011-05-10 18:03:34271 base::subtle::Release_Store(value_, kMagicValue);
272
273 // Sleep for a few milliseconds so the two threads are more likely to live
274 // simultaneously. Otherwise we may miss the report due to mutex
275 // lock/unlock's inside thread creation code in pure-happens-before mode...
[email protected]a1b75b942011-12-31 22:53:51276 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
[email protected]f49ecd8f2011-05-10 18:03:34277 }
278 private:
279 base::subtle::Atomic32 *value_;
280};
281
282class AcquireLoadThread : public PlatformThread::Delegate {
283 public:
284 explicit AcquireLoadThread(base::subtle::Atomic32 *value) : value_(value) {}
Chris Watkinsbb7211c2017-11-29 07:16:38285 ~AcquireLoadThread() override = default;
dcheng56488182014-10-21 10:54:51286 void ThreadMain() override {
[email protected]f49ecd8f2011-05-10 18:03:34287 // Wait for the other thread to make Release_Store
[email protected]a1b75b942011-12-31 22:53:51288 PlatformThread::Sleep(TimeDelta::FromMilliseconds(100));
[email protected]f49ecd8f2011-05-10 18:03:34289 base::subtle::Acquire_Load(value_);
290 }
291 private:
292 base::subtle::Atomic32 *value_;
293};
294
295void RunInParallel(PlatformThread::Delegate *d1, PlatformThread::Delegate *d2) {
296 PlatformThreadHandle a;
297 PlatformThreadHandle b;
298 PlatformThread::Create(0, d1, &a);
299 PlatformThread::Create(0, d2, &b);
300 PlatformThread::Join(a);
301 PlatformThread::Join(b);
302}
303
[email protected]b11d38d02014-06-26 13:10:50304#if defined(THREAD_SANITIZER)
305void DataRace() {
[email protected]a4057982013-03-23 11:28:17306 bool *shared = new bool(false);
307 TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(shared), thread2(shared);
[email protected]f49ecd8f2011-05-10 18:03:34308 RunInParallel(&thread1, &thread2);
[email protected]a4057982013-03-23 11:28:17309 EXPECT_TRUE(*shared);
310 delete shared;
[email protected]b11d38d02014-06-26 13:10:50311 // We're in a death test - crash.
312 CHECK(0);
[email protected]f49ecd8f2011-05-10 18:03:34313}
[email protected]b11d38d02014-06-26 13:10:50314#endif
315
316} // namespace
317
318#if defined(THREAD_SANITIZER)
319// A data race detector should report an error in this test.
320TEST(ToolsSanityTest, DataRace) {
321 // The suppression regexp must match that in base/debug/tsan_suppressions.cc.
322 EXPECT_DEATH(DataRace(), "1 race:base/tools_sanity_unittest.cc");
323}
324#endif
[email protected]f49ecd8f2011-05-10 18:03:34325
326TEST(ToolsSanityTest, AnnotateBenignRace) {
327 bool shared = false;
328 ANNOTATE_BENIGN_RACE(&shared, "Intentional race - make sure doesn't show up");
329 TOOLS_SANITY_TEST_CONCURRENT_THREAD thread1(&shared), thread2(&shared);
330 RunInParallel(&thread1, &thread2);
331 EXPECT_TRUE(shared);
332}
333
334TEST(ToolsSanityTest, AtomicsAreIgnored) {
335 base::subtle::Atomic32 shared = 0;
336 ReleaseStoreThread thread1(&shared);
337 AcquireLoadThread thread2(&shared);
338 RunInParallel(&thread1, &thread2);
339 EXPECT_EQ(kMagicValue, shared);
[email protected]0716cba2009-12-17 12:37:58340}
[email protected]ce072a72010-12-31 20:02:16341
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24342#if BUILDFLAG(CFI_ENFORCEMENT_TRAP)
Peter Collingbourne355546f2017-10-12 19:51:27343#if defined(OS_WIN)
344#define CFI_ERROR_MSG "EXCEPTION_ILLEGAL_INSTRUCTION"
345#elif defined(OS_ANDROID)
346// TODO(pcc): Produce proper stack dumps on Android and test for the correct
347// si_code here.
348#define CFI_ERROR_MSG "^$"
349#else
Vlad Tsyrklevich37f1e352017-08-15 23:45:10350#define CFI_ERROR_MSG "ILL_ILLOPN"
Peter Collingbourne355546f2017-10-12 19:51:27351#endif
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24352#elif BUILDFLAG(CFI_ENFORCEMENT_DIAGNOSTIC)
Vlad Tsyrklevich37f1e352017-08-15 23:45:10353#define CFI_ERROR_MSG "runtime error: control flow integrity check"
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24354#endif // BUILDFLAG(CFI_ENFORCEMENT_TRAP || CFI_ENFORCEMENT_DIAGNOSTIC)
pcc07364912015-07-31 00:19:06355
Vlad Tsyrklevich37f1e352017-08-15 23:45:10356#if defined(CFI_ERROR_MSG)
krasin59d37182016-07-13 03:24:34357class A {
358 public:
359 A(): n_(0) {}
360 virtual void f() { n_++; }
361 protected:
362 int n_;
363};
364
365class B: public A {
366 public:
367 void f() override { n_--; }
368};
369
Vlad Tsyrklevich37f1e352017-08-15 23:45:10370class C: public B {
371 public:
372 void f() override { n_ += 2; }
373};
374
krasin59d37182016-07-13 03:24:34375NOINLINE void KillVptrAndCall(A *obj) {
376 *reinterpret_cast<void **>(obj) = 0;
377 obj->f();
378}
379
Vlad Tsyrklevich37f1e352017-08-15 23:45:10380TEST(ToolsSanityTest, BadVirtualCallNull) {
krasin59d37182016-07-13 03:24:34381 A a;
382 B b;
Vlad Tsyrklevich37f1e352017-08-15 23:45:10383 EXPECT_DEATH({ KillVptrAndCall(&a); KillVptrAndCall(&b); }, CFI_ERROR_MSG);
krasin59d37182016-07-13 03:24:34384}
385
Vlad Tsyrklevich37f1e352017-08-15 23:45:10386NOINLINE void OverwriteVptrAndCall(B *obj, A *vptr) {
387 *reinterpret_cast<void **>(obj) = *reinterpret_cast<void **>(vptr);
388 obj->f();
389}
390
391TEST(ToolsSanityTest, BadVirtualCallWrongType) {
392 A a;
393 B b;
394 C c;
395 EXPECT_DEATH({ OverwriteVptrAndCall(&b, &a); OverwriteVptrAndCall(&b, &c); },
396 CFI_ERROR_MSG);
397}
398
399// TODO(pcc): remove CFI_CAST_CHECK, see https://crbug.com/626794.
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24400#if BUILDFLAG(CFI_CAST_CHECK)
Vlad Tsyrklevich37f1e352017-08-15 23:45:10401TEST(ToolsSanityTest, BadDerivedCast) {
402 A a;
403 EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
404}
405
406TEST(ToolsSanityTest, BadUnrelatedCast) {
407 class A {
408 virtual void f() {}
409 };
410
411 class B {
412 virtual void f() {}
413 };
414
415 A a;
416 EXPECT_DEATH((void)(B*)&a, CFI_ERROR_MSG);
417}
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24418#endif // BUILDFLAG(CFI_CAST_CHECK)
Vlad Tsyrklevich37f1e352017-08-15 23:45:10419
Vlad Tsyrkleviche0408ff2017-10-13 19:35:24420#endif // CFI_ERROR_MSG
pcc07364912015-07-31 00:19:06421
Mostyn Bramley-Moored0ecd6a2017-12-06 19:13:21422#undef CFI_ERROR_MSG
423#undef MAYBE_AccessesToNewMemory
424#undef MAYBE_AccessesToMallocMemory
425#undef MAYBE_ArrayDeletedWithoutBraces
426#undef MAYBE_SingleElementDeletedWithBraces
427#undef HARMFUL_ACCESS
428#undef HARMFUL_ACCESS_IS_NOOP
429
[email protected]ce072a72010-12-31 20:02:16430} // namespace base