[Bug analyzer/109802] [regression] during IPA pass: analyzer: internal compiler error (using dubious flexible arrays in unions)

2023-05-10 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109802

--- Comment #2 from Alejandro Colomar  ---
Here's a simplified version that will cause the same internal compiler error.
This one will probably cause less brain damage to readers,
as it has significantly less magic.


$ cat flexi2.c 
#include 
#include 
#include 
#include 

struct s {
int x;
ptrdiff_t off[0];
};

int
main(void)
{
char  *p;
struct s  *s;

s = malloc(sizeof(struct s) +
   sizeof(ptrdiff_t) * 2 +
   sizeof("foo") + sizeof("bar"));

p = (void *) s + sizeof(struct s) + sizeof(ptrdiff_t) * 2;

s->off[0] = p - (char *) s;
p = stpcpy(p, "foo") + 1;
s->off[1] = p - (char *) s;
p = stpcpy(p, "bar") + 1;

puts((char *) s + s->off[0]);
puts((char *) s + s->off[1]);
}


$ gcc-12 -Wall -Wextra -Werror -fanalyzer -O3 flexi2.c 
$ ./a.out 
foo
bar
$ gcc-13 -Wall -Wextra -Werror -O3 flexi2.c 
$ ./a.out 
foo
bar
$ gcc-13 -Wall -Wextra -Werror -fanalyzer -O3 flexi2.c 
during IPA pass: analyzer
flexi2.c: In function ‘main’:
flexi2.c:29:33: internal compiler error: in make, at analyzer/store.cc:132
   29 | puts((char *) s + s->off[1]);
  |   ~~^~~
0xcec8a5 ana::binding_key::make(ana::store_manager*, ana::region const*)
../../src/gcc/analyzer/store.cc:132
0xcf9533 ana::binding_cluster::get_binding(ana::store_manager*, ana::region
const*) const
../../src/gcc/analyzer/store.cc:1567
0xcf95eb ana::binding_cluster::get_binding_recursive(ana::store_manager*,
ana::region const*) const
../../src/gcc/analyzer/store.cc:1604
0xd05e49 ana::binding_cluster::get_any_binding(ana::store_manager*, ana::region
const*) const
../../src/gcc/analyzer/store.cc:1627
0xcd45f7 ana::region_model::get_store_value(ana::region const*,
ana::region_model_context*) const
../../src/gcc/analyzer/region-model.cc:2407
0xcd4e72 ana::region_model::get_rvalue(ana::path_var,
ana::region_model_context*) const
../../src/gcc/analyzer/region-model.cc:2297
0xcd6a5c ana::region_model::on_assignment(gassign const*,
ana::region_model_context*)
../../src/gcc/analyzer/region-model.cc:1156
0xcdc2da ana::exploded_node::on_stmt(ana::exploded_graph&, ana::supernode
const*, gimple const*, ana::program_state*, ana::uncertainty_t*,
ana::path_context*)
../../src/gcc/analyzer/engine.cc:1471
0xcdc877 ana::exploded_graph::process_node(ana::exploded_node*)
../../src/gcc/analyzer/engine.cc:4063
0xcdd8b9 ana::exploded_graph::process_worklist()
../../src/gcc/analyzer/engine.cc:3466
0xcddc57 ana::impl_run_checkers(ana::logger*)
../../src/gcc/analyzer/engine.cc:6125
0xcde4ff ana::run_checkers()
../../src/gcc/analyzer/engine.cc:6213
0xcde54b execute
../../src/gcc/analyzer/analyzer-pass.cc:87
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See  for instructions.


I didn't attach the preprocessed source of this simplified example, since I
guess it would be repetitive with the previous one.

[Bug analyzer/109802] [regression] during IPA pass: analyzer: internal compiler error (using dubious flexible arrays in unions)

2023-05-10 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109802

--- Comment #1 from Alejandro Colomar  ---
Please use this:

Reported-by: Alejandro Colomar 

[Bug analyzer/109802] New: [regression] during IPA pass: analyzer: internal compiler error (using dubious flexible arrays in unions)

2023-05-10 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109802

Bug ID: 109802
   Summary: [regression] during IPA pass: analyzer: internal
compiler error (using dubious flexible arrays in
unions)
   Product: gcc
   Version: 13.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

Created attachment 55039
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55039=edit
preprocessed_source

Hi!

I was compiling some reduced version of some nasty code I found in a project,
to see
what GCC has to say about it.  I'm not sure if it has defined behavior or not,
according to strict-aliasing rules.  That code managed to get GCC on its knees
:)


$ cat flexi.c 
#include 
#include 
#include 
#include 

union u {
char   base[0];
ptrdiff_t  off;
};

struct s {
int x;
union u u[0];
};

int
main(void)
{
char  *p;
struct s  *s;

s = malloc(sizeof(struct s) +
   sizeof(union u) * 2 +
   sizeof("foo") + sizeof("bar"));

p = (void *) s + sizeof(struct s) + sizeof(union u) * 2;

s->u[0].off = p - s->u[0].base;
p = stpcpy(p, "foo") + 1;
s->u[1].off = p - s->u[1].base;
p = stpcpy(p, "bar") + 1;

puts(s->u[0].base + s->u[0].off);
puts(s->u[1].base + s->u[1].off);
}


$ gcc-12 -Wall -Wextra -Werror -fanalyzer -O3 flexi.c
$ ./a.out 
foo
bar


$ gcc-13 -Wall -Wextra -Werror -fanalyzer -O3 flexi.c -freport-bug
during IPA pass: analyzer
flexi.c: In function ‘main’:
flexi.c:34:36: internal compiler error: in make, at analyzer/store.cc:132
   34 | puts(s->u[1].base + s->u[1].off);
  | ~~~^~~~
