Geoffrey1014/SA_Bugs

CSA dose not realize that `( ((void *)0) + 0 ) < ( ((void *)0) + 1 )` is true

Opened this issue · 4 comments

date: 2023-1-5
commit: 0c0681b7414c385d0fd5fad302c0d48607262050
args: --analyze -Xclang -analyzer-stats -Xclang -analyzer-constraints=range -Xclang -setup-static-analyzer -Xclang -analyzer-config -Xclang eagerly-assume=false -Xclang -analyzer-checker=core,debug.ExprInspection
test:

#include "stdio.h"
#include <stdint.h>
#include <stdbool.h>
void clang_analyzer_eval(int);


int foo(int a, int b) {

     if ((( (void*)0) == (void*)0)){
        //fact
        clang_analyzer_eval((( (void *)0) == (void *)0)==true);
        clang_analyzer_eval(((( (void *)0))!=((void *)0))==false);
        clang_analyzer_eval(((( (void *)0))+0)==(((void *)0)+0));

        clang_analyzer_eval(((( (void *)0))+0)<(((void *)0)+1));
        clang_analyzer_eval(((( (void *)0))-1)>(((void *)0)-0)); 
    

    }
}

report: llvm/llvm-project#59856
fix:
original:

Hi, I found a problem that CSA dose not realize that both ( ((void *)0) + 0 ) < ( ((void *)0) + 1 ) and ( ((void *)0) - 1 ) < ( ((void *)0) - 0 ) are true. These two expressions' compilation and running results are both true.

https://godbolt.org/z/os7d8MMWd

Input:

#include "stdio.h"
#include <stdint.h>
#include <stdbool.h>
void clang_analyzer_eval(int);


int foo(int a, int b) {

        clang_analyzer_eval((( (void *)0) == (void *)0)==true);
        clang_analyzer_eval(((( (void *)0))!=((void *)0))==false);
        clang_analyzer_eval(((( (void *)0))+0)==(((void *)0)+0));

        clang_analyzer_eval(((( (void *)0))+0)<(((void *)0)+1));
        clang_analyzer_eval(((( (void *)0))-1)>(((void *)0)-0)); 
    
}

Output:

<source>:9:9: warning: TRUE [debug.ExprInspection]
        clang_analyzer_eval((( (void *)0) == (void *)0)==true);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:10:9: warning: TRUE [debug.ExprInspection]
        clang_analyzer_eval(((( (void *)0))!=((void *)0))==false);
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:11:9: warning: TRUE [debug.ExprInspection]
        clang_analyzer_eval(((( (void *)0))+0)==(((void *)0)+0));
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:13:9: warning: FALSE [debug.ExprInspection]
        clang_analyzer_eval(((( (void *)0))+0)<(((void *)0)+1));
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:14:9: warning: FALSE [debug.ExprInspection]
        clang_analyzer_eval(((( (void *)0))-1)>(((void *)0)-0)); 
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
===-------------------------------------------------------------------------===
                                Analyzer timers
===-------------------------------------------------------------------------===
  Total Execution Time: 0.0016 seconds (0.0077 wall clock)

   ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
   0.0000 (  0.0%)   0.0010 ( 67.6%)   0.0010 ( 63.3%)   0.0049 ( 63.4%)  Path exploration time
   0.0001 (100.0%)   0.0002 ( 13.7%)   0.0003 ( 19.2%)   0.0025 ( 32.9%)  Syntax-based analysis time
   0.0000 (  0.0%)   0.0003 ( 18.7%)   0.0003 ( 17.5%)   0.0003 (  3.7%)  Path-sensitive report post-processing time
   0.0001 (100.0%)   0.0015 (100.0%)   0.0016 (100.0%)   0.0077 (100.0%)  Total

5 warnings generated.
Compiler returned: 0

Compiled and run:
image

A CSA developer says "This is a result of a very ugly hack we have from the early days to assist null pointer dereference analysis", which probably means they can not fix it soon.