Skip to content
Snippets Groups Projects
Commit 888ae4e3 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Check that natural integer cannot become negative on decrement

parent fcbca642
No related branches found
No related tags found
1 merge request!145git subrepo clone git@gitlab.com:OlMon/org-themes.git packages/org-themes
...@@ -16,6 +16,11 @@ struct IncDecOp<language::unary_minusminus> ...@@ -16,6 +16,11 @@ struct IncDecOp<language::unary_minusminus>
PUGS_INLINE A PUGS_INLINE A
eval(A& a) eval(A& a)
{ {
if constexpr (std::is_same_v<A, uint64_t>) {
if (a == 0) {
throw std::domain_error("decrement would produce negative value");
}
}
return --a; return --a;
} }
}; };
...@@ -38,6 +43,11 @@ struct IncDecOp<language::post_minusminus> ...@@ -38,6 +43,11 @@ struct IncDecOp<language::post_minusminus>
PUGS_INLINE A PUGS_INLINE A
eval(A& a) eval(A& a)
{ {
if constexpr (std::is_same_v<A, uint64_t>) {
if (a == 0) {
throw std::domain_error("decrement would produce negative value");
}
}
return a--; return a--;
} }
}; };
...@@ -64,8 +74,13 @@ class IncDecExpressionProcessor final : public INodeProcessor ...@@ -64,8 +74,13 @@ class IncDecExpressionProcessor final : public INodeProcessor
DataVariant DataVariant
execute(ExecutionPolicy&) execute(ExecutionPolicy&)
{ {
try {
return IncDecOp<IncDecOpT>().eval(std::get<DataT>(*p_value)); return IncDecOp<IncDecOpT>().eval(std::get<DataT>(*p_value));
} }
catch (std::domain_error& e) {
throw ParseError(e.what(), m_node.children[0]->begin());
}
}
IncDecExpressionProcessor(ASTNode& node) : m_node{node} IncDecExpressionProcessor(ASTNode& node) : m_node{node}
{ {
......
...@@ -58,6 +58,23 @@ ...@@ -58,6 +58,23 @@
REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error_message); \ REQUIRE_THROWS_WITH(ASTNodeDataTypeBuilder{*ast}, error_message); \
} }
#define CHECK_INCDEC_THROWS_WITH(data, error_message) \
{ \
TAO_PEGTL_NAMESPACE::string_input input{data, "test.pgs"}; \
auto ast = ASTBuilder::build(input); \
\
ASTSymbolTableBuilder{*ast}; \
ASTNodeDataTypeBuilder{*ast}; \
\
ASTNodeDeclarationToAffectationConverter{*ast}; \
ASTNodeTypeCleaner<language::var_declaration>{*ast}; \
\
ASTNodeExpressionBuilder{*ast}; \
ExecutionPolicy exec_policy; \
\
REQUIRE_THROWS_WITH(ast->execute(exec_policy), error_message); \
}
// clazy:excludeall=non-pod-global-static // clazy:excludeall=non-pod-global-static
TEST_CASE("IncDecExpressionProcessor", "[language]") TEST_CASE("IncDecExpressionProcessor", "[language]")
...@@ -124,6 +141,16 @@ TEST_CASE("IncDecExpressionProcessor", "[language]") ...@@ -124,6 +141,16 @@ TEST_CASE("IncDecExpressionProcessor", "[language]")
SECTION("errors") SECTION("errors")
{ {
SECTION("negative pre -- operator for N")
{
CHECK_INCDEC_THROWS_WITH(R"(let n:N, n=0;--n;)", "decrement would produce negative value");
}
SECTION("negative post -- operator for N")
{
CHECK_INCDEC_THROWS_WITH(R"(let n:N, n=0;n--;)", "decrement would produce negative value");
}
SECTION("undefined pre -- operator") SECTION("undefined pre -- operator")
{ {
auto error_message = [](std::string type_name) { auto error_message = [](std::string type_name) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment