rui314 / chibicc

A small C compiler
MIT License
9.7k stars 884 forks source link

Bug with array initializer #35

Closed stefanos82 closed 1 year ago

stefanos82 commented 3 years ago

The following code

#include <stdio.h>

#define SIZE 10

extern int myarr[SIZE];
int myarr[] = { 11, 34, };

int main(void)
{
    for (int i = 0; i < SIZE; ++i)
        printf("%d: %d\n", i, myarr[i]);

    return 0;
}

should produce the following output:

0: 11
1: 34
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0

Instead of the above, I get the following with chibicc:

0: 11
1: 34
2: 1635147615
3: 1735549279
4: 7366239
5: 1635147615
6: 1735549279
7: 7366239
8: 1635147615
9: 1735549279

I guess this feature has not being implemented yet?

utkuboduroglu commented 3 years ago

From what I understand, chibicc assumes that the array myarr[SIZE] was already created because of the extern and is happy to assign values in the line int myarr[] = { 11, 34, };. In reality, the definition of myarr was actually done during initialization and so is actually myarr[2], hence the remaining values are garbage. After a quick check, I saw that there is no boundary checking yet, so that is why we can read outside the array.

If instead of

extern int myarr[SIZE];
int myarr[] = { 11, 34, };

you write

int myarr[SIZE];

chibicc successfully zero-initializes the array and outputs:

0: 0
1: 0
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0

Although I'm not certain, I think that chibicc also doesn't check for redeclarations, because running

int myarr[SIZE];
int myarr[] = {11, 34};

again doesn't give the desired result.

utkuboduroglu commented 3 years ago

Just a minor edit, I haven't been able to look at the code responsible for this yet, but I suspect that this is not related to extern, but rather that chibicc indeed doesn't have re-declaration checks and that the second statement just 'overwrites' the first one.

The statements

int myarr[SIZE];
int myarr[] = {11, 34};

compile to garbage, but

int myarr[SIZE] = {11, 34};

does indeed give the desired output, so this is possibly not because of a not implemented feature but just a lack of re-declaration checks.

stefanos82 commented 3 years ago

The reason I reported this is because I saw this bug in TinyCC and decided to give it a try in chibicc; I replicated the exact tcc buggy behavior but of course with different output results.

Maybe @rui314 plans to fix this at the cleanup procedure when the majority of compiler is nearly complete?