1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2018 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/sanitizer.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
14*d9f75844SAndroid Build Coastguard Worker
15*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
16*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
17*d9f75844SAndroid Build Coastguard Worker
18*d9f75844SAndroid Build Coastguard Worker #if RTC_HAS_MSAN
19*d9f75844SAndroid Build Coastguard Worker #include <sanitizer/msan_interface.h>
20*d9f75844SAndroid Build Coastguard Worker #endif
21*d9f75844SAndroid Build Coastguard Worker
22*d9f75844SAndroid Build Coastguard Worker namespace rtc {
23*d9f75844SAndroid Build Coastguard Worker namespace {
24*d9f75844SAndroid Build Coastguard Worker
25*d9f75844SAndroid Build Coastguard Worker // Test sanitizer_impl::IsTriviallyCopyable (at compile time).
26*d9f75844SAndroid Build Coastguard Worker
27*d9f75844SAndroid Build Coastguard Worker // Trivially copyable.
28*d9f75844SAndroid Build Coastguard Worker
29*d9f75844SAndroid Build Coastguard Worker struct TrTrTr {
30*d9f75844SAndroid Build Coastguard Worker TrTrTr(const TrTrTr&) = default;
31*d9f75844SAndroid Build Coastguard Worker TrTrTr& operator=(const TrTrTr&) = default;
32*d9f75844SAndroid Build Coastguard Worker ~TrTrTr() = default;
33*d9f75844SAndroid Build Coastguard Worker };
34*d9f75844SAndroid Build Coastguard Worker static_assert(sanitizer_impl::IsTriviallyCopyable<TrTrTr>(), "");
35*d9f75844SAndroid Build Coastguard Worker
36*d9f75844SAndroid Build Coastguard Worker struct TrDeTr {
37*d9f75844SAndroid Build Coastguard Worker TrDeTr(const TrDeTr&) = default;
38*d9f75844SAndroid Build Coastguard Worker TrDeTr& operator=(const TrDeTr&) = delete;
39*d9f75844SAndroid Build Coastguard Worker ~TrDeTr() = default;
40*d9f75844SAndroid Build Coastguard Worker };
41*d9f75844SAndroid Build Coastguard Worker static_assert(sanitizer_impl::IsTriviallyCopyable<TrDeTr>(), "");
42*d9f75844SAndroid Build Coastguard Worker
43*d9f75844SAndroid Build Coastguard Worker // Non trivially copyable.
44*d9f75844SAndroid Build Coastguard Worker
45*d9f75844SAndroid Build Coastguard Worker struct TrTrNt {
46*d9f75844SAndroid Build Coastguard Worker TrTrNt(const TrTrNt&) = default;
47*d9f75844SAndroid Build Coastguard Worker TrTrNt& operator=(const TrTrNt&) = default;
48*d9f75844SAndroid Build Coastguard Worker ~TrTrNt();
49*d9f75844SAndroid Build Coastguard Worker };
50*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<TrTrNt>(), "");
51*d9f75844SAndroid Build Coastguard Worker
52*d9f75844SAndroid Build Coastguard Worker struct TrNtTr {
53*d9f75844SAndroid Build Coastguard Worker TrNtTr(const TrNtTr&) = default;
54*d9f75844SAndroid Build Coastguard Worker TrNtTr& operator=(const TrNtTr&);
55*d9f75844SAndroid Build Coastguard Worker ~TrNtTr() = default;
56*d9f75844SAndroid Build Coastguard Worker };
57*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<TrNtTr>(), "");
58*d9f75844SAndroid Build Coastguard Worker
59*d9f75844SAndroid Build Coastguard Worker struct TrNtNt {
60*d9f75844SAndroid Build Coastguard Worker TrNtNt(const TrNtNt&) = default;
61*d9f75844SAndroid Build Coastguard Worker TrNtNt& operator=(const TrNtNt&);
62*d9f75844SAndroid Build Coastguard Worker ~TrNtNt();
63*d9f75844SAndroid Build Coastguard Worker };
64*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<TrNtNt>(), "");
65*d9f75844SAndroid Build Coastguard Worker
66*d9f75844SAndroid Build Coastguard Worker struct TrDeNt {
67*d9f75844SAndroid Build Coastguard Worker TrDeNt(const TrDeNt&) = default;
68*d9f75844SAndroid Build Coastguard Worker TrDeNt& operator=(const TrDeNt&) = delete;
69*d9f75844SAndroid Build Coastguard Worker ~TrDeNt();
70*d9f75844SAndroid Build Coastguard Worker };
71*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<TrDeNt>(), "");
72*d9f75844SAndroid Build Coastguard Worker
73*d9f75844SAndroid Build Coastguard Worker struct NtTrTr {
74*d9f75844SAndroid Build Coastguard Worker NtTrTr(const NtTrTr&);
75*d9f75844SAndroid Build Coastguard Worker NtTrTr& operator=(const NtTrTr&) = default;
76*d9f75844SAndroid Build Coastguard Worker ~NtTrTr() = default;
77*d9f75844SAndroid Build Coastguard Worker };
78*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<NtTrTr>(), "");
79*d9f75844SAndroid Build Coastguard Worker
80*d9f75844SAndroid Build Coastguard Worker struct NtTrNt {
81*d9f75844SAndroid Build Coastguard Worker NtTrNt(const NtTrNt&);
82*d9f75844SAndroid Build Coastguard Worker NtTrNt& operator=(const NtTrNt&) = default;
83*d9f75844SAndroid Build Coastguard Worker ~NtTrNt();
84*d9f75844SAndroid Build Coastguard Worker };
85*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<NtTrNt>(), "");
86*d9f75844SAndroid Build Coastguard Worker
87*d9f75844SAndroid Build Coastguard Worker struct NtNtTr {
88*d9f75844SAndroid Build Coastguard Worker NtNtTr(const NtNtTr&);
89*d9f75844SAndroid Build Coastguard Worker NtNtTr& operator=(const NtNtTr&);
90*d9f75844SAndroid Build Coastguard Worker ~NtNtTr() = default;
91*d9f75844SAndroid Build Coastguard Worker };
92*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<NtNtTr>(), "");
93*d9f75844SAndroid Build Coastguard Worker
94*d9f75844SAndroid Build Coastguard Worker struct NtNtNt {
95*d9f75844SAndroid Build Coastguard Worker NtNtNt(const NtNtNt&);
96*d9f75844SAndroid Build Coastguard Worker NtNtNt& operator=(const NtNtNt&);
97*d9f75844SAndroid Build Coastguard Worker ~NtNtNt();
98*d9f75844SAndroid Build Coastguard Worker };
99*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<NtNtNt>(), "");
100*d9f75844SAndroid Build Coastguard Worker
101*d9f75844SAndroid Build Coastguard Worker struct NtDeTr {
102*d9f75844SAndroid Build Coastguard Worker NtDeTr(const NtDeTr&);
103*d9f75844SAndroid Build Coastguard Worker NtDeTr& operator=(const NtDeTr&) = delete;
104*d9f75844SAndroid Build Coastguard Worker ~NtDeTr() = default;
105*d9f75844SAndroid Build Coastguard Worker };
106*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<NtDeTr>(), "");
107*d9f75844SAndroid Build Coastguard Worker
108*d9f75844SAndroid Build Coastguard Worker struct NtDeNt {
109*d9f75844SAndroid Build Coastguard Worker NtDeNt(const NtDeNt&);
110*d9f75844SAndroid Build Coastguard Worker NtDeNt& operator=(const NtDeNt&) = delete;
111*d9f75844SAndroid Build Coastguard Worker ~NtDeNt();
112*d9f75844SAndroid Build Coastguard Worker };
113*d9f75844SAndroid Build Coastguard Worker static_assert(!sanitizer_impl::IsTriviallyCopyable<NtDeNt>(), "");
114*d9f75844SAndroid Build Coastguard Worker
115*d9f75844SAndroid Build Coastguard Worker // Trivially copyable types.
116*d9f75844SAndroid Build Coastguard Worker
117*d9f75844SAndroid Build Coastguard Worker struct Foo {
118*d9f75844SAndroid Build Coastguard Worker uint32_t field1;
119*d9f75844SAndroid Build Coastguard Worker uint16_t field2;
120*d9f75844SAndroid Build Coastguard Worker };
121*d9f75844SAndroid Build Coastguard Worker
122*d9f75844SAndroid Build Coastguard Worker struct Bar {
123*d9f75844SAndroid Build Coastguard Worker uint32_t ID;
124*d9f75844SAndroid Build Coastguard Worker Foo foo;
125*d9f75844SAndroid Build Coastguard Worker };
126*d9f75844SAndroid Build Coastguard Worker
127*d9f75844SAndroid Build Coastguard Worker // Run the callback, and expect a crash if it *doesn't* make an uninitialized
128*d9f75844SAndroid Build Coastguard Worker // memory read. If MSan isn't on, just run the callback.
129*d9f75844SAndroid Build Coastguard Worker template <typename F>
MsanExpectUninitializedRead(F && f)130*d9f75844SAndroid Build Coastguard Worker void MsanExpectUninitializedRead(F&& f) {
131*d9f75844SAndroid Build Coastguard Worker #if RTC_HAS_MSAN
132*d9f75844SAndroid Build Coastguard Worker EXPECT_DEATH(f(), "");
133*d9f75844SAndroid Build Coastguard Worker #else
134*d9f75844SAndroid Build Coastguard Worker f();
135*d9f75844SAndroid Build Coastguard Worker #endif
136*d9f75844SAndroid Build Coastguard Worker }
137*d9f75844SAndroid Build Coastguard Worker
138*d9f75844SAndroid Build Coastguard Worker } // namespace
139*d9f75844SAndroid Build Coastguard Worker
TEST(SanitizerTest,MsanUninitialized)140*d9f75844SAndroid Build Coastguard Worker TEST(SanitizerTest, MsanUninitialized) {
141*d9f75844SAndroid Build Coastguard Worker Bar bar = MsanUninitialized<Bar>({});
142*d9f75844SAndroid Build Coastguard Worker // Check that a read after initialization is OK.
143*d9f75844SAndroid Build Coastguard Worker bar.ID = 1;
144*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, bar.ID);
145*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "read after init passed";
146*d9f75844SAndroid Build Coastguard Worker // Check that other fields are uninitialized and equal to zero.
147*d9f75844SAndroid Build Coastguard Worker MsanExpectUninitializedRead([&] { EXPECT_EQ(0u, bar.foo.field1); });
148*d9f75844SAndroid Build Coastguard Worker MsanExpectUninitializedRead([&] { EXPECT_EQ(0u, bar.foo.field2); });
149*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "read with no init passed";
150*d9f75844SAndroid Build Coastguard Worker }
151*d9f75844SAndroid Build Coastguard Worker
152*d9f75844SAndroid Build Coastguard Worker } // namespace rtc
153