0

[BRP/clang-plugin] emit error for unsafe raw_ptr<T>/raw_ref<T> casting

- Add an option `check-bad-raw-ptr-cast-nested` to the clang plugin
  - When specified, bad casting check for `raw_ptr<T>` or `raw_ref<T>`
    becomes more strict
- Add a class `CastingUnsafePredicate` to judge a type is "casting
  unsafe" or not.
  - `raw_ptr<T>` or `raw_ref<T>` are "casting unsafe"
  - Pointers, references and arrays of "casting unsafe" element(s) are
    "casting unsafe"
  - Classes and structs having a "casting unsafe" member are
    "casting unsafe"
  - Classes and structs having a "casting unsafe" base class are
    "casting unsafe"
- Casting into/from "casting unsafe" is illegal if the casting type is
  one of followings:
  - `CK_BitCast`: `static_cast<T>` or `reinretpret_cast<T>`
  - `CK_LValueBitCast`: similar to above, but as a part of assignment
    to a reference
  - `CK_LValueToRValueBitCast`: `std::bit_cast<T>` or `__builtin_bit_cast`
  - `CK_PointerToIntegral`, `CK_IntegralToPointer`: to prevent
    "pointer -> integral -> pointer" casting.

Fixed: 1439745
Change-Id: I584ec879c1211ee436de8f5e7cd46c49713b2d0b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4482025
Reviewed-by: Keishi Hattori <keishi@chromium.org>
Commit-Queue: Mikihito Matsuura <mikt@google.com>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1144534}
This commit is contained in:
mikt
2023-05-16 03:05:31 +00:00
committed by Chromium LUCI CQ
parent 112224843f
commit bfe42acde8
32 changed files with 2101 additions and 96 deletions

@ -762,8 +762,8 @@ _BANNED_CPP_FUNCTIONS : Sequence[BanRule] = (
# Fuchsia provides C++ libraries that use std::shared_ptr<>.
'^base/fuchsia/.*\.(cc|h)',
'.*fuchsia.*test\.(cc|h)',
# Needed for clang plugin tests
'^tools/clang/plugins/tests/',
# Clang plugins have different build config.
'^tools/clang/plugins/',
_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders.
),
BanRule(
@ -1023,7 +1023,12 @@ _BANNED_CPP_FUNCTIONS : Sequence[BanRule] = (
'absl::optional instead.',
),
True,
[_THIRD_PARTY_EXCEPT_BLINK], # Not an error in third_party folders.
[
# Clang plugins have different build config.
'^tools/clang/plugins/',
# Not an error in third_party folders.
_THIRD_PARTY_EXCEPT_BLINK,
],
),
BanRule(
r'/#include <chrono>',

@ -6,6 +6,7 @@ set(plugin_sources
FindBadRawPtrPatterns.cpp
CheckIPCVisitor.cpp
CheckLayoutObjectMethodsVisitor.cpp
RawPtrCastingUnsafeChecker.cpp
RawPtrHelpers.cpp
StackAllocatedChecker.cpp
Util.cpp

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "FindBadRawPtrPatterns.h"
#include <memory>
#include "RawPtrHelpers.h"
#include "RawPtrManualPathsToIgnore.h"
@ -22,29 +23,48 @@ using namespace clang::ast_matchers;
namespace chrome_checker {
const char kBadCastSignature[] =
"[chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not "
"allowed as it may cause BRP ref count mismatch and bypass security "
"checks.";
constexpr char kBadCastDiagnostic[] =
"[chromium-style] casting '%0' to '%1 is not allowed.";
constexpr char kBadCastDiagnosticNoteExplanation[] =
"[chromium-style] '%0' manages BackupRefPtr refcounts; bypassing its C++ "
"interface or treating it as a POD will lead to memory safety errors.";
constexpr char kBadCastDiagnosticNoteType[] =
"[chromium-style] '%0' manages BackupRefPtr or its container here.";
class BadCastMatcher : public MatchFinder::MatchCallback {
public:
explicit BadCastMatcher(clang::CompilerInstance& compiler)
: compiler_(compiler) {
error_bad_raw_ptr_cast_signature_ =
error_bad_cast_signature_ = compiler_.getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Error, kBadCastDiagnostic);
note_bad_cast_signature_explanation_ =
compiler_.getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Error, kBadCastSignature);
clang::DiagnosticsEngine::Note, kBadCastDiagnosticNoteExplanation);
note_bad_cast_signature_type_ = compiler_.getDiagnostics().getCustomDiagID(
clang::DiagnosticsEngine::Note, kBadCastDiagnosticNoteType);
}
void Register(MatchFinder& match_finder) {
// TODO(keishi): Also find casts to and from classes that contain raw_ptr.
// Matches anything contains |raw_ptr<T>| / |raw_ref<T>|.
auto src_type =
type(isCastingUnsafe(casting_unsafe_predicate_)).bind("srcType");
auto dst_type =
type(isCastingUnsafe(casting_unsafe_predicate_)).bind("dstType");
// Matches |static_cast| on pointers, all |bit_cast|
// and all |reinterpret_cast|.
auto cast_kind = castExpr(anyOf(
hasCastKind(CK_BitCast), hasCastKind(CK_LValueBitCast),
hasCastKind(CK_LValueToRValueBitCast),
hasCastKind(CK_PointerToIntegral), hasCastKind(CK_IntegralToPointer)));
// Implicit/explicit casting from/to |raw_ptr<T>| matches.
// Both casting direction is unsafe.
// https://godbolt.org/z/zqKMzcKfo
auto cast_matcher =
castExpr(
allOf(hasSourceExpression(hasType(pointerType(pointee(
hasUnqualifiedDesugaredType(recordType(hasDeclaration(
cxxRecordDecl(classTemplateSpecializationDecl(
hasName("base::raw_ptr")))))))))),
hasCastKind(CK_BitCast)))
allOf(anyOf(hasSourceExpression(hasType(src_type)),
implicitCastExpr(hasImplicitDestinationType(dst_type)),
explicitCastExpr(hasDestinationType(dst_type))),
cast_kind))
.bind("castExpr");
match_finder.addMatcher(cast_matcher, this);
}
@ -61,32 +81,65 @@ class BadCastMatcher : public MatchFinder::MatchCallback {
// Using raw_ptr<T> in a stdlib collection will cause a cast.
// e.g.
// https://source.chromium.org/chromium/chromium/src/+/main:components/feed/core/v2/xsurface_datastore.h;drc=a0ff03edcace35ec020edd235f4d9e9735fc9690;l=107
if (file_path.find("buildtools/third_party/libc++") != std::string::npos)
return;
// CHECK(raw_ptr<T>) will cause a cast.
// e.g.
// https://source.chromium.org/chromium/chromium/src/+/main:base/task/sequence_manager/thread_controller_with_message_pump_impl.cc;drc=c49b7434a9d4a61c49fc0123e904a6c5e7162731;l=121
if (file_path.find("base/check_op.h") != std::string::npos)
return;
// raw_ptr<T>* is cast to ui::metadata::PropertyKey
// https://source.chromium.org/chromium/chromium/src/+/main:ui/views/view.cc;drc=a0ff03edcace35ec020edd235f4d9e9735fc9690;l=2417
if (file_path.find("ui/views/controls/table/table_view.cc") !=
std::string::npos)
return;
// XdgActivation::activation_queue_ is a base::queue<raw_ptr> which causes a
// cast in VectorBuffer and circular_deque.
if (file_path.find("base/containers/vector_buffer.h") != std::string::npos)
return;
if (file_path.find("base/containers/circular_deque.h") != std::string::npos)
// |__bit/bit_cast.h| header is excluded to perform checking on
// |std::bit_cast<T>|.
if (file_path.find("buildtools/third_party/libc++") != std::string::npos &&
file_path.find("__bit/bit_cast.h") == std::string::npos) {
return;
}
// Exclude casts via "unsafe_raw_ptr_*_cast".
if (file_path.find(
"base/allocator/partition_allocator/pointers/raw_ptr_cast.h") !=
std::string::npos) {
return;
}
clang::PrintingPolicy printing_policy(result.Context->getLangOpts());
const std::string src_name =
cast_expr->getSubExpr()->getType().getAsString(printing_policy);
const std::string dst_name =
cast_expr->getType().getAsString(printing_policy);
const auto* src_type = result.Nodes.getNodeAs<clang::Type>("srcType");
const auto* dst_type = result.Nodes.getNodeAs<clang::Type>("dstType");
assert((src_type || dst_type) &&
"matcher should bind 'srcType' or 'dstType'");
compiler_.getDiagnostics().Report(cast_expr->getEndLoc(),
error_bad_raw_ptr_cast_signature_);
error_bad_cast_signature_)
<< src_name << dst_name;
std::shared_ptr<CastingSafety> type_note;
if (src_type != nullptr) {
compiler_.getDiagnostics().Report(cast_expr->getEndLoc(),
note_bad_cast_signature_explanation_)
<< src_name;
type_note = casting_unsafe_predicate_.GetCastingSafety(src_type);
} else {
compiler_.getDiagnostics().Report(cast_expr->getEndLoc(),
note_bad_cast_signature_explanation_)
<< dst_name;
type_note = casting_unsafe_predicate_.GetCastingSafety(dst_type);
}
while (type_note) {
if (type_note->source_loc()) {
const auto& type_name = clang::QualType::getAsString(
type_note->type(), {}, printing_policy);
compiler_.getDiagnostics().Report(*type_note->source_loc(),
note_bad_cast_signature_type_)
<< type_name;
}
type_note = type_note->source();
}
}
private:
clang::CompilerInstance& compiler_;
unsigned error_bad_raw_ptr_cast_signature_;
CastingUnsafePredicate casting_unsafe_predicate_;
unsigned error_bad_cast_signature_;
unsigned note_bad_cast_signature_explanation_;
unsigned note_bad_cast_signature_type_;
};
const char kNeedRawPtrSignature[] =