0xcec8a5 ana::binding_key::make(ana::store_manager*, ana::region const*)
../../src/gcc/analyzer/store.cc:132
0xcf9533 ana::binding_cluster::get_binding(ana::store_manager*, ana::region
const*) const
../../src/gcc/analyzer/store.cc:1567
0xcf95eb ana::binding_cluster::get_binding_recursive(ana::store_manager*,
ana::region const*) const
../../src/gcc/analyzer/store.cc:1604
0xd05e49 ana::binding_cluster::get_any_binding(ana::store_manager*, ana::region
const*) const
../../src/gcc/analyzer/store.cc:1627
0xcd45f7 ana::region_model::get_store_value(ana::region const*,
ana::region_model_context*) const
../../src/gcc/analyzer/region-model.cc:2407
0xcd4e72 ana::region_model::get_rvalue(ana::path_var,
ana::region_model_context*) const
../../src/gcc/analyzer/region-model.cc:2297
0xcd6a5c ana::region_model::on_assignment(gassign const*,
ana::region_model_context*)
../../src/gcc/analyzer/region-model.cc:1156
0xcdc2da ana::exploded_node::on_stmt(ana::exploded_graph&, ana::supernode
const*, gimple const*, ana::program_state*, ana::uncertainty_t*,
ana::path_context*)
../../src/gcc/analyzer/engine.cc:1471
0xcdc877 ana::exploded_graph::process_node(ana::exploded_node*)
../../src/gcc/analyzer/engine.cc:4063
0xcdd8b9 ana::exploded_graph::process_worklist()
../../src/gcc/analyzer/engine.cc:3466
0xcddc57 ana::impl_run_checkers(ana::logger*)
../../src/gcc/analyzer/engine.cc:6125
0xcde4ff ana::run_checkers()
../../src/gcc/analyzer/engine.cc:6213
0xcde54b execute
../../src/gcc/analyzer/analyzer-pass.cc:87
Please submit a full bug report, with preprocessed source.
Please include the complete backtrace with any bug report.
See  for instructions.
Preprocessed source stored into /tmp/ccZKUz79.out file, please attach this to
your bugreport.


You'll find attached the file produced by GCC, as per its own instructions.

[Bug analyzer/109335] -Wanalyzer-malloc-leak false positives and false negatives

2023-05-05 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109335

Alejandro Colomar  changed:

   What|Removed |Added

 CC||colomar.6.4.3 at gmail dot com

--- Comment #1 from Alejandro Colomar  ---
I can still reproduce it with GCC-13 and glibc 2.36:


$ cat glibc.c 
#include 

int main(void)
{
printf("glibc version: %d.%d\n", __GLIBC__, __GLIBC_MINOR__);
}

$ gcc-13 -Wall -Wextra glibc.c 
$ ./a.out 
glibc version: 2.36
$ gcc-13 --version
gcc-13 (Debian 13.1.0-1) 13.1.0
Copyright (C) 2023 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.

[Bug analyzer/109335] New: -Wanalyzer-malloc-leak false positives and false negatives

2023-03-29 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109335

Bug ID: 109335
   Summary: -Wanalyzer-malloc-leak false positives and false
negatives
   Product: gcc
   Version: 13.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

Created attachment 54786
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54786=edit
Preprocessed reproducer

Link:
<https://inbox.sourceware.org/gcc/45c0584d-b326-a975-7ebc-cef76e154...@gmail.com/T/#u>

With both GCC 12.2.0 (Debian), and GCC 13.0.1 20230315 (built from source),
I can reproduce these false positives.  I'm on Debian Sid with
libbsd-dev 0.11.7-4, and libc-dev 2.36-8.

The reproducer program is a small program that checks a password against a
hardcoded string, and conditionally prints "validated".  I wrote it
precisely to demonstrate how [[gnu::malloc(deallocator)]] can be used to
ensure that passwords are not leaked in memory, but I found out that it
fails to detect some conditions.

Here's the program (it uses agetpass(), as defined in the shadow project):

$ cat pass.c 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#define PASS_MAX  BUFSIZ - 1


#define MALLOCARRAY(n, type)   ((type *) mallocarray(n, sizeof(type)))


[[gnu::malloc, gnu::malloc(free)]] void *mallocarray(size_t nmemb, size_t
size);
void erase_pass(char *pass);
[[gnu::malloc(erase_pass)]] char *agetpass(const char *prompt);


void
do_work(void)
{
char  *pass;

pass = agetpass("Enter your password: ");
if (pass == NULL)
err(EXIT_FAILURE, "agetpass");

if (strcmp(pass, "secret") == 0)
puts("validated");

/* erase_pass() zeroes the memory (think of memset(3), or bzero(3))
   and then releases the memory to the system (think of free(3)).
   If you only call free(pass), then you release the memory to the
   system without zeroing it.  Remember it contains a password!
   We would be leaking a password into the system memory, which can
   later be assigned to a different process.

   So, we should call erase_pass() as soon as possible, but let's
   say we forgot, and just call free():
*/
#if defined(BUG_1)
// We forgot to zero the memory.
free(pass);
// GCC correctly catches this as -Wmismatched-dealloc
#elif defined(BUG_2)
// We zeroed, but forgot to free(3).
bzero(pass, PASS_MAX + 2);
// GCC misses this.
#elif defined(BUG_3)
// We forgot both of them.
// GCC also misses this.
#else
erase_pass(pass);  // OK, but 2 false positives.
#endif
}


int
main(void)
{
do_work();

for (;;)
sleep(1);
}


void *
mallocarray(size_t nmemb, size_t size)
{
return reallocarray(NULL, nmemb, size);
}


char *
agetpass(const char *prompt)
{
char*pass;
size_t  len;

pass = MALLOCARRAY(PASS_MAX + 2, char);
if (pass == NULL)
return NULL;

if (readpassphrase(prompt, pass, PASS_MAX + 2, RPP_REQUIRE_TTY) ==
NULL)
goto fail;

len = strlen(pass);
if (len == PASS_MAX + 1) {
errno = ENOBUFS;
goto fail;
}

return pass;

fail:
freezero(pass, PASS_MAX + 2);
return NULL;
}


void
erase_pass(char *pass)
{
freezero(pass, PASS_MAX + 2);
}



This shows the false positives:


$ cc -Wall -Wextra pass.c $(pkgconf --cflags --libs libbsd-overlay) -fanalyzer
-O3
pass.c: In function ‘agetpass’:
pass.c:84:12: warning: leak of ‘pass’ [CWE-401] [-Wanalyzer-malloc-leak]
   84 | if (pass == NULL)
  |^
  ‘do_work’: events 1-3
|
|   22 | do_work(void)
|  | ^~~
|  | |
|  | (1) entry to ‘do_work’
|..
|   26 | pass = agetpass("Enter your password: ");
|  |~
|  ||
|  |(2) allocated here
|  |(3) calling ‘agetpass’ from ‘do_work’
|
+--> ‘agetpass’: events 4-5
   |
   |   78 | agetpass(const char *prompt)
   |  | ^~~~
   |  | |
   |  | (4) entry to ‘agetpass’
   |..
   |   84 | if (pass == NULL)
   |  |~
   |  ||
   |  |(5) ‘pass’ leaks here; was allocated at (2)
   |
