From dd60374126aa780f0947d0d9fbcebcc254339740 Mon Sep 17 00:00:00 2001
From: Christian Gram Kalhauge <chrg@dtu.dk>
Date: Thu, 7 Mar 2024 13:08:30 +0100
Subject: [PATCH] Make infinite for loops an addon

---
 rtree-c/src/ReduceC.hs                        | 27 ++++++++++---------
 .../test/expected/clang-23353/reduction/x7.c  |  4 +--
 .../test/expected/clang-23353/reduction/x8.c  |  6 ++---
 3 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/rtree-c/src/ReduceC.hs b/rtree-c/src/ReduceC.hs
index 97388bc..8c5f524 100644
--- a/rtree-c/src/ReduceC.hs
+++ b/rtree-c/src/ReduceC.hs
@@ -40,6 +40,7 @@ import Data.Vector.Internal.Check (HasCallStack)
 --
 -- Todo stuckt names
 
+import Control.Applicative
 import Control.Monad
 import qualified Control.Monad.IRTree as IRTree
 import Data.Monoid
@@ -73,6 +74,7 @@ data Keyword
   | NoSemantics
   | AllowEmptyDeclarations
   | DisallowVariableInlining
+  | AllowInfiniteForLoops
   deriving (Show, Read, Enum, Eq, Ord)
 
 type Lab = (String, C.Position)
@@ -309,7 +311,7 @@ handleDecl d ctx = case inlineTypeDefsCDeclaration d ctx of
           spc1 <- trySplit ("remove static", C.posOf ni') spc $ filter \case
             C.CStorageSpec (C.CStatic _) -> False
             _ow -> True
-          pure $ (C.CDecl spc1 decl' ni')
+          pure $ C.CDecl spc1 decl' ni'
     case (decl', structIds spc) of
       ([], [])
         | AllowEmptyDeclarations `isIn` ctx' ->
@@ -471,24 +473,25 @@ reduceCStatement smt ctx = case smt of
       d -> don'tHandle d
 
     s' <- reduceCStatementOrEmptyBlock s ctx'
-    case me1' of
-      Nothing -> do
-        split ("remove the for loop", C.posOf smt) (pure s') do
+    let forloop n = do
           e2' <- case e2 of
             Just e2' -> maybeSplit ("remove check", C.posOf e2') (reduceCExpr e2' ctx')
             Nothing -> pure Nothing
           e3' <- case e3 of
             Just e3' -> maybeSplit ("remove iterator", C.posOf e3') (reduceCExpr e3' ctx')
             Nothing -> pure Nothing
-          pure $ C.CFor (C.CForInitializing Nothing) e2' e3' s' ni
+          let e2'' =
+                if AllowInfiniteForLoops `isIn` ctx || isNothing e2
+                  then e2'
+                  else e2' <|> Just zeroExpr
+          pure $ C.CFor n e2'' e3' s' ni
+
+    case me1' of
+      Nothing -> do
+        split ("remove the for loop", C.posOf smt) (pure s') do
+          forloop (C.CForInitializing Nothing)
       Just e1' -> do
-        e2' <- case e2 of
-          Just e2' -> maybeSplit ("remove check", C.posOf e2') (reduceCExpr e2' ctx')
-          Nothing -> pure Nothing
-        e3' <- case e3 of
-          Just e3' -> maybeSplit ("remove iterator", C.posOf e3') (reduceCExpr e3' ctx')
-          Nothing -> pure Nothing
-        pure $ C.CFor e1' e2' e3' s' ni
+        forloop e1'
   C.CBreak ni -> Just do
     pure (C.CBreak ni)
   C.CCont ni -> Just do
diff --git a/rtree-c/test/expected/clang-23353/reduction/x7.c b/rtree-c/test/expected/clang-23353/reduction/x7.c
index c9d4bf9..04d7d34 100644
--- a/rtree-c/test/expected/clang-23353/reduction/x7.c
+++ b/rtree-c/test/expected/clang-23353/reduction/x7.c
@@ -1452,7 +1452,7 @@ static const uint8_t func_43(uint64_t p_44,
                     volatile struct S1 * l_795 = &g_313;
                     const uint32_t l_802 = 18446744073709551615uL;
                     *l_795 = g_794;
-                    for (;;)
+                    for (; 0;)
                     {
                         uint8_t l_806 = 0xcaL;
                         * (*l_709) = ((l_802, 15), 0x5f2d07f39e332341LL) ^ * (*l_781);
@@ -1941,7 +1941,7 @@ static uint64_t func_47(int32_t * p_48)
             int16_t l_142 = 0x2dffL;
             int32_t l_149 = 0xcd878405L;
             int32_t l_199 = -4L;
-            for (;;)
+            for (; 0;)
             {
                 int32_t * l_148;
                 int32_t * l_150;
diff --git a/rtree-c/test/expected/clang-23353/reduction/x8.c b/rtree-c/test/expected/clang-23353/reduction/x8.c
index f862155..6bccd46 100644
--- a/rtree-c/test/expected/clang-23353/reduction/x8.c
+++ b/rtree-c/test/expected/clang-23353/reduction/x8.c
@@ -417,7 +417,7 @@ static struct S1 {
         int32_t * l_4211;
         int32_t * l_4212 = (void *) 0;
         uint8_t l_4213 = 0x23L;
-        for (;;)
+        for (; 0;)
         {
             int32_t * l_4168;
             int32_t * * l_4169 = &l_4147;
@@ -1390,7 +1390,7 @@ static const uint8_t func_43(uint64_t p_44,
                 {
                     volatile struct S1 * l_795;
                     const uint32_t l_802 = 18446744073709551615uL;
-                    for (;;)
+                    for (; 0;)
                     {
                         uint8_t l_806 = 0xcaL;
                         * (*l_709) = ((l_802, 15), 0x5f2d07f39e332341LL) ^ * (*l_781);
@@ -1878,7 +1878,7 @@ static uint64_t func_47(int32_t * p_48)
             int16_t l_142 = 0x2dffL;
             int32_t l_149 = 0xcd878405L;
             int32_t l_199 = -4L;
-            for (;;)
+            for (; 0;)
             {
                 int32_t * l_148;
                 int32_t * l_150;
-- 
GitLab