@ -0,0 +1,149 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "RawPtrCastingUnsafeChecker.h"
#include <vector>
#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/ScopeExit.h"
// Removes any pointers, references, arrays and aliases.
static const clang::Type* GetBaseType(const clang::Type* type) {
const clang::Type* last_type = nullptr;
while (type && type != last_type) {
last_type = type;
// Unwrap type aliases.
type = type->getUnqualifiedDesugaredType();
// Unwrap arrays and pointers.
type = type->getPointeeOrArrayElementType();
// Unwrap references (and pointers).
const auto pointee = type->getPointeeType();
if (!pointee.isNull()) {
type = pointee.getTypePtrOrNull();
}
}
return type;
}
bool CastingUnsafePredicate::IsCastingUnsafe(const clang::Type* type) const {
return GetCastingSafety(type)->verdict_ == CastingSafety::kUnsafe;
}
std::shared_ptr<CastingSafety> CastingUnsafePredicate::GetCastingSafety(
const clang::Type* type,
std::set<const clang::Type*>* visited) const {
// Retrieve a "base" type because:
// - A pointer pointing to a casting-unsafe type IS casting-unsafe.
// - A reference pointing to a casting-unsafe type IS casting-unsafe.
// - An array having casting-unsafe elements IS casting-unsafe.
const clang::Type* raw_type = GetBaseType(type);
if (!raw_type || !raw_type->isRecordType()) {
// We assume followings ARE NOT casting-unsafe.
// - function type
// - enum type
// - builtin type
// - complex type
// - obj-C types
// We should not have these types here because we desugared.
// - using type
// - typeof type
return std::make_shared<CastingSafety>(type);
}
const clang::RecordDecl* decl = raw_type->getAsRecordDecl();
assert(decl);
// Use a memoized result if exists.
auto iter = cache_.find(type);
if (iter != cache_.end()) {
return iter->second;
}
// This performs DFS on a directed graph composed of |clang::Type*|.
// Avoid searching for visited nodes by managing |visited|, as this can lead
// to infinite loops in the presence of self-references and cross-references.
// Since |type| being casting-unsafe is equivalent to being able to reach node
// |raw_ptr<T>| or node |raw_ref<T>| from node |type|, there is no need to
// look up visited nodes again.
bool root = visited == nullptr;
if (root) {
// Will be deleted as a part of |clean_up()|.
visited = new std::set<const clang::Type*>();
} else if (visited->count(type)) {
// This type is already visited but not memoized,
// therefore this node is reached by following cross-references from
// ancestors. The safety of this node cannot be determined without waiting
// for computation in its ancestors.
return std::make_shared<CastingSafety>(raw_type,
CastingSafety::kUndetermined);
}
visited->insert(type);
auto safety = std::make_shared<CastingSafety>(raw_type);
// Clean-up: this lambda is called automatically at the scope exit.
const auto clean_up =
llvm::make_scope_exit([this, &visited, &raw_type, &root, &safety] {
if (root) {
delete visited;
}
// Memoize the result if finalized.
if (safety->verdict_ != CastingSafety::kUndetermined) {
this->cache_.insert({raw_type, safety});
}
});
const std::string record_name = decl->getQualifiedNameAsString();
if (record_name == "base::raw_ptr" || record_name == "base::raw_ref") {
// Base case: |raw_ptr<T>| and |raw_ref<T>| are never safe to cast to/from.
safety->verdict_ = CastingSafety::kUnsafe;
return safety;
}
// Check member fields
for (const auto& field : decl->fields()) {
safety->MergeSubResult(
GetCastingSafety(field->getType().getTypePtrOrNull(), visited),
field->getBeginLoc());
// Verdict finalized: early return.
if (safety->verdict_ == CastingSafety::kUnsafe) {
return safety;
}
}
// Check base classes
const auto* cxx_decl = clang::dyn_cast<clang::CXXRecordDecl>(decl);
if (cxx_decl && cxx_decl->hasDefinition()) {
for (const auto& base_specifier : cxx_decl->bases()) {
safety->MergeSubResult(
GetCastingSafety(base_specifier.getType().getTypePtr(), visited),
base_specifier.getBeginLoc());
// Verdict finalized: early return.
if (safety->verdict_ == CastingSafety::kUnsafe) {
return safety;
}
}
for (const auto& base_specifier : cxx_decl->vbases()) {
safety->MergeSubResult(
GetCastingSafety(base_specifier.getType().getTypePtr(), visited),
base_specifier.getBeginLoc());
// Verdict finalized: early return.
if (safety->verdict_ == CastingSafety::kUnsafe) {
return safety;
}
}
}
// All reachable types have been traversed but the root type has not
// been marked as unsafe; therefore it must be safe.
if (root && safety->verdict_ == CastingSafety::kUndetermined) {
safety->verdict_ = CastingSafety::kSafe;
}
return safety;
}

@ -0,0 +1,107 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_CLANG_PLUGINS_RAWPTRCASTINGUNSAFECHECKER_H_
#define TOOLS_CLANG_PLUGINS_RAWPTRCASTINGUNSAFECHECKER_H_
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
// Represents a casting safety judgement |verdict_|.
// - CastingSafety::kSafe: the |type| is casting-safe.
// - CastingSafety::kUnsafe: the |type| is casting-unsafe.
// - CastingSafety::kUndetermined: This denotes the safety status
// is not yet determined, due to cross references.
// Holds some additional information to tell reasons.
class CastingSafety {
public:
enum Verdict {
kSafe,
kUnsafe,
// This denotes the safety status is not yet determined.
kUndetermined,
};
explicit CastingSafety(const clang::Type* type) : type_(type) {}
explicit CastingSafety(const clang::Type* type, Verdict verdict)
: type_(type), verdict_(verdict) {}
const clang::Type* type() const { return type_; }
Verdict verdict() const { return this->verdict_; }
std::shared_ptr<CastingSafety> source() const { return this->source_; }
std::optional<clang::SourceLocation> source_loc() const {
return this->source_loc_;
}
private:
friend class CastingUnsafePredicate;
// Merges a sub verdict into this type's verdict.
//
// | this \ sub | kSafe | kUndetermined | kUnsafe |
// +---------------+---------------+---------------+---------+
// | kSafe | kSafe | kUndetermined | kUnsafe |
// | kUndetermined | kUndetermined | kUndetermined | kUnsafe |
// | kUnsafe | kUnsafe | kUnsafe | kUnsafe |
Verdict MergeSubResult(
std::shared_ptr<CastingSafety> sub,
std::optional<clang::SourceLocation> loc = std::nullopt) {
if (sub->verdict_ == kUnsafe && this->verdict_ != kUnsafe) {
this->verdict_ = kUnsafe;
this->source_ = std::move(sub);
this->source_loc_ = loc;
} else if (sub->verdict_ == kUndetermined && this->verdict_ == kSafe) {
this->verdict_ = kUndetermined;
this->source_ = std::move(sub);
this->source_loc_ = loc;
}
return this->verdict_;
}
// |type_| is considered to be casting-safety |verdict_|.
// Optionally, the result contains a reason for the verdict, |source_|.
// There can be multiple reasons (e.g. |type_| has multiple |raw_ptr| member
// variables), but only one of them is stored. The relation between |type_|
// and |source_| is shown at |source_loc_|.
const clang::Type* type_;
Verdict verdict_ = kSafe;
std::shared_ptr<CastingSafety> source_;
std::optional<clang::SourceLocation> source_loc_;
};
// Determines a type is "casting unsafe" or not.
// A type is considered "casting unsafe" if ref counting can be broken as a
// result of casting. We determine "casting unsafe" types by applying these
// rules recursively:
// - |raw_ptr<T>| or |raw_ref<T>| are casting unsafe; when implemented as
// BackupRefPtr, assignment needs to go through the C++ operators to ensure the
// refcount is properly maintained.
// - Pointers, references and arrays to "casting unsafe" element(s) are
// "casting unsafe"
// - Classes and structs having a "casting unsafe" member are "casting unsafe"
// - Classes and structs having a "casting unsafe" base class are "casting
// unsafe"
// `CastingUnsafePredicate` has a cache to memorize "casting unsafety" results.
class CastingUnsafePredicate {
public:
bool IsCastingUnsafe(const clang::Type* type) const;
std::shared_ptr<CastingSafety> GetCastingSafety(
const clang::Type* type,
std::set<const clang::Type*>* visited = nullptr) const;
// Cache to efficiently determine casting safety.
mutable std::map<const clang::Type*, std::shared_ptr<CastingSafety>> cache_;
};
#endif // TOOLS_CLANG_PLUGINS_RAWPTRCASTINGUNSAFECHECKER_H_

@ -7,6 +7,7 @@
#include <optional>
#include "RawPtrCastingUnsafeChecker.h"
#include "StackAllocatedChecker.h"
#include "Util.h"
#include "clang/ASTMatchers/ASTMatchers.h"
@ -360,4 +361,8 @@ AST_MATCHER_P(clang::CXXRecordDecl,
return checker.IsStackAllocated(&Node);
}
AST_MATCHER_P(clang::Type, isCastingUnsafe, CastingUnsafePredicate, checker) {
return checker.IsCastingUnsafe(&Node);
}
#endif // TOOLS_CLANG_PLUGINS_RAWPTRHELPERS_H_

