[cfe-dev] Static Analyzer and signed 64bit constraints
- yrp via cfe-dev
cfe-dev at lists.llvm.org
Mon Jan 29 21:28:05 PST 2018
Hi Artem,
Thanks for the reply and info. After minimizing it appears this is related to sizeof + 64bit perhaps? I had to modify your testcase slightly to demonstrate the behavior Im seeing:
#include <stdlib.h>
#include <stdio.h>
void foo(void) {
int64_t z = -1;
read(1, &z, sizeof(z));
char x[20] = { 0 };
char y[20] = { 0 };
// if (z > 20)
if (z > sizeof x)
exit(-1);
memcpy(x, y, z);
// triggers state dump via ExprInspection
clang_analyzer_printState();
// don't garbage-collect 'z' until now
z;
}
$ clang --analyze test.c -Xclang -analyzer-checker -Xclang debug.ExprInspection
...
conj_$0{int64_t} : { [1, 20] }
If I change the type of 'z' to int32_t I get:
conj_$0{int32_t} : { [-2147483648, -1], [1, 20] }
If I change the if guard on 'z' to the literal '20' and keep the type as int64_t I get the expected range:
conj_$0{int64_t} : { [-9223372036854775808, -1], [1, 20] }
Have I misunderstood some C behavior regarding sizeof and this is expected? I'll feel pretty silly if this is the case...
In case it's relevant: clang version 6.0.0 (trunk 318002) running on linux
Cheers!
yrp
On Monday, January 29, 2018, 6:18:51 PM PST, Artem Dergachev <noqnoqneo at gmail.com> wrote:
> The constraint on the above value is printed as 'conj_$0{int32_t} : {
[-2147483648, -1], [1, 20] }'. What happened to zero? My best guess is
the static analyzer realizing that 'memcpy(x, y, 0)' is a nop and
pruning that program state?
Yes, indeed, it is an effect of how we model 'memcpy'. I don't think
it's the desired behavior though. In particular, we don't display a
warning on 'memcpy(NULL, y, 0)', even though it's UB. So, yeah, sounds
like either a minor bug. It's not obvious for me how often paths with
zero-size memcpys are actually feasible in real-world programs.
> However, if I switch this to an int64_t I get:
> conj_$0{int64_t} : { [1, 20] }
Hmm, weird, i'm not able to reproduce it. Could you provide more info?
I'm trying:
$ cat test.c
#include <stdlib.h>
#include <stdio.h>
void foo(void *x, void *y) {
int64_t z = -1;
read(1, &z, sizeof(z));
if (z > 20)
exit(-1);
memcpy(x, y, z);
// triggers state dump via ExprInspection
clang_analyzer_printState();
// don't garbage-collect 'z' until now
z;
}
$ clang --analyze test.c -Xclang -analyzer-checker -Xclang
debug.ExprInspection
Store (direct and default bindings), 0x7fcf3114a5e8 :
(z,0,direct) : conj_$0{int64_t}
(GlobalInternalSpaceRegion,0,default) : conj_$1{int}
(GlobalSystemSpaceRegion,0,default) : conj_$2{int}
Expressions:
(0x7fcf30579920,0x7fcf3113c0c0) clang_analyzer_printState :
&code{clang_analyzer_printState}
Ranges of symbol values:
conj_$0{int64_t} : { [-9223372036854775808, -1], [1, 20] }
On 29/01/2018 12:25 AM, - yrp via cfe-dev wrote:
> Hello,
>
> I'm attempting to write a checker to look for certain signedness
> issues. I have code similar to the following:
>
> int32_t z = -1;
> read (STDIN_FILENO, &z, sizeof(z));
>
> if (z > 20) exit (EXIT_FAILURE);
>
> memcpy (x, y, z);
>
> Inside the checker I am printing the constraints on the SVal 'z' with
> a PreCall, filtering on memcpy:
>
> ProgramStateRef State = C.getState();
> State->getConstraintManager().print(State, llvm::outs(), "\n", " ");
>
> I have two questions related to this:
>
> 1. The constraint on the above value is printed as 'conj_$0{int32_t} :
> { [-2147483648, -1], [1, 20] }'. What happened to zero? My best guess
> is the static analyzer realizing that 'memcpy(x, y, 0)' is a nop and
> pruning that program state?
>
> 2. The above code, aside from the zero exception, makes sense when z
> is an int8_t, int16_t, or an int32_t:
>
> conj_$0{int8_t} : { [-128, -1], [1, 20] }
> conj_$0{int16_t} : { [-32768, -1], [1, 20] }
> conj_$0{int32_t} : { [-2147483648, -1], [1, 20] }
>
> However, if I switch this to an int64_t I get:
>
> conj_$0{int64_t} : { [1, 20] }
>
> What happened to all the negative numbers?
>
> Apologies if I've missed something obvious.
>
> Cheers!
> -yrp
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
More information about the cfe-dev
mailing list