RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
MemorySanitizer.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2018 Roman Lebedev
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
20
21#pragma once
22
25#include <cstddef>
26
27// see http://clang.llvm.org/docs/LanguageExtensions.html
28#ifndef __has_feature // Optional of course.
29#define __has_feature(x) 0 // Compatibility with non-clang compilers.
30#endif
31#ifndef __has_extension
32#define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
33#endif
34
35#if __has_feature(memory_sanitizer) || defined(__SANITIZE_MEMORY__)
36#include <sanitizer/msan_interface.h>
37#endif
38
39namespace rawspeed {
40
41struct MSan final {
42 // Do not instantiate.
43 MSan() = delete;
44 MSan(const MSan&) = delete;
45 MSan(MSan&&) = delete;
46 MSan& operator=(const MSan&) = delete;
47 MSan& operator=(MSan&&) = delete;
48 ~MSan() = delete;
49
50private:
51 // Declare memory chunk as being newly-allocated.
52 static void Allocated(const void* addr, size_t size);
54
55public:
56 template <typename T> static void Allocated(const T& elt);
57 static void Allocated(CroppedArray2DRef<std::byte> frame);
58
59private:
60 // Checks that memory range is fully initialized,
61 // and reports an error if it
62 static void CheckMemIsInitialized(const void* addr, size_t size);
64
65public:
66 // Checks that memory range is fully initialized,
67 // and reports an error if it
69};
70
71#if __has_feature(memory_sanitizer) || defined(__SANITIZE_MEMORY__)
72inline void MSan::Allocated(const void* addr, size_t size) {
73 __msan_allocated_memory(addr, size);
74}
75#else
76inline void MSan::Allocated([[maybe_unused]] const void* addr,
77 [[maybe_unused]] size_t size) {
78 // If we are building without MSAN, then there is no way to have a non-empty
79 // body of this function. It's better than to have a macros, or to use
80 // preprocessor in every place it is called.
81}
82#endif
83
84template <typename T> inline void MSan::Allocated(const T& elt) {
85 Allocated(&elt, sizeof(T));
86}
91 for (int row = 0; row < frame.croppedHeight; row++)
92 Allocated(frame[row]);
93}
94
95#if __has_feature(memory_sanitizer) || defined(__SANITIZE_MEMORY__)
96inline void MSan::CheckMemIsInitialized(const void* addr, size_t size) {
97 __msan_check_mem_is_initialized(addr, size);
98}
99#else
100inline void MSan::CheckMemIsInitialized([[maybe_unused]] const void* addr,
101 [[maybe_unused]] size_t size) {
102 // If we are building without MSAN, then there is no way to have a non-empty
103 // body of this function. It's better than to have a macros, or to use
104 // preprocessor in every place it is called.
105}
106#endif
107
112 for (int row = 0; row < frame.croppedHeight; row++)
113 CheckMemIsInitialized(frame[row]);
114}
115
116} // namespace rawspeed
int RAWSPEED_READONLY size() const
throw T(buf.data())
static void Allocated(const void *addr, size_t size)
MSan(MSan &&)=delete
~MSan()=delete
MSan & operator=(const MSan &)=delete
static void CheckMemIsInitialized(const void *addr, size_t size)
MSan & operator=(MSan &&)=delete
MSan(const MSan &)=delete