// Copyright 2024 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This is a "No Compile Test" suite. // https://dev.chromium.org/developers/testing/no-compile-tests #include #include #include #include #include #include "base/memory/raw_ptr.h" #include "base/memory/raw_ref.h" #include "base/memory/scoped_refptr.h" #include "base/memory/read_only_shared_memory_region.h" #include "base/memory/safe_ref.h" #include "base/memory/shared_memory_mapping.h" #include "base/memory/weak_ptr.h" namespace base { namespace { struct NotTriviallyCopyable { std::string data; }; static_assert(!std::is_trivially_copyable_v); struct NotLockFree { int large_array[1024] = {}; }; using NotLockFreeAtomic = std::atomic; static_assert(std::is_trivially_copyable_v); static_assert(!NotLockFreeAtomic::is_always_lock_free); // Assert that common smart pointer types fail the is_trivially_copyable test. // This ensures that they can't be used in a shared memory mapping, without // needing explicit handling in SharedMemorySafetyChecker. If one of these // asserts fails because a type is now trivially copyable, replace it with a // SharedMemorySafetyChecker specialization in shared_memory_safety_checker.h // that disallows the type. static_assert(!std::is_trivially_copyable_v>); static_assert(!std::is_trivially_copyable_v>); static_assert(!std::is_trivially_copyable_v>); static_assert(!std::is_trivially_copyable_v>); static_assert(!std::is_trivially_copyable_v>); } // namespace void RequireTriviallyCopyable() { auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(NotTriviallyCopyable)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } void RequireLockFreeAtomic() { auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(NotLockFreeAtomic)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } void NoPointers() { auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(int*)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } void NoFunctionPointers() { using FunctionPtr = void (*)(); auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(FunctionPtr)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } void NoMemberFunctionPointers() { using MemberFunctionPtr = size_t (std::string::*)() const; auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(MemberFunctionPtr)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } void NoAtomicPointers() { using AtomicPtr = std::atomic; auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(AtomicPtr)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } void NoArraysOfBannedTypes() { using Array = NotLockFreeAtomic[2]; auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(Array)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } void NoStdArraysOfBannedTypes() { using Array = std::array; auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(Array)); WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping); write_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} write_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} write_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} ReadOnlySharedMemoryMapping read_map = mapped_region.region.Map(); read_map.GetMemoryAs(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}} read_map.GetMemoryAsSpan(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} read_map.GetMemoryAsSpan(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}} } } // namespace base