pass.c:91:12: warning: leak of ‘pass’ [CWE-401] [-Wanalyzer-malloc-leak]
   91 | if (len == PASS_MAX + 1) {
  |^
  ‘do_work’: events 1-3
|
|   22 | do_work(void

[Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function

2022-12-09 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108036

--- Comment #5 from Alejandro Colomar  ---
Interesting.  Thanks for clarifying :)

[Bug middle-end/108036] [11/12/13 Regression] Spurious warning for zero-sized array parameters to a function

2022-12-09 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108036

--- Comment #3 from Alejandro Colomar  ---
Hi Andrew!

Just a few nitpicks:

-  In the first testcase you posted, the [] is missing the 0: [0].

-  In the reduced test case, you call the pointer to one past the end as 'end'.
 That is misleading, since 'end' is commonly also used for pointers to the last
byte in an array, normally the NUL byte in strings.  Using the term 'end'
meaning one-past-the-end is likely to end up in off-by-one errors.  So much
that I found a few of them for exactly that reason this week :)

This last point is why I like using array syntax, so I can clrealy specify
'end[1]' and 'past_end[0]', and they are clearly different things.

Cheers,

Alex

[Bug c/108036] New: Spurious warning for zero-sized array parameters to a function

2022-12-09 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108036

Bug ID: 108036
   Summary: Spurious warning for zero-sized array parameters to a
function
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

It's interesting to pass pointers to one past the end of an array to a
function, acting as a sentinel value that serves as an alternative to the size
of the buffer.  It helps chaining string copy functions, for example:


char *
ustr2stpe(char *dst, const char *restrict src, size_t n, char past_end[0])
{
bool   trunc;
char   *end;
ptrdiff_t  len;

if (dst == past_end)
return past_end;

trunc = false;
len = strnlen(src, n);
if (len > past_end - dst - 1) {
len = past_end - dst - 1;
trunc = true;
}

end = mempcpy(dst, src, len);
*end = '\0';

return trunc ? past_end : end;
}


However, if you use array syntax for it, which clarifies where it points to,
the GCC complains, not at the function implementation, but at call site:


#define nitems(arr)  (sizeof((arr)) / sizeof((arr)[0]))

int
main(void)
{
char pre[4] = "pre.";
char *post = ".post";
char *src = "some-long-body.post";
char dest[100];
 char *p, *past_end;

past_end = dest + nitems(dest);
p = dest;
p = ustr2stpe(p, pre, nitems(pre), past_end);
p = ustr2stpe(p, src, strlen(src) - strlen(post), past_end);
p = ustr2stpe(p, "", 0, past_end);
if (p == past_end)
fprintf(stderr, "truncation\n");

puts(dest);  // "pre.some-long-body"
}

$ cc -Wall -Wextra ustr2stpe.c
ustr2stpe.c: In function ‘main’:
ustr2stpe.c:43:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
43 | p = ustr2stpe(p, pre, nitems(pre), past_end);
   | ^~~~
ustr2stpe.c:43:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
   | ^
ustr2stpe.c:44:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
44 | p = ustr2stpe(p, src, strlen(src) - strlen(post), past_end);
   | ^~~
ustr2stpe.c:44:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
   | ^
ustr2stpe.c:45:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
45 | p = ustr2stpe(p, "", 0, past_end);
   | ^
ustr2stpe.c:45:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
   | ^
ustr2stpe.c:43:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
43 | p = ustr2stpe(p, pre, nitems(pre), past_end);
   | ^~~~
ustr2stpe.c:43:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
   | ^
ustr2stpe.c:44:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
44 | p = ustr2stpe(p, src, strlen(src) - strlen(post), past_end);
   | ^~~
ustr2stpe.c:44:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
   | ^
ustr2stpe.c:45:13: warning: ‘ustr2stpe’ accessing 1 byte in a region of size 0
[-Wstringop-overflow=]
45 | p = ustr2stpe(p, "", 0, past_end);
   | ^
ustr2stpe.c:45:13: note: referencing argument 4 of type ‘char[0]’
ustr2stpe.c:10:1: note: in a call to function ‘ustr2stpe’
10 | ustr2stpe(char *dst, const char *restrict src, size_t n, char
past_end[0])
   | ^


The warnings are invalid.  While it's true that I'm referencing a pointer of
size 0, it's false that I'm "accessing 1 byte" in that region.  I guess this is
all about the bogu

[Bug c/102989] Implement C2x's n2763 (_BitInt)

2022-10-28 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102989

--- Comment #29 from Alejandro Colomar  ---
Hi!

On 10/28/22 12:51, rguenther at suse dot de wrote:
> Quite likely yes (OTOH __BIGGEST_ALIGNMENT__ changed as well).  That
> also means BITINT_MAXWIDTH should eventually be decided by the ABI
> groups?
> 
> I also can hardly see any use for very big N other than "oh, cool".  I
> mean, we don't have _Float(N) either for N == 65000 even though what
> would be cool as well.

I do have a use.  Okay, I don't need 8M bits, but 1k is something that would 
help me.  Basically, it's a transparent bignum library, for which I can use
most 
standard C features.  BTW, it would also be nice if stdc_count_ones(3) would be 
implemented to support very wide _BitInt()s as an extension (C23 only
guarantees 
support for _BitInt()s that match a standard or extended type).

I have some program that works with matrices of 512x512, represented as arrays 
of 512 members of uint64_t[8], and it popcounts rows, which now means looping 
over an array of uint64_t[8] and using the builtin popcount.  And I'm not sure 
if I could still optimize it a little bit more.  If I could just call the 
type-generic stdc_count_ones(), and know that the implementation has written a 
quite optimal loop, that would be great (both for simplicity and performance).

Cheers,

Alex

> 
>> Anyway, I'm afraid we probably don't have enough time to implement this
>> properly in stage1, so might need to target GCC 14 with it.  Unless somebody
>> spends on it
>> the remaining 2 weeks full time.
> 
> It's absolutely a GCC 14 task given the ABI and library issue.
>

[Bug c/107348] documentation: __builtin_classify_type() undocumented

2022-10-21 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107348

--- Comment #6 from Alejandro Colomar  ---
Thanks!

Maybe a working __builtin_classify_type2() would be useful...  Maybe not...

BTW, maybe it's worth checking all the code in gcc that is comparing the result
against 14, and see if it should be removed, or fixed, or if it actually works
somehow.

Cheers,
Alex

P.S.:  Maybe having a search function, or a single-HTML-page manual (as glibc
does) would be good for finding this stuff.  I don't know.  I tried searching
in the PDF, and I didn't find it.

[Bug c/107348] documentation: __builtin_classify_type() undocumented

2022-10-21 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107348

--- Comment #4 from Alejandro Colomar  ---
Hmm.  Then I wonder if array_type_class is being used at all, or if it's unused
code.

[Bug c/107348] documentation: __builtin_classify_type() undocumented

2022-10-21 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107348

--- Comment #2 from Alejandro Colomar  ---
Being a builtin, I expected that you could just do "compiler magic" to avoid
the decay.

[Bug c/107348] New: documentation: __builtin_classify_type() undocumented

2022-10-21 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107348

Bug ID: 107348
   Summary: documentation: __builtin_classify_type() undocumented
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

I can't find any documentation about `__builtin_classify_type()`.

Moreover, it behaves weird with arrays.

$ grepc type_class
./gcc/typeclass.h:30:
enum type_class
{
  no_type_class = -1,
  void_type_class, integer_type_class, char_type_class,
  enumeral_type_class, boolean_type_class,
  pointer_type_class, reference_type_class, offset_type_class,
  real_type_class, complex_type_class,
  function_type_class, method_type_class,
  record_type_class, union_type_class,
  array_type_class, string_type_class,
  lang_type_class, opaque_type_class
};


One would expect that for arrays, it would return `array_type_class`, i.e.,
`14`, but it returns `5`, i.e., `pointer_type_class`.

alx@debian:~/tmp$ cat ptr.c 
#include 

int
main(void)
{
int a[5];

printf("%d\n", __builtin_classify_type(a));
}
alx@debian:~/tmp$ cc -Wall -Wextra ptr.c 
alx@debian:~/tmp$ ./a.out 
5

Please document the builtin (and also fix the handling of arrays).

[Bug analyzer/106854] [[gnu::malloc(deallocator)]] for non-pointer functions (e.g., fd)

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106854

--- Comment #6 from Alejandro Colomar  ---
timerfd_create() might not be important if the timer is not correctly deleted. 
pthread_mutex_init() is another one that is quite more important, as leaking
such a thing in a multithreaded program will be a pain to debug for sure.  This
attribute could help detect that.

[Bug analyzer/106854] [[gnu::malloc(deallocator)]] for non-pointer functions (e.g., fd)

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106854

--- Comment #5 from Alejandro Colomar  ---
We could also keep the old [[gnu::malloc(...)]] attribute, of course, if a new
attribute would be an issue.  We would just have to add an extra argument (the
third?, or one before the function name?) to mark the position of the
initialized object.

Either [[gnu::malloc(3, timerfd_close)]] with an optional third argument of 1,
or [[gnu::malloc(timerfd_close, 1, 3)]] and force to specify the position in
the closer if the position in the initializer needs to be specified.

The second form would probably be easier to implement, and the first one might
be easier to use (having to specify less things).

[Bug analyzer/106854] [[gnu::malloc(deallocator)]] for non-pointer functions (e.g., fd)

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106854

--- Comment #4 from Alejandro Colomar  ---
Hi David,

I was missing that this is to be introduced in GCC 13, which of course I still
don't have; but thanks!  It'll be a great improvement.

Still, this doesn't seem to cover all cases.  See for example the case of

   int timer_create(clockid_t clockid, struct sigevent *restrict sevp,
timer_t *restrict timerid);
   int timer_delete(timer_t timerid);

One needs to pair those two functions.

The case with these functions has another problem: the initialized object
(which is an arithmetic type; check clockid_t(3type) --or clockid_t(3) in older
systems--) is returned via a parameter, instead of the return value.

It would be good if a more generic attribute could be used to mark such cases. 
We would need to be careful to accept both pointers and integers, to not
unnecessarily make it unusable in some future use cases, so it could be used
for malloc(3), for open(2), for timer_create(3), and for any other functions
that one may create.

I think the following syntax would make sense:

   [[gnu::init(3, timer_delete, 1)]]
   int timer_create(clockid_t clockid, struct sigevent *restrict sevp,
timer_t *restrict timerid);

Where the first argument, 3, refers to the position of the parameter that is
initialized to a unique value; the second refers to the function that
deinitializes it; and the third (optional), refers to the position in the
deinitializer function where the parameter is expected.  For a function like
malloc(3) or open(2), where the initialized value is returned via the return
value, the first argument should be 0.

Does this make sense?

This would superseed the [[gnu::malloc(...)]] attribute, which would be less
confusing (having two different attributes with the same name is confusing,
IMHO).

[Bug analyzer/106854] [[gnu::malloc(deallocator)]] for non-pointer functions (e.g., fd)

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106854

--- Comment #2 from Alejandro Colomar  ---
Also interesting might be that one function might have more than one closer.

For example, open(2) might be closed by close(2), but it is also closed by
fdopen(3), in the sense that the file descriptor can't be (safely) used again
after that, and also that it can't be passed to close(2) after that --even if
in reality the file descriptor is still valid, for obvious reasons--.

[Bug c/106854] New: [[gnu::malloc(deallocator)]] for non-pointer functions (e.g., fd)

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106854

Bug ID: 106854
   Summary: [[gnu::malloc(deallocator)]] for non-pointer functions
(e.g., fd)
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

Some stuff is allocated and deallocated through non-pointer types.  Most of the
time it's file descriptors, i.e., int.

Since [[gnu::malloc(f)]] is independent of [[gnu::malloc]], it could be used
for such cases:

int close(int fd);

[[gnu::malloc(close)]]
int open(const char *pathname, int flags, ...);

Notice that [[gnu::malloc]] can't be used above.

[[gnu::malloc(f)]] has no reason to be restricted to functions returning
pointers, has it?

Could you allow using it for file descriptors?  Otherwise, a more generic
[[open(close)]] attribute might be reasonable.


Currently, it results in a warning:

$ cat fd.c && echo && cc -Wall -Wextra -S fd.c 
#include 
#include 

[[gnu::malloc(close)]]
int g(void)
{
return open("foo", O_RDONLY);
}

fd.c:6:1: warning: ‘malloc’ attribute ignored on functions returning ‘int’;
valid only for pointer return types [-Wattributes]
6 | {
  | ^

[Bug c/106850] restrict type qualifier ignored on function return type

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106850

--- Comment #3 from Alejandro Colomar  ---
Ahhh, yeah, something like rvalues don't have qualifiers.  I seem to remember
now.

Maybe the standard should fix this for restrict, because things like clang's
_Nonnull would benefit from being kept in such cases.

Of course, that might complicate the compiler...

[Bug c/106850] restrict type qualifier ignored on function return type

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106850

--- Comment #1 from Alejandro Colomar  ---
The benefits are:

- It's standard.
- It's less bytes to type.

[Bug c/106850] New: restrict type qualifier ignored on function return type

2022-09-06 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106850

Bug ID: 106850
   Summary: restrict type qualifier ignored on function return
type
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

Related: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87313>

The description of the restrict qualifier would lead one to think that it can
be used as a standard way of describing a function that returns a unique
pointer, as the [[gnu::malloc]] attribute does in GNU C.

GCC currently ignores the qualifier, so it can't use it for the optimizations
that [[gnu::malloc]] allows, but if GCC didn't ignore the qualifier, it could
be used for that.

```c
#include 
#include 
#include 
#include 

[[gnu::malloc(free)]]
void *restrict
my_malloc(size_t size)
{
void *p;

p = malloc(size);  
if (!p)
err(EXIT_FAILURE, "malloc(2)");

return p;
}
```
```sh
$ cc -Wall -Wextra my_malloc.c -S
my_malloc.c:8:1: warning: type qualifiers ignored on function return type
[-Wignored-qualifiers]
8 | my_malloc(size_t size)
  | ^
```

Could you please not ignore the qualifier, and treat it as synonym of
[[gnu::malloc]]?

[Bug c++/103862] -Wold-style-cast warns about system macros

2021-12-30 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103862

Alejandro Colomar  changed:

   What|Removed |Added

 CC||colomar.6.4.3 at gmail dot com

--- Comment #4 from Alejandro Colomar  ---
Hi,

I tried GCC 12 from Debian experimental and I can still reproduce the bug:

$ g++-12 --version
g++-12 (Debian 12-20211217-1) 12.0.0 20211217 (experimental) [master
r12-6027-g774269aa4b9]


I found something weird: if you enclose the macro argument in parentheses, the
warning is silenced:

#define MY_CAST(x) ((int)(x))


P.S.: If system header macros can be warned if part of the expression comes
from user code, I'd really like see -Wsizeof-pointer-div reporting warnings. 
See <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94746>

[Bug analyzer/103233] Warning from system libraries in user code: CWE-476 -Werror=analyzer-null-dereference

2021-11-15 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103233

--- Comment #6 from Alejandro Colomar  ---
I mean, I'm not against that,
in fact I think it's good to know if my program is going to crash,
even if it's not my fault,
but then I wonder if cases such as

should also report a warning in user code,
even with more reason (in that other case it is the user's fault).

[Bug analyzer/103233] Warning from system libraries in user code: CWE-476 -Werror=analyzer-null-dereference

2021-11-15 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103233

--- Comment #5 from Alejandro Colomar  ---
Is `-fanalyzer` allowed to report errors from system headers exclusively?

I mean,
ignoring the fact that C++ is unsupported,
there's no report at all that relates that error report to my code;
not even to libopencv's code.

If glibc had a bug,
and I compiled a C program that had perfectly defined behavior,
would I receive a report for that error?

[Bug c++/103233] Warning from system libraries in user code: CWE-476 -Werror=analyzer-null-dereference

2021-11-14 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103233

--- Comment #1 from Alejandro Colomar  ---
$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux bookworm/sid"
NAME="Debian GNU/Linux"
ID=debian
HOME_URL="https://www.debian.org/;
SUPPORT_URL="https://www.debian.org/support;
BUG_REPORT_URL="https://bugs.debian.org/;



$ dpkg -l "*[cg]++*"
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name  Version  Architecture Description
+++-=---===
un  c++-compiler(no description
available)
un  c++abi2-dev (no description
available)
ii  g++   4:11.2.0-2   amd64GNU C++ compiler
ii  g++-1111.2.0-10amd64GNU C++ compiler
un  g++-11-multilib (no description
available)
un  g++-multilib(no description
available)
un  g++-x86-64-linux-gnu(no description
available)
ii  lib32stdc++6  11.2.0-10amd64GNU Standard C++
Library v3 (32 bit Version)
un  libg++2.8-dev   (no description
available)
un  libg++27-dev(no description
available)
un  libg++272-dev   (no description
available)
un  libsigc++-2.0-0c2a  (no description
available)
ii  libsigc++-2.0-0v5:amd64   2.10.4-2 amd64type-safe Signal
Framework for C++ - runtime
ii  libstdc++-10-dev:amd6410.3.0-12amd64GNU Standard C++
Library v3 (development files)
un  libstdc++-10-doc(no description
available)
ii  libstdc++-11-dev:amd6411.2.0-10amd64GNU Standard C++
Library v3 (development files)
un  libstdc++-11-doc(no description
available)
un  libstdc++-dev   (no description
available)
un  libstdc++2.10-dev   (no description
available)
un  libstdc++2.8-dev(no description
available)
un  libstdc++2.9-dev(no description
available)
un  libstdc++2.9-glibc2.1-dev   (no description
available)
un  libstdc++3.0-dev(no description
available)
ii  libstdc++6:amd64  11.2.0-10amd64GNU Standard C++
Library v3
un  libstdc++6-11-dbg   (no description
available)

[Bug c++/103233] New: Warning from system libraries in user code: CWE-476 -Werror=analyzer-null-dereference

2021-11-14 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103233

Bug ID: 103233
   Summary: Warning from system libraries in user code: CWE-476
-Werror=analyzer-null-dereference
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

There are two problems here:

One is a dereference of a NULL pointer in the standard C++ library code
(at least that's what -fanalyzer reports).
Another is that I'm seeing the error while compiling user code (my library):
<https://github.com/alejandro-colomar/libalx>

c++ -D _GNU_SOURCE -D _POSIX_C_SOURCE=200809L -D
SYSCONFDIR_='"/usr/local/etc/alx"' -O3 -Wall -Wextra -Winvalid-pch -fno-common
-Werror -fpic -isystem/usr/local/include -D_GNU_SOURCE
-D_POSIX_C_SOURCE=200809L -isystem/usr/include/opencv4
-isystem/usr/local/include -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L
-isystem/usr/local/include -D_GNU_SOURCE -D_POSIX_C_SOURCE=200809L -fanalyzer
-std=gnu++20 -Wno-vla -I /home/alx/src/alx/libalx/include -fpreprocessed -S
-o /home/alx/src/alx/libalx/tmp/alx/cv/features2d/orb.cxx.s
/home/alx/src/alx/libalx/tmp/alx/cv/features2d/orb.cxx.i
In member function 'void std::vector<_Tp,
_Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...)
[with _Args = {const cv::Point_&}; _Tp = cv::Point_; _Alloc =
std::allocator >]':
cc1plus: error: dereference of NULL '__cur' [CWE-476]
[-Werror=analyzer-null-dereference]
  'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp,
_Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_&}; _Tp =
cv::Point_; _Alloc = std::allocator >]': events 1-2
|
|/usr/include/c++/11/bits/vector.tcc:426:7:
|  426 |   vector<_Tp, _Alloc>::
|  |   ^~~
|  |   |
|  |   (1) entry to 'std::vector
>::_M_realloc_insert&>'
|..
|  436 | _M_check_len(size_type(1), "vector::_M_realloc_insert");
|  | ~~~
|  | |
|  | (2) calling 'std::vector
>::_M_check_len' from 'std::vector >::_M_realloc_insert&>'
|
+--> 'std::vector<_Tp, _Alloc>::size_type std::vector<_Tp,
_Alloc>::_M_check_len(std::vector<_Tp, _Alloc>::size_type, const char*) const
[with _Tp = cv::Point_; _Alloc = std::allocator >]':
events 3-5
   |
   |/usr/include/c++/11/bits/stl_vector.h:1756:7:
   | 1756 |   _M_check_len(size_type __n, const char* __s) const
   |  |   ^~~~
   |  |   |
   |  |   (3) entry to 'std::vector
>::_M_check_len'
   | 1757 |   {
   | 1758 | if (max_size() - size() < __n)
   |  | ~~
   |  | |
   |  | (4) following 'false' branch...
   |..
   | 1761 | const size_type __len = size() + (std::max)(size(),
__n);
   |  | ~~
   |  | |
   |  | (5)
...to here
   |
<--+
|
  'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp,
_Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_&}; _Tp =
cv::Point_; _Alloc = std::allocator >]': event 6
|
|/usr/include/c++/11/bits/vector.tcc:436:21:
|  436 | _M_check_len(size_type(1), "vector::_M_realloc_insert");
|  | ^~~
|  | |
|  | (6) returning to
'std::vector >::_M_realloc_insert&>'
from 'std::vector >::_M_check_len'
|
  'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp,