@ -2,16 +2,117 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "bad_raw_ptr_cast.h"
#include <cstdint>
#include "base/memory/raw_ptr.h"
void* my_memcpy(void* destination, const void* source);
struct RawPtrWrapper {
raw_ptr<int> ptr;
};
void BadRawPtr::Check() {
// Explicit cast from raw_ptr<T>* is not allowed.
void* bar = reinterpret_cast<void*>(&foo_);
bar = static_cast<void*>(&foo_);
bar = (void*)&foo_;
// Implicit cast from raw_ptr<T>* is not allowed.
bar = &foo_;
my_memcpy(&foo_, &foo_);
struct RawPtrWrapperWrapper {
RawPtrWrapper* ptr;
};
class RawPtrWrapperWrapperWrapper {
public:
explicit RawPtrWrapperWrapperWrapper(RawPtrWrapperWrapper& ptr) : ptr_(ptr) {}
RawPtrWrapperWrapper& ptr_;
};
struct RawPtrWrapperSub : RawPtrWrapper {};
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
void MyFunc(void* p) {}
void CastFromCastingUnsafe() {
// "Casting unsafe" type variables;
raw_ptr<int> p0;
RawPtrWrapper p1;
RawPtrWrapperWrapper p2;
RawPtrWrapperWrapperWrapper p3(p2);
RawPtrWrapper p4[10];
RawPtrWrapperSub p5;
RawPtrWrapperVirtualSub p6;
// CK_BitCast via |static_cast| should emit an error.
(void)static_cast<void*>(&p0);
(void)static_cast<void*>(&p1);
(void)static_cast<void*>(&p2);
(void)static_cast<void*>(&p3);
(void)static_cast<void*>(&p4);
(void)static_cast<void*>(&p5);
(void)static_cast<void*>(&p6);
// CK_BitCast via C-style casting should emit an error.
(void)(void*)&p0;
(void)(void*)&p1;
(void)(void*)&p2;
(void)(void*)&p3;
(void)(void*)&p4;
(void)(void*)&p5;
(void)(void*)&p6;
// CK_BitCast via |reinterpret_cast| should emit an error.
(void)reinterpret_cast<void*>(&p0);
(void)reinterpret_cast<void*>(&p1);
(void)reinterpret_cast<void*>(&p2);
(void)reinterpret_cast<void*>(&p3);
(void)reinterpret_cast<void*>(&p4);
(void)reinterpret_cast<void*>(&p5);
(void)reinterpret_cast<void*>(&p6);
// CK_LValueToRValueBitCast via |bit_cast| should emit an error.
(void)__builtin_bit_cast(void*, &p0);
(void)__builtin_bit_cast(void*, &p1);
(void)__builtin_bit_cast(void*, &p2);
(void)__builtin_bit_cast(void*, &p3);
(void)__builtin_bit_cast(void*, &p4);
(void)__builtin_bit_cast(void*, &p5);
(void)__builtin_bit_cast(void*, &p6);
// CK_BitCast via implicit casting should emit an error.
MyFunc(&p0);
MyFunc(&p1);
MyFunc(&p2);
MyFunc(&p3);
MyFunc(&p4);
MyFunc(&p5);
MyFunc(&p6);
}
void CastToCastingUnsafe() {
void* p = nullptr;
// CK_BitCast via |static_cast| should emit an error.
(void)static_cast<raw_ptr<int>*>(p);
(void)static_cast<RawPtrWrapper*>(p);
(void)static_cast<RawPtrWrapperWrapper*>(p);
(void)static_cast<RawPtrWrapperWrapperWrapper*>(p);
(void)static_cast<RawPtrWrapperSub*>(p);
(void)static_cast<RawPtrWrapperVirtualSub*>(p);
// CK_BitCast via C-style casting should emit an error.
(void)(raw_ptr<int>*)p;
(void)(RawPtrWrapper*)p;
(void)(RawPtrWrapperWrapper*)p;
(void)(RawPtrWrapperWrapperWrapper*)p;
(void)(RawPtrWrapperSub*)p;
(void)(RawPtrWrapperVirtualSub*)p;
// CK_BitCast via |reinterpret_cast| should emit an error.
(void)reinterpret_cast<raw_ptr<int>*>(p);
(void)reinterpret_cast<RawPtrWrapper*>(p);
(void)reinterpret_cast<RawPtrWrapperWrapper*>(p);
(void)reinterpret_cast<RawPtrWrapperWrapperWrapper*>(p);
(void)reinterpret_cast<RawPtrWrapperSub*>(p);
(void)reinterpret_cast<RawPtrWrapperVirtualSub*>(p);
// CK_LValueToRValueBitCast via |bit_cast| should emit an error.
(void)__builtin_bit_cast(raw_ptr<int>*, p);
(void)__builtin_bit_cast(RawPtrWrapper*, p);
(void)__builtin_bit_cast(RawPtrWrapperWrapper*, p);
(void)__builtin_bit_cast(RawPtrWrapperWrapperWrapper*, p);
(void)__builtin_bit_cast(RawPtrWrapperSub*, p);
(void)__builtin_bit_cast(RawPtrWrapperVirtualSub*, p);
}

@ -1 +1 @@
-Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast
-ferror-limit=0 -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast

@ -1,18 +0,0 @@
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
#define TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_
#include "base/memory/raw_ptr.h"
class BadRawPtr {
public:
void Check();
private:
raw_ptr<int> foo_;
};
#endif // TOOLS_CLANG_PLUGINS_TESTS_BAD_RAW_PTR_CAST_H_

@ -1,19 +1,522 @@
bad_raw_ptr_cast.cpp:11:44: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
void* bar = reinterpret_cast<void*>(&foo_);
^
bad_raw_ptr_cast.cpp:12:29: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
bar = static_cast<void*>(&foo_);
bad_raw_ptr_cast.cpp:39:29: error: [chromium-style] casting 'raw_ptr<int> *' to 'void * is not allowed.
(void)static_cast<void*>(&p0);
^
bad_raw_ptr_cast.cpp:13:17: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
bar = (void*)&foo_;
bad_raw_ptr_cast.cpp:39:29: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:40:29: error: [chromium-style] casting 'RawPtrWrapper *' to 'void * is not allowed.
(void)static_cast<void*>(&p1);
^
bad_raw_ptr_cast.cpp:40:29: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:41:29: error: [chromium-style] casting 'RawPtrWrapperWrapper *' to 'void * is not allowed.
(void)static_cast<void*>(&p2);
^
bad_raw_ptr_cast.cpp:41:29: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:42:29: error: [chromium-style] casting 'RawPtrWrapperWrapperWrapper *' to 'void * is not allowed.
(void)static_cast<void*>(&p3);
^
bad_raw_ptr_cast.cpp:42:29: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:43:29: error: [chromium-style] casting 'RawPtrWrapper (*)[10]' to 'void * is not allowed.
(void)static_cast<void*>(&p4);
^
bad_raw_ptr_cast.cpp:43:29: note: [chromium-style] 'RawPtrWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:44:29: error: [chromium-style] casting 'RawPtrWrapperSub *' to 'void * is not allowed.
(void)static_cast<void*>(&p5);
^
bad_raw_ptr_cast.cpp:44:29: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:45:29: error: [chromium-style] casting 'RawPtrWrapperVirtualSub *' to 'void * is not allowed.
(void)static_cast<void*>(&p6);
^
bad_raw_ptr_cast.cpp:45:29: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:48:17: error: [chromium-style] casting 'raw_ptr<int> *' to 'void * is not allowed.
(void)(void*)&p0;
^
bad_raw_ptr_cast.cpp:15:10: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
bar = &foo_;
^
bad_raw_ptr_cast.cpp:16:14: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
my_memcpy(&foo_, &foo_);
^
bad_raw_ptr_cast.cpp:16:21: error: [chromium-raw-ptr-cast] Casting raw_ptr<T>* to another type is not allowed as it may cause BRP ref count mismatch and bypass security checks.
my_memcpy(&foo_, &foo_);
^
6 errors generated.
bad_raw_ptr_cast.cpp:48:17: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:49:17: error: [chromium-style] casting 'RawPtrWrapper *' to 'void * is not allowed.
(void)(void*)&p1;
^
bad_raw_ptr_cast.cpp:49:17: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:50:17: error: [chromium-style] casting 'RawPtrWrapperWrapper *' to 'void * is not allowed.
(void)(void*)&p2;
^
bad_raw_ptr_cast.cpp:50:17: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:51:17: error: [chromium-style] casting 'RawPtrWrapperWrapperWrapper *' to 'void * is not allowed.
(void)(void*)&p3;
^
bad_raw_ptr_cast.cpp:51:17: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:52:17: error: [chromium-style] casting 'RawPtrWrapper (*)[10]' to 'void * is not allowed.
(void)(void*)&p4;
^
bad_raw_ptr_cast.cpp:52:17: note: [chromium-style] 'RawPtrWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:53:17: error: [chromium-style] casting 'RawPtrWrapperSub *' to 'void * is not allowed.
(void)(void*)&p5;
^
bad_raw_ptr_cast.cpp:53:17: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:54:17: error: [chromium-style] casting 'RawPtrWrapperVirtualSub *' to 'void * is not allowed.
(void)(void*)&p6;
^
bad_raw_ptr_cast.cpp:54:17: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:57:36: error: [chromium-style] casting 'raw_ptr<int> *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p0);
^
bad_raw_ptr_cast.cpp:57:36: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:58:36: error: [chromium-style] casting 'RawPtrWrapper *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p1);
^
bad_raw_ptr_cast.cpp:58:36: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:59:36: error: [chromium-style] casting 'RawPtrWrapperWrapper *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p2);
^
bad_raw_ptr_cast.cpp:59:36: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:60:36: error: [chromium-style] casting 'RawPtrWrapperWrapperWrapper *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p3);
^
bad_raw_ptr_cast.cpp:60:36: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:61:36: error: [chromium-style] casting 'RawPtrWrapper (*)[10]' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p4);
^
bad_raw_ptr_cast.cpp:61:36: note: [chromium-style] 'RawPtrWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:62:36: error: [chromium-style] casting 'RawPtrWrapperSub *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p5);
^
bad_raw_ptr_cast.cpp:62:36: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:63:36: error: [chromium-style] casting 'RawPtrWrapperVirtualSub *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p6);
^
bad_raw_ptr_cast.cpp:63:36: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:66:38: error: [chromium-style] casting 'raw_ptr<int> *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p0);
^
bad_raw_ptr_cast.cpp:66:38: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:67:38: error: [chromium-style] casting 'RawPtrWrapper *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p1);
^
bad_raw_ptr_cast.cpp:67:38: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:68:38: error: [chromium-style] casting 'RawPtrWrapperWrapper *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p2);
^
bad_raw_ptr_cast.cpp:68:38: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:69:38: error: [chromium-style] casting 'RawPtrWrapperWrapperWrapper *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p3);
^
bad_raw_ptr_cast.cpp:69:38: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:70:38: error: [chromium-style] casting 'RawPtrWrapper (*)[10]' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p4);
^
bad_raw_ptr_cast.cpp:70:38: note: [chromium-style] 'RawPtrWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:71:38: error: [chromium-style] casting 'RawPtrWrapperSub *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p5);
^
bad_raw_ptr_cast.cpp:71:38: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:72:38: error: [chromium-style] casting 'RawPtrWrapperVirtualSub *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p6);
^
bad_raw_ptr_cast.cpp:72:38: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:75:11: error: [chromium-style] casting 'raw_ptr<int> *' to 'void * is not allowed.
MyFunc(&p0);
^
bad_raw_ptr_cast.cpp:75:11: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:76:11: error: [chromium-style] casting 'RawPtrWrapper *' to 'void * is not allowed.
MyFunc(&p1);
^
bad_raw_ptr_cast.cpp:76:11: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:77:11: error: [chromium-style] casting 'RawPtrWrapperWrapper *' to 'void * is not allowed.
MyFunc(&p2);
^
bad_raw_ptr_cast.cpp:77:11: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:78:11: error: [chromium-style] casting 'RawPtrWrapperWrapperWrapper *' to 'void * is not allowed.
MyFunc(&p3);
^
bad_raw_ptr_cast.cpp:78:11: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:79:11: error: [chromium-style] casting 'RawPtrWrapper (*)[10]' to 'void * is not allowed.
MyFunc(&p4);
^
bad_raw_ptr_cast.cpp:79:11: note: [chromium-style] 'RawPtrWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:80:11: error: [chromium-style] casting 'RawPtrWrapperSub *' to 'void * is not allowed.
MyFunc(&p5);
^
bad_raw_ptr_cast.cpp:80:11: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:81:11: error: [chromium-style] casting 'RawPtrWrapperVirtualSub *' to 'void * is not allowed.
MyFunc(&p6);
^
bad_raw_ptr_cast.cpp:81:11: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:88:37: error: [chromium-style] casting 'void *' to 'raw_ptr<int> * is not allowed.
(void)static_cast<raw_ptr<int>*>(p);
^
bad_raw_ptr_cast.cpp:88:37: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:89:38: error: [chromium-style] casting 'void *' to 'RawPtrWrapper * is not allowed.
(void)static_cast<RawPtrWrapper*>(p);
^
bad_raw_ptr_cast.cpp:89:38: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:90:45: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapper * is not allowed.
(void)static_cast<RawPtrWrapperWrapper*>(p);
^
bad_raw_ptr_cast.cpp:90:45: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:91:52: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapperWrapper * is not allowed.
(void)static_cast<RawPtrWrapperWrapperWrapper*>(p);
^
bad_raw_ptr_cast.cpp:91:52: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:92:41: error: [chromium-style] casting 'void *' to 'RawPtrWrapperSub * is not allowed.
(void)static_cast<RawPtrWrapperSub*>(p);
^
bad_raw_ptr_cast.cpp:92:41: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:93:48: error: [chromium-style] casting 'void *' to 'RawPtrWrapperVirtualSub * is not allowed.
(void)static_cast<RawPtrWrapperVirtualSub*>(p);
^
bad_raw_ptr_cast.cpp:93:48: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:96:24: error: [chromium-style] casting 'void *' to 'raw_ptr<int> * is not allowed.
(void)(raw_ptr<int>*)p;
^
bad_raw_ptr_cast.cpp:96:24: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:97:25: error: [chromium-style] casting 'void *' to 'RawPtrWrapper * is not allowed.
(void)(RawPtrWrapper*)p;
^
bad_raw_ptr_cast.cpp:97:25: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:98:32: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapper * is not allowed.
(void)(RawPtrWrapperWrapper*)p;
^
bad_raw_ptr_cast.cpp:98:32: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:99:39: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapperWrapper * is not allowed.
(void)(RawPtrWrapperWrapperWrapper*)p;
^
bad_raw_ptr_cast.cpp:99:39: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:100:28: error: [chromium-style] casting 'void *' to 'RawPtrWrapperSub * is not allowed.
(void)(RawPtrWrapperSub*)p;
^
bad_raw_ptr_cast.cpp:100:28: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:101:35: error: [chromium-style] casting 'void *' to 'RawPtrWrapperVirtualSub * is not allowed.
(void)(RawPtrWrapperVirtualSub*)p;
^
bad_raw_ptr_cast.cpp:101:35: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:104:42: error: [chromium-style] casting 'void *' to 'raw_ptr<int> * is not allowed.
(void)reinterpret_cast<raw_ptr<int>*>(p);
^
bad_raw_ptr_cast.cpp:104:42: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:105:43: error: [chromium-style] casting 'void *' to 'RawPtrWrapper * is not allowed.
(void)reinterpret_cast<RawPtrWrapper*>(p);
^
bad_raw_ptr_cast.cpp:105:43: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:106:50: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapper * is not allowed.
(void)reinterpret_cast<RawPtrWrapperWrapper*>(p);
^
bad_raw_ptr_cast.cpp:106:50: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:107:57: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapperWrapper * is not allowed.
(void)reinterpret_cast<RawPtrWrapperWrapperWrapper*>(p);
^
bad_raw_ptr_cast.cpp:107:57: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:108:46: error: [chromium-style] casting 'void *' to 'RawPtrWrapperSub * is not allowed.
(void)reinterpret_cast<RawPtrWrapperSub*>(p);
^
bad_raw_ptr_cast.cpp:108:46: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:109:53: error: [chromium-style] casting 'void *' to 'RawPtrWrapperVirtualSub * is not allowed.
(void)reinterpret_cast<RawPtrWrapperVirtualSub*>(p);
^
bad_raw_ptr_cast.cpp:109:53: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:112:44: error: [chromium-style] casting 'void *' to 'raw_ptr<int> * is not allowed.
(void)__builtin_bit_cast(raw_ptr<int>*, p);
^
bad_raw_ptr_cast.cpp:112:44: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:113:45: error: [chromium-style] casting 'void *' to 'RawPtrWrapper * is not allowed.
(void)__builtin_bit_cast(RawPtrWrapper*, p);
^
bad_raw_ptr_cast.cpp:113:45: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:114:52: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapper * is not allowed.
(void)__builtin_bit_cast(RawPtrWrapperWrapper*, p);
^
bad_raw_ptr_cast.cpp:114:52: note: [chromium-style] 'RawPtrWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:115:59: error: [chromium-style] casting 'void *' to 'RawPtrWrapperWrapperWrapper * is not allowed.
(void)__builtin_bit_cast(RawPtrWrapperWrapperWrapper*, p);
^
bad_raw_ptr_cast.cpp:115:59: note: [chromium-style] 'RawPtrWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:20:3: note: [chromium-style] 'RawPtrWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapperWrapper& ptr_;
^
bad_raw_ptr_cast.cpp:13:3: note: [chromium-style] 'RawPtrWrapperWrapper' manages BackupRefPtr or its container here.
RawPtrWrapper* ptr;
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:116:48: error: [chromium-style] casting 'void *' to 'RawPtrWrapperSub * is not allowed.
(void)__builtin_bit_cast(RawPtrWrapperSub*, p);
^
bad_raw_ptr_cast.cpp:116:48: note: [chromium-style] 'RawPtrWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:23:27: note: [chromium-style] 'RawPtrWrapperSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperSub : RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast.cpp:117:55: error: [chromium-style] casting 'void *' to 'RawPtrWrapperVirtualSub * is not allowed.
(void)__builtin_bit_cast(RawPtrWrapperVirtualSub*, p);
^
bad_raw_ptr_cast.cpp:117:55: note: [chromium-style] 'RawPtrWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast.cpp:24:34: note: [chromium-style] 'RawPtrWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
^
bad_raw_ptr_cast.cpp:9:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
59 errors generated.

