assign_expr is not valid
According to the C grammar, assign_expr
should be
assign_expr :
| cond_expr
| unary_expr TAssign assign_expr
| unary_expr TEq assign_expr
We currently have
assign_expr :
| cond_expr
| assign_expr TAssign assign_expr
| assign_expr TEq assign_expr
This happened at commit 20005f09 when "fixing" assign_expr
for test assign_deref_funcall_in_macro_it
(see !101 (merged)). Before that commit we had:
assign_expr :
| cond_expr
| cast_expr TAssign assign_expr
| cast_expr TEq assign_expr
which is invalid but was also justified under wrong assumptions (allowing (int * ) xxx = &yy;
which is not valid C code)
Not only the current definition still allows for invalid constructs that the previous one allowed (because cast_expr
can be reduced to assign_expr
through arith_expr
and cond_expr
) but it allowed for more (hence the new test and 11 more files of the Linux kernel passing). I only created more false positives when making that mistake (at least it is now documented and we got rid of wrong misleading comments)
Test assign_deref_funcall_in_macro_it
passes under the current definition of assign_expr
because code:
for_one(1)
*id(ptr) = 0;
is read as (a * b) = c;
(which is not valid in C) instead of a (*b = c);
. To illustrate that, use the attached cocci patch (expr_mul.cocci) with the assign_deref_funcall_in_macro_it.c
Using unary_expr
as the grammar requires leads the test to fail. For it to pass, we need to have for_one(1)
understood as a loop header and therefore have for_one
seen as a TMacroIterator
which would then make the above code be reduced as an iteration
(which will then be reduced as statement
), ensuring that we properly understand the code as a (*b = c);
Maybe some work similar to what has been done for TMacroStmt
(see !92 (merged)) could be done for TMacroIterator
but I have not investigated the problem far enough to be confident that this would work
For reference, annex A.2.1 of the C99 standard exposes the grammar for expressions while section 6.5 details them with their semantics and constraints
I think this issue is of high priority because our current state might mislead us into believing something is working (through tests) while they are actually misunderstood by the parser, causing some automated tools to produce erroneous patches/code transformations