From 4c7045a28a92388e2d7d2a2f2151c21eae9a17d5 Mon Sep 17 00:00:00 2001
From: Terraneo Federico <fede.tft@miosix.org>
Date: Mon, 31 Jul 2023 09:45:06 +0200
Subject: [PATCH] Fix class Queue not calling destructors for types that need
 it

---
 miosix/kernel/queue.h | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/miosix/kernel/queue.h b/miosix/kernel/queue.h
index cf8a82d8..3b98623b 100644
--- a/miosix/kernel/queue.h
+++ b/miosix/kernel/queue.h
@@ -175,11 +175,7 @@ public:
      * Same as reset(), but to be used only inside IRQs or when interrupts are
      * disabled.
      */
-    void IRQreset()
-    {
-        IRQwakeWaitingThread();
-        putPos=getPos=numElem=0;
-    }
+    void IRQreset();
 
     //Unwanted methods
     Queue(const Queue& s) = delete;
@@ -290,11 +286,28 @@ bool Queue<T,len>::IRQget(T& elem, bool *hppw)
     IRQwakeWaitingThread();
     if(isEmpty()) return false;
     numElem--;
-    elem=buffer[getPos];
+    elem=std::move(buffer[getPos]);
     if(++getPos==len) getPos=0;
     return true;
 }
 
+template <typename T, unsigned int len>
+void Queue<T,len>::IRQreset()
+{
+    IRQwakeWaitingThread();
+    //Relying on constant folding to omit this code for trivial types
+    if(std::is_trivially_destructible<T>::value==false)
+    {
+        while(!isEmpty())
+        {
+            numElem--;
+            buffer[getPos].~T();
+            if(++getPos==len) getPos=0;
+        }
+    }
+    putPos=getPos=numElem=0;
+}
+
 //This partial specialization is meant to to produce compiler errors in case an
 //attempt is made to instantiate a Queue with zero size, as it is forbidden
 template<typename T> class Queue<T,0> {};
-- 
GitLab