[clang-tools-extra] [clang-tidy] Add bugprone-smart-ptr-initialization (PR #181570)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 15 20:29:21 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra
@llvm/pr-subscribers-clang-tidy
Author: Denis Mikhailov (denzor200)
<details>
<summary>Changes</summary>
The contents of this pull request were substantially written using Cursors default model and Deepseek. I've reviewed to the best of my ability (I had 8 months expirience working on Clang Tidy).
I've tested it on llvm codebase with `-DLLVM_ENABLE_PROJECTS="bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;polly"`.
It provided 1288 warnings without fixits. See [18.log](https://github.com/user-attachments/files/25328253/18.log) based on trunk https://github.com/llvm/llvm-project/commit/038591a1c8452099cd5212b2795b325787a6e57b.
Fixes: https://github.com/llvm/llvm-project/issues/86471
---
Patch is 34.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/181570.diff
13 Files Affected:
- (modified) clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp (+3)
- (modified) clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt (+1)
- (added) clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.cpp (+160)
- (added) clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.h (+38)
- (modified) clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp (+3)
- (modified) clang-tools-extra/docs/ReleaseNotes.rst (+11)
- (added) clang-tools-extra/docs/clang-tidy/checks/bugprone/smart-ptr-initialization.rst (+106)
- (added) clang-tools-extra/docs/clang-tidy/checks/cert/mem56-cpp.rst (+10)
- (modified) clang-tools-extra/docs/clang-tidy/checks/list.rst (+1)
- (added) clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/smart-ptr-initialization/std_smart_ptr.h (+101)
- (added) clang-tools-extra/test/clang-tidy/checkers/bugprone/smart-ptr-initialization-array-cxx17.cpp (+116)
- (added) clang-tools-extra/test/clang-tidy/checkers/bugprone/smart-ptr-initialization-array.cpp (+118)
- (added) clang-tools-extra/test/clang-tidy/checkers/bugprone/smart-ptr-initialization.cpp (+160)
``````````diff
diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
index 4150442c25d61..4dfeac254f1d6 100644
--- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
@@ -74,6 +74,7 @@
#include "SignedCharMisuseCheck.h"
#include "SizeofContainerCheck.h"
#include "SizeofExpressionCheck.h"
+#include "SmartPtrInitializationCheck.h"
#include "SpuriouslyWakeUpFunctionsCheck.h"
#include "StandaloneEmptyCheck.h"
#include "StdNamespaceModificationCheck.h"
@@ -176,6 +177,8 @@ class BugproneModule : public ClangTidyModule {
"bugprone-incorrect-enable-if");
CheckFactories.registerCheck<IncorrectEnableSharedFromThisCheck>(
"bugprone-incorrect-enable-shared-from-this");
+ CheckFactories.registerCheck<SmartPtrInitializationCheck>(
+ "bugprone-smart-ptr-initialization");
CheckFactories.registerCheck<UnintendedCharOstreamOutputCheck>(
"bugprone-unintended-char-ostream-output");
CheckFactories.registerCheck<ReturnConstRefFromParameterCheck>(
diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
index db1256d91d311..e46edc5bafea2 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
@@ -37,6 +37,7 @@ add_clang_library(clangTidyBugproneModule STATIC
IncorrectEnableIfCheck.cpp
IncorrectEnableSharedFromThisCheck.cpp
InvalidEnumDefaultInitializationCheck.cpp
+ SmartPtrInitializationCheck.cpp
UnintendedCharOstreamOutputCheck.cpp
ReturnConstRefFromParameterCheck.cpp
SuspiciousStringviewDataUsageCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.cpp
new file mode 100644
index 0000000000000..786d949903d7a
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.cpp
@@ -0,0 +1,160 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "SmartPtrInitializationCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::bugprone {
+
+namespace {
+
+const auto DefaultSharedPointers = "::std::shared_ptr;::boost::shared_ptr";
+const auto DefaultUniquePointers = "::std::unique_ptr";
+const auto DefaultDefaultDeleters = "::std::default_delete";
+
+} // namespace
+
+SmartPtrInitializationCheck::SmartPtrInitializationCheck(
+ StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ SharedPointers(utils::options::parseStringList(
+ Options.get("SharedPointers", DefaultSharedPointers))),
+ UniquePointers(utils::options::parseStringList(
+ Options.get("UniquePointers", DefaultUniquePointers))),
+ DefaultDeleters(utils::options::parseStringList(
+ Options.get("DefaultDeleters", DefaultDefaultDeleters))) {}
+
+void SmartPtrInitializationCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "SharedPointers",
+ utils::options::serializeStringList(SharedPointers));
+ Options.store(Opts, "UniquePointers",
+ utils::options::serializeStringList(UniquePointers));
+ Options.store(Opts, "DefaultDeleters",
+ utils::options::serializeStringList(DefaultDeleters));
+}
+
+void SmartPtrInitializationCheck::registerMatchers(MatchFinder *Finder) {
+ const auto IsSharedPtr = hasAnyName(SharedPointers);
+ const auto IsUniquePtr = hasAnyName(UniquePointers);
+ const auto IsSmartPtr = anyOf(IsSharedPtr, IsUniquePtr);
+ const auto IsDefaultDeleter = hasAnyName(DefaultDeleters);
+
+ const auto IsSharedPtrRecord = cxxRecordDecl(IsSharedPtr);
+ const auto IsUniquePtrRecord = cxxRecordDecl(IsUniquePtr);
+ const auto IsSmartPtrRecord = cxxRecordDecl(IsSmartPtr);
+
+ auto ReleaseMethod = cxxMethodDecl(hasName("release"));
+ auto ResetMethod = cxxMethodDecl(hasName("reset"));
+
+ auto ReleaseCallMatcher = cxxMemberCallExpr(callee(ReleaseMethod));
+
+ // Array automatically decays to pointer
+ auto PointerArg = expr(anyOf(hasType(pointerType()), hasType(arrayType())))
+ .bind("pointer-arg");
+
+ // Matcher for unique_ptr types with custom deleters
+ auto UniquePtrWithCustomDeleter = classTemplateSpecializationDecl(
+ IsUniquePtr, templateArgumentCountIs(2),
+ hasTemplateArgument(
+ 1, refersToType(
+ unless(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+ classTemplateSpecializationDecl(IsDefaultDeleter))))))));
+
+ // Matcher for smart pointer constructors
+ // Exclude constructors with custom deleters:
+ // - shared_ptr with 2+ arguments (second is deleter)
+ // - unique_ptr with 2+ template args where second is not default_delete
+ auto HasCustomDeleter = anyOf(
+ allOf(hasDeclaration(cxxConstructorDecl(ofClass(IsSharedPtrRecord))),
+ hasArgument(1, anything())),
+ allOf(hasType(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(UniquePtrWithCustomDeleter)))),
+ hasDeclaration(cxxConstructorDecl(ofClass(IsUniquePtrRecord)))));
+
+ auto SmartPtrConstructorMatcher =
+ cxxConstructExpr(
+ hasDeclaration(cxxConstructorDecl(ofClass(IsSmartPtrRecord))),
+ hasArgument(0, PointerArg), unless(HasCustomDeleter),
+ unless(hasArgument(0, cxxNewExpr())),
+ unless(hasArgument(0, ReleaseCallMatcher)))
+ .bind("constructor");
+
+ // Matcher for reset() calls
+ // Exclude reset() calls with custom deleters:
+ // - shared_ptr with 2+ arguments (second is deleter)
+ // - unique_ptr with custom deleter type (2+ template args where second is not
+ // default_delete)
+ auto HasCustomDeleterInReset = anyOf(
+ allOf(on(hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration(
+ classTemplateSpecializationDecl(IsSharedPtr)))))),
+ hasArgument(1, anything())),
+ on(hasType(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(UniquePtrWithCustomDeleter))))));
+
+ auto ResetCallMatcher =
+ cxxMemberCallExpr(
+ on(hasType(hasUnqualifiedDesugaredType(recordType(
+ hasDeclaration(classTemplateSpecializationDecl(IsSmartPtr)))))),
+ callee(ResetMethod), hasArgument(0, PointerArg),
+ unless(HasCustomDeleterInReset), unless(hasArgument(0, cxxNewExpr())),
+ unless(hasArgument(0, ReleaseCallMatcher)))
+ .bind("reset-call");
+
+ Finder->addMatcher(SmartPtrConstructorMatcher, this);
+ Finder->addMatcher(ResetCallMatcher, this);
+}
+
+void SmartPtrInitializationCheck::check(
+ const MatchFinder::MatchResult &Result) {
+ const auto *PointerArg = Result.Nodes.getNodeAs<Expr>("pointer-arg");
+ const auto *Constructor =
+ Result.Nodes.getNodeAs<CXXConstructExpr>("constructor");
+ const auto *ResetCall =
+ Result.Nodes.getNodeAs<CXXMemberCallExpr>("reset-call");
+ assert(PointerArg);
+
+ const SourceLocation Loc = PointerArg->getBeginLoc();
+ const CXXMethodDecl *MethodDecl =
+ Constructor ? Constructor->getConstructor()
+ : (ResetCall ? ResetCall->getMethodDecl() : nullptr);
+ if (!MethodDecl)
+ return;
+
+ const auto *Record = MethodDecl->getParent();
+ if (!Record)
+ return;
+
+ const std::string TypeName = Record->getQualifiedNameAsString();
+ diag(Loc, "passing a raw pointer '%0' to %1%2 may cause double deletion")
+ << getPointerDescription(PointerArg, *Result.Context) << TypeName
+ << (Constructor ? " constructor" : "::reset()");
+}
+
+std::string
+SmartPtrInitializationCheck::getPointerDescription(const Expr *PointerExpr,
+ ASTContext &Context) {
+ std::string Description;
+ llvm::raw_string_ostream OS(Description);
+
+ // Try to get a readable representation of the expression
+ PrintingPolicy Policy(Context.getLangOpts());
+ Policy.SuppressSpecifiers = false;
+ Policy.SuppressTagKeyword = true;
+
+ PointerExpr->printPretty(OS, nullptr, Policy);
+ return OS.str();
+}
+
+} // namespace clang::tidy::bugprone
diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.h b/clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.h
new file mode 100644
index 0000000000000..e8814387d0bc4
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/bugprone/SmartPtrInitializationCheck.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRINITIALIZATIONCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRINITIALIZATIONCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::bugprone {
+
+/// Detects dangerous initialization of smart pointers with raw pointers
+/// that are already owned elsewhere, which can lead to double deletion.
+///
+/// For the user-facing documentation see:
+/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/smart-ptr-initialization.html
+class SmartPtrInitializationCheck : public ClangTidyCheck {
+public:
+ SmartPtrInitializationCheck(StringRef Name, ClangTidyContext *Context);
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+
+private:
+ std::string getPointerDescription(const Expr *PointerExpr,
+ ASTContext &Context);
+ const std::vector<StringRef> SharedPointers;
+ const std::vector<StringRef> UniquePointers;
+ const std::vector<StringRef> DefaultDeleters;
+};
+
+} // namespace clang::tidy::bugprone
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_SMARTPTRINITIALIZATIONCHECK_H
diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
index f64cb47d18b4e..32d273c374511 100644
--- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -21,6 +21,7 @@
#include "../bugprone/SignalHandlerCheck.h"
#include "../bugprone/SignedCharMisuseCheck.h"
#include "../bugprone/SizeofExpressionCheck.h"
+#include "../bugprone/SmartPtrInitializationCheck.h"
#include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h"
#include "../bugprone/StdNamespaceModificationCheck.h"
#include "../bugprone/SuspiciousMemoryComparisonCheck.h"
@@ -267,6 +268,8 @@ class CERTModule : public ClangTidyModule {
CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>(
"cert-err61-cpp");
// MEM
+ CheckFactories.registerCheck<bugprone::SmartPtrInitializationCheck>(
+ "cert-mem56-cpp");
CheckFactories
.registerCheck<bugprone::DefaultOperatorNewOnOveralignedTypeCheck>(
"cert-mem57-cpp");
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 8cf2006172d3f..e3c3ea6cc648d 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -97,6 +97,12 @@ Improvements to clang-tidy
New checks
^^^^^^^^^^
+- New :doc:`bugprone-smart-ptr-initialization
+ <clang-tidy/checks/bugprone/smart-ptr-initialization>` check.
+
+ Detects dangerous initialization of smart pointers with raw pointers that are
+ already owned elsewhere, which can lead to double deletion.
+
- New :doc:`llvm-type-switch-case-types
<clang-tidy/checks/llvm/type-switch-case-types>` check.
@@ -137,6 +143,11 @@ New checks
New check aliases
^^^^^^^^^^^^^^^^^
+- New alias :doc:`cert-mem56-cpp <clang-tidy/checks/cert/mem56-cpp>` to
+ :doc:`bugprone-smart-ptr-initialization
+ <clang-tidy/checks/bugprone/smart-ptr-initialization>`
+ was added.
+
Changes in existing checks
^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/smart-ptr-initialization.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/smart-ptr-initialization.rst
new file mode 100644
index 0000000000000..f1cce7e97c0fd
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/smart-ptr-initialization.rst
@@ -0,0 +1,106 @@
+.. title:: clang-tidy - bugprone-smart-ptr-initialization
+
+bugprone-smart-ptr-initialization
+==================================
+
+Detects dangerous initialization of smart pointers with raw pointers that are
+already owned elsewhere, which can lead to double deletion.
+
+This check implements CERT C++ rule `MEM56-CPP. Do not store an already-owned
+pointer value in an unrelated smart pointer
+<https://wiki.sei.cmu.edu/confluence/display/cplusplus/MEM56-CPP.+Do+not+store+an+already-owned+pointer+value+in+an+unrelated+smart+pointer>`_.
+
+Examples
+--------
+
+The check flags cases where raw pointers that are already owned or managed
+elsewhere are passed to smart pointer constructors or ``reset()`` methods:
+
+.. code-block:: c++
+
+ A& getA();
+ void foo() {
+ // Warning: '&getA()' is already managed elsewhere
+ std::shared_ptr<A> a(&getA());
+ }
+
+ void bar() {
+ int x = 10;
+ // Warning: '&x' points to a local variable
+ std::unique_ptr<int> ptr(&x);
+ }
+
+ void baz() {
+ std::vector<int> vec{1, 2, 3};
+ std::shared_ptr<int> sp;
+ // Warning: '&vec[0]' is managed by the vector
+ sp.reset(&vec[0]);
+ }
+
+Allowed cases
+-------------
+
+The check ignores legitimate cases:
+
+1. **New expressions**: Pointers from ``new`` operators are safe:
+
+ .. code-block:: c++
+
+ std::unique_ptr<int> p(new int(5)); // OK
+
+2. **Release calls**: Pointers from ``release()`` method are transferred:
+
+ .. code-block:: c++
+
+ auto p1 = std::make_unique<int>(5);
+ std::unique_ptr<int> p2(p1.release()); // OK
+
+3. **Custom deleters**: Smart pointers with custom deleters are ignored:
+
+ .. code-block:: c++
+
+ void customDeleter(int* p) { delete p; }
+ std::unique_ptr<int, decltype(&customDeleter)> p(&getA(), customDeleter);
+
+4. **Null pointers**: ``nullptr`` is always safe:
+
+ .. code-block:: c++
+
+ std::shared_ptr<int> p(nullptr); // OK
+ p.reset(nullptr); // OK
+
+Options
+-------
+
+.. option:: SharedPointers
+
+ A semicolon-separated list of (fully qualified) shared pointer type names
+ that should be checked. Default value is
+ `::std::shared_ptr;::boost::shared_ptr`.
+
+.. option:: UniquePointers
+
+ A semicolon-separated list of (fully qualified) unique pointer type names
+ that should be checked. Default value is
+ `::std::unique_ptr`.
+
+.. option:: DefaultDeleters
+
+ A semicolon-separated list of (fully qualified) default deleter type names.
+ Smart pointers with deleters matching these types are considered to use the
+ default deleter and are checked. Smart pointers with custom deleters are
+ ignored. Default value is `::std::default_delete`.
+
+Limitations
+-----------
+
+This check only supports smart pointers with shared and unique ownership
+semantics. Smart pointers with different semantics, such as
+``boost::scoped_ptr``, cannot be used with the current version of this check.
+
+References
+----------
+
+* `CERT C++ MEM56-CPP <https://wiki.sei.cmu.edu/confluence/display/cplusplus/MEM56-CPP.+Do+not+store+an+already-owned+pointer+value+in+an+unrelated+smart+pointer>`_
+* `C++ Core Guidelines R.3: A raw pointer (a T*) is non-owning <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r3-a-raw-pointer-a-t-is-non-owning>`_
+* `C++ Core Guidelines R.20: Use unique_ptr or shared_ptr to represent ownership <https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r20-use-unique_ptr-or-shared_ptr-to-represent-ownership>`_
diff --git a/clang-tools-extra/docs/clang-tidy/checks/cert/mem56-cpp.rst b/clang-tools-extra/docs/clang-tidy/checks/cert/mem56-cpp.rst
new file mode 100644
index 0000000000000..c822756ad921b
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/cert/mem56-cpp.rst
@@ -0,0 +1,10 @@
+.. title:: clang-tidy - cert-mem56-cpp
+.. meta::
+ :http-equiv=refresh: 5;URL=../bugprone/smart-ptr-initialization.html
+
+cert-mem56-cpp
+==============
+
+The `cert-mem56-cpp` check is an alias, please see
+:doc:`bugprone-smart-ptr-initialization <../bugprone/smart-ptr-initialization>`
+for more information.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 34d1c2ce0a174..a21d986e3a02b 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -144,6 +144,7 @@ Clang-Tidy Checks
:doc:`bugprone-signed-char-misuse <bugprone/signed-char-misuse>`,
:doc:`bugprone-sizeof-container <bugprone/sizeof-container>`,
:doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
+ :doc:`bugprone-smart-ptr-initialization <bugprone/smart-ptr-initialization>`,
:doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
:doc:`bugprone-standalone-empty <bugprone/standalone-empty>`, "Yes"
:doc:`bugprone-std-namespace-modification <bugprone/std-namespace-modification>`,
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/smart-ptr-initialization/std_smart_ptr.h b/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/smart-ptr-initialization/std_smart_ptr.h
new file mode 100644
index 0000000000000..afb9a2e95792a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/smart-ptr-initialization/std_smart_ptr.h
@@ -0,0 +1,101 @@
+namespace std {
+
+typedef decltype(nullptr) nullptr_t;
+typedef unsigned long size_t;
+
+template <typename T>
+struct default_delete {
+ void operator()(T* p) const;
+};
+
+template <typename T>
+struct default_delete<T[]> {
+ void operator()(T* p) const;
+};
+
+template <typename T, typename Deleter = default_delete<T>>
+class unique_ptr {
+public:
+ unique_ptr();
+ explicit unique_ptr(T* p);
+ unique_ptr(T* p, Deleter d) {}
+ unique_ptr(std::nullptr_t);
+
+ T* release();
+
+ void reset(T* p = nullptr);
+
+ template <typename D>
+ void reset(T* p, D d) {}
+};
+
+template <typename T, typename Deleter>
+class unique_ptr<T[], Deleter> {
+public:
+ unique_ptr();
+ template <typename U>
+ explicit unique_ptr(U* p);
+ template <typename U>
+ unique_ptr(U* p, Deleter d) {}
+ unique_ptr(std::nullptr_t);
+
+ T* release();
+
+ void reset(T* p = nullptr);
+
+ template <typename D>
+ void reset(T* p, D d) {}
+};
+
+template <typename T>
+class shared_ptr {
+public:
+ shared_ptr();
+ explicit shared_ptr(T* p);
+ template <typename Deleter>
+ shared_ptr(T* p, Deleter d) {}
+ shared_ptr(std::nullptr_t);
+
+ T* release();
+
+ void reset(T* p = nullptr);
+
+ template <typename Deleter>
+ void reset(T* p, Deleter d) {}
+};
+
+template <typename T>
+class shared_ptr<T[]> {
+public:
+ shared_ptr();
+ template <typename U>
+ explicit shared_ptr(U* p);
+ template <typename U, typename Deleter>
+ shared_ptr(U* p, Deleter d) {}
+ shared_ptr(std::nullptr_t);
+
+ T* release();
+
+ void reset(T* p = nullptr);
+
+ template <typename Deleter>
+ void reset(T* p, Deleter d) {}
+};
+
+template<typename T>
+ struct remove_reference
+ { using type = T; };
+
+template<typename T>
+ struct remove_reference<T&>
+ { using type = T; };
+
+template<typename T>
+ struct remove_reference<T&&>
+ { using type = T; };
+
+template<typename T>
+ constexpr typename std::remove_reference<T>::typ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/181570
More information about the cfe-commits
mailing list