_Alloc>::iterator, _Args&& ...) [with _Args = {const cv::Point_&}; _Tp =
cv::Point_; _Alloc = std::allocator >]': event 7
|
|/usr/include/c++/11/bits/stl_vector.h:346:25:
|  346 | return __n != 0 ? _Tr::allocate(_M_impl, __n) : pointer();
|  |~^
|  | |
|  | (7) following 'false' branch...
|
  'void std::vector<_Tp, _Alloc>::_M_realloc_insert(std::vector<_Tp,
_Alloc>::iterator, _Ar

[Bug c/102989] Implement C2x's n2763 (_BitInt)

2021-11-11 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102989

--- Comment #9 from Alejandro Colomar  ---
Is there any proposal regarding suffices for constants?  I didn't see it in the
main proposal for _BitInt().

I mean something like 1u8 to create a constant of type unsigned _BitInt(8).

---

@Joseph

Regarding your request for help, I didn't answer, because I didn't consider
myself qualified to do that.  However, I would love to help if I can, so if you
point me to something I could help, I'll be happy to try :)

[Bug c/102989] Add Clang's _ExtInt(N)

2021-10-28 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102989

--- Comment #5 from Alejandro Colomar  ---
Thanks for that info.  It's nice to see the standard is considering that.

Yes, we should add what the standard is going to add, so I'd wait to see what
the standard decides in the end.

