[LLVMdev] New type of smart pointer for LLVM

Anton Yartsev anton.yartsev at gmail.com
Wed Sep 24 19:12:30 PDT 2014


Hello everyone,

I bring to discussion the necessity/design of a new type of smart 
pointer. r215176 and r217791 rise the problem, D5443 
<http://reviews.llvm.org/D5443> is devoted to the solution.
r215176 applies several temporary ugly fixes of memory leaks in 
TGParser.cpp which would be great to be refactored using smart pointers. 
D5443 <http://reviews.llvm.org/D5443> demonstrates how the solution with 
a certain type of smart pointer would look like (see changes in 
TGParser::ParseDef(), TGParser::InstantiateMulticlassDef() and 
TGParser::ParseSimpleValue()).

Briefly:
consider a leaky example:
{
   T* p = new T;
   if (condition1) {
     f(p); // takes ownership of p
   }
   p->SomeMethod();

   if (condition2) {
     return nullptr; // Leak!
   }

   g(p); // don't take ownership of p
   return p;
}

The preferred solution would look like:
{
   smart_ptr<T> p(new T);
   if (condition1) {
     f(p.StopOwn()); // takes ownership of p
   }
   p->SomeMethod();

   if (condition2) {
     return nullptr; //
   }

   g(p.Get());  // don't take ownership of p
   return p.StopOwn();
}

Neither unique_ptr nor shared_ptr can be used in the place of smart_ptr 
as unique_ptr sets the raw pointer to nullptr after release() (StopOwn() 
in the example above) whereas shared_ptr is unable to release.

Attached is a scratch that illustrates how the minimal 
API/implementation of a desired smart pointer sufficient for refactoring 
would look like. Any ideas and suggestions are appreciated.

-- 
Anton

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140925/fb27d622/attachment.html>
-------------- next part --------------
//===-- CondOwnershipPtr.h - Smart ptr with conditional release -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//===----------------------------------------------------------------------===//

#ifndef LLVM_ADT_CONDOWNERSHIPPTR_H
#define LLVM_ADT_CONDOWNERSHIPPTR_H

namespace llvm {

template<class T> 
class CondOwnershipPtr {
  T* Ptr;
  bool Own;

  void Delete() {
    if (Ptr && !Own)
      delete Ptr;
  }

public:
  CondOwnershipPtr() : Ptr(nullptr), Own(true) {}
  explicit CondOwnershipPtr(T* p) : Ptr(p), Own(true) {}

  ~CondOwnershipPtr() {
    Delete();
  }

  T* Get() const {
    return Ptr;
  }

  T* StopOwn() const {
    Own = false;
    return Ptr;
  }

  void Reset(T* P = nullptr) {
    if (P != Ptr) {
      Delete();
      Ptr = P;
      Own = true;
    }
  }

  bool Owns() const {
    return Own;
  }

  operator bool() const {
    return Ptr != nullptr;
  }

  T& operator*() const {
    return *Ptr;
  }

  T* operator->() const {
    return Ptr;
  }
};

} // end namespace llvm

#endif


More information about the llvm-dev mailing list