Opened 6 days ago

#316 new defect

Const initialization from computation is ignored within same compile unit

Reported by: mlbrooks Owned by:
Priority: major Component: cfa-cc
Version: 1.0 Keywords: const init compunit
Cc:

Description

CFA allows a constant to have a nontrivial expression as its initializer (like C++), though C does not. Current lowering works for access between compile units, but fails within one compile unit, leaving the value 0 in place of the correct one.

// $ cfa -c -DSPLIT_CU=1 demo.cfa -o demo.1.o
// $ cfa -c -DSPLIT_CU=2 demo.cfa -o demo.2.o
// $ cfa demo.1.o demo.2.o 
// $ ./a.out
#if SPLIT_CU == 1

    const unsigned int x = 25;
    const unsigned int y = 5 * 5;

    void in_cu() {
        printf( "in-compunit access: %u %u\n", x, y );
    }

#elif SPLIT_CU == 2

    extern const unsigned int x;
    extern const unsigned int y;
    extern void in_cu();

    void cross_cu() {
        printf( "cross-compunit access: %u %u\n", x, y );
    }

    int main() {
        in_cu();
        cross_cu();
    }

#else
    #error Bad SPLIT_CU value
#endif

Expected:

in-compunit access: 25 25
cross-compunit access: 25 25

Actual:

in-compunit access: 25 0
cross-compunit access: 25 25

We understand the reason is the CU-1 lowering produces

const unsigned int x = 25;
const unsigned int y;

along with startup-time code to initialize y. There, C semantics say, "y is defined to be 'constexpr' with value 0." So, at the usage (in_cu's print), GCC does not emit loads for (x and) y. Rather, it uses the statically "known" values. This effect occurs even at -O0. As a result, even though the initialization code correctly writes the evaluation of of 5 * 5 into the location of y (via const cast, before main runs), in_cu never reads it.

We believe our current lowering "of constants as constants" is fundamentally incorrect, due to the above phenomenon. Rather, when lowering a constant that requires (early) runtime initialization, it should be lowered as a mutable global variable.

Change History (0)

Note: See TracTickets for help on using tickets.