| Issue |
178702
|
| Summary |
clang reports _Generic type coersion as passing NULL to strlen
|
| Labels |
clang
|
| Assignees |
|
| Reporter |
aalmkainzi
|
Given this code:
```C
#include <stdio.h>
#include <string.h>
struct MyString
{
char *chars;
size_t len;
};
#define coerce_type(x, ty) \
_Generic(x, ty: x, default: (ty){})
#define slen(s) \
_Generic(s, \
char*: strlen(coerce_type(s, char*)), \
struct MyString: coerce_type(s, struct MyString).len \
)
int main()
{
struct MyString ms = {"123", 3};
size_t i = slen(ms);
size_t i2 = slen("4567");
printf("%zu %zu", i, i2);
}
```
Which is a common technique when using `_Generic` to make sure all branches are valid expressions.
Clang generates the following reports:
```console
<source>:22:16: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
22 | size_t i = slen(ms);
| ^~~~~~~~
<source>:15:19: note: expanded from macro 'slen'
15 | char*: strlen(coerce_type(s, char*)), \
| ^~~~~~~~~~~~~~~~~~~~~
<source>:10:28: note: expanded from macro 'coerce_type'
10 | #define coerce_type(x, ty) \
| ^
11 | _Generic(x, ty: x, default: (ty){})
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
```
In reality, the _expression_ `strlen((ty){})` (which expands to `strlen((char*){})` aka `strlen(NULL)`) will never be the result of the `_Generic` when passing a `struct MyString`.
[Godbolt link](https://godbolt.org/z/13dKnWTET)
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs