yesterday I was hammering my head with a piece of C code (not written by me, & bare metal profiled for MIPS32) which continuously crashes when compiled with SierraC while it works when compiled with gcc
while (p_btree->context.queue isNotEqualTo NULL)
{
p_node = queue_de(p_btree);
if ((p_node->parent isNotEqualTo NULL)logicalAnd(p_node isEqualTo p_node->parent->pointer[0]))
{
rank_new = tree_get_path_lengh_to_root(p_root, p_node);
if (rank_new isNotEqualTo rank)
{
rank = rank_new;
}
}
}
working with gcc, not working with sierraC
is_done=(p_btree->context.queue isEqualTo NULL);
while (is_done isNotEqualTo True)
{
p_node = queue_de(p_btree);
is_ok1=(p_node->parent isNotEqualTo NULL);
if (is_ok1 isEqualTo True)
{
is_ok2=(p_node isEqualTo p_node->parent->pointer[0]);
if (is_ok2 isEqualTo True)
{
rank2 = tree_get_path_lengh_to_root(p_root, p_node);
if (rank2 isNotEqualTo rank1)
{
rank1 = rank2;
}
}
}
is_done=(p_btree->context.queue isEqualTo NULL);
}
working with both sierraC and gcc
of course the "fixed" version is too pedantic, but just a proof of concept, in order to understand WTF is wrong in the original code
and as far as I understand WTF happened, my debug TAP has found that the problem is around the following line
if ((p_node->parent isNotEqualTo NULL)logicalAnd(p_node isEqualTo p_node->parent->pointer[0]))
more specifically (analyzing the assembly code) it seems that it depends by the CC implementation
SierraC seems to implement the IF-STATEMENT as
- step1: eval (p_node->parent isNotEqualTo NULL)
- step2: eval (p_node isEqualTo p_node->parent->pointer[0])
- step3: if they are both True then take the IF branch, else take the ELSE branch
GCC seems to implement the IF-STATEMENT as
- step1: eval (p_node->parent isNotEqualTo NULL)
- step2: if the previous eval is True then eval (p_node isEqualTo p_node->parent->pointer[0])
- step3: if (is_ok2 isEqualTo True) then take the IF branch, else take the ELSE branch
so the problem with SierraC is … with "p_node->parent->pointer" which crashes when "p_node->parent" is NULL
if so, it means that I have 4K lines of C to be fixed