[cfe-dev] RFC-0x000 - Should (automatic) local variables be initialized to 0 for the programmer?

dan chap dchapiesky at yahoo.com
Sun Jun 13 11:28:56 PDT 2010


RFC-0x0000

For clang release mode compiles: 

Should (automatic) local variables be initialized to 0 for the programmer?

---------------------------------------------------------------------------

Consider:

    main()
    {
        int a;

        printf("a: %d\n",a);
    }

Run:
    ./a.out

    a: XXX
    

----------------------------------------------------------------------------

What is XXX?  

    0? 

    or garbage?

----------------------------------------------------------------------------

I was fiddling about with clang and gcc one night and found that gcc release mode ALWAYS initializes local variables to zero (evidently diverging from standards documents).

For 

    gcc debug,
    clang release,
    clang release for bitcode and run through lli,
    clang debug,
    clang debug for bitcode and run through lli,

local variables are NOT initialized to 0.

(Caveat #0: this is not a question about standards such as C99... this is about runtime compatibility with the existing code base which was developed using gcc and the reasonable expectations that software has when compiled with clang...)

(Caveat #1: this assumes x86 32 bit code generation.... I have not tested x64 or other target cpus)

(Caveat #2: both STATIC globals and STATIC local variables ARE SET TO 0 AUTOMATICALLY BY ALL compilers and build types)



Why this is so for gcc release mode, I offer the following hypothesis:

    A) There is a lot of crappy code out there...
    B) The crappy code is in a lot of useful and ubiquitous tools (see GNU/linux et al)
    C) These tools are always compiled in release mode for packaging in larger distributions (see ubuntu, redhat, etc..)
    D) The compiler used is gcc....
    E) The crappy code assumes locals are 0 and runs happily in hundreds of scripts and commands on your very own computer.


Why this interests the clang/llvm community, I offer the following:

    A) It would be nice to drop in clang instead of gcc (duh)
    B) No one wants to fix a bunch of crappy code (even with the great static analysis we get from clang) (duh huh)
    C) the insidiousness of the test results for release mode binaries as described further below.... (it's a good one)


IMHO... For debug mode, you obviously want the behaviour of not setting locals to 0 because it does help to find cheesy code and there is clang static analysis anyway....


So here is my Request For Comment Question:

    Q:    Should clang release mode emulate gcc behaviour and set (automatic) local variables to 0 if not explicitly initialized by the programmer? 


Before answering!!!! Please consider the insidious bug I detail below which shows how the reasonable expectation of many existing programs could be broken....


I hope this stirs up some interesting conversation...

(and part of me hopes I am somehow being incredibly stupid and that the bugs I detail below are somehow a figment of my imagination...
if that proves to be the case, less than polite comments on my programming ability are invited)


Sincerely,

Daniel Chapiesky

------------------------------------------------------------------------------
------------------------------------------------------------------------------

I wrote the attached testkit: local_var_test

It is a simple C program and shell script.

The script compiles the program using gcc and clang in the various modes, runs thems, and stores the results.

I have included the results from my own system in ./my_results_on_ubuntu_x86

It will create a ./bin and ./results directory and run each version of the program leaving the results for you to check out.

The test checks:

    the stack from invocation of main()
    the stack of a function called with no arguments: test_function_A()
    the stack of a function called with arguments: test_function_B()
    the stack as A() and B() are interleaved with each other in a loop.

    for the hell of it I threw in C() also, which tests initialization of statics.


For my test runs, the reference compilers were:

    clang version 1.1 (branches/release_27 1089)        [The 2.7 tarball as reference)
    Target: i386-pc-linux-gnu
    Thread model: posix

    gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4)             [The gcc from Ubuntu as reference - NOT the llvm-gcc]
    Target: i486-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.3.3-5ubuntu4' --with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.3 --program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
    Thread model: posix


llvm-gcc was not used (as I do not...)


