Re: A GNU/Linux issue which is apparently affected by GCC.
Hi, Le samedi 25 mai 2019 à 14:44 +0545, Prabesh bhattarai a écrit : > Please, read this small thread discussion: > > https://gitlab.gnome.org/GNOME/gnome-settings-daemon/issues/413#note_518001 > > Hope GCC help Linux users. In this comment, g-c-c is for GNOME Control Center. It's not related to GNU Compiler Collection. Regards. -- Yann Droneaud OPTEYA
alignof(type, field); sizeof(type, field); typeof(type, field): getting type information on nested field
Hi, I'm sometime in need to "probe" the size, the type, (and less often the alignment) of a field inside a structure. In such case I have to write "ugly" thing like struct A { struct { type_t t; } B; }; typeof(((struct A *)NULL)->B.t) V; It would have been some much pleasing to have 2 parameters version of sizeof(), typeof(), and alignof(), which would look like a lot like offsetof() usage: typeof(struct A, B.t) V; if (sizeof(struct A, B.t) != sizeof(long)) ... ; if (alignof(struct A, B.t) < alignof(long)) ... ; As sizeof is an operator, this is not straightforward to implement. Currently sizeof (0, variable); is a valid construct, giving the size of "variable". Hence, turning sizeof() to a variadic function-like thing would break existing code. Maybe it would possible to add such function-like operator as _Sizeof() ? And have a header #define'ing sizeof(...) as _Sizeof() for code wanting the new behavior ? Is this possible ? Is such feature was already considered ? Regards. -- Yann Droneaud OPTEYA
Re: stdc_bit_ceil(3) and wrapping
Hi, 30 décembre 2022 à 20:55 "Alejandro Colomar via Libc-alpha" a écrit: > > I'm implementing a small part of equivalent code for shadow. I > need > stdc_bit_ceilul() for a random number generator limited to a range (you've > seen > some of this in the glibc mailing list. > > $ grepc -tfd shadow_random_uniform > ./libmisc/random.c:76: > unsigned long > shadow_random_uniform(unsigned long upper_bound) > { > unsigned long r; > > do { > r = shadow_random(); > r &= bit_ceil_wrapul(upper_bound) - 1; // optimization > } while (r > upper_bound - 1); > > return r; > } > What's wrong with the following ? if (upper_bound < 2) return 0; unsigned long max = upper_bound - 1; unsigned long mask = ULONG_MAX >> __builtin_clzl(max); do { r = shadow_random(); r &= mask; } while (r > max); return r; > However, I need that it doesn't have undefined behavior if it doesn't fit the > type, but rather that it wraps around (as the simplest implementation would > do, > BTW). I've done the following: > > $ cat lib/bit.h > #include > > inline int leading_zerosul(unsigned long x); > inline int bit_widthul(unsigned long x); > inline int bit_ceil_wrapul(unsigned long x); > > inline int > leading_zerosul(unsigned long x) > { > return (x == 0) ? ULONG_WIDTH : __builtin_clz(x); > } > > inline int > bit_widthul(unsigned long x) > { > return ULONG_WIDTH - leading_zerosul(x); > } > > /* Similar to stdc_bit_ceilul(), but wrap around instead of UB. */ > inline int > bit_ceil_wrapul(unsigned long x) > { > return 1 << bit_widthul(x - 1); > } > > I was wondering if there was any reason to make that UB in the standard, when > unsigned wrapping has always been well-defined, and this is a case that is > likely to be implemented with some operation that wraps around, right? I > can't > imagine of an implementation that invokes UB. Moreover, as you can see, it is > useful to make it wrap around in a defined way. > > Would you consider either or both of being more generous in the GNU > implementation and guarantee wrap around, and/or suggest that the standard > guarantees the wrap around? > > And BTW, if any of this code helps you implement that for GNU, please feel > free > to take it. :) > -- Yann Droneaud OPTEYA
Re: Missed warning (-Wuse-after-free)
Hi, Le 16/02/2023 à 15:35, Alejandro Colomar via Gcc a écrit : Hi! I was preparing an example program of a use-after-realloc bug, when I found that GCC doesn't warn in a case where it should. alx@debian:~/tmp$ cat realloc.c #include #include #include #include #include static inline char * xstrdup(const char *s) { char *p; p = strdup(s); if (p == NULL) exit(EXIT_FAILURE); return p; } static inline char * strnul(const char *s) { return (char *) s + strlen(s); } int main(void) { char *p, *q; p = xstrdup(""); q = strnul(p); if (p == q) puts("equal before"); else exit(EXIT_FAILURE); // It's an empty string; this won't happen printf("p = %p; q = %p\n", p, q); p = realloc(p, UINT16_MAX); if (p == NULL) exit(EXIT_FAILURE); puts("realloc()"); if (p == q) { // Use after realloc. I'd expect a warning here. puts("equal after"); } else { /* Can we get here? Let's see the options: - realloc(3) fails: We exit immediately. We don't arrive here. - realloc(3) doesn't move the memory: p == q, as before - realloc(3) moved the memory: p is guaranteed to be a unique pointer, and q is now an invalid pointer. It is Undefined Behavior to read `q`, so `p == q` is UB. As we see, there's no _defined_ path where this can happen */ printf("PID = %i\n", (int) getpid()); } printf("p = %p; q = %p\n", p, q); } alx@debian:~/tmp$ cc -Wall -Wextra realloc.c -O3 -fanalyzer realloc.c: In function ‘main’: realloc.c:67:9: warning: pointer ‘p’ may be used after ‘realloc’ [-Wuse-after-free] 67 | printf("p = %p; q = %p\n", p, q); | ^~~~ realloc.c:39:13: note: call to ‘realloc’ here 39 | p = realloc(p, UINT16_MAX); | ^~ alx@debian:~/tmp$ ./a.out equal before p = 0x55bff80802a0; q = 0x55bff80802a0 realloc() PID = 25222 p = 0x55bff80806d0; q = 0x55bff80802a0 Did I miss anything? -Wuse-after-free=3 Regards. -- Yann Droneaud OPTEYA