the compiler used to skip zero initialization when initializer
list was given not covering unspecified elements. now we zero
all non explicitely initialized elements. for example:
typedef struct F F;
struct F
{
int a;
int b;
int c;
};
void
main(void)
{
char a[16] = { 1, 2, 3 }; /* a[3..15] initialized to zero */
F f = { .b = 1 }; /* f.a, f.c initialized to zero */
}
the emited code that initializes local variables did not handle
unaligned data causing stack corruption, affecting code like:
void main(void)
{
char a[9] = {0};
}
this change will emit code that does byte stores for the unaligned
bytes and also handles small objects (<= 16 bytes) without branches.
i made a mistake here as this change breaks the arm and mips compilers
which lack an optimiation in xcom() that folds constant pointer arithmetic
into the offset. on arm, the a node is a complex expression with op OADD of
type TIND but the test rejected the (valid) pointer arithmetic.
instead, we now test for the operations which cannot be constant instead
of using the type as a proxy.
> warning: a.c:9 useless or misleading comparison: UINT < 0
the error can be observed by compiling the following code
with warnings enabled:
#include <u.h>
#include <libc.h>
uint r;
void
main(int argc, char *argv[])
{
int r;
if(r < 0){
exits(0);
}
}
the offending code in the compiler is:
- if(l->op == ONAME && l->sym->type){
- lt = l->sym->type;
- if(lt->etype == TARRAY)
- lt = lt->link;
- }
compiler handles scope by overwritin and reverting
symbols while parsing. in the ccom phase, the nodes symbol
(n->sym) is not in the right scope and we wrongly think r
is uint instead of int.
it is not clear to me what this code tried to accomplish in
the first place nor could anyone answer me this question.
the risk is small as this change doesnt affect the compiled
program, only the warning, so removing the offending code.
When running "?c -p ...", ensure the backend cpp recognizes C++ comments.
2c(1) states that the compilers recognize // comments, and the bare compilers
do. But if you invoke the compiler with '-p', the backend cpp process
doesn't handle // comments properly unless you also give ?c the undocumented
'-+' option (which it passes through to cpp).