The basic code fragment used for testing was:

    static int result = 0; // 0 - success , 1 - failure (bash exit status rules)

    void test_function_A()
    {
        unsigned long a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;

        unsigned long AA,BB,CC,DD;

        AA = 0x01;
        BB = 0xFF01;
        CC = 0x01AA01;
        DD = 0xFF01AA01;

        printf("test_function_A() - 26 local ints - all should be 0\n");
        printf("\ta: %lu\tb: %lu\tc: %lu\td: %lu\te: %lu\n",a,b,c,d,e);
        printf("\tf: %lu\tg: %lu\th: %lu\ti: %lu\tj: %lu\n",f,g,h,i,j);
        printf("\tk: %lu\tl: %lu\tm: %lu\tn: %lu\to: %lu\n",k,l,m,n,o);
        printf("\tp: %lu\tq: %lu\tr: %lu\ts: %lu\tt: %lu\n",p,q,r,s,t);
        printf("\tu: %lu\tv: %lu\tw: %lu\tx: %lu\ty: %lu\n",u,v,w,x,y);
        printf("\tz: %lu\n\n",z);

        if (a || b || c || d || e || f || g || h || i || j || k || l || m || n || o || p || q || r || s || t || u || v || w || x || z) {
            printf("******* local variable was not zero! ****************\n");
            result = 1; // 0 - success , 1 - failure (bash exit status rules)
        }

        printf("\tLocal assigned variables:\n");
        printf("\t\tAA: %0lX should be 0x01\n",AA);
        printf("\t\tBB: %0lX should be 0xff01\n",BB);
        printf("\t\tCC: %0lX should be 0x01aa01\n",CC);
        printf("\t\tDD: %0lX should be 0xff01aa01\n",DD);

        if ((AA != 0x01) || (BB !=0xFF01) || (CC != 0x01AA01) || (DD != 0xFF01AA01)) {
            printf("******* assigned variable was not assigned value! ****************\n");
            result = 1; // 0 - success , 1 - failure (bash exit status rules)
        }

    }


A summary of the results (as taken directly from output files) were:

    GCC Release

        main() - 26 local ints - all should be 0
            a: 0    b: 0    c: 0    d: 0    e: 0
            f: 0    g: 0    h: 0    i: 0    j: 0
            k: 0    l: 0    m: 0    n: 0    o: 0
            p: 0    q: 0    r: 0    s: 0    t: 0
            u: 0    v: 0    w: 0    x: 0    y: 0
            z: 0

    GCC Debug

        main() - 26 local ints - all should be 0
            a: 3086260336    b: 134516041    c: 3215293832    d: 134524916    e: 3086053364
            f: 134513384    g: 3215293800    h: 134524916    i: 3085799897    j: 3085070158
            k: 3215295786    l: 0    m: 0    n: 0    o: 0
            p: 0    q: 0    r: 0    s: 0    t: 0
            u: 0    v: 0    w: 3086204928    x: 0    y: 0
            z: 0

        ******* local variable was not zero! ****************

    Clang Release

        main() - 26 local ints - all should be 0
            a: 41    b: 41    c: 41    d: 41    e: 41
            f: 31    g: 31    h: 31    i: 31    j: 31
            k: 31    l: 31    m: 31    n: 31    o: 31
            p: 31    q: 31    r: 31    s: 31    t: 31
            u: 31    v: 31    w: 31    x: 31    y: 31
            z: 31

        ******* local variable was not zero! ****************

    Clang Debug

        main() - 26 local ints - all should be 0
            a: 134516425    b: 3214154872    c: 134524916    d: 3087020020    e: 134513348
            f: 3214154840    g: 134524916    h: 3086766553    i: 3086036814    j: 3214161198
            k: 0    l: 0    m: 0    n: 0    o: 0
            p: 0    q: 0    r: 0    s: 0    t: 0
            u: 0    v: 3087171584    w: 0    x: 0    y: 0
            z: 0

        ******* local variable was not zero! ****************

------------------------------------------------------------------------------------------------


    ************************************************************************************************
    ************************* INSIDIOUS BUG ALERT !!! **********************************************
    ************************* INSIDIOUS BUG ALERT !!! **********************************************
    ************************* INSIDIOUS BUG ALERT !!! (at least I think it is....) *****************
    ************************************************************************************************


Here are the results from the compile and run shell script:

    ./bin does not exist... making it...woooo
    ./results does not exist... making it...woooo

    Compiling test with GNU gcc (debug mode)
    Compiling test with GNU gcc (release mode)
    Compiling test with clang (debug mode for native)
    Compiling test with clang (release mode for native)
    Compiling test with clang (debug BC mode for lli)
    Compiling test with clang (release BC mode for lli)

    *** gcc debug does not init locals to 0

    !!! gcc release does init locals to 0

    *** clang debug does not init locals to 0

    !!! clang release does init locals to 0

    *** clang debug BC does not init locals to 0

    !!! clang release BC does init locals to 0


