<div dir="ltr">The relevant prior art here is -Wsizeof-pointer-memaccess (supported by both GCC and Clang):<div><br></div><div> // <a href="https://godbolt.org/z/ccf3W3dvd">https://godbolt.org/z/ccf3W3dvd</a></div><div> #include <stdlib.h></div><div> #include <string.h></div><div> struct S { void *field; };</div><div> int main() {</div><div> struct S s1;</div><div> struct S *s2 = malloc(sizeof(s2)); // no warning, oops</div><div> memcpy(s2, &s1, sizeof(s2)); // -Wsizeof-pointer-memaccess</div><div> memset(s2, '\0', sizeof(s2)); // -Wsizeof-pointer-memaccess</div><div> }<br></div><div><br></div><div>Both GCC and Clang warn on memcpy and memset, but neither one warns on the original malloc. My guess is that the original malloc is harder, because the relevant relationship is no longer between <i>two arguments to the same call</i>, but rather between the argument and <i>the left-hand side of the assignment where the result is actually used</i>. To me this smells a lot more like "dataflow analysis" than the existing memcpy/memset case does.</div><div>However, if people are interested in pursuing this, I'd definitely recommend looking at -Wsizeof-pointer-memaccess and thinking about how to generalize it beyond argument-argument relationships.</div><div><br></div><div>my $.02,</div><div>–Arthur</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Aug 16, 2021 at 5:51 PM Joerg Sonnenberger via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Mon, Aug 16, 2021 at 05:19:45PM +0000, Leander Besting wrote:<br>
> The following doesn't produce any warnings but I don't know about clang-tidy.<br>
> <br>
> $ clang a.c --analyze --analyzer-output text<br>
> <br>
> // a.c<br>
> #include <stdlib.h><br>
> struct S {<br>
> int x, y, z;<br>
> };<br>
> int main() {<br>
> // sizeof (struct S) == 12<br>
> // sizeof (s) == 8<br>
> struct S *s = malloc(sizeof(struct S) * 2);<br>
> free(s);<br>
> }<br>
<br>
This is fine, because the compiler can statically assert that no<br>
overflow can happen. But the following IMO should have a warning:<br>
<br>
#include <stdlib.h><br>
<br>
struct S {<br>
int x, y, z;<br>
};<br>
<br>
size_t len;<br>
<br>
int main() {<br>
struct S *s = malloc(sizeof(struct S) * len);<br>
free(s);<br>
}<br>
<br>
At least for the static analyzer. It's a very common category of bugs.<br>
<br>
Joerg<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>