Cheers,

Alex

[Bug c/102989] Add Clang's _ExtInt(N)

2021-10-28 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102989

--- Comment #3 from Alejandro Colomar  ---
D'oh.

s/comma/parenthesis/

[Bug c/102989] Add Clang's _ExtInt(N)

2021-10-28 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102989

--- Comment #2 from Alejandro Colomar  ---
There was a missing comma.  Fix:

#define __STYPE_MAX(t) (t) 1 << (widthof(t) - 2)) - 1) << 1) + 1)

[Bug c/102989] Add Clang's _ExtInt(N)

2021-10-28 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102989

--- Comment #1 from Alejandro Colomar  ---
This also triggers the following wish:

'widthof(t)', which would be equivalent to 'sizeof(t) * CHAR_BIT' for normal
types, but would be equal to N in the case of _ExtInt(N).

It could also be used to mean the exact bit width of a bitfield.

This is helpful to have a generic TYPE_MAX(t) macro (yet another wish, although
this would be for glibc once widthof() is in GCC), which could be implemented
as:

#define ISSIGNED(t)(((t) - 1) < 0)
#define __STYPE_MAX(t) (t) 1 << widthof(t) - 2)) - 1) << 1) + 1)
#define __UTYPE_MAX(t) ((t) -1)
#define TYPE_MAX(t)(ISSIGNED(t) ? __STYPE_MAX(t) : __UTYPE_MAX(t))
#define TYPE_MIN(t)((t) ~TYPE_MAX(t))