@ -0,0 +1,94 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <array>
#include <cstdint>
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_cast.h"
struct RawPtrWrapper {
raw_ptr<int> ptr;
};
struct RawPtrWrapperWrapper {
RawPtrWrapper* ptr;
};
class RawPtrWrapperWrapperWrapper {
public:
explicit RawPtrWrapperWrapperWrapper(RawPtrWrapperWrapper& ptr) : ptr_(ptr) {}
RawPtrWrapperWrapper& ptr_;
};
struct RawPtrWrapperSub : RawPtrWrapper {};
struct RawPtrWrapperVirtualSub : virtual RawPtrWrapper {};
void MyFunc(void* p) {}
// 'unsafe_raw_ptr_*_cast' should not emit errors.
void CastFromCastingUnsafeExclusion() {
// "Casting unsafe" type variables;
raw_ptr<int> p0;
RawPtrWrapper p1;
RawPtrWrapperWrapper p2;
RawPtrWrapperWrapperWrapper p3(p2);
RawPtrWrapper p4[10];
RawPtrWrapperSub p5;
RawPtrWrapperVirtualSub p6;
(void)base::unsafe_raw_ptr_static_cast<void*>(&p0);
(void)base::unsafe_raw_ptr_static_cast<void*>(&p1);
(void)base::unsafe_raw_ptr_static_cast<void*>(&p2);
(void)base::unsafe_raw_ptr_static_cast<void*>(&p3);
(void)base::unsafe_raw_ptr_static_cast<void*>(&p4);
(void)base::unsafe_raw_ptr_static_cast<void*>(&p5);
(void)base::unsafe_raw_ptr_static_cast<void*>(&p6);
(void)base::unsafe_raw_ptr_reinterpret_cast<void*>(&p0);
(void)base::unsafe_raw_ptr_reinterpret_cast<void*>(&p1);
(void)base::unsafe_raw_ptr_reinterpret_cast<void*>(&p2);
(void)base::unsafe_raw_ptr_reinterpret_cast<void*>(&p3);
(void)base::unsafe_raw_ptr_reinterpret_cast<void*>(&p4);
(void)base::unsafe_raw_ptr_reinterpret_cast<void*>(&p5);
(void)base::unsafe_raw_ptr_reinterpret_cast<void*>(&p6);
(void)base::unsafe_raw_ptr_bit_cast<void*>(&p0);
(void)base::unsafe_raw_ptr_bit_cast<void*>(&p1);
(void)base::unsafe_raw_ptr_bit_cast<void*>(&p2);
(void)base::unsafe_raw_ptr_bit_cast<void*>(&p3);
(void)base::unsafe_raw_ptr_bit_cast<void*>(&p4);
(void)base::unsafe_raw_ptr_bit_cast<void*>(&p5);
(void)base::unsafe_raw_ptr_bit_cast<void*>(&p6);
}
// 'unsafe_raw_ptr_*_cast' should not emit errors.
void CastToCastingUnsafeExclusion() {
void* p = nullptr;
// CK_BitCast via |base::unsafe_raw_ptr_static_cast| should emit an error.
(void)base::unsafe_raw_ptr_static_cast<raw_ptr<int>*>(p);
(void)base::unsafe_raw_ptr_static_cast<RawPtrWrapper*>(p);
(void)base::unsafe_raw_ptr_static_cast<RawPtrWrapperWrapper*>(p);
(void)base::unsafe_raw_ptr_static_cast<RawPtrWrapperWrapperWrapper*>(p);
(void)base::unsafe_raw_ptr_static_cast<RawPtrWrapperSub*>(p);
(void)base::unsafe_raw_ptr_static_cast<RawPtrWrapperVirtualSub*>(p);
// CK_BitCast via |base::unsafe_raw_ptr_reinterpret_cast| should emit an
// error.
(void)base::unsafe_raw_ptr_reinterpret_cast<raw_ptr<int>*>(p);
(void)base::unsafe_raw_ptr_reinterpret_cast<RawPtrWrapper*>(p);
(void)base::unsafe_raw_ptr_reinterpret_cast<RawPtrWrapperWrapper*>(p);
(void)base::unsafe_raw_ptr_reinterpret_cast<RawPtrWrapperWrapperWrapper*>(p);
(void)base::unsafe_raw_ptr_reinterpret_cast<RawPtrWrapperSub*>(p);
(void)base::unsafe_raw_ptr_reinterpret_cast<RawPtrWrapperVirtualSub*>(p);
// CK_BitCast via |bit_cast| should emit an error.
(void)base::unsafe_raw_ptr_bit_cast<raw_ptr<int>*>(p);
(void)base::unsafe_raw_ptr_bit_cast<RawPtrWrapper*>(p);
(void)base::unsafe_raw_ptr_bit_cast<RawPtrWrapperWrapper*>(p);
(void)base::unsafe_raw_ptr_bit_cast<RawPtrWrapperWrapperWrapper*>(p);
(void)base::unsafe_raw_ptr_bit_cast<RawPtrWrapperSub*>(p);
(void)base::unsafe_raw_ptr_bit_cast<RawPtrWrapperVirtualSub*>(p);
}

