[go: nahoru, domu]

Bug 113984 - -Wfree-nonheap-object false positive with VLA parameter that has a size which is not a simple decl
Summary: -Wfree-nonheap-object false positive with VLA parameter that has a size which...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 13.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wfree-nonheap-object
  Show dependency treegraph
 
Reported: 2024-02-19 00:03 UTC by Alejandro Colomar
Modified: 2024-02-19 03:02 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-02-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alejandro Colomar 2024-02-19 00:03:06 UTC
I can reproduce it with both of these:

$ gcc-13 --version | head -n1
gcc-13 (Debian 13.2.0-13) 13.2.0
$ gcc-14 --version | head -n1
gcc-14 (Debian 14-20240201-3) 14.0.1 20240131 (experimental) [master r14-8680-g2f14c0dbb78]


See a small reproducer:


```c
#include <err.h>
#include <stddef.h>
#include <stdlib.h>


static const char **add_string(size_t *restrict n,
    const char *strings[restrict *n], const char *restrict string);


int
main(int argc, char *argv[argc + 1])
{
	size_t      n = 0;
	const char  **strings = NULL;

	add_string(&n, strings, argv[0]);
}


static const char **
add_string(size_t *restrict n, const char *strings[restrict *n],
    const char *restrict string)
{
	strings = reallocarray(strings, ++*n, sizeof(const char *));
	if (strings == NULL)
		err(EXIT_FAILURE, "reallocarray(3)");

	strings[*n - 1] = string;

	return strings;
}
```


alx@debian:~/tmp$ gcc-13 -Wall nonheap.c 
nonheap.c: In function ‘add_string’:
nonheap.c:24:19: warning: ‘reallocarray’ called on unallocated object ‘strings’ [-Wfree-nonheap-object]
   24 |         strings = reallocarray(strings, ++*n, sizeof(const char *));
      |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nonheap.c:21:44: note: declared here
   21 | add_string(size_t *restrict n, const char *strings[restrict *n],
      |                                ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
alx@debian:~/tmp$ gcc-14 -Wall nonheap.c 
nonheap.c: In function ‘add_string’:
nonheap.c:24:19: warning: ‘reallocarray’ called on unallocated object ‘strings’ [-Wfree-nonheap-object]
   24 |         strings = reallocarray(strings, ++*n, sizeof(const char *));
      |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nonheap.c:21:44: note: declared here
   21 | add_string(size_t *restrict n, const char *strings[restrict *n],
      |                                ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~


If I change the function to have the parameter be `const char **restrict strings`, the warning vanishes.
Comment 1 Alejandro Colomar 2024-02-19 00:05:18 UTC
With -O3, the warning also vanishes, as the function is probably inlined, and there's no VLA parameter any more.

alx@debian:~/tmp$ gcc-14 -Wall -O3 nonheap.c 
alx@debian:~/tmp$ gcc-13 -Wall -O3 nonheap.c 
alx@debian:~/tmp$
Comment 2 Andrew Pinski 2024-02-19 00:19:39 UTC
Confirmed, reduced testcase:
```
const char **
add_string(int *restrict n, const char *strings[restrict *n])
{
  strings = __builtin_realloc(strings, *n);
  if (!strings)
    return 0;
  return strings;
}
```

Note if we had `int n` instead of a pointer, then there would be no warning.
Comment 3 Andrew Pinski 2024-02-19 00:20:57 UTC
Another testcase:
```
struct a
{
  int n;
};
const char **
add_string(struct a n, const char *strings[restrict n.n])
{
  strings = __builtin_realloc(strings, n.n);
  if (!strings)
    return 0;
  return strings;
}
```