These macros could be used for *any* integer type, including _ExtInt() and
bitfields, if the compiler provided widthof().

[Bug c/102989] New: Add Clang's _ExtInt(N)

2021-10-28 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102989

Bug ID: 102989
   Summary: Add Clang's _ExtInt(N)
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

I'd like to see Clang's _ExtInt(N) arbitrary-precision fixed-width integers
(https://clang.llvm.org/docs/LanguageExtensions.html#extended-integer-types) in
GCC.

I have in mind at least a scenario where they would help:

- Bignum

They are much simpler than using GMP.  I have a project of mine where I ended
up doing my own type made of an array: 'typedef uint64_t uint512_a[8];'. 
Having the ability to handle 'typedef unsigned _ExtInt(512) uint512;' as easily
as __int128 is great.

[Bug c/101545] [[nodiscard]]: Incorrect warning when creating a function alias

2021-07-21 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101545

--- Comment #1 from Alejandro Colomar  ---
The same code with [[gnu::warn_unused_result]] instead of [[nodiscard]] doesn't
trigger the warning.

[Bug c/101545] New: [[nodiscard]]: Incorrect warning when creating a function alias

2021-07-21 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101545

Bug ID: 101545
   Summary: [[nodiscard]]: Incorrect warning when creating a
function alias
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

The following code never discards that `42`, passing it to the caller of
foobar() (in a different translation unit), and forcing it to read the value.
The warnings about an ignored [[nodiscard]] are therefore incorrect.

I put the contents of the header in the same source file just for simplicity.


$ cat nodiscard.c 
[[nodiscard]] int foo(void);

[[gnu::copy(foo)]] extern __typeof__(foo) bar;

[[nodiscard]] int foobar(void);


int foo(void)
{
return 42;
}

int foobar(void)
{
return bar();  /* This will return 42 */
}

[[gnu::alias("foo")]] [[gnu::copy(foo)]] extern __typeof__(foo) bar;


$ cc -Wall -Wextra -std=c2x -c nodiscard.c 
nodiscard.c:3:1: warning: 'nodiscard' attribute directive ignored
[-Wattributes]
3 | [[gnu::copy(foo)]] extern __typeof__(foo) bar;
  | ^
nodiscard.c:18:1: warning: 'nodiscard' attribute directive ignored
[-Wattributes]
   18 | [[gnu::alias("foo")]] [[gnu::copy(foo)]] extern __typeof__(foo) bar;
  | ^

[Bug preprocessor/89808] An option to disable warning "#pragma once in main file"

2021-06-14 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89808

Alejandro Colomar  changed:

   What|Removed |Added

 CC||colomar.6.4.3 at gmail dot com

--- Comment #12 from Alejandro Colomar  ---
Still buggy in gcc-11 (Debian 11.1.0-3) 11.1.0

I'll have a look at the code and see if I can fix it.

[Bug pch/64117] warning control #pragmas in precompiled headers are not obeyed for template code

2021-06-14 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64117

--- Comment #7 from Alejandro Colomar  ---
Oops, sorry, I meant the previous comment for another bug.  I don't know if
it's solved or not in gcc-11

[Bug pch/64117] warning control #pragmas in precompiled headers are not obeyed for template code

2021-06-14 Thread colomar.6.4.3 at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64117

Alejandro Colomar  changed:

   What|Removed |Added

 CC||colomar.6.4.3 at gmail dot com

--- Comment #6 from Alejandro Colomar  ---
Still buggy in gcc-11 (gcc-11 (Debian 11.1.0-3) 11.1.0)

I'll have a look at the code and see if I can fix it.

[Bug c/95024] No way to pass "-Wno-error=..." with #pragma GCC diagnostic

2020-05-09 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95024

--- Comment #2 from Alejandro Colomar  ---
If I use

#pragma GCC diagnostic ignored "-Wconversion"

I will loose the warning.  I still want the warning, but not the error.
That's what I have right now as a workaround, but it's not what I want.

__

And this:

#pragma GCC diagnostic warning "-Wconversion"

hardcodes the warning.  I want to be able to enable or disable "-Wconversion"
in the command line.

__

There is no way to express that I want to enable or disable a warning/error at
command line, but that some part of the code should never be an error.

[Bug c/95024] New: No way to pass "-Wno-error=..." with #pragma GCC diagnostic

2020-05-09 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95024

Bug ID: 95024
   Summary: No way to pass "-Wno-error=..." with #pragma GCC
diagnostic
   Product: gcc
   Version: 10.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

There is no way to disable `-Werror` for specific lines of code.

I would use something like this:


// I want errors about conversion here

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Werror=conversion"
// I don't want errors about conversion here
#pragma GCC diagnostic push

// I want errors about conversion here

[Bug c/94746] -Wsizeof-pointer-div not triggered by system header macros

2020-04-25 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94746

--- Comment #3 from Alejandro Colomar  ---
I tried to use ``#pragma GCC diagnostic`` to enable ``-Wsystem-headers`` only
for that macro.  It bloated me with completely unrelated errors from libraries.
 So it is not an option.

The only workaround right now is to use a ``_Static_assert``:

.. code-block:: c

#include 


#define is_same_type(a, b)  \
__builtin_types_compatible_p(__typeof__(a), __typeof__(b))

#define is_array(a) (!is_same_type((a), &(a)[0]))

#define Static_assert_array(a)  \
_Static_assert(is_array(a), "Not a `[]` !")

#define ARRAY_SIZE(arr) __extension__(  \
{   \
Static_assert_array(arr);   \
__arraycount((arr));\
}   \
)