@ -0,0 +1 @@
-Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast

@ -0,0 +1,49 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <array>
#include "base/memory/raw_ptr.h"
// Real examples of bad casting, cited from here.
// https://docs.google.com/document/d/14Ol_adOdNpy4Ge-XReI7CXNKMzs_LL5vucDQIERDQyg/edit?usp=sharing
// ==============================
// Example 1. "Initialization"
// ==============================
struct A {
raw_ptr<int> ptr;
};
A* ExampleOne(void* buf) {
return reinterpret_cast<A*>(buf); // Should error.
}
// ==============================
// Example 2. "Matching Struct"
// ==============================
struct ThirdPartyA {
int* ptr;
};
A* ExampleTwo(ThirdPartyA* obj) {
return reinterpret_cast<A*>(obj); // Should error.
}
// ==============================
// Example 3. "Reinterpreting as void**"
// ==============================
int** ExampleThree(raw_ptr<int>* ptr) {
return reinterpret_cast<int**>(ptr); // Should error.
}
// ==============================
// Example 4. "Reinterpreting pointer to embedder class as void*"
// ==============================
void* my_memset(void* s, int c, std::size_t n);
void ExampleFour() {
A obj;
A* obj_ptr = &obj;
my_memset(obj_ptr, 0, sizeof(obj_ptr)); // Should error.
}

@ -0,0 +1 @@
-ferror-limit=0 -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast

@ -0,0 +1,26 @@
bad_raw_ptr_cast_in_the_wild.cpp:19:34: error: [chromium-style] casting 'void *' to 'A * is not allowed.
return reinterpret_cast<A*>(buf); // Should error.
^
bad_raw_ptr_cast_in_the_wild.cpp:19:34: note: [chromium-style] 'A *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_in_the_wild.cpp:15:3: note: [chromium-style] 'A' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_in_the_wild.cpp:30:34: error: [chromium-style] casting 'ThirdPartyA *' to 'A * is not allowed.
return reinterpret_cast<A*>(obj); // Should error.
^
bad_raw_ptr_cast_in_the_wild.cpp:30:34: note: [chromium-style] 'A *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_in_the_wild.cpp:15:3: note: [chromium-style] 'A' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_in_the_wild.cpp:37:37: error: [chromium-style] casting 'raw_ptr<int> *' to 'int ** is not allowed.
return reinterpret_cast<int**>(ptr); // Should error.
^
bad_raw_ptr_cast_in_the_wild.cpp:37:37: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_in_the_wild.cpp:48:13: error: [chromium-style] casting 'A *' to 'void * is not allowed.
my_memset(obj_ptr, 0, sizeof(obj_ptr)); // Should error.
^
bad_raw_ptr_cast_in_the_wild.cpp:48:13: note: [chromium-style] 'A *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_in_the_wild.cpp:15:3: note: [chromium-style] 'A' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
4 errors generated.

@ -0,0 +1,63 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <array>
#include <cstdint>
#include "base/memory/raw_ptr.h"
struct RawPtrWrapper {
raw_ptr<int> ptr;
};
struct RawPtrWrapperSub : RawPtrWrapper {};
void VariousCasting() {
raw_ptr<int> ptr;
RawPtrWrapper wrapped;
RawPtrWrapper arr[10];
void* void_ptr = nullptr;
// CK_BitCast should emit an error.
(void)reinterpret_cast<RawPtrWrapper*>(void_ptr);
// CK_LValueBitCast should emit an error.
RawPtrWrapper& ref = wrapped;
ref = reinterpret_cast<RawPtrWrapper&>(void_ptr);
// CK_LValueToRValueBitCast should emit an error.
(void)__builtin_bit_cast(int*, ptr);
(void)__builtin_bit_cast(raw_ptr<int>, wrapped);
(void)__builtin_bit_cast(int*, wrapped);
// CK_PointerToIntegral should emit an error.
uintptr_t i = reinterpret_cast<uintptr_t>(&wrapped);
// CK_IntegralToPointer should emit an error.
wrapped = *reinterpret_cast<RawPtrWrapper*>(i);
// CK_ArrayToPointerDecay should be safe.
(void)static_cast<RawPtrWrapper*>(arr);
// This line has two casts, CK_ArrayToPointerDecay and CK_BitCast.
// q = (void*) (RawPtrWrapper*) arr;
// The latter should emit an error.
void_ptr = arr;
// CK_BaseToDerived should be safe.
RawPtrWrapperSub* sub = static_cast<RawPtrWrapperSub*>(&wrapped);
// CK_DerivedToBase should be safe.
wrapped = *static_cast<RawPtrWrapper*>(sub);
// CK_ToVoid should be safe.
(void)&wrapped;
// Illegal casts: should be disallowed by the compiler.
(void)static_cast<int*>(ptr);
(void)static_cast<raw_ptr<int>>(wrapped);
(void)static_cast<int*>(wrapped);
(void)reinterpret_cast<int*>(ptr);
(void)reinterpret_cast<raw_ptr<int>>(wrapped);
(void)reinterpret_cast<int*>(wrapped);
}

