diff --git a/src/language/ASTNodeDataTypeBuilder.cpp b/src/language/ASTNodeDataTypeBuilder.cpp
index 68bb5a9203f71eb27d7e64a0eb17d0440e7edf9a..a320695ac7b95a29ffa22e4fc5d83f66d5d475c1 100644
--- a/src/language/ASTNodeDataTypeBuilder.cpp
+++ b/src/language/ASTNodeDataTypeBuilder.cpp
@@ -1,5 +1,7 @@
 #include <ASTNodeDataTypeBuilder.hpp>
 
+#include <ASTNodeNaturalConversionChecker.hpp>
+
 #include <PEGGrammar.hpp>
 #include <PugsAssert.hpp>
 #include <SymbolTable.hpp>
@@ -65,6 +67,15 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
     for (auto& child : n.children) {
       this->_buildNodeDataTypes(*child);
     }
+
+    if (n.is_type<language::for_statement>()) {
+      const ASTNode& test_node = *n.children[1];
+
+      if (not n.children[1]->is_type<language::for_test>()) {
+        ASTNodeNaturalConversionChecker{test_node, test_node.m_data_type, ASTNodeDataType::bool_t};
+      }   // in the case of empty for_test (not simplified node), nothing to check!
+    }
+
     n.m_data_type = ASTNodeDataType::void_t;
   } else {
     if (n.has_content()) {
@@ -255,26 +266,16 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
       n.m_data_type = ASTNodeDataType::void_t;
     } else if (n.is_type<language::if_statement>() or n.is_type<language::while_statement>()) {
       n.m_data_type = ASTNodeDataType::void_t;
-      if ((n.children[0]->m_data_type > ASTNodeDataType::double_t) or
-          (n.children[0]->m_data_type < ASTNodeDataType::bool_t)) {
-        const ASTNodeDataType type_0 = n.children[0]->m_data_type;
-        std::ostringstream message;
-        message << "Cannot convert data type to boolean value\n"
-                << "note: incompatible operand '" << n.children[0]->string() << "' of type " << dataTypeName(type_0)
-                << std::ends;
-        throw parse_error(message.str(), n.children[0]->begin());
-      }
+
+      const ASTNode& test_node = *n.children[0];
+      ASTNodeNaturalConversionChecker{test_node, test_node.m_data_type, ASTNodeDataType::bool_t};
+
     } else if (n.is_type<language::do_while_statement>()) {
       n.m_data_type = ASTNodeDataType::void_t;
-      if ((n.children[1]->m_data_type > ASTNodeDataType::double_t) or
-          (n.children[1]->m_data_type < ASTNodeDataType::bool_t)) {
-        const ASTNodeDataType type_0 = n.children[1]->m_data_type;
-        std::ostringstream message;
-        message << "Cannot convert data type to boolean value\n"
-                << "note: incompatible operand '" << n.children[1]->string() << "' of type " << dataTypeName(type_0)
-                << std::ends;
-        throw parse_error(message.str(), n.children[1]->begin());
-      }
+
+      const ASTNode& test_node = *n.children[1];
+      ASTNodeNaturalConversionChecker{test_node, test_node.m_data_type, ASTNodeDataType::bool_t};
+
     } else if (n.is_type<language::unary_not>() or n.is_type<language::lesser_op>() or
                n.is_type<language::lesser_or_eq_op>() or n.is_type<language::greater_op>() or
                n.is_type<language::greater_or_eq_op>() or n.is_type<language::eqeq_op>() or
diff --git a/tests/test_DoWhileProcessor.cpp b/tests/test_DoWhileProcessor.cpp
index 135c8d221dda475ca2552826e7f338fa80b3e8c2..d68b2f9e44b07a7c35fc2cb40b02a5667caa0f0b 100644
--- a/tests/test_DoWhileProcessor.cpp
+++ b/tests/test_DoWhileProcessor.cpp
@@ -48,6 +48,16 @@
     REQUIRE(value == expected_value);                                         \
   }
 
+#define CHECK_DO_WHILE_PROCESSOR_THROWS_WITH(data, error_message)     \
+  {                                                                   \
+    string_input input{data, "test.pgs"};                             \
+    auto ast = ASTBuilder::build(input);                              \
+                                                                      \
+    ASTSymbolTableBuilder{*ast};                                      \
+                                                                      \
+    REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error_message); \
+  }
+
 TEST_CASE("DoWhileProcessor", "[language]")
 {
   SECTION("simple loop")
@@ -90,4 +100,17 @@ do {
 )";
     CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul);
   }
