[coco] Invoke detach from each Child class (#1713)
author박종현/동작제어Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>
Tue, 2 Oct 2018 04:57:09 +0000 (13:57 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 2 Oct 2018 04:57:09 +0000 (13:57 +0900)
* [coco] Invoke detach from each Child class

The current implementation invokes 'detach' inside the destructor of Node.

Unfortunately, this may result in undefined behavior as detach may access the
internal of Child class (through leaving hook), but Child class is already
destructed.

With this commit, unlink on destruction is the responsibility of each
Child class.

Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
* Add a comment

contrib/coco/core/include/coco/ADT/DLinkedList.h
contrib/coco/core/include/coco/IR/Block.h
contrib/coco/core/include/coco/IR/Instr.h
contrib/coco/core/src/ADT/DLinkedList.test.cpp

index d5a0d32..3bbe655 100644 (file)
@@ -177,11 +177,11 @@ template <typename Child, typename Parent> struct DLinkedList
   public:
     virtual ~Node()
     {
-      if (parent())
-      {
-        // Detach itself on destruction (if it belongs to a list).
-        detach();
-      }
+      // Each Child should unlink itself on destruction
+      //
+      // NOTE detach invokes "leaving" hook which may access the internal of each Child,
+      //      so it is not safe to invoke detach here
+      assert(parent() == nullptr);
     }
 
   public:
index b7c5926..cd92d6f 100644 (file)
@@ -53,6 +53,15 @@ public:
   Block(Block &&) = delete;
 
 public:
+  ~Block()
+  {
+    if (parent())
+    {
+      detach();
+    }
+  }
+
+public:
   InstrList *instr(void) { return &_instr; }
   const InstrList *instr(void) const { return &_instr; }
 
index 1218f3f..302abc5 100644 (file)
@@ -58,7 +58,15 @@ public:
   Instr(Instr &&) = delete;
 
 public:
-  virtual ~Instr() = default;
+  virtual ~Instr()
+  {
+    if (parent())
+    {
+      // NOTE It is safe to invoke detach here (although "Instr" is not a final class)
+      //      as "leaving" hook accesses only the internal of "Instr" class
+      detach();
+    }
+  }
 
 public:
 #define INSTR(Name)                                \
index 6aacc27..563a396 100644 (file)
@@ -51,7 +51,14 @@ private:
 
 class Child final : public coco::DLinkedList<Child, Parent>::Node
 {
-  // DO NOTHING
+public:
+  ~Child()
+  {
+    if (parent())
+    {
+      detach();
+    }
+  }
 };
 
 } // namespace