@ -0,0 +1 @@
-ferror-limit=0 -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast

@ -0,0 +1,77 @@
bad_raw_ptr_cast_kinds.cpp:56:9: error: cannot cast from type 'raw_ptr<int>' to pointer type 'int *'
(void)static_cast<int*>(ptr);
^~~~~~~~~~~~~~~~~~~~~~
bad_raw_ptr_cast_kinds.cpp:57:9: error: no matching conversion for static_cast from 'RawPtrWrapper' to 'raw_ptr<int>'
(void)static_cast<raw_ptr<int>>(wrapped);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./base/allocator/partition_allocator/pointers/raw_ptr.h:11:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'RawPtrWrapper' to 'const raw_ptr<int>' for 1st argument
class raw_ptr {
^
./base/allocator/partition_allocator/pointers/raw_ptr.h:11:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'RawPtrWrapper' to 'raw_ptr<int>' for 1st argument
./base/allocator/partition_allocator/pointers/raw_ptr.h:11:7: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
bad_raw_ptr_cast_kinds.cpp:58:9: error: cannot cast from type 'RawPtrWrapper' to pointer type 'int *'
(void)static_cast<int*>(wrapped);
^~~~~~~~~~~~~~~~~~~~~~~~~~
bad_raw_ptr_cast_kinds.cpp:60:9: error: reinterpret_cast from 'raw_ptr<int>' to 'int *' is not allowed
(void)reinterpret_cast<int*>(ptr);
^~~~~~~~~~~~~~~~~~~~~~~~~~~
bad_raw_ptr_cast_kinds.cpp:61:9: error: reinterpret_cast from 'RawPtrWrapper' to 'raw_ptr<int>' is not allowed
(void)reinterpret_cast<raw_ptr<int>>(wrapped);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bad_raw_ptr_cast_kinds.cpp:62:9: error: reinterpret_cast from 'RawPtrWrapper' to 'int *' is not allowed
(void)reinterpret_cast<int*>(wrapped);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bad_raw_ptr_cast_kinds.cpp:21:50: error: [chromium-style] casting 'void *' to 'RawPtrWrapper * is not allowed.
(void)reinterpret_cast<RawPtrWrapper*>(void_ptr);
^
bad_raw_ptr_cast_kinds.cpp:21:50: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:10:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_kinds.cpp:25:50: error: [chromium-style] casting 'void *' to 'RawPtrWrapper is not allowed.
ref = reinterpret_cast<RawPtrWrapper&>(void_ptr);
^
bad_raw_ptr_cast_kinds.cpp:25:50: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:10:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_kinds.cpp:28:37: error: [chromium-style] casting 'raw_ptr<int>' to 'int * is not allowed.
(void)__builtin_bit_cast(int*, ptr);
^
bad_raw_ptr_cast_kinds.cpp:28:37: note: [chromium-style] 'raw_ptr<int>' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:29:49: error: [chromium-style] casting 'RawPtrWrapper' to 'raw_ptr<int> is not allowed.
(void)__builtin_bit_cast(raw_ptr<int>, wrapped);
^
bad_raw_ptr_cast_kinds.cpp:29:49: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:10:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_kinds.cpp:30:41: error: [chromium-style] casting 'RawPtrWrapper' to 'int * is not allowed.
(void)__builtin_bit_cast(int*, wrapped);
^
bad_raw_ptr_cast_kinds.cpp:30:41: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:10:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_kinds.cpp:33:53: error: [chromium-style] casting 'RawPtrWrapper *' to 'uintptr_t is not allowed.
uintptr_t i = reinterpret_cast<uintptr_t>(&wrapped);
^
bad_raw_ptr_cast_kinds.cpp:33:53: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:10:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_kinds.cpp:36:48: error: [chromium-style] casting 'uintptr_t' to 'RawPtrWrapper * is not allowed.
wrapped = *reinterpret_cast<RawPtrWrapper*>(i);
^
bad_raw_ptr_cast_kinds.cpp:36:48: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:10:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_kinds.cpp:44:14: error: [chromium-style] casting 'RawPtrWrapper *' to 'void * is not allowed.
void_ptr = arr;
^
bad_raw_ptr_cast_kinds.cpp:44:14: note: [chromium-style] 'RawPtrWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_kinds.cpp:10:3: note: [chromium-style] 'RawPtrWrapper' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
14 errors generated.

@ -0,0 +1,40 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/memory/raw_ptr.h"
struct A;
struct B;
struct C;
struct D;
// raw_ptr<int> <-- A <-> B --> C
// ^
// |
// D
// A, B and D are casting-unsafe.
struct A {
B* b;
raw_ptr<int> ptr;
};
struct B {
A* a;
C* c;
};
struct C {};
struct D {
B* b;
};
void CastToCastingUnsafe() {
void* p = nullptr;
(void)static_cast<A*>(p); // Error.
(void)static_cast<B*>(p); // Error.
(void)static_cast<C*>(p); // OK.
(void)static_cast<D*>(p); // Error.
}

@ -0,0 +1 @@
-ferror-limit=0 -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast

@ -0,0 +1,31 @@
bad_raw_ptr_cast_recursive.cpp:36:26: error: [chromium-style] casting 'void *' to 'A * is not allowed.
(void)static_cast<A*>(p); // Error.
^
bad_raw_ptr_cast_recursive.cpp:36:26: note: [chromium-style] 'A *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_recursive.cpp:19:3: note: [chromium-style] 'A' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_recursive.cpp:37:26: error: [chromium-style] casting 'void *' to 'B * is not allowed.
(void)static_cast<B*>(p); // Error.
^
bad_raw_ptr_cast_recursive.cpp:37:26: note: [chromium-style] 'B *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_recursive.cpp:23:3: note: [chromium-style] 'B' manages BackupRefPtr or its container here.
A* a;
^
bad_raw_ptr_cast_recursive.cpp:19:3: note: [chromium-style] 'A' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
bad_raw_ptr_cast_recursive.cpp:39:26: error: [chromium-style] casting 'void *' to 'D * is not allowed.
(void)static_cast<D*>(p); // Error.
^
bad_raw_ptr_cast_recursive.cpp:39:26: note: [chromium-style] 'D *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ptr_cast_recursive.cpp:30:3: note: [chromium-style] 'D' manages BackupRefPtr or its container here.
B* b;
^
bad_raw_ptr_cast_recursive.cpp:23:3: note: [chromium-style] 'B' manages BackupRefPtr or its container here.
A* a;
^
bad_raw_ptr_cast_recursive.cpp:19:3: note: [chromium-style] 'A' manages BackupRefPtr or its container here.
raw_ptr<int> ptr;
^
3 errors generated.

@ -0,0 +1,119 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <array>
#include <cstdint>
#include "base/memory/raw_ptr.h"
struct RawRefWrapper {
raw_ref<int> ref;
};
struct RawRefWrapperWrapper {
RawRefWrapper* ref;
};
class RawRefWrapperWrapperWrapper {
public:
explicit RawRefWrapperWrapperWrapper(RawRefWrapperWrapper& ref) : ref_(ref) {}
RawRefWrapperWrapper& ref_;
};
struct RawRefWrapperSub : RawRefWrapper {};
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
void MyFunc(void* p) {}
void CastFromCastingUnsafe() {
// "Casting unsafe" type variables;
raw_ref<int> p0;
RawRefWrapper p1;
RawRefWrapperWrapper p2;
RawRefWrapperWrapperWrapper p3(p2);
RawRefWrapper p4[10];
RawRefWrapperSub p5;
RawRefWrapperVirtualSub p6;
// CK_BitCast via |static_cast| should emit an error.
(void)static_cast<void*>(&p0);
(void)static_cast<void*>(&p1);
(void)static_cast<void*>(&p2);
(void)static_cast<void*>(&p3);
(void)static_cast<void*>(&p4);
(void)static_cast<void*>(&p5);
(void)static_cast<void*>(&p6);
// CK_BitCast via C-style casting should emit an error.
(void)(void*)&p0;
(void)(void*)&p1;
(void)(void*)&p2;
(void)(void*)&p3;
(void)(void*)&p4;
(void)(void*)&p5;
(void)(void*)&p6;
// CK_BitCast via |reinterpret_cast| should emit an error.
(void)reinterpret_cast<void*>(&p0);
(void)reinterpret_cast<void*>(&p1);
(void)reinterpret_cast<void*>(&p2);
(void)reinterpret_cast<void*>(&p3);
(void)reinterpret_cast<void*>(&p4);
(void)reinterpret_cast<void*>(&p5);
(void)reinterpret_cast<void*>(&p6);
// CK_LValueToRValueBitCast via |bit_cast| should emit an error.
(void)__builtin_bit_cast(void*, &p0);
(void)__builtin_bit_cast(void*, &p1);
(void)__builtin_bit_cast(void*, &p2);
(void)__builtin_bit_cast(void*, &p3);
(void)__builtin_bit_cast(void*, &p4);
(void)__builtin_bit_cast(void*, &p5);
(void)__builtin_bit_cast(void*, &p6);
// CK_BitCast via implicit casting should emit an error.
MyFunc(&p0);
MyFunc(&p1);
MyFunc(&p2);
MyFunc(&p3);
MyFunc(&p4);
MyFunc(&p5);
MyFunc(&p6);
}
void CastToCastingUnsafe() {
void* p = nullptr;
// CK_BitCast via |static_cast| should emit an error.
(void)static_cast<raw_ref<int>*>(p);
(void)static_cast<RawRefWrapper*>(p);
(void)static_cast<RawRefWrapperWrapper*>(p);
(void)static_cast<RawRefWrapperWrapperWrapper*>(p);
(void)static_cast<RawRefWrapperSub*>(p);
(void)static_cast<RawRefWrapperVirtualSub*>(p);
// CK_BitCast via C-style casting should emit an error.
(void)(raw_ptr<int>*)p;
(void)(RawRefWrapper*)p;
(void)(RawRefWrapperWrapper*)p;
(void)(RawRefWrapperWrapperWrapper*)p;
(void)(RawRefWrapperSub*)p;
(void)(RawRefWrapperVirtualSub*)p;
// CK_BitCast via |reinterpret_cast| should emit an error.
(void)reinterpret_cast<raw_ref<int>*>(p);
(void)reinterpret_cast<RawRefWrapper*>(p);
(void)reinterpret_cast<RawRefWrapperWrapper*>(p);
(void)reinterpret_cast<RawRefWrapperWrapperWrapper*>(p);
(void)reinterpret_cast<RawRefWrapperSub*>(p);
(void)reinterpret_cast<RawRefWrapperVirtualSub*>(p);
// CK_LValueToRValueBitCast via |bit_cast| should emit an error.
(void)__builtin_bit_cast(raw_ref<int>*, p);
(void)__builtin_bit_cast(RawRefWrapper*, p);
(void)__builtin_bit_cast(RawRefWrapperWrapper*, p);
(void)__builtin_bit_cast(RawRefWrapperWrapperWrapper*, p);
(void)__builtin_bit_cast(RawRefWrapperSub*, p);
(void)__builtin_bit_cast(RawRefWrapperVirtualSub*, p);
}

@ -0,0 +1 @@
-ferror-limit=0 -Xclang -plugin-arg-find-bad-constructs -Xclang check-bad-raw-ptr-cast

@ -0,0 +1,522 @@
bad_raw_ref_cast.cpp:40:29: error: [chromium-style] casting 'raw_ref<int> *' to 'void * is not allowed.
(void)static_cast<void*>(&p0);
^
bad_raw_ref_cast.cpp:40:29: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:41:29: error: [chromium-style] casting 'RawRefWrapper *' to 'void * is not allowed.
(void)static_cast<void*>(&p1);
^
bad_raw_ref_cast.cpp:41:29: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:42:29: error: [chromium-style] casting 'RawRefWrapperWrapper *' to 'void * is not allowed.
(void)static_cast<void*>(&p2);
^
bad_raw_ref_cast.cpp:42:29: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:43:29: error: [chromium-style] casting 'RawRefWrapperWrapperWrapper *' to 'void * is not allowed.
(void)static_cast<void*>(&p3);
^
bad_raw_ref_cast.cpp:43:29: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:44:29: error: [chromium-style] casting 'RawRefWrapper (*)[10]' to 'void * is not allowed.
(void)static_cast<void*>(&p4);
^
bad_raw_ref_cast.cpp:44:29: note: [chromium-style] 'RawRefWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:45:29: error: [chromium-style] casting 'RawRefWrapperSub *' to 'void * is not allowed.
(void)static_cast<void*>(&p5);
^
bad_raw_ref_cast.cpp:45:29: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:46:29: error: [chromium-style] casting 'RawRefWrapperVirtualSub *' to 'void * is not allowed.
(void)static_cast<void*>(&p6);
^
bad_raw_ref_cast.cpp:46:29: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:49:17: error: [chromium-style] casting 'raw_ref<int> *' to 'void * is not allowed.
(void)(void*)&p0;
^
bad_raw_ref_cast.cpp:49:17: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:50:17: error: [chromium-style] casting 'RawRefWrapper *' to 'void * is not allowed.
(void)(void*)&p1;
^
bad_raw_ref_cast.cpp:50:17: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:51:17: error: [chromium-style] casting 'RawRefWrapperWrapper *' to 'void * is not allowed.
(void)(void*)&p2;
^
bad_raw_ref_cast.cpp:51:17: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:52:17: error: [chromium-style] casting 'RawRefWrapperWrapperWrapper *' to 'void * is not allowed.
(void)(void*)&p3;
^
bad_raw_ref_cast.cpp:52:17: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:53:17: error: [chromium-style] casting 'RawRefWrapper (*)[10]' to 'void * is not allowed.
(void)(void*)&p4;
^
bad_raw_ref_cast.cpp:53:17: note: [chromium-style] 'RawRefWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:54:17: error: [chromium-style] casting 'RawRefWrapperSub *' to 'void * is not allowed.
(void)(void*)&p5;
^
bad_raw_ref_cast.cpp:54:17: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:55:17: error: [chromium-style] casting 'RawRefWrapperVirtualSub *' to 'void * is not allowed.
(void)(void*)&p6;
^
bad_raw_ref_cast.cpp:55:17: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:58:36: error: [chromium-style] casting 'raw_ref<int> *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p0);
^
bad_raw_ref_cast.cpp:58:36: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:59:36: error: [chromium-style] casting 'RawRefWrapper *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p1);
^
bad_raw_ref_cast.cpp:59:36: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:60:36: error: [chromium-style] casting 'RawRefWrapperWrapper *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p2);
^
bad_raw_ref_cast.cpp:60:36: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:61:36: error: [chromium-style] casting 'RawRefWrapperWrapperWrapper *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p3);
^
bad_raw_ref_cast.cpp:61:36: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:62:36: error: [chromium-style] casting 'RawRefWrapper (*)[10]' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p4);
^
bad_raw_ref_cast.cpp:62:36: note: [chromium-style] 'RawRefWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:63:36: error: [chromium-style] casting 'RawRefWrapperSub *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p5);
^
bad_raw_ref_cast.cpp:63:36: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:64:36: error: [chromium-style] casting 'RawRefWrapperVirtualSub *' to 'void * is not allowed.
(void)reinterpret_cast<void*>(&p6);
^
bad_raw_ref_cast.cpp:64:36: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:67:38: error: [chromium-style] casting 'raw_ref<int> *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p0);
^
bad_raw_ref_cast.cpp:67:38: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:68:38: error: [chromium-style] casting 'RawRefWrapper *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p1);
^
bad_raw_ref_cast.cpp:68:38: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:69:38: error: [chromium-style] casting 'RawRefWrapperWrapper *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p2);
^
bad_raw_ref_cast.cpp:69:38: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:70:38: error: [chromium-style] casting 'RawRefWrapperWrapperWrapper *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p3);
^
bad_raw_ref_cast.cpp:70:38: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:71:38: error: [chromium-style] casting 'RawRefWrapper (*)[10]' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p4);
^
bad_raw_ref_cast.cpp:71:38: note: [chromium-style] 'RawRefWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:72:38: error: [chromium-style] casting 'RawRefWrapperSub *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p5);
^
bad_raw_ref_cast.cpp:72:38: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:73:38: error: [chromium-style] casting 'RawRefWrapperVirtualSub *' to 'void * is not allowed.
(void)__builtin_bit_cast(void*, &p6);
^
bad_raw_ref_cast.cpp:73:38: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:76:11: error: [chromium-style] casting 'raw_ref<int> *' to 'void * is not allowed.
MyFunc(&p0);
^
bad_raw_ref_cast.cpp:76:11: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:77:11: error: [chromium-style] casting 'RawRefWrapper *' to 'void * is not allowed.
MyFunc(&p1);
^
bad_raw_ref_cast.cpp:77:11: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:78:11: error: [chromium-style] casting 'RawRefWrapperWrapper *' to 'void * is not allowed.
MyFunc(&p2);
^
bad_raw_ref_cast.cpp:78:11: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:79:11: error: [chromium-style] casting 'RawRefWrapperWrapperWrapper *' to 'void * is not allowed.
MyFunc(&p3);
^
bad_raw_ref_cast.cpp:79:11: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:80:11: error: [chromium-style] casting 'RawRefWrapper (*)[10]' to 'void * is not allowed.
MyFunc(&p4);
^
bad_raw_ref_cast.cpp:80:11: note: [chromium-style] 'RawRefWrapper (*)[10]' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:81:11: error: [chromium-style] casting 'RawRefWrapperSub *' to 'void * is not allowed.
MyFunc(&p5);
^
bad_raw_ref_cast.cpp:81:11: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:82:11: error: [chromium-style] casting 'RawRefWrapperVirtualSub *' to 'void * is not allowed.
MyFunc(&p6);
^
bad_raw_ref_cast.cpp:82:11: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:89:37: error: [chromium-style] casting 'void *' to 'raw_ref<int> * is not allowed.
(void)static_cast<raw_ref<int>*>(p);
^
bad_raw_ref_cast.cpp:89:37: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:90:38: error: [chromium-style] casting 'void *' to 'RawRefWrapper * is not allowed.
(void)static_cast<RawRefWrapper*>(p);
^
bad_raw_ref_cast.cpp:90:38: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:91:45: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapper * is not allowed.
(void)static_cast<RawRefWrapperWrapper*>(p);
^
bad_raw_ref_cast.cpp:91:45: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:92:52: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapperWrapper * is not allowed.
(void)static_cast<RawRefWrapperWrapperWrapper*>(p);
^
bad_raw_ref_cast.cpp:92:52: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:93:41: error: [chromium-style] casting 'void *' to 'RawRefWrapperSub * is not allowed.
(void)static_cast<RawRefWrapperSub*>(p);
^
bad_raw_ref_cast.cpp:93:41: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:94:48: error: [chromium-style] casting 'void *' to 'RawRefWrapperVirtualSub * is not allowed.
(void)static_cast<RawRefWrapperVirtualSub*>(p);
^
bad_raw_ref_cast.cpp:94:48: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:97:24: error: [chromium-style] casting 'void *' to 'raw_ptr<int> * is not allowed.
(void)(raw_ptr<int>*)p;
^
bad_raw_ref_cast.cpp:97:24: note: [chromium-style] 'raw_ptr<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:98:25: error: [chromium-style] casting 'void *' to 'RawRefWrapper * is not allowed.
(void)(RawRefWrapper*)p;
^
bad_raw_ref_cast.cpp:98:25: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:99:32: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapper * is not allowed.
(void)(RawRefWrapperWrapper*)p;
^
bad_raw_ref_cast.cpp:99:32: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:100:39: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapperWrapper * is not allowed.
(void)(RawRefWrapperWrapperWrapper*)p;
^
bad_raw_ref_cast.cpp:100:39: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:101:28: error: [chromium-style] casting 'void *' to 'RawRefWrapperSub * is not allowed.
(void)(RawRefWrapperSub*)p;
^
bad_raw_ref_cast.cpp:101:28: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:102:35: error: [chromium-style] casting 'void *' to 'RawRefWrapperVirtualSub * is not allowed.
(void)(RawRefWrapperVirtualSub*)p;
^
bad_raw_ref_cast.cpp:102:35: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:105:42: error: [chromium-style] casting 'void *' to 'raw_ref<int> * is not allowed.
(void)reinterpret_cast<raw_ref<int>*>(p);
^
bad_raw_ref_cast.cpp:105:42: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:106:43: error: [chromium-style] casting 'void *' to 'RawRefWrapper * is not allowed.
(void)reinterpret_cast<RawRefWrapper*>(p);
^
bad_raw_ref_cast.cpp:106:43: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:107:50: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapper * is not allowed.
(void)reinterpret_cast<RawRefWrapperWrapper*>(p);
^
bad_raw_ref_cast.cpp:107:50: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:108:57: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapperWrapper * is not allowed.
(void)reinterpret_cast<RawRefWrapperWrapperWrapper*>(p);
^
bad_raw_ref_cast.cpp:108:57: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:109:46: error: [chromium-style] casting 'void *' to 'RawRefWrapperSub * is not allowed.
(void)reinterpret_cast<RawRefWrapperSub*>(p);
^
bad_raw_ref_cast.cpp:109:46: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:110:53: error: [chromium-style] casting 'void *' to 'RawRefWrapperVirtualSub * is not allowed.
(void)reinterpret_cast<RawRefWrapperVirtualSub*>(p);
^
bad_raw_ref_cast.cpp:110:53: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:113:44: error: [chromium-style] casting 'void *' to 'raw_ref<int> * is not allowed.
(void)__builtin_bit_cast(raw_ref<int>*, p);
^
bad_raw_ref_cast.cpp:113:44: note: [chromium-style] 'raw_ref<int> *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:114:45: error: [chromium-style] casting 'void *' to 'RawRefWrapper * is not allowed.
(void)__builtin_bit_cast(RawRefWrapper*, p);
^
bad_raw_ref_cast.cpp:114:45: note: [chromium-style] 'RawRefWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:115:52: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapper * is not allowed.
(void)__builtin_bit_cast(RawRefWrapperWrapper*, p);
^
bad_raw_ref_cast.cpp:115:52: note: [chromium-style] 'RawRefWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:116:59: error: [chromium-style] casting 'void *' to 'RawRefWrapperWrapperWrapper * is not allowed.
(void)__builtin_bit_cast(RawRefWrapperWrapperWrapper*, p);
^
bad_raw_ref_cast.cpp:116:59: note: [chromium-style] 'RawRefWrapperWrapperWrapper *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:21:3: note: [chromium-style] 'RawRefWrapperWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapperWrapper& ref_;
^
bad_raw_ref_cast.cpp:14:3: note: [chromium-style] 'RawRefWrapperWrapper' manages BackupRefPtr or its container here.
RawRefWrapper* ref;
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:117:48: error: [chromium-style] casting 'void *' to 'RawRefWrapperSub * is not allowed.
(void)__builtin_bit_cast(RawRefWrapperSub*, p);
^
bad_raw_ref_cast.cpp:117:48: note: [chromium-style] 'RawRefWrapperSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:24:27: note: [chromium-style] 'RawRefWrapperSub' manages BackupRefPtr or its container here.
struct RawRefWrapperSub : RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
bad_raw_ref_cast.cpp:118:55: error: [chromium-style] casting 'void *' to 'RawRefWrapperVirtualSub * is not allowed.
(void)__builtin_bit_cast(RawRefWrapperVirtualSub*, p);
^
bad_raw_ref_cast.cpp:118:55: note: [chromium-style] 'RawRefWrapperVirtualSub *' manages BackupRefPtr refcounts; bypassing its C++ interface or treating it as a POD will lead to memory safety errors.
bad_raw_ref_cast.cpp:25:34: note: [chromium-style] 'RawRefWrapperVirtualSub' manages BackupRefPtr or its container here.
struct RawRefWrapperVirtualSub : virtual RawRefWrapper {};
^
bad_raw_ref_cast.cpp:10:3: note: [chromium-style] 'RawRefWrapper' manages BackupRefPtr or its container here.
raw_ref<int> ref;
^
59 errors generated.

