// 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 <atomic>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/raw_span.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<NotTriviallyCopyable>);
struct NotLockFree {
int large_array[1024] = {};
};
using NotLockFreeAtomic = std::atomic<NotLockFree>;
static_assert(std::is_trivially_copyable_v<NotLockFreeAtomic>);
static_assert(!NotLockFreeAtomic::is_always_lock_free);
// Assert that common smart pointer types fail the is_trivially_copyable test.
static_assert(!std::is_trivially_copyable_v<std::unique_ptr<int>>);
static_assert(!std::is_trivially_copyable_v<raw_ptr<int>>);
static_assert(!std::is_trivially_copyable_v<raw_ref<int>>);
static_assert(!std::is_trivially_copyable_v<raw_span<int>>);
static_assert(!std::is_trivially_copyable_v<base::SafeRef<int>>);
static_assert(!std::is_trivially_copyable_v<base::WeakPtr<int>>);
} // namespace
void RequireTriviallyCopyable() {
auto mapped_region =
ReadOnlySharedMemoryRegion::Create(sizeof(NotTriviallyCopyable));
WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping);
write_map.GetMemoryAs<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<NotTriviallyCopyable>(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<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<NotTriviallyCopyable>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<NotTriviallyCopyable>(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<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<NotLockFreeAtomic>(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<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<NotLockFreeAtomic>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<NotLockFreeAtomic>(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<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<int*>(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<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<int*>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<int*>(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<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<FunctionPtr>(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<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<FunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<FunctionPtr>(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<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<MemberFunctionPtr>(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<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<MemberFunctionPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<MemberFunctionPtr>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
}
void NoAtomicPointers() {
using AtomicPtr = std::atomic<int*>;
auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(AtomicPtr));
WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping);
write_map.GetMemoryAs<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<AtomicPtr>(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<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<AtomicPtr>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<AtomicPtr>(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<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<Array>(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<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<Array>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
}
void NoStdArraysOfBannedTypes() {
using Array = std::array<NotLockFreeAtomic, 2>;
auto mapped_region = ReadOnlySharedMemoryRegion::Create(sizeof(Array));
WritableSharedMemoryMapping write_map = std::move(mapped_region.mapping);
write_map.GetMemoryAs<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
write_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
write_map.GetMemoryAsSpan<Array>(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<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAs'}}
read_map.GetMemoryAsSpan<Array>(); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
read_map.GetMemoryAsSpan<Array>(1); // expected-error@base/memory/shared_memory_mapping_nocompile.nc:* {{no matching member function for call to 'GetMemoryAsSpan'}}
}
} // namespace base