1// Copyright 2024 The Chromium Authors 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// This is a "No Compile Test" suite. 6// https://dev.chromium.org/developers/testing/no-compile-tests 7 8#include <atomic> 9#include <memory> 10#include <string> 11#include <type_traits> 12#include <utility> 13 14#include "base/memory/raw_ptr.h" 15#include "base/memory/raw_ref.h" 16#include "base/memory/scoped_refptr.h" 17#include "base/memory/read_only_shared_memory_region.h" 18#include "base/memory/safe_ref.h" 19#include "base/memory/shared_memory_mapping.h" 20#include "base/memory/weak_ptr.h" 21 22namespace base { 23 24namespace { 25 26struct NotTriviallyCopyable { 27 std::string data; 28}; 29 30static_assert(!std::is_trivially_copyable_v<NotTriviallyCopyable>); 31 32struct NotLockFree { 33 int large_array[1024] = {}; 34}; 35 36using NotLockFreeAtomic = std::atomic<NotLockFree>; 37 38static_assert(std::is_trivially_copyable_v<NotLockFreeAtomic>); 39static_assert(!NotLockFreeAtomic::is_always_lock_free); 40 41// Assert that common smart pointer types fail the is_trivially_copyable test. 42// This ensures that they can't be used in a shared memory mapping, without 43// needing explicit handling in SharedMemorySafetyChecker. If one of these 44// asserts fails because a type is now trivially copyable, replace it with a 45// SharedMemorySafetyChecker specialization in shared_memory_safety_checker.h 46// that disallows the type. 47static_assert(!std::is_trivially_copyable_v<std::unique_ptr<int>>); 48static_assert(!std::is_trivially_copyable_v<raw_ptr<int>>); 49static_assert(!std::is_trivially_copyable_v<raw_ref<int>>); 50static_assert(!std::is_trivially_copyable_v<base::SafeRef<int>>); 51static_assert(!std::is_trivially_copyable_v<base::WeakPtr<int>>); 52 53} // namespace 54 55void RequireTriviallyCopyable() { 56 auto mapped_region = 57 ReadOnlySharedMemoryRegion::Create(sizeof(NotTriviallyCopyable)); 58 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 59 write_map.GetMemoryAs<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 60 write_map.GetMemoryAsSpan<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 61 write_map.GetMemoryAsSpan<NotTriviallyCopyable>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 62 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 63 read_map.GetMemoryAs<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 64 read_map.GetMemoryAsSpan<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 65 read_map.GetMemoryAsSpan<NotTriviallyCopyable>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 66} 67 68void RequireLockFreeAtomic() { 69 auto mapped_region = 70 ReadOnlySharedMemoryRegion::Create(sizeof(NotLockFreeAtomic)); 71 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 72 write_map.GetMemoryAs<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 73 write_map.GetMemoryAsSpan<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 74 write_map.GetMemoryAsSpan<NotLockFreeAtomic>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 75 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 76 read_map.GetMemoryAs<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 77 read_map.GetMemoryAsSpan<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 78 read_map.GetMemoryAsSpan<NotLockFreeAtomic>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 79} 80 81void NoPointers() { 82 auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(int*)); 83 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 84 write_map.GetMemoryAs<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 85 write_map.GetMemoryAsSpan<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 86 write_map.GetMemoryAsSpan<int*>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 87 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 88 read_map.GetMemoryAs<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 89 read_map.GetMemoryAsSpan<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 90 read_map.GetMemoryAsSpan<int*>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 91} 92 93void NoFunctionPointers() { 94 using FunctionPtr = void (*)(); 95 auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(FunctionPtr)); 96 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 97 write_map.GetMemoryAs<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 98 write_map.GetMemoryAsSpan<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 99 write_map.GetMemoryAsSpan<FunctionPtr>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 100 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 101 read_map.GetMemoryAs<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 102 read_map.GetMemoryAsSpan<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 103 read_map.GetMemoryAsSpan<FunctionPtr>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 104} 105 106void NoMemberFunctionPointers() { 107 using MemberFunctionPtr = size_t (std::string::*)() const; 108 auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(MemberFunctionPtr)); 109 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 110 write_map.GetMemoryAs<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 111 write_map.GetMemoryAsSpan<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 112 write_map.GetMemoryAsSpan<MemberFunctionPtr>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 113 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 114 read_map.GetMemoryAs<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 115 read_map.GetMemoryAsSpan<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 116 read_map.GetMemoryAsSpan<MemberFunctionPtr>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 117} 118 119void NoAtomicPointers() { 120 using AtomicPtr = std::atomic<int*>; 121 auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(AtomicPtr)); 122 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 123 write_map.GetMemoryAs<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 124 write_map.GetMemoryAsSpan<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 125 write_map.GetMemoryAsSpan<AtomicPtr>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 126 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 127 read_map.GetMemoryAs<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 128 read_map.GetMemoryAsSpan<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 129 read_map.GetMemoryAsSpan<AtomicPtr>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 130} 131 132void NoArraysOfBannedTypes() { 133 using Array = NotLockFreeAtomic[2]; 134 auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(Array)); 135 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 136 write_map.GetMemoryAs<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 137 write_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 138 write_map.GetMemoryAsSpan<Array>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 139 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 140 read_map.GetMemoryAs<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 141 read_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 142 read_map.GetMemoryAsSpan<Array>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 143} 144 145void NoStdArraysOfBannedTypes() { 146 using Array = std::array<NotLockFreeAtomic, 2>; 147 auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(Array)); 148 WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); 149 write_map.GetMemoryAs<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 150 write_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 151 write_map.GetMemoryAsSpan<Array>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 152 ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); 153 read_map.GetMemoryAs<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} 154 read_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 155 read_map.GetMemoryAsSpan<Array>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} 156} 157 158} // namespace base 159