@ -0,0 +1,25 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_H_
#define TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_H_
namespace base {
template <typename T>
class raw_ptr {
T* ptr;
};
template <typename T>
class raw_ref {
T* ref;
};
} // namespace base
using base::raw_ptr;
using base::raw_ref;
#endif // TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_H_

@ -0,0 +1,27 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_CAST_H_
#define TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_CAST_H_
namespace base {
template <typename Dest, typename Source>
inline constexpr Dest unsafe_raw_ptr_static_cast(Source source) {
return static_cast<Dest>(source);
}
template <typename Dest, typename Source>
inline constexpr Dest unsafe_raw_ptr_reinterpret_cast(Source source) {
return reinterpret_cast<Dest>(source);
}
template <typename Dest, typename Source>
inline constexpr Dest unsafe_raw_ptr_bit_cast(Source source) {
return __builtin_bit_cast(Dest, source);
}
} // namespace base
#endif // TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_CAST_H_

@ -0,0 +1,12 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_EXCLUSION_H_
#define TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_EXCLUSION_H_
// Marks a field as excluded from the raw_ptr usage enforcement clang plugin.
// Example: RAW_PTR_EXCLUSION Foo* foo_;
#define RAW_PTR_EXCLUSION __attribute__((annotate("raw_ptr_exclusion")))
#endif // TOOLS_CLANG_PLUGINS_TESTS_BASE_ALLOCATOR_PARTITION_ALLOCATOR_POINTERS_RAW_PTR_EXCLUSION_H_

