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

Reply via email to