The shell script is reporting THAT CLANG RELEASE MODE DOES INIT LOCALS TO 0!!!!????!!!????????? ?    ?     ?



In release mode, the code fragment:

        printf("\tz: %lu\n\n",z);

        if (a || b || c || d || e || f || g || h || i || j || k || l || m || n || o || p || q || r || s || t || u || v || w || x || z) {
            printf("******* local variable was not zero! ****************\n");
        }

        printf("\tLocal assigned variables:\n");


becomes

        printf("\tz: %lu\n\n",z);

        // removed - if (a || b || c || d || e || f || g || h || i || j || k || l || m || n || o || p || q || r || s || t || u || v || w || x || z) {
        // removed -    printf("******* local variable was not zero! ****************\n");
        // removed -    result = 1; // 0 - success , 1 - failure (bash exit status rules)
        // removed - }

        printf("\tLocal assigned variables:\n");


because the compiler assumes all variables are 0 and can evaluate the the above statement away.... 
the variable "result" never gets set to 1 and the shell script never gets to say that things went wrong....


Insidious Bug Part 1: ******************************************************************************************
Unfortunately, even though the compiler assumes all variables are 0.... they are, in fact, not guaranteed to be:
****************************************************************************************************************


Clang Release

        main() - 26 local ints - all should be 0
            a: 41    b: 41    c: 41    d: 41    e: 41
            f: 31    g: 31    h: 31    i: 31    j: 31
            k: 31    l: 31    m: 31    n: 31    o: 31
            p: 31    q: 31    r: 31    s: 31    t: 31
            u: 31    v: 31    w: 31    x: 31    y: 31
            z: 31


---------------------------------------------------------------------------------------------------------------------------


I realized I wanted a little better output for the shell script, so I modified it to send some
messages to stderr.  You now get...


    ./bin does not exist... making it...woooo
    ./results does not exist... making it...woooo

    Compiling test with GNU gcc (debug mode)
    Compiling test with GNU gcc (release mode)
    Compiling test with clang (debug mode for native)
    Compiling test with clang (release mode for native)
    Compiling test with clang (debug BC mode for lli)
    Compiling test with clang (release BC mode for lli)

    ./bin/local_var_test_gnu_gcc_debug [3086 garbage 51316836134519012] should be [00000000000000000000000000]
    *** gcc debug does not init locals to 0

    ./bin/local_var_test_gnu_gcc_release [00000000000000000000000000] should be [00000000000000000000000000]
    !!! gcc release does init locals to 0

    ./bin/local_var_test_clang_debug [30870 garbage 70855683085656992] should be [00000000000000000000000000]
    *** clang debug does not init locals to 0

    ./bin/local_var_test_clang_release [3086079 garbage 3086079328] should be [00000000000000000000000000]
    !!! clang release does init locals to 0

    ./bin/local_var_test_clang_debug_BC [03084344160 garbage 12883872] should be [00000000000000000000000000]
    *** clang debug BC does not init locals to 0

    ./bin/local_var_test_clang_release_BC [3086 garbage 403086067040] should be [00000000000000000000000000]
    !!! clang release BC does init locals to 0


Insidious Bug Part 2: *********************************************************************************************
Note that gcc release does output the block of 0's and the others fool the shell script with clever optimizations.
*******************************************************************************************************************



-----------------------------------------------------------------------------

The complete gcc release run results were:


    ./bin/local_var_test_gnu_gcc_release

    main() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    == test A ========================
    test_function_A() call # 1

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01

    test_function_A() call # 0

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01



    == test B ========================
    test_function_B(32,64,128,256,512) call # 1

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512

    test_function_B(32,64,128,256,512) call # 0

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512



    == test A + B ========================

    interleaved test_function_A() call # 3

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 3

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512


    interleaved test_function_A() call # 2

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 2

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512


    interleaved test_function_A() call # 1

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 1

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512


    interleaved test_function_A() call # 0

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 0

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512






    == test C (statics) ========================
    test_function_C() - 26 static unsigned longs - all should be 0
        s_a: 0    s_b: 0    s_c: 0    s_d: 0    s_e: 0
        s_f: 0    s_g: 0    s_h: 0    s_i: 0    s_j: 0
        s_k: 0    s_l: 0    s_m: 0    s_n: 0    s_o: 0
        s_p: 0    s_q: 0    s_r: 0    s_s: 0    s_t: 0
        s_u: 0    s_v: 0    s_w: 0    s_x: 0    s_y: 0
        s_z: 0


        local static unsigned longs - all should be 0:
            local_s_a: 0 should be 0
            local_s_b: 0 should be 0
            local_s_c: 0 should be 0
            local_s_d: 0 should be 0

        static assigned variables:
            s_AA: 1 should be 0x01
            s_BB: FF01 should be 0xff01
            s_CC: 1AA01 should be 0x01aa01
            s_DD: FF01AA01 should be 0xff01aa01






    == test D (structures) ========================
    test_function_D() - 26 local unsigned longs in a structure - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01






    == test E (should always succeed) ========================
    test_function_E() - 26 local unsigned longs - explicitly set to 0 - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01