@ -5,17 +5,9 @@
#ifndef TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_H_
#define TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_H_
namespace base {
template <typename T>
class raw_ptr {};
template <typename T>
class raw_ref {};
} // namespace base
using base::raw_ptr;
using base::raw_ref;
// Although `raw_ptr` is part of the standalone PA distribution, it is
// easier to use the shorter path in `//base/memory`. We retain this
// facade header for ease of typing.
#include "base/allocator/partition_allocator/pointers/raw_ptr.h" // IWYU pragma: export
#endif // TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_H_

@ -0,0 +1,13 @@
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_CAST_H_
#define TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_CAST_H_
// Although `raw_ptr` is part of the standalone PA distribution, it is
// easier to use the shorter path in `//base/memory`. We retain this
// facade header for ease of typing.
#include "base/allocator/partition_allocator/pointers/raw_ptr_cast.h" // IWYU pragma: export
#endif // TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_CAST_H_

@ -5,8 +5,9 @@
#ifndef TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_EXCLUSION_H_
#define TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_EXCLUSION_H_
// Marks a field as excluded from the raw_ptr usage enforcement clang plugin.
// Example: RAW_PTR_EXCLUSION Foo* foo_;
#define RAW_PTR_EXCLUSION __attribute__((annotate("raw_ptr_exclusion")))
// Although `raw_ptr` is part of the standalone PA distribution, it is
// easier to use the shorter path in `//base/memory`. We retain this
// facade header for ease of typing.
#include "base/allocator/partition_allocator/pointers/raw_ptr_exclusion.h" // IWYU pragma: export
#endif // TOOLS_CLANG_PLUGINS_TESTS_BASE_MEMORY_RAW_PTR_EXCLUSION_H_

@ -23,8 +23,11 @@ class ChromeStylePluginTest(plugin_testing.ClangPluginTest):
# Skip code generation
'-fsyntax-only',
# Fake system directory for tests
'-isystem', os.path.join(os.getcwd(), 'system'),
'-isystem',
os.path.join(os.getcwd(), 'system'),
'-Wno-inconsistent-missing-override',
'--include-directory',
'.',
])