From b64b18216a1d6e17c52e46e50de02be1ed92360c Mon Sep 17 00:00:00 2001 From: Sam Vervaeck Date: Wed, 31 May 2023 13:14:46 +0200 Subject: [PATCH] Second attemmpt at fixing critical bug in Node::unref() --- include/bolt/CST.hpp | 9 ++------- src/CST.cc | 25 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/include/bolt/CST.hpp b/include/bolt/CST.hpp index 67ca881b5..a41d0a5e9 100644 --- a/include/bolt/CST.hpp +++ b/include/bolt/CST.hpp @@ -197,12 +197,7 @@ namespace bolt { ++RefCount; } - inline void unref() { - --RefCount; - if (RefCount == 0) { - delete this; - } - } + void unref(); void setParents(); @@ -249,7 +244,7 @@ namespace bolt { virtual Scope* getScope(); - virtual ~Node(); + virtual ~Node() {} }; diff --git a/src/CST.cc b/src/CST.cc index 5cb02fbbb..8779dbb69 100644 --- a/src/CST.cc +++ b/src/CST.cc @@ -289,19 +289,26 @@ namespace bolt { } - Node::~Node() { + void Node::unref() { - struct UnrefVisitor : public CSTVisitor { + --RefCount; - void visit(Node* N) { - visitEachChild(N); - N->unref(); - } + if (RefCount == 0) { - }; + // You may be wondering why we aren't unreffing the children in the + // destructor. This is due to a behaviour in Clang where a top-level + // destructor ~Node() wont get access to the fields in derived classes + // because they may already have been destroyed. + struct UnrefVisitor : public CSTVisitor { + void visit(Node* N) { + N->unref(); + } + }; + UnrefVisitor V; + V.visitEachChild(this); - UnrefVisitor V; - V.visitEachChild(this); + delete this; + } }