This macro is safe no matter which warnings are enabled.  There is no other way
to write a safe macro in a system library for calculating the size of an array.
 I would call that a bug.  The warning is completely useless, unless you keep
copy that macro for each and every project, which is of course *wrong*.

[Bug c/94746] -Wsizeof-pointer-div not triggered by system header macros

2020-04-25 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94746

--- Comment #2 from Alejandro Colomar  ---
Maybe the design is not perfect.

Maybe some special warnings should still be warned about when they are used in
user's code.  I don't think there are any possible false positives with this
warning.  But still I don't know.

Maybe I should add a pragma in the system header to enable `-Wsystem-headers`
for that macro.

[Bug analyzer/94754] -fanalyzer false positive due to it ignoring previous if

2020-04-24 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94754

--- Comment #1 from Alejandro Colomar  ---
__builin_unreachable() helped silencing that specific bug, as a temporary
workaround:

[[gnu::nonnull]]
static
int init_x(int cond, int **x, int *y)
{

if (!cond)
return  -1;
*x = y;
return  0;
}

int foo(int cond)
{
int *x;
int y = 7;

if (cond < 2)
return  -1;

/* cond >= 2 != 0, so it will initialize x and return 0 */
if (init_x(cond, , ))
__builtin_unreachable();

return  *x;
}

[Bug analyzer/94754] New: -fanalyzer false positive due to it ignoring previous if

2020-04-24 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94754

Bug ID: 94754
   Summary: -fanalyzer false positive due to it ignoring previous
if
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: analyzer
  Assignee: dmalcolm at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

The analyzer follows branches that are incompatible (sometimes).

Code to reproduce the bug:

[[gnu::nonnull]]
static
voidinit_x(int cond, int **x, int *y)
{

if (!cond)
return;
*x = y;
}

int foo(int cond)
{
int *x;
int y = 7;

if (cond < 2)
return  -1;

/* cond >= 2 != 0, so it will initialize x */
init_x(cond, , );

return  *x;
}

$ gcc-10 -c false_positive.c -o foo -fanalyzer
In function ‘foo’:
false_positive.c:22:9: warning: use of uninitialized value ‘x’ [CWE-457]
[-Wanalyzer-use-of-uninitialized-value]
   22 |  return *x;
  | ^~
  ‘foo’: events 1-4
|
|   11 | int foo(int cond)
|  | ^~~
|  | |
|  | (1) entry to ‘foo’
|..
|   16 |  if (cond < 2)
|  | ~
|  | |
|  | (2) following ‘false’ branch (when ‘cond > 1’)...
|..
|   20 |  init_x(cond, , );
|  |  
|  |  |
|  |  (3) ...to here
|  |  (4) calling ‘init_x’ from ‘foo’
|
+--> ‘init_x’: events 5-7
   |
   |3 | void init_x(int cond, int **x, int *y)
   |  |  ^~
   |  |  |
   |  |  (5) entry to ‘init_x’
   |..
   |6 |  if (!cond)
   |  | ~ 
   |  | |
   |  | (6) following ‘true’ branch (when ‘cond == 0’)...
!!! cond == 0, but previously it assumed cond > 1 !!!
   |7 |   return;
   |  |   ~~
   |  |   |
   |  |   (7) ...to here
   |
<--+
|
  ‘foo’: events 8-9
|
|   20 |  init_x(cond, , );
|  |  ^~~~
|  |  |
|  |  (8) returning to ‘foo’ from ‘init_x’
|   21 | 
|   22 |  return *x;
|  | ~~
|  | |
|  | (9) use of uninitialized value ‘x’ here
|
$

___

But.

 - If I copy (manual inline) `init_x` code inside `foo`, the warning goes
away.
 - If I use pointers instead of double pointers (`void init_x(int cond, int *x,
int y)`), the warning goes away.

[Bug c/94746] New: -Wsizeof-pointer-div not triggered by system header macros

2020-04-24 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94746

Bug ID: 94746
   Summary: -Wsizeof-pointer-div not triggered by system header
macros
   Product: gcc
   Version: 9.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

I found out that the macro `#define __arraycount(__x) (sizeof(__x) /
sizeof(__x[0]))` which is in libbsd's  doesn't trigger any warning
when applied to a pointer.

I investigated the reason, and I found out that my own `#define ARRAY_SIZE(arr)
(sizeof(arr) / sizeof((arr)[0]))` doesn't trigger any warnings either (it is
installed in `/usr/local/include/`, but it does trigger warnings when compiling
before installing it.