-----------------------------------------------------------------------------


The complete clang release run results were:

NOTE that the message "******* local variable was not zero! ****************" does not appear in the
output because that printf was optimized away into the ether....


    ./bin/local_var_test_clang_release

    main() - 26 local unsigned longs - all should be 0
        a: 51    b: 51    c: 51    d: 51    e: 51
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    == test A ========================
    test_function_A() call # 1

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01

    test_function_A() call # 0

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01



    == test B ========================
    test_function_B(32,64,128,256,512) call # 1

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512

    test_function_B(32,64,128,256,512) call # 0

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512



    == test A + B ========================

    interleaved test_function_A() call # 3

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 3

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512


    interleaved test_function_A() call # 2

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 2

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512


    interleaved test_function_A() call # 1

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 1

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512


    interleaved test_function_A() call # 0

    test_function_A() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01


    interleaved test_function_B(32,64,128,256,512) call # 0

    test_function_B() - 26 local unsigned longs - all should be 0
        a: 62    b: 62    c: 62    d: 62    e: 62
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01
        Argument variables:
            arg_a 32 should be 32
            arg_b 64 should be 64
            arg_c 128 should be 128
            arg_d 256 should be 256
            arg_e 512 should be 512






    == test C (statics) ========================
    test_function_C() - 26 static unsigned longs - all should be 0
        s_a: 0    s_b: 0    s_c: 0    s_d: 0    s_e: 0
        s_f: 0    s_g: 0    s_h: 0    s_i: 0    s_j: 0
        s_k: 0    s_l: 0    s_m: 0    s_n: 0    s_o: 0
        s_p: 0    s_q: 0    s_r: 0    s_s: 0    s_t: 0
        s_u: 0    s_v: 0    s_w: 0    s_x: 0    s_y: 0
        s_z: 0


        local static unsigned longs - all should be 0:
            local_s_a: 0 should be 0
            local_s_b: 0 should be 0
            local_s_c: 0 should be 0
            local_s_d: 0 should be 0

        static assigned variables:
            s_AA: 1 should be 0x01
            s_BB: FF01 should be 0xff01
            s_CC: 1AA01 should be 0x01aa01
            s_DD: FF01AA01 should be 0xff01aa01






    == test D (structures) ========================
    test_function_D() - 26 local unsigned longs in a structure - all should be 0
        a: 77    b: 77    c: 77    d: 77    e: 77
        f: 31    g: 31    h: 31    i: 31    j: 31
        k: 31    l: 31    m: 31    n: 31    o: 31
        p: 31    q: 31    r: 31    s: 31    t: 31
        u: 31    v: 31    w: 31    x: 31    y: 31
        z: 31

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01






    == test E (should always succeed) ========================
    test_function_E() - 26 local unsigned longs - explicitly set to 0 - all should be 0
        a: 0    b: 0    c: 0    d: 0    e: 0
        f: 0    g: 0    h: 0    i: 0    j: 0
        k: 0    l: 0    m: 0    n: 0    o: 0
        p: 0    q: 0    r: 0    s: 0    t: 0
        u: 0    v: 0    w: 0    x: 0    y: 0
        z: 0

        Local assigned variables:
            AA: 1 should be 0x01
            BB: FF01 should be 0xff01
            CC: 1AA01 should be 0x01aa01
            DD: FF01AA01 should be 0xff01aa01



------------------------------------------------------------------------------

Pure conjecture: I was thinking about those guys who compiled netBSD with clang....  Did they experience any problems with
                 tools being buggy?  Or did they use llvm-gcc which I assume does do the init to 0 for locals???

------------------------------------------------------------------------------


      
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100613/03d5105e/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: local_var_test_RFC0x0000.tar.gz
Type: application/x-compressed
Size: 9929 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100613/03d5105e/attachment.bin>


More information about the cfe-dev mailing list