[MUDFLAP] Is sizeof(ARRAY[0]) equivalent to sizeof(*ARRAY) ?

Discussion in 'C Programming' started by m.labanowicz@gmail.com, Jan 9, 2013.

  1. Guest

    Hi,

    I'm looking for the reason of the MUDFLAP violation
    on my 'BIG' C project (no possibility to show),
    system: Ubuntu:12.04, gcc:4.6.3.

    NOTE: The same 'BIG' project has been successfully executed
    on my old system: Ubuntu:10.04, gcc-(version don't remember).
    Mudflap was silent.

    My investigation shows that there
    are called some functions before 'main', like:
    _GLOBAL__sub_I_00099_0_<org_fun_name>

    Currently MUDFLAP violates before calling 'main' in
    _GLOBAL__sub_I_00099_0_<my_function>

    if I change source code of <my_function>
    from sizeof(*ARRAY)
    to sizeof(ARRAY[0])
    then violation source shifts to another
    _GLOBAL__sub_I_00099_0_... function.

    But this algoritm failed in case MUDFLAP violates
    at function that has no usage of sizeof(ARRAY) operator.

    Common for the all functions that MUDFLAP violates is the
    static const ARRAY usage, example:

    /*--EXAMPLE-BEG----------------*/
    01: extern unsigned my_function_check(unsigned a, unsigned b, unsigned c);
    02: void my_function(void)
    03: {
    04: unsigned const SCALE [] = { 0, 1, 2 };
    05: unsigned const TOSTEP [][2] = {
    06: { 10, 1},
    07: { 100, 8}
    08: };
    09: unsigned s = sizeof(SCALE) / sizeof(SCALE[0]);
    10: while (s--)
    11: {
    12: unsigned i = 0;
    13: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0])))
    14: {
    15: unsigned current = 0;
    16: unsigned value = 0;
    17: current = my_function_check(SCALE, TOSTEP[0], value);
    18: if (current)
    19: {
    20: return;
    21: }
    22: ++i;
    23: }
    24: }
    25: }
    /*--EXAMPLE-BEG----------------*/

    In this example I have not found any reason of
    violate before calling the main.

    There is amazing difference that depends
    on usage of the sizeof operator:

    --[TEST-BEG]------------------------------
    + uname -a
    Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
    + gcc --version
    gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
    Copyright (C) 2011 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    + gawk '{printf("%02u: %s\n", NR, $0);}'
    + cat bar.c
    01: #include <stddef.h> /* size_t */
    02: static int const BAR [] = {0,1,2,3,4};
    03: size_t bar_element_sizeof(void) {
    04: #if ASTERISK
    05: return sizeof(*BAR);
    06: #else
    07: return sizeof(BAR[0]);
    08: #endif
    09: }
    + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DnotASTERISK -c bar.c -o bar_notASTERISK.o
    + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DASTERISK -c bar.c -o bar_ASTERISK.o
    + objdump -d bar_notASTERISK.o
    + objdump -d bar_ASTERISK.o
    + diff bar_notASTERISK.S bar_ASTERISK.S
    2c2
    < bar_notASTERISK.o: file format elf32-i386
    ---
    > bar_ASTERISK.o: file format elf32-i386

    17c17
    < d: 83 ec 08 sub $0x8,%esp
    ---
    > d: 83 ec 18 sub $0x18,%esp

    19,20c19,28
    < 15: c9 leave
    < 16: c3 ret
    ---
    > 15: c7 44 24 0c 14 00 00 movl $0x14,0xc(%esp)
    > 1c: 00
    > 1d: c7 44 24 08 04 00 00 movl $0x4,0x8(%esp)
    > 24: 00
    > 25: c7 44 24 04 14 00 00 movl $0x14,0x4(%esp)
    > 2c: 00
    > 2d: c7 04 24 00 00 00 00 movl $0x0,(%esp)
    > 34: e8 fc ff ff ff call 35 <_GLOBAL__sub_I_00099_0_bar_element_sizeof+0x2b>
    > 39: c9 leave
    > 3a: c3 ret

    --[TEST-EOF]------------------------------

    Is there any clear reason of such difference ?

    Best Regards

    --
    Maciek
     
    , Jan 9, 2013
    #1
    1. Advertising

  2. James Kuyper Guest

    On 01/09/2013 10:26 AM, wrote:
    ....
    > + cat bar.c
    > 01: #include <stddef.h> /* size_t */
    > 02: static int const BAR [] = {0,1,2,3,4};
    > 03: size_t bar_element_sizeof(void) {
    > 04: #if ASTERISK
    > 05: return sizeof(*BAR);
    > 06: #else
    > 07: return sizeof(BAR[0]);
    > 08: #endif
    > 09: }
    > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DnotASTERISK -c bar.c -o bar_notASTERISK.o
    > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DASTERISK -c bar.c -o bar_ASTERISK.o
    > + objdump -d bar_notASTERISK.o
    > + objdump -d bar_ASTERISK.o


    As far as C is concerned, with the above definition for BAR,
    sizeof(*BAR) and sizeof(BAR[0]) are exactly equivalent (and the
    parentheses are unnecessary). As implied by the extensive use of
    "mudflap" and "MUDFLAP" throughout your message, this is a problem
    specific to gcc's -fmudflap option - without that option, gcc generates
    identical object code whether or not ASTERISK is #defined. Therefore,
    the best place to get answers to this question are on a forum specific
    to gcc. I don't know the answer.
    --
    James Kuyper
     
    James Kuyper, Jan 9, 2013
    #2
    1. Advertising

  3. Eric Sosman Guest

    On 1/9/2013 10:26 AM, wrote:
    > I'm looking for the reason of the MUDFLAP violation
    > on my 'BIG' C project (no possibility to show),
    > system: Ubuntu:12.04, gcc:4.6.3.


    I don't have mudflap available and can't help with it, so
    my comments are limited to the C aspects of the question. I hope
    they may be of some help anyhow ...

    > Currently MUDFLAP violates before calling 'main' in
    > _GLOBAL__sub_I_00099_0_<my_function>


    Are you sure this is a C program, and not a C++ program?
    In a C program, there's no way for any of your own code to run
    before main() is called, whereas in C++ some of your code may
    run during pre-main() initialization. I suppose the mudflap
    instrumentation might do some non-C-ish things, but ...

    > if I change source code of <my_function>
    > from sizeof(*ARRAY)
    > to sizeof(ARRAY[0])
    > then violation source shifts to another
    > _GLOBAL__sub_I_00099_0_... function.


    From the perspective of the C language, the two expressions
    have identical meaning. That's because of the way C defines the
    array subscript operator, in 6.5.2.1p2: "The definition of the
    subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))."
    In your case `E1' and `E2' are `ARRAY' and `0', so your second
    expression is identical to `sizeof((*((ARRAY)+(0))))', which is
    equivalent to `sizeof *ARRAY' after simplification.

    Two points, though. First, the expression that is the operand
    of `sizeof' isn't evaluated at all (not in this case, anyhow);
    all that matters is the expression's type. Second, the compiler
    is not required to evaluate two equivalent expressions the same
    way; it's perfectly all right for the compiler to emit different
    code for `x = 42' and for `x = 40 + 2', or even for `x = 052'.
    C requires that `sizeof(*ARRAY)' and `sizeof(ARRAY[0])' produce
    the same type and value, but does not require that they use the
    same mechanisms to generate the result.

    > There is amazing difference that depends
    > on usage of the sizeof operator:
    > [... sizeof(*BAR) and sizeof(BAR[0]) generate different code ...]
    > Is there any clear reason of such difference ?


    None that I can see -- although, as explained above, C does
    not dictate any particular style of code generation. My wild
    guess is that since mudflap is concerned with array bounds
    checking, the difference may arise from the way mudflap adds
    instrumentation: Perhaps it recognizes one construct as an array-
    using expression but not the other, and therefore instruments
    them differently.

    --
    Eric Sosman
    d
     
    Eric Sosman, Jan 9, 2013
    #3
  4. Eric Sosman <> writes:
    > On 1/9/2013 10:26 AM, wrote:

    [...]
    >> There is amazing difference that depends
    >> on usage of the sizeof operator:
    >> [... sizeof(*BAR) and sizeof(BAR[0]) generate different code ...]
    >> Is there any clear reason of such difference ?

    >
    > None that I can see -- although, as explained above, C does
    > not dictate any particular style of code generation. My wild
    > guess is that since mudflap is concerned with array bounds
    > checking, the difference may arise from the way mudflap adds
    > instrumentation: Perhaps it recognizes one construct as an array-
    > using expression but not the other, and therefore instruments
    > them differently.


    Mudflap probably shouldn't be instrumenting code that's an argument
    to sizeof in the first place, since it's never executed (barring
    VLAs).

    For example, given `int arr[10];` this expression: `sizeof arr[1000]`
    is perfectly valid, and evaluates to the same value as `sizeof
    (int)`.

    "My code is fine, it must be a bug in the development tools" is
    not the first thought you should have, but in this case it's a
    distinct possibility.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 9, 2013
    #4
  5. Shao Miller Guest

    On 1/9/2013 10:26, wrote:
    >
    > I'm looking for the reason of the MUDFLAP violation
    > on my 'BIG' C project (no possibility to show),
    > system: Ubuntu:12.04, gcc:4.6.3.
    >


    You don't need to show the big project, but it might help if you showed
    the violation!

    Are you linking with libmudflap by using '-lmudflap' with GCC?

    > NOTE: The same 'BIG' project has been successfully executed
    > on my old system: Ubuntu:10.04, gcc-(version don't remember).
    > Mudflap was silent.
    >
    > My investigation shows that there
    > are called some functions before 'main', like:
    > _GLOBAL__sub_I_00099_0_<org_fun_name>
    >
    > Currently MUDFLAP violates before calling 'main' in
    > _GLOBAL__sub_I_00099_0_<my_function>
    >
    > if I change source code of <my_function>
    > from sizeof(*ARRAY)
    > to sizeof(ARRAY[0])
    > then violation source shifts to another
    > _GLOBAL__sub_I_00099_0_... function.
    >


    That suggests to me the possibility that you are running afoul of
    undefined behaviour _before_ coming across your 'sizeof' usage, because
    if you run afoul of undefined behaviour, anything can happen and the
    precise nature of the weirdness can depend on things that _shouldn't_
    make a difference, such as the difference between your two 'sizeof's.

    > But this algoritm failed in case MUDFLAP violates
    > at function that has no usage of sizeof(ARRAY) operator.
    >


    That's quite possible, since the undefined behaviour might be invoked
    _before_ the 'sizeof' use. That's the thing about undefined
    behaviour... While trying to track it down, you might think it's
    because of "thing #1". (But it's not.) Then you change "thing #1" and
    find that things change! (But you haven't fixed the undefined
    behaviour.) But then later it looks like "thing #2" has a problem.

    > Common for the all functions that MUDFLAP violates is the
    > static const ARRAY usage, example:
    >
    > /*--EXAMPLE-BEG----------------*/
    > 01: extern unsigned my_function_check(unsigned a, unsigned b, unsigned c);
    > 02: void my_function(void)
    > 03: {
    > 04: unsigned const SCALE [] = { 0, 1, 2 };
    > 05: unsigned const TOSTEP [][2] = {
    > 06: { 10, 1},
    > 07: { 100, 8}
    > 08: };
    > 09: unsigned s = sizeof(SCALE) / sizeof(SCALE[0]);
    > 10: while (s--)
    > 11: {
    > 12: unsigned i = 0;
    > 13: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0])))
    > 14: {
    > 15: unsigned current = 0;
    > 16: unsigned value = 0;
    > 17: current = my_function_check(SCALE, TOSTEP[0], value);
    > 18: if (current)
    > 19: {
    > 20: return;
    > 21: }
    > 22: ++i;
    > 23: }
    > 24: }
    > 25: }
    > /*--EXAMPLE-BEG----------------*/
    >
    > In this example I have not found any reason of
    > violate before calling the main.
    >
    > There is amazing difference that depends
    > on usage of the sizeof operator:
    >


    It's not that amazing, if undefined behaviour is involved.

    > --[TEST-BEG]------------------------------
    > + uname -a
    > Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
    > + gcc --version
    > gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
    > Copyright (C) 2011 Free Software Foundation, Inc.
    > This is free software; see the source for copying conditions. There is NO
    > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    >
    > + gawk '{printf("%02u: %s\n", NR, $0);}'
    > + cat bar.c
    > 01: #include <stddef.h> /* size_t */
    > 02: static int const BAR [] = {0,1,2,3,4};
    > 03: size_t bar_element_sizeof(void) {
    > 04: #if ASTERISK
    > 05: return sizeof(*BAR);
    > 06: #else
    > 07: return sizeof(BAR[0]);
    > 08: #endif
    > 09: }
    > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DnotASTERISK -c bar.c -o bar_notASTERISK.o
    > + gcc -W -Wall -ansi -pedantic -Werror -fmudflap -DASTERISK -c bar.c -o bar_ASTERISK.o
    > + objdump -d bar_notASTERISK.o
    > + objdump -d bar_ASTERISK.o
    > + diff bar_notASTERISK.S bar_ASTERISK.S
    > 2c2
    > < bar_notASTERISK.o: file format elf32-i386
    > ---
    >> bar_ASTERISK.o: file format elf32-i386

    > 17c17
    > < d: 83 ec 08 sub $0x8,%esp
    > ---
    >> d: 83 ec 18 sub $0x18,%esp

    > 19,20c19,28
    > < 15: c9 leave
    > < 16: c3 ret
    > ---
    >> 15: c7 44 24 0c 14 00 00 movl $0x14,0xc(%esp)
    >> 1c: 00
    >> 1d: c7 44 24 08 04 00 00 movl $0x4,0x8(%esp)
    >> 24: 00
    >> 25: c7 44 24 04 14 00 00 movl $0x14,0x4(%esp)
    >> 2c: 00
    >> 2d: c7 04 24 00 00 00 00 movl $0x0,(%esp)
    >> 34: e8 fc ff ff ff call 35 <_GLOBAL__sub_I_00099_0_bar_element_sizeof+0x2b>
    >> 39: c9 leave
    >> 3a: c3 ret

    > --[TEST-EOF]------------------------------
    >
    > Is there any clear reason of such difference ?
    >


    Yes. The difference is fully permitted, and even useful.

    Furthermore, if the undefined behaviour theory is correct, whatever is
    going wrong is simply accidentally running into this difference, but the
    _difference_ is not the _cause_ of the undefined behaviour, surely.

    I'd suggest reviewing _all_ code that is executed _before_ the first
    mudflap violation.

    - Shao Miller
     
    Shao Miller, Jan 9, 2013
    #5
  6. Guest

    Ok, after long investigation I have successfully prepared simple C program that illustrates the issue:
    3 files:
    - bar.h
    - bar.c
    - main.c

    ------------[TEST-BEG]-------------------------
    + gawk '{printf("%02u: %s\n", NR, $0);}' bar.h
    01: typedef struct
    02: {
    03: char const * name;
    04: int val;
    05: } bar_cfg_t;
    06: int bar_fun(void);
    + gawk '{printf("%02u: %s\n", NR, $0);}' bar.c
    01: #include "bar.h"
    02: #include <stddef.h> /* size_t */
    03: int bar_fun(void)
    04: {
    05: int result = 0;
    06: bar_cfg_t bar_cfg [] =
    07: {
    08: {"@", 0},
    09: {"#", 0},
    10: {"0", 0},
    11: {"1", 0},
    12: {"2", 0},
    13: {"3", 0},
    14: {"4", 0},
    15: {"5", 0},
    16: #ifdef WORKAROUND_FOR_MUDFLAP
    17: {"6", 0},
    18: #endif
    19: {"7", 0}
    20: };
    21: bar_cfg_t * bc = bar_cfg;
    22: size_t i = 0;
    23: while (i++ < (sizeof(bar_cfg) / sizeof(bar_cfg[0])))
    24: {
    25: bc->val = 123 + (unsigned)(bc->name[0]);
    26: result += bc->val;
    27: ++bc;
    28: }
    29: return result;
    30: }
    + gawk '{printf("%02u: %s\n", NR, $0);}' main.c
    01: #include <stdio.h> /* printf, size_t */
    02: #include <stdlib.h> /* EXIT_SUCCESS */
    03: #include "bar.h"
    04: static int foo_fun(void)
    05: {
    06: int result = 0;
    07: unsigned int const TOSTEP [][2] =
    08: {
    09: { 100u, 1u},
    10: { 100u, 8u},
    11: { 0x2333445u, 123344u},
    12: { 0x2333445u, 1233446u},
    13: {0x00BFC000u, 0x20000u},
    14: {0x00FFC000u, 0x20000u},
    15: {0x01FFC000u, 0x20000u},
    16: {0x02FFC000u, 0x20000u},
    17: {0x06FFC000u, 0x10000u},
    18: {0x0DFFC000u, 0x10000u}
    19: };
    20: size_t i = 0;
    21: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0])))
    22: {
    23: result = TOSTEP[0] + TOSTEP[1];
    24: i++;
    25: }
    26: return result;
    27: }
    28: int main(void)
    29: {
    30: printf("Hello World !\r\n");
    31: printf("foo_fun = %d\r\n", foo_fun());
    32: printf("bar_fun = %d\r\n", bar_fun());
    33: return EXIT_SUCCESS;
    34: }
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c bar.c
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c
    + gcc -Wl,-Map,a.map main.o bar.o -lmudflap
    + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations
    + ./a.out
    01: *******
    02: mudflap violation 1 (register): time=1357813939.099625 ptr=0xbfe56c28 size=72
    03: pc=0xb767685e
    04: /usr/lib/i386-linux-gnu/libmudflap.so.0(__mf_register+0x3e) [0xb767685e]
    05: ./a.out() [0x8048ce0]
    06: ./a.out() [0x8048d42]
    07: Nearby object 1: checked region begins 8B into and ends 79B into
    08: mudflap object 0x8cbf1e8: name=`constant'
    09: bounds=[0xbfe56c20,0xbfe56c6f] size=80 area=static check=0r/0w liveness=0
    10: alloc time=1357813939.099612 pc=0xb767685e
    11: number of nearby objects: 1
    12: mf: alloca stack level 0xbfe56b18
    13: Hello World !
    14: foo_fun = 234930176
    15: bar_fun = 1564
    16: *******
    17: mudflap violation 2 (unregister): time=1357813939.100370 ptr=0x8cbfa20 size=0
    18: pc=0xb76763d6
    19: number of nearby objects: 0
    20: number of leaked objects: 0
    -----[with: WORKAORUND_FOR_MUDFLAP]------------
    + rm -fr bar.o main.o a.map a.out
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -DWORKAROUND_FOR_MUDFLAP=1 -c bar.c
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c
    + gcc -Wl,-Map,a.map main.o bar.o -lmudflap
    + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations
    + ./a.out
    01: mf: harmless duplicate reg 0xbfe45950-0xbfe4599f `constant'
    02: mf: alloca stack level 0xbfe45848
    03: Hello World !
    04: foo_fun = 234930176
    05: bar_fun = 1741
    06: number of leaked objects: 0
    ------------[TEST-EOF]-------------------------

    Please note, that after applying additional element to array
    the issue has gone.

    So, if this is valid ANSI-C program then this
    is an issue connected to GCC/MUDFLAP.

    --
    Maciej Labanowicz
     
    , Jan 10, 2013
    #6
  7. Shao Miller Guest

    On 1/10/2013 05:40, wrote:
    > Ok, after long investigation I have successfully prepared simple C program that illustrates the issue:
    > 3 files:
    > - bar.h
    > - bar.c
    > - main.c
    >
    > ------------[TEST-BEG]-------------------------
    > + gawk '{printf("%02u: %s\n", NR, $0);}' bar.h
    > 01: typedef struct
    > 02: {
    > 03: char const * name;
    > 04: int val;
    > 05: } bar_cfg_t;
    > 06: int bar_fun(void);


    Maybe add a helper macro in here:

    #if USE_ASTERISK
    # define Countof(array) (sizeof (array) / sizeof *(array))
    #else
    # define Countof(array) (sizeof (array) / sizeof (array)[0])
    #endif

    > + gawk '{printf("%02u: %s\n", NR, $0);}' bar.c
    > 01: #include "bar.h"
    > 02: #include <stddef.h> /* size_t */
    > 03: int bar_fun(void)
    > 04: {
    > 05: int result = 0;
    > 06: bar_cfg_t bar_cfg [] =
    > 07: {
    > 08: {"@", 0},
    > 09: {"#", 0},
    > 10: {"0", 0},
    > 11: {"1", 0},
    > 12: {"2", 0},
    > 13: {"3", 0},
    > 14: {"4", 0},
    > 15: {"5", 0},
    > 16: #ifdef WORKAROUND_FOR_MUDFLAP
    > 17: {"6", 0},
    > 18: #endif
    > 19: {"7", 0}
    > 20: };
    > 21: bar_cfg_t * bc = bar_cfg;
    > 22: size_t i = 0;
    > 23: while (i++ < (sizeof(bar_cfg) / sizeof(bar_cfg[0])))
    > 24: {
    > 25: bc->val = 123 + (unsigned)(bc->name[0]);
    > 26: result += bc->val;
    > 27: ++bc;
    > 28: }
    > 29: return result;
    > 30: }


    Note that 'i' is being used for iteration over 'bar_cfg', but by line
    29, its index is _two_past_ the array. That's worth a bounds-checking
    diagnostic, would you agree?

    I don't know why you're not using a 'for' loop:

    /* Circa line 22 */
    size_t i;

    for (i = 0; i < Countof(bar_cfg); ++i)
    {
    bc->val = 123 + (unsigned)(bc->name[0]);
    result += bc->val;
    ++bc;
    }
    return result;
    }

    > + gawk '{printf("%02u: %s\n", NR, $0);}' main.c
    > 01: #include <stdio.h> /* printf, size_t */
    > 02: #include <stdlib.h> /* EXIT_SUCCESS */
    > 03: #include "bar.h"
    > 04: static int foo_fun(void)
    > 05: {
    > 06: int result = 0;
    > 07: unsigned int const TOSTEP [][2] =
    > 08: {
    > 09: { 100u, 1u},
    > 10: { 100u, 8u},
    > 11: { 0x2333445u, 123344u},
    > 12: { 0x2333445u, 1233446u},
    > 13: {0x00BFC000u, 0x20000u},
    > 14: {0x00FFC000u, 0x20000u},
    > 15: {0x01FFC000u, 0x20000u},
    > 16: {0x02FFC000u, 0x20000u},
    > 17: {0x06FFC000u, 0x10000u},
    > 18: {0x0DFFC000u, 0x10000u}
    > 19: };
    > 20: size_t i = 0;
    > 21: while (i < (sizeof(TOSTEP) / sizeof(TOSTEP[0])))
    > 22: {
    > 23: result = TOSTEP[0] + TOSTEP[1];
    > 24: i++;
    > 25: }
    > 26: return result;


    /* Circa line 20 */
    size_t i;

    for (i = 0; i < Countof(TOSTEP); ++i)
    result = TOSTEP[0] + TOSTEP[1];

    return result;

    > 27: }
    > 28: int main(void)
    > 29: {
    > 30: printf("Hello World !\r\n");
    > 31: printf("foo_fun = %d\r\n", foo_fun());
    > 32: printf("bar_fun = %d\r\n", bar_fun());
    > 33: return EXIT_SUCCESS;
    > 34: }
    > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c bar.c
    > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c
    > + gcc -Wl,-Map,a.map main.o bar.o -lmudflap
    > + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations
    > + ./a.out
    > 01: *******
    > 02: mudflap violation 1 (register): time=1357813939.099625 ptr=0xbfe56c28 size=72
    > 03: pc=0xb767685e
    > 04: /usr/lib/i386-linux-gnu/libmudflap.so.0(__mf_register+0x3e) [0xb767685e]
    > 05: ./a.out() [0x8048ce0]
    > 06: ./a.out() [0x8048d42]
    > 07: Nearby object 1: checked region begins 8B into and ends 79B into
    > 08: mudflap object 0x8cbf1e8: name=`constant'
    > 09: bounds=[0xbfe56c20,0xbfe56c6f] size=80 area=static check=0r/0w liveness=0
    > 10: alloc time=1357813939.099612 pc=0xb767685e
    > 11: number of nearby objects: 1
    > 12: mf: alloca stack level 0xbfe56b18
    > 13: Hello World !
    > 14: foo_fun = 234930176
    > 15: bar_fun = 1564
    > 16: *******
    > 17: mudflap violation 2 (unregister): time=1357813939.100370 ptr=0x8cbfa20 size=0
    > 18: pc=0xb76763d6
    > 19: number of nearby objects: 0
    > 20: number of leaked objects: 0
    > -----[with: WORKAORUND_FOR_MUDFLAP]------------
    > + rm -fr bar.o main.o a.map a.out
    > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -DWORKAROUND_FOR_MUDFLAP=1 -c bar.c
    > + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c
    > + gcc -Wl,-Map,a.map main.o bar.o -lmudflap
    > + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations
    > + ./a.out
    > 01: mf: harmless duplicate reg 0xbfe45950-0xbfe4599f `constant'
    > 02: mf: alloca stack level 0xbfe45848
    > 03: Hello World !
    > 04: foo_fun = 234930176
    > 05: bar_fun = 1741
    > 06: number of leaked objects: 0
    > ------------[TEST-EOF]-------------------------
    >
    > Please note, that after applying additional element to array
    > the issue has gone.
    >
    > So, if this is valid ANSI-C program then this
    > is an issue connected to GCC/MUDFLAP.
    >


    MUDFLAP can diagnose stuff that's permitted by C90, such as warning you
    that an index used for iteration has gone too far. Usually you want to
    index one-past an array, at most. Do the 'for' loops have any problems?

    - Shao Miller
     
    Shao Miller, Jan 10, 2013
    #7
  8. Shao Miller Guest

    On 1/10/2013 08:31, Shao Miller wrote:
    > On 1/10/2013 05:40, wrote:
    >> 21: bar_cfg_t * bc = bar_cfg;
    >> 22: size_t i = 0;
    >> 23: while (i++ < (sizeof(bar_cfg) / sizeof(bar_cfg[0])))
    >> 24: {
    >> 25: bc->val = 123 + (unsigned)(bc->name[0]);
    >> 26: result += bc->val;
    >> 27: ++bc;
    >> 28: }
    >> 29: return result;
    >> 30: }

    >
    > Note that 'i' is being used for iteration over 'bar_cfg', but by line
    > 29, its index is _two_past_ the array. That's worth a bounds-checking
    > diagnostic, would you agree?
    >
    > I don't know why you're not using a 'for' loop:
    >
    > /* Circa line 22 */
    > size_t i;
    >
    > for (i = 0; i < Countof(bar_cfg); ++i)
    > {
    > bc->val = 123 + (unsigned)(bc->name[0]);
    > result += bc->val;
    > ++bc;
    > }
    > return result;
    > }
    >


    There is another "problem" here, and that's that you are indexing into
    the array with two difference indices. I'd suggest either:

    /* Circa line 21 */
    size_t i;

    for (i = 0; i < Countof(bar_cfg); ++i)
    {
    bar_cfg->val = 123 + (unsigned)(bar_cfg->name[0]);
    result += bar_cfg->val;
    }
    return result;
    }

    Or:

    /* Circa line 21 */
    bar_cfg_t * const end = bar_cfg + Countof(bar_cfg);
    bar_cfg_t * bc;

    for (bc = bar_cfg; bc < end; ++bc)
    {
    bc->val = 123 + (unsigned)(bc->name[0]);
    result += bc->val;
    }
    return result;
    }

    (By the way, I like your spaces surrounding your asterisk in the pointer
    declaration. :) )

    - Shao Miller
     
    Shao Miller, Jan 10, 2013
    #8
  9. writes:

    > Ok, after long investigation I have successfully prepared simple C
    > program that illustrates the issue:
    > 3 files:
    > - bar.h
    > - bar.c
    > - main.c


    A data point: your example compiles and runs clean with gcc 4.7.2 and
    mudflap 4.7.

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Jan 10, 2013
    #9
  10. Guest

    Code without loops, issue is still present:

    ----------------------------------------------
    + uname -a
    Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
    + gcc --version
    gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
    Copyright (C) 2011 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    + gawk '{printf("%02u: %s\n", NR, $0);}' bar.h
    01: int bar_fun(unsigned idx);
    02: #define ARRAY_NO_OF_ELEMENTS(a) ((unsigned)(sizeof(a) / sizeof(*a)))
    + gawk '{printf("%02u: %s\n", NR, $0);}' bar.c
    01: #include "bar.h"
    02: int bar_fun(unsigned idx)
    03: {
    04: int bar_cfg [][2] =
    05: {
    06: {9, 0},
    07: {8, 1},
    08: {7, 2},
    09: {6, 3},
    10: {5, 4},
    11: {4, 5},
    12: {3, 6},
    13: {2, 7},
    14: #ifdef WORKAROUND_FOR_MUDFLAP
    15: {1, 8},
    16: #endif
    17: {0, 9}
    18: };
    19: return (idx < ARRAY_NO_OF_ELEMENTS(bar_cfg)) ? bar_cfg[idx][1] : -1;
    20: }
    + gawk '{printf("%02u: %s\n", NR, $0);}' main.c
    01: #include <stdio.h> /* printf */
    02: #include <stdlib.h> /* EXIT_SUCCESS */
    03: #include "bar.h"
    04: static int foo_fun(unsigned idx)
    05: {
    06: int const TOSTEP [][2] =
    07: {
    08: {0, 9},
    09: {1, 8},
    10: {2, 7},
    11: {3, 6},
    12: {4, 5},
    13: {5, 4},
    14: {6, 3},
    15: {7, 2},
    16: {8, 1},
    17: {9, 0}
    18: };
    19: return (idx < ARRAY_NO_OF_ELEMENTS(TOSTEP)) ? TOSTEP[idx][1] : -1;
    20: }
    21: int main(void)
    22: {
    23: printf("Hello World !\r\n");
    24: printf("foo_fun = %d\r\n", foo_fun(4));
    25: printf("bar_fun = %d\r\n", bar_fun(4));
    26: return EXIT_SUCCESS;
    27: }
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c bar.c
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c
    + gcc -Wl,-Map,a.map main.o bar.o -lmudflap
    + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations
    + ./a.out
    + gawk '{printf("%02u: %s\n", NR, $0);}'
    01: *******
    02: mudflap violation 1 (register): time=1357829219.568594 ptr=0xbfd9f6b8 size=72
    03: pc=0xb762b85e
    04: /usr/lib/i386-linux-gnu/libmudflap.so.0(__mf_register+0x3e) [0xb762b85e]
    05: ./a.out() [0x8048979]
    06: ./a.out() [0x80489e2]
    07: Nearby object 1: checked region begins 8B into and ends 79B into
    08: mudflap object 0x9a021e8: name=`constant'
    09: bounds=[0xbfd9f6b0,0xbfd9f6ff] size=80 area=static check=0r/0w liveness=0
    10: alloc time=1357829219.568588 pc=0xb762b85e
    11: number of nearby objects: 1
    12: mf: alloca stack level 0xbfd9f5a8
    13: Hello World !
    14: foo_fun = 5
    15: bar_fun = 4
    16: *******
    17: mudflap violation 2 (unregister): time=1357829219.569060 ptr=0x9a02678 size=0
    18: pc=0xb762b3d6
    19: number of nearby objects: 0
    20: number of leaked objects: 0
    ------------[with: WORKAROUND_FOR_MUDFLAP]--------------------
    + rm -fr bar.o main.o a.map a.out
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -DWORKAROUND_FOR_MUDFLAP=1 -c bar.c
    + gcc -ansi -pedantic -Wall -W -Werror -fmudflap -c main.c
    + gcc -Wl,-Map,a.map main.o bar.o -lmudflap
    + MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations
    + ./a.out
    + gawk '{printf("%02u: %s\n", NR, $0);}'
    01: mf: harmless duplicate reg 0xbfbc1c50-0xbfbc1c9f `constant'
    02: mf: alloca stack level 0xbfbc1b48
    03: Hello World !
    04: foo_fun = 5
    05: bar_fun = 4
    06: number of leaked objects: 0
    ----------------------------------------------

    Usage of sizeof(ARRAY[0]) or sizeof(*ARRAY) has no impact to the result,
    issue is present.

    Best Regards

    --
    Maciej Labanowicz
     
    , Jan 10, 2013
    #10
  11. Guest

    W dniu czwartek, 10 stycznia 2013 15:37:45 UTC+1 użytkownik Ben Bacarisse napisał:
    > writes:
    >
    >
    >
    > > Ok, after long investigation I have successfully prepared simple C

    >
    > > program that illustrates the issue:

    >
    > > 3 files:

    >
    > > - bar.h

    >
    > > - bar.c

    >
    > > - main.c

    >
    >
    >
    > A data point: your example compiles and runs clean with gcc 4.7.2 and
    >
    > mudflap 4.7.
    >
    >


    Thanks for information.
    I'm going to update my system with newer GCC+MUDFLAP.

    --
    Maciek
     
    , Jan 10, 2013
    #11
  12. Shao Miller Guest

    On 1/10/2013 09:48, wrote:
    > 02: mudflap violation 1 (register): time=1357829219.568594 ptr=0xbfd9f6b8 size=72
    > 03: pc=0xb762b85e
    > 04: /usr/lib/i386-linux-gnu/libmudflap.so.0(__mf_register+0x3e) [0xb762b85e]
    > 05: ./a.out() [0x8048979]
    > 06: ./a.out() [0x80489e2]
    > 07: Nearby object 1: checked region begins 8B into and ends 79B into
    > 08: mudflap object 0x9a021e8: name=`constant'
    > 09: bounds=[0xbfd9f6b0,0xbfd9f6ff] size=80 area=static check=0r/0w liveness=0
    > 10: alloc time=1357829219.568588 pc=0xb762b85e
    > 11: number of nearby objects: 1
    > 12: mf: alloca stack level 0xbfd9f5a8


    Oops. Missed 'alloca', before. I'd guess that it has a bug. If you
    change your arrays to 'static' storage duration, perhaps the problem
    would disappear, as 'alloca' wouldn't be used. - Shao
     
    Shao Miller, Jan 10, 2013
    #12
  13. Guest

    > > A data point: your example compiles and runs clean with gcc 4.7.2 and
    >
    > >

    >
    > > mudflap 4.7.


    Upgraded GCC to 4.7:
    Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
    gcc (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2
    libmudflap0-4.7-dev

    Issue is still present - today I'm giving up :(

    --
    Maciek
     
    , Jan 10, 2013
    #13
  14. writes:

    >> > A data point: your example compiles and runs clean with gcc 4.7.2 and

    >>
    >> >

    >>
    >> > mudflap 4.7.

    >
    > Upgraded GCC to 4.7:
    > Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
    > gcc (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2
    > libmudflap0-4.7-dev
    >
    > Issue is still present - today I'm giving up :(


    Just to confirm:

    $ gcc -ansi -pedantic -Wall -W -Werror -fmudflap bar.c main.c -lmudflap
    $ ./a.out
    Hello World !
    foo_fun = 234930176
    bar_fun = 1564
    $ gcc --version
    gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
    Copyright © 2012 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    $ dpkg -s libmudflap0
    Package: libmudflap0
    Status: install ok installed
    Priority: optional
    Section: libs
    Installed-Size: 270
    Maintainer: Ubuntu Core developers <>
    Architecture: amd64
    Multi-Arch: same
    Source: gcc-4.7
    Version: 4.7.2-2ubuntu1
    Depends: gcc-4.7-base (= 4.7.2-2ubuntu1), libc6 (>= 2.14)
    Pre-Depends: multiarch-support
    Breaks: gcc-4.1, gcc-4.3 (<< 4.3.6-1), gcc-4.4 (<< 4.4.6-4), gcc-4.5 (<< 4.5.3-2)
    Description: GCC mudflap shared support libraries
    The libmudflap libraries are used by GCC for instrumenting pointer and array
    dereferencing operations.
    Homepage: http://gcc.gnu.org/
    Original-Maintainer: Debian GCC Maintainers <>
    $ uname -a
    Linux tinky 3.5.0-21-generic-tuxonice #32~ppa1-Ubuntu SMP Tue Dec 18 20:29:04 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

    --
    Ben.
     
    Ben Bacarisse, Jan 10, 2013
    #14
  15. Shao Miller Guest

    On 1/10/2013 10:41, wrote:
    >>> A data point: your example compiles and runs clean with gcc 4.7.2 and

    >>
    >>>

    >>
    >>> mudflap 4.7.

    >
    > Upgraded GCC to 4.7:
    > Linux ldrlinux 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 i686 i386 GNU/Linux
    > gcc (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2
    > libmudflap0-4.7-dev
    >
    > Issue is still present - today I'm giving up :(
    >


    I was unable to reproduce the violations with:
    - gcc version 4.7.2 20120921 (Red Hat 4.7.2-2)
    - libmudflap 4.7.2, release 2.fc17

    - Shao Miller
     
    Shao Miller, Jan 10, 2013
    #15
  16. Guest

    I have executed this test on UBUNTU 12.04 on 64 bit machine and issue is not present.

    BUT, after change the type of the elemnt array from int(4bytes) to long(8bytes) issue comes back:

    --------------------------
    + uname -a
    Linux qa-stream-server 3.2.0-29-generic #46-Ubuntu SMP Fri Jul 27 17:03:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
    + gcc --version
    gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
    Copyright (C) 2011 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    + dpkg -s libmudflap0
    Package: libmudflap0
    Status: install ok installed
    Multi-Arch: same
    Priority: optional
    Section: libs
    Installed-Size: 266
    Maintainer: Ubuntu Core developers <>
    Architecture: amd64
    Source: gcc-4.6
    Version: 4.6.3-1ubuntu5
    Depends: gcc-4.6-base (= 4.6.3-1ubuntu5), libc6 (>= 2.14)
    Pre-Depends: multiarch-support
    Breaks: gcc-4.1, gcc-4.3 (<< 4.3.6-1), gcc-4.4 (<< 4.4.6-4), gcc-4.5 (<< 4.5.3-2)
    Description: GCC mudflap shared support libraries
    The libmudflap libraries are used by GCC for instrumenting pointer and array
    dereferencing operations.
    Homepage: http://gcc.gnu.org/
    Original-Maintainer: Debian GCC Maintainers <>
    + gawk '{printf("%02u: %s\n", NR, $0);}' bar.h
    01: int bar_fun(unsigned idx);
    02: #define ARRAY_NO_OF_ELEMENTS(a) ((unsigned)(sizeof(a) / sizeof(*a)))
    + gawk '{printf("%02u: %s\n", NR, $0);}' bar.c
    01: #include "bar.h"
    02: int bar_fun(unsigned idx)
    03: {
    04: long bar_cfg [][2] =
    05: {
    06: {9, 0},
    07: {8, 1},
    08: {7, 2},
    09: {6, 3},
    10: {5, 4},
    11: {4, 5},
    12: {3, 6},
    13: {2, 7},
    14: #ifdef WORKAROUND_FOR_MUDFLAP
    15: {1, 8},
    16: #endif
    17: {0, 9}
    18: };
    19: return (idx < ARRAY_NO_OF_ELEMENTS(bar_cfg)) ? (int)(bar_cfg[idx][1]) : -1;
    20: }
    + gawk '{printf("%02u: %s\n", NR, $0);}' main.c
    01: #include <stdio.h> /* printf */
    02: #include <stdlib.h> /* EXIT_SUCCESS */
    03: #include "bar.h"
    04: static int foo_fun(unsigned idx)
    05: {
    06: long const TOSTEP [][2] =
    07: {
    08: {0, 9},
    09: {1, 8},
    10: {2, 7},
    11: {3, 6},
    12: {4, 5},
    13: {5, 4},
    14: {6, 3},
    15: {7, 2},
    16: {8, 1},
    17: {9, 0}
    18: };
    19: return (idx < ARRAY_NO_OF_ELEMENTS(TOSTEP)) ? (int)(TOSTEP[idx][1]) : -1;
    20: }
    21: int main(void)
    22: {
    23: printf("Hello World ! (c=%u,s=%u,i=%u,l=%u,p=%u)\r\n", \
    24: (unsigned)sizeof(char), (unsigned)sizeof(short), \
    25: (unsigned)sizeof(int), (unsigned)sizeof(long), \
    26: (unsigned)sizeof(void *));
    27: printf("foo_fun = %d\r\n", foo_fun(4));
    28: printf("bar_fun = %d\r\n", bar_fun(4));
    29: return EXIT_SUCCESS;
    30: }
    + export 'MUDFLAP_OPTIONS=-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations'
    + MUDFLAP_OPTIONS='-mode-check -viol-nop -verbose-trace -internal-checking -print-leaks -check-initialization -verbose-violations'
    + gcc -ggdb -g3 -ansi -pedantic -Wall -W -Werror -fmudflap bar.c main.c -lmudflap
    + ./a.out
    + gawk '{printf("%02u: %s\n", NR, $0);}'
    01: *******
    02: mudflap violation 1 (register): time=1357902146.588238 ptr=0x7fff9312cfd0 size=160
    03: pc=0x7ff09ad05291
    04: /usr/lib/x86_64-linux-gnu/libmudflap.so.0(__mf_register+0x41) [0x7ff09ad05291]
    05: ./a.out() [0x400d0f]
    06: ./a.out(__libc_csu_init+0x5d) [0x400dbd]
    07: Nearby object 1: checked region begins 16B before and ends 143B into
    08: mudflap object 0x22d6370: name=`constant'
    09: bounds=[0x7fff9312cfe0,0x7fff9312d06f] size=144 area=static check=0r/0w liveness=0
    10: alloc time=1357902146.588237 pc=0x7ff09ad05291
    11: number of nearby objects: 1
    12: mf: alloca stack level 0x7fff9312cf20
    13: Hello World ! (c=1,s=2,i=4,l=8,p=8)
    14: foo_fun = 5
    15: bar_fun = 4
    16: *******
    17: mudflap violation 2 (unregister): time=1357902146.588445 ptr=0x22d6970 size=0
    18: pc=0x7ff09ad04e36
    19: number of nearby objects: 0
    20: number of leaked objects: 0
    + gcc -ggdb -g3 -ansi -pedantic -Wall -W -Werror -fmudflap -DWORKAROUND_FOR_MUDFLAP bar.c main.c -lmudflap
    + ./a.out
    + gawk '{printf("%02u: %s\n", NR, $0);}'
    01: mf: harmless duplicate reg 0x7fff7ffebcc0-0x7fff7ffebd5f `constant'
    02: mf: alloca stack level 0x7fff7ffebc20
    03: Hello World ! (c=1,s=2,i=4,l=8,p=8)
    04: foo_fun = 5
    05: bar_fun = 4
    06: number of leaked objects: 0
    --------------------------

    I'm going to check that issue on GCC 4.7.

    --
    Maciek
     
    , Jan 11, 2013
    #16
  17. Guest

    W dniu piątek, 11 stycznia 2013 12:03:51 UTC+1 użytkownik napisał:
    > I have executed this test on UBUNTU 12.04 on 64 bit machine and issue is not present.
    > BUT, after change the type of the elemnt array from int(4bytes) to long(8bytes) issue comes back:
    >

    ....
    >
    > I'm going to check that issue on GCC 4.7.
    >


    GCC 4.7 (64bitMachine) issue still present:
    $ uname -a
    Linux qa-stream-server 3.2.0-29-generic #46-Ubuntu SMP Fri Jul 27 17:03:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
    $ gcc --version
    gcc (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2
    Copyright (C) 2012 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    $ dpkg -s libmudflap0
    Package: libmudflap0
    Status: install ok installed
    Multi-Arch: same
    Priority: optional
    Section: libs
    Installed-Size: 270
    Maintainer: Ubuntu Core developers <>
    Architecture: amd64
    Source: gcc-4.7
    Version: 4.7.2-11precise2
    Depends: gcc-4.7-base (= 4.7.2-11precise2), libc6 (>= 2.14)
    Pre-Depends: multiarch-support
    Breaks: gcc-4.1, gcc-4.3 (<< 4.3.6-1), gcc-4.4 (<< 4.4.6-4), gcc-4.5 (<< 4.5.3-2)
    Description: GCC mudflap shared support libraries
    The libmudflap libraries are used by GCC for instrumenting pointer and array
    dereferencing operations.
    Homepage: http://gcc.gnu.org/
    Original-Maintainer: Debian GCC Maintainers <>

    --
    Maciek
     
    , Jan 11, 2013
    #17
  18. James Kuyper Guest

    On 01/11/2013 07:14 AM, wrote:
    [more on problems with gcc -mudflap]

    I'm curious - why haven't you followed up yet on my suggestion that you
    take this question to a gcc forum, such as gnu.gcc.help, where you're
    likely to get better answers to your question?

    Also, see <http://gcc.gnu.org/bugs/>. <http://gcc.gnu.org/bugzilla/>
    lists 64 open bugs containing the word "mudflap". I'd recommend checking
    whether any of those bugs matches your problem, before filing a new one.

    --
    James Kuyper
     
    James Kuyper, Jan 11, 2013
    #18
  19. Shao Miller <> writes:
    [...]
    > MUDFLAP can diagnose stuff that's permitted by C90, such as warning you
    > that an index used for iteration has gone too far. Usually you want to
    > index one-past an array, at most. Do the 'for' loops have any problems?


    As I'm sure you know, it's legal to construct a pointer one element
    past the end of an array, but not to dererence it. Constructing a
    pointer before the beginning of an array or more than one element
    past the end of it, or deferencing a pointer one past the end of it,
    has undefined behavior. I'm not aware of any relevant changes in
    this area from C90 to C99 to C11.

    Are you saying that Mudflap complains about stuff that's legal *and
    has defined behavior* in C90? If it complained about something
    like this:

    int arr[N];
    int *ptr;
    for (ptr = arr; ptr < arr + N; ptr ++) {
    /* ... */
    }

    that would IMHO be a serious bug in Mudflap.

    (I haven't analyzed the posted code, but from the discussion I don't
    think that's what's going on.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 11, 2013
    #19
  20. Shao Miller Guest

    On 1/11/2013 11:19, Keith Thompson wrote:
    > Shao Miller <> writes:
    > [...]
    >> MUDFLAP can diagnose stuff that's permitted by C90, such as warning you
    >> that an index used for iteration has gone too far. Usually you want to
    >> index one-past an array, at most. Do the 'for' loops have any problems?

    >
    > As I'm sure you know, it's legal to construct a pointer one element
    > past the end of an array, but not to dererence it. Constructing a
    > pointer before the beginning of an array or more than one element
    > past the end of it, or deferencing a pointer one past the end of it,
    > has undefined behavior. I'm not aware of any relevant changes in
    > this area from C90 to C99 to C11.
    >
    > Are you saying that Mudflap complains about stuff that's legal *and
    > has defined behavior* in C90? If it complained about something
    > like this:
    >
    > int arr[N];
    > int *ptr;
    > for (ptr = arr; ptr < arr + N; ptr ++) {
    > /* ... */
    > }
    >
    > that would IMHO be a serious bug in Mudflap.
    >
    > (I haven't analyzed the posted code, but from the discussion I don't
    > think that's what's going on.)
    >


    Nah, I tried to be careful and chose to type "index" instead of "point".
    The code I was criticizing used both an integer index as well as a
    pointer. Their pointer would never point more than one past the array,
    but their integer would index two past the array. That seems to be
    permitted by C90.

    I seem to recall some bit about this situation being easily detectable
    and reportable as a bonus diagnostic, perhaps in the hopes of alerting
    the programmer that there's a better way to write their loop without
    stepping out of bounds, conceptually.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
     
    Shao Miller, Jan 11, 2013
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Derek
    Replies:
    7
    Views:
    24,421
    Ron Natalie
    Oct 14, 2004
  2. Trevor

    sizeof(str) or sizeof(str) - 1 ?

    Trevor, Apr 3, 2004, in forum: C Programming
    Replies:
    9
    Views:
    664
    CBFalconer
    Apr 10, 2004
  3. Vinu
    Replies:
    13
    Views:
    1,506
    Lawrence Kirby
    May 12, 2005
  4. Tomás Ó hÉilidhe

    Can anyone get mudflap to work properly?!

    Tomás Ó hÉilidhe, Dec 13, 2008, in forum: C Programming
    Replies:
    10
    Views:
    1,660
    Kenny McCormack
    Dec 15, 2008
  5. Neal Becker

    use mudflap with python extensions?

    Neal Becker, Dec 21, 2009, in forum: Python
    Replies:
    0
    Views:
    289
    Neal Becker
    Dec 21, 2009
Loading...

Share This Page