So I came to the conclusion that the bug is the following:

GCC suppresses warnings in system headers, which of course is a generally good
thing, but in this case it is not a good thing.

Maybe a solution would be to not suppress warnings about macros defined in
system headers (this might suddenly trigger lots of warnings, some of them
maybe unwanted, I don't know).  There might be more bugs like this one being
ignored.

Code to reproduce the bug:

#include 

int main(void)
{
int *p;

return  __arraycount(p);
}

Minimum compilation settings to reproduce the bug:

$ gcc -Wsizeof-pointer-div bug.c `pkg-config --cflags libbsd-overlay`

[Bug c/91107] __attribute__((pure)) to function with non-const pointers

2019-07-08 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91107

--- Comment #2 from Alejandro Colomar  ---
Technically it can modify globals as long as that doesn't affect the state of
the program, but in this case it is affecting the state of the program, so it
isn't a pure function.

Fair enough, then the bug claim is that GCC shouldn't allow functions accepting
non-const pointers.

--- Comment #3 from Alejandro Colomar  ---
Technically it can modify globals as long as that doesn't affect the state of
the program, but in this case it is affecting the state of the program, so it
isn't a pure function.

Fair enough, then the bug claim is that GCC shouldn't allow functions accepting
non-const pointers.

[Bug c/91107] __attribute__((pure)) to function with non-const pointers

2019-07-08 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91107

--- Comment #2 from Alejandro Colomar  ---
Technically it can modify globals as long as that doesn't affect the state of
the program, but in this case it is affecting the state of the program, so it
isn't a pure function.

Fair enough, then the bug claim is that GCC shouldn't allow functions accepting
non-const pointers.

--- Comment #3 from Alejandro Colomar  ---
Technically it can modify globals as long as that doesn't affect the state of
the program, but in this case it is affecting the state of the program, so it
isn't a pure function.

Fair enough, then the bug claim is that GCC shouldn't allow functions accepting
non-const pointers.

[Bug c/91107] New: __attribute__((pure)) to function with non-const pointers

2019-07-07 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91107

Bug ID: 91107
   Summary: __attribute__((pure)) to function with non-const
pointers
   Product: gcc
   Version: 8.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: colomar.6.4.3 at gmail dot com
  Target Milestone: ---

I have a function that takes two arrays and writes into a third array the
result of a pure function (c_i = a_i / b_i):

inline
voidarray_division  (ptrdiff_t nmemb,
 double dest[static nmemb],
 const double src1[static nmemb],
 const double src2[static nmemb])
__attribute__((nonnull, pure));

inline
voidarray_division  (ptrdiff_t nmemb,
 double dest[static nmemb],
 const double src1[static nmemb],
 const double src2[static nmemb])
{

for (ptrdiff_t i = 0; i < nmemb; i++)
dest[i] = src1[i] / src2[i];
}

Given that it works with full arrays instead of single variables, I can't just
return the output, and therefore need to modify the array through a pointer,
which goes against what a pure function is by the docs.

However, I think it is still as valid as any other pure function to be
optimized as a pure function.

A pure function is one that acts as a function of its parameters, and the
values pointed to by those parameters; and if none of the parameters, nor the
values pointed to by them, change between two calls, they should be redundant
and the call can be omitted, evaluating to the same value returned by the
previous call.

This function follows all those rules: If none of the 3 arrays change between
two function calls, the function call can be completely removed; and they
evaluate to the same value (which is none, because it's void).

Am I right in thinking that GCC should allow this usage of
__attibute__((pure))?

Or is there any optimization achieved by pure that would be defeated by this
function?


Btw, I tricked GCC into accepting to compile this code just by adding a dummy
`return 0;`.  Is that safe, or is the optimization likely to produce broken
code?


If this function is finally accepted as a pure function, pure should be
accepted to be used in a void function, and accept non-const parameters, but if
not, I think there's no reason at all to allow non-const pointers, and should
probably be banned.

[Bug tree-optimization/10980] vararg functions are not inlined

2019-07-04 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10980

Alejandro Colomar  changed:

   What|Removed |Added

 CC||colomar.6.4.3 at gmail dot com

--- Comment #13 from Alejandro Colomar  ---
static inline void TELL(const char *fmt, ...)
__attribute__((format(printf, 1, 2), always_inline));

static inline void TELL(const char *fmt, ...)
{
va_list ap;

va_start(ap,fmt);
vsyslog(LOG_NOTICE,_(fmt),ap);
va_end(ap);
}


The compiler should be able to see that it is a varargs
function with printf-like format, and that the only reason
for `va_list` to exist is to pass the varargs and not to use
them.

It is trivial to see that an inlined version would be
simplified to a call to `syslog`.

Example:

void foo(void)
{
char *world = "world";
char newline = '\n';

TELL("Hello %s%c%c", world, '!', newline);
}

could be inlined to the following code:

void foo(void)
{
char *world = "world";
char newline = '\n';

syslog(LOG_NOTICE, "Hello %s%c%c", world, '!', newline);
}


The same should happen with `vprintf`->`printf` and all those
families of functions.

[Bug c/80354] Poor support to silence -Wformat-truncation=1

2019-01-06 Thread colomar.6.4.3 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80354

Alejandro Colomar  changed:

   What|Removed |Added

 CC||colomar.6.4.3 at gmail dot com

--- Comment #10 from Alejandro Colomar  ---
In some cases, that warning saved me from writing dangerous code (using file
paths), and it's been very useful.  But casting to void means one and only one
thing:  _I DO know what I'm doing and I do NOT care, so STFU!_
And if the casting to void is dangerous (ie. casting to void the result of
storing a path), that's my fault.

I currently have a program where I want, for some reason, to truncate the
output to an 80-char line:


#include 

#define LINE_SIZE   (80)

int main(int argc, char *argv[])
{
chartruncated[LINE_SIZE];

(void)snprintf(truncated, LINE_SIZE, "I DO want to truncate this line "
"to a 80 char line, and discard any remaining text so "
"that it is not displayed or stored anywhere because I
"
"don't care about it. "
" Usually one would check for the return value of "
"snprintf, but in this precise situation, I do not "
"care about it, so the explicit cast to (void) should "
"silence the warning, just like it does in other "
"warnings such as -Wunused-variable.");

printf("%s\n", truncated);

return 0;
}


But in the same project I have paths and that kind of uses of snprintf where I
still want to have the warnings enabled (and even more, -Werror so that they
never compile):


if (snprintf(file_name, FILENAME_MAX, "%s/%s", file_path, saved_name))
{
goto err_path;
}


Many other warnings are supressed with (void), why is this one so special?


Anyways, I'm reporting a new bug, because this one is "RESOLVED INVALID".