Description of problem: I've got some code that heavily uses inline, and GCC seems to be miscompiling it at -O2 (-O1 works). Specifically this code (505 to 510 in ustr-main-code.h): printf("1. p=%p, osz=%zu, nsz=%zu\n", p, osz, nsz); if (p != NULL) { printf("2. p=%p, osz=%zu, nsz=%zu\n", p, osz, nsz); ret = USTR_CONF_POOL_REALLOC(p, *ps1, osz, nsz); } ...produces the following: 1. p=(nil), osz=8, nsz=256 2. p=(nil), osz=8, nsz=256 /bin/sh: line 3: 14360 Segmentation fault ./$tst ...the last line because p isn't supposed to be NULL after there, and the code doesn't handle it. Version-Release number of selected component (if applicable): % rpm -q gcc gcc(0:4.1.1-51.fc6).i386 How reproducible: Always. Steps to Reproduce: 1. grab: http://illiter.at/gcc-test-ustr.tar (attached) 2. untar 3. make check Additional info: Again, note that compiling with -O1 works. Also if I change the #if on line 36 of ustr-fmt-code.h to be 0, the problem disappears ... even though that if branch isn't taken anyway. I'm not 100% sure that this is a problem in GCC, although everything I can test heavily implies that. I've put the severity/priority up on the assumption that it is miscompiling the code. I'll also attached the tarball of source.
Created attachment 155143 [details] Tarball of GCC miscompiling problem, just type make check
That's not a GCC bug, but documented behavior. USTR_CONF_e_PROTO int ustrp__rw_realloc(void *, struct Ustr **, int, size_t, size_t) USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_A(); where USTR__COMPILE_ATTR_NONNULL_A() expands to __attribute__((nonnull)). This means you say that the first and second arguments to the function must be non-null. `nonnull (ARG-INDEX, ...)' The `nonnull' attribute specifies that some function parameters should be non-null pointers. For instance, the declaration: extern void * my_memcpy (void *dest, const void *src, size_t len) __attribute__((nonnull (1, 2))); causes the compiler to check that, in calls to `my_memcpy', arguments DEST and SRC are non-null. If the compiler determines that a null pointer is passed in an argument slot marked as non-null, and the `-Wnonnull' option is enabled, a warning is issued. The compiler may also choose to make optimizations based on the knowledge that certain function arguments will not be null. If no argument index list is given to the `nonnull' attribute, all pointer arguments are marked as non-null. To illustrate, the following declaration is equivalent to the previous example: extern void * my_memcpy (void *dest, const void *src, size_t len) __attribute__((nonnull)); Especially note the 'The compiler may also choose'... sentence. With -O2 the compiler chose to take advantage of that guarantee (in VRP pass particularly), but at runtime you violated that promise.
int ustrp__rw_realloc(void *, struct Ustr **, int, size_t, size_t) USTR__COMPILE_ATTR_WARN_UNUSED_RET() USTR__COMPILE_ATTR_NONNULL_A(); ...argghhh ... damn, I was looking for a screwup like that on the external functions, for some reason I didn't think about the internal ones. Sorry, and thanks Jackub.