blob: fdd10f5562b51857fe06883268207c9b8da718c1 [file] [edit]
//=======- RawPtrRefSafetyModel.h -------------------------------*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYZER_WEBKIT_RAWPTRREFSAFETYMODEL_H
#define LLVM_CLANG_ANALYZER_WEBKIT_RAWPTRREFSAFETYMODEL_H
#include "PtrTypesSemantics.h"
#include <memory>
#include <optional>
#include <string>
namespace clang {
class CXXRecordDecl;
class Decl;
class Expr;
class QualType;
class SourceManager;
/// Models one WebKit pointer-safety policy: ref-counted (RefPtr), checked
/// (CheckedPtr), or retainable (RetainPtr/OSPtr).
///
/// It captures the family-specific "what is a safe/unsafe pointer" questions
/// that are shared by the various RawPtrRef* checkers, independently of how
/// each checker traverses the AST (call arguments, local variables, members,
/// lambda captures, ...). This lets a single policy be defined once and reused
/// across every traversal.
class PtrRefSafetyModel {
public:
virtual ~PtrRefSafetyModel() = default;
/// \returns whether \p QT itself is an unsafe (smart-pointer-capable but not
/// managed) type, false if not, std::nullopt if inconclusive.
virtual std::optional<bool> isUnsafeType(QualType QT) const = 0;
/// \returns whether \p QT is a raw pointer or reference to an unsafe type,
/// false if not, std::nullopt if inconclusive. \p IgnoreARC requests that
/// Objective-C ARC be ignored when deciding retainability.
virtual std::optional<bool> isUnsafePtr(QualType QT,
bool IgnoreARC = false) const = 0;
/// \returns whether \p Record is a safe smart pointer for this policy.
virtual bool isSafePtr(const CXXRecordDecl *Record) const = 0;
/// \returns whether \p T is a safe smart pointer type for this policy.
virtual bool isSafePtrType(QualType T) const = 0;
/// \returns whether \p Name is the name of a safe smart pointer class for
/// this policy.
virtual bool isPtrType(const std::string &Name) const = 0;
/// \returns whether \p E is known to produce a safe value for this policy.
virtual bool isSafeExpr(const Expr *) const { return false; }
/// \returns whether \p D refers to a declaration that is safe by construction
/// for this policy (e.g. immortal system-header globals).
virtual bool isSafeDecl(const Decl *, const SourceManager &) const {
return false;
}
/// \returns a human readable name for the safe type category, used in
/// diagnostics (e.g. "RefPtr-capable type").
virtual const char *typeName() const = 0;
/// \returns the RetainTypeChecker backing this policy, or nullptr if the
/// policy does not track retain/OS types.
virtual RetainTypeChecker *retainTypeChecker() const { return nullptr; }
};
/// Applies the memory-management exemptions that hold for a variable, member,
/// or lambda capture (but not for a call argument) before consulting \p Model:
/// a __strong / __weak Objective-C storage location is memory managed and thus
/// safe. \returns whether \p T is an unsafe pointer in such a storage context.
std::optional<bool> isUnsafePtrForStorage(const PtrRefSafetyModel &Model,
QualType T, bool IgnoreARC = false);
/// \returns a policy that treats ref-counted / checked pointers as safe.
std::unique_ptr<PtrRefSafetyModel> makeRefPtrSafetyModel();
/// \returns a policy that treats checked pointers as safe.
std::unique_ptr<PtrRefSafetyModel> makeCheckedPtrSafetyModel();
/// \returns a policy that treats RetainPtr / OSPtr as safe.
std::unique_ptr<PtrRefSafetyModel> makeRetainPtrSafetyModel();
} // namespace clang
#endif