[cfe-dev] Unexpected warning (confused by non-zero safemalloc?)

Eli Friedman eli.friedman at gmail.com
Mon Jul 8 14:11:06 PDT 2013


On Fri, Jul 5, 2013 at 5:23 PM,  <solo-clang at goeswhere.com> wrote:
> I have:
>
> $ clang --version
> Debian clang version 3.4-1~exp1 (trunk) (based on LLVM 3.4)
> Target: x86_64-pc-linux-gnu
> Thread model: posix
>
>  *** 1:3.4~svn185715-1~exp1 0
>    500 http://llvm.org/apt/wheezy/ llvm-toolchain-wheezy/main amd64 Packages
>
> ..and I'm trying to compile:
>
> #include <stdint.h>
> #include <string.h>
> #include <stdlib.h>
>
> void *smalloc(size_t size) {
>     if (size == 0) {
>         return malloc(1);
>     } else {
>         return malloc(size);
>     }
> }
>
> char *dupstr(const char *s) {
>     const int len = strlen(s);
>     char *p = smalloc(len + 1);
>     strcpy(p, s);
>     return p;
> }
>
> I get:
>
> $ clang -Weverything --analyze -c misc.c
> misc.c:16:5: warning: String copy function overflows destination buffer
>     strcpy(p, s);
>     ^~~~~~~~~~~~
> 1 warning generated.
>
> It appears to be confused by the presence of that "if (size == 0)"
> block in smalloc.  Basically any change to this code removes the warning,
> although size <= 1 leaves it.
>
> Is this a bug, or did I do something silly?

Well, the assignment from a size_t into an int is silly... but there's
still an issue reported even if you fix that.

The analyzer sees two paths here: one where strlen(s)+1 == 0, and one
where strlen(s)+1 != 0.  On the strlen(s)+1 == 0 path, you're copying
a string of length SIZE_MAX into a buffer of length 1, an overflow.

Of course, strlen(s) == SIZE_MAX is impossible because s would cover
the entire address-space... so it's possible the analyzer should be a
bit smarter here.

-Eli



More information about the cfe-dev mailing list