+
+  SECTION("errors")
+  {
+    SECTION("bad test type")
+    {
+      std::string_view data = R"(
+do {
+} while(1);
+)";
+
+      CHECK_DO_WHILE_PROCESSOR_THROWS_WITH(data, "invalid implicit conversion: Z -> B");
+    }
+  }
 }
diff --git a/tests/test_ForProcessor.cpp b/tests/test_ForProcessor.cpp
index 7b4faa85585e36290794a39ea5a5199f2487f3b8..51195d9b3fa75bb5569bef8151a653cc31b9db38 100644
--- a/tests/test_ForProcessor.cpp
+++ b/tests/test_ForProcessor.cpp
@@ -48,6 +48,16 @@
     REQUIRE(value == expected_value);                                         \
   }
 
+#define CHECK_FOR_PROCESSOR_THROWS_WITH(data, error_message)          \
+  {                                                                   \
+    string_input input{data, "test.pgs"};                             \
+    auto ast = ASTBuilder::build(input);                              \
+                                                                      \
+    ASTSymbolTableBuilder{*ast};                                      \
+                                                                      \
+    REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error_message); \
+  }
+
 TEST_CASE("ForProcessor", "[language]")
 {
   SECTION("simple for")
@@ -84,4 +94,17 @@ for(N l=0; l<10; ++l) {
 )";
     CHECK_FOR_PROCESSOR_RESULT(data, "i", 42ul);
   }
+
+  SECTION("errors")
+  {
+    SECTION("bad test type")
+    {
+      std::string_view data = R"(
+for(N l=0; l; ++l) {
+}
+)";
+
+      CHECK_FOR_PROCESSOR_THROWS_WITH(data, "invalid implicit conversion: N -> B");
+    }
+  }
 }
diff --git a/tests/test_IfProcessor.cpp b/tests/test_IfProcessor.cpp
index 9df57fc071bb385ce57b86ec484145682dd5ad59..492d9b7b308dc06d6c89795b313421eeb2657ffb 100644
--- a/tests/test_IfProcessor.cpp
+++ b/tests/test_IfProcessor.cpp
@@ -48,6 +48,16 @@
     REQUIRE(value == expected_value);                                         \
   }
 
+#define CHECK_IF_PROCESSOR_THROWS_WITH(data, error_message)           \
+  {                                                                   \
+    string_input input{data, "test.pgs"};                             \
+    auto ast = ASTBuilder::build(input);                              \
+                                                                      \
+    ASTSymbolTableBuilder{*ast};                                      \
+                                                                      \
+    REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error_message); \
+  }
+
 TEST_CASE("IfProcessor", "[language]")
 {
   SECTION("simple if(true)")
@@ -97,4 +107,18 @@ if(false) {
 )";
     CHECK_IF_PROCESSOR_RESULT(data, "i", 2ul);
   }
+
+  SECTION("errors")
+  {
+    SECTION("bad test type")
+    {
+      std::string_view data = R"(
+if (1.2) {
+}
+
+)";
+
+      CHECK_IF_PROCESSOR_THROWS_WITH(data, "invalid implicit conversion: R -> B");
+    }
+  }
 }
diff --git a/tests/test_WhileProcessor.cpp b/tests/test_WhileProcessor.cpp
index d9200a1f5395a59de3edeb26297ba856869cf486..98e46e73ee06a3c0f352b823ab46494bcd5425ab 100644
--- a/tests/test_WhileProcessor.cpp
+++ b/tests/test_WhileProcessor.cpp
@@ -48,6 +48,16 @@
     REQUIRE(value == expected_value);                                         \
   }
 
+#define CHECK_WHILE_PROCESSOR_THROWS_WITH(data, error_message)        \
+  {                                                                   \
+    string_input input{data, "test.pgs"};                             \
+    auto ast = ASTBuilder::build(input);                              \
+                                                                      \
+    ASTSymbolTableBuilder{*ast};                                      \
+                                                                      \
+    REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error_message); \
+  }
+
 TEST_CASE("WhileProcessor", "[language]")
 {
   SECTION("simple loop")
@@ -90,4 +100,17 @@ while(i<10) {
 )";
     CHECK_WHILE_PROCESSOR_RESULT(data, "i", 12ul);
   }
+
+  SECTION("errors")
+  {
+    SECTION("bad test type")
+    {
+      std::string_view data = R"(
+while(1) {
+}
+)";
+
+      CHECK_WHILE_PROCESSOR_THROWS_WITH(data, "invalid implicit conversion: Z -> B");
+    }
+  }
 }