Geoffrey1014 / SA_Bugs

record bugs of static analyzers
3 stars 1 forks source link

CSA evaluates `clang_analyzer_eval(((a())<(0))||((a())==(0)));` to be TRUE, but function `a()` is a unknown function. #36

Open Geoffrey1014 opened 1 year ago

Geoffrey1014 commented 1 year ago

date: 2023-1-10 commit: args: --analyze -Xclang -analyzer-stats -Xclang -analyzer-checker=core,debug.ExprInspection test:

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

uint16_t b() {
  for (;;)
    if (a() <= 0) {
      clang_analyzer_eval((a() <= 0)==true);
      clang_analyzer_eval(((a())<(0))||((a())==(0)));
      clang_analyzer_eval(((a())+0)<=((0)+0));
      clang_analyzer_eval(((a())+0)<=((0)+1));
      clang_analyzer_eval(((a())+1)<=((0)+1));
      clang_analyzer_eval(((a())+0)<=((0)+2));
      clang_analyzer_eval(((a())+1)<=((0)+2));
      clang_analyzer_eval(((a())+2)<=((0)+2));
      clang_analyzer_eval(((a())-0)<=((0)-0));
      clang_analyzer_eval((!(a() <= 0))==false);
      clang_analyzer_eval((((a())>=(0))&&((a())!=(0)))==false);
      clang_analyzer_eval(true);
      ;
    }
}

report: https://github.com/llvm/llvm-project/issues/61517 fix: original:

Geoffrey1014 commented 1 year ago

CSA evaluates clang_analyzer_eval(((a())<(0))||((a())==(0))); to be TRUE, but function a() is a unknown function. See it live: https://godbolt.org/z/dYdqG9fzG

Input:

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

uint16_t b() {
  for (;;)
    if (a() <= 0) {
      clang_analyzer_eval((a() <= 0)==true);
      clang_analyzer_eval(((a())<(0))||((a())==(0)));
      clang_analyzer_eval(((a())+0)<=((0)+0));
      clang_analyzer_eval(((a())+0)<=((0)+1));
      clang_analyzer_eval(((a())+1)<=((0)+1));
      clang_analyzer_eval(((a())+0)<=((0)+2));
      clang_analyzer_eval(((a())+1)<=((0)+2));
      clang_analyzer_eval(((a())+2)<=((0)+2));
      clang_analyzer_eval(((a())-0)<=((0)-0));
      clang_analyzer_eval((!(a() <= 0))==false);
      clang_analyzer_eval((((a())>=(0))&&((a())!=(0)))==false);
      clang_analyzer_eval(true);
      ;
    }
}

CSA Output:

<source>:9:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval((a() <= 0)==true);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:10:7: warning: TRUE [debug.ExprInspection]
      clang_analyzer_eval(((a())<(0))||((a())==(0)));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:10:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())<(0))||((a())==(0)));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:11:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())+0)<=((0)+0));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:12:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())+0)<=((0)+1));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:13:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())+1)<=((0)+1));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:14:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())+0)<=((0)+2));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:15:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())+1)<=((0)+2));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())+2)<=((0)+2));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:17:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval(((a())-0)<=((0)-0));
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:18:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval((!(a() <= 0))==false);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:7: warning: TRUE [debug.ExprInspection]
      clang_analyzer_eval((((a())>=(0))&&((a())!=(0)))==false);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:7: warning: UNKNOWN [debug.ExprInspection]
      clang_analyzer_eval((((a())>=(0))&&((a())!=(0)))==false);
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:20:7: warning: TRUE [debug.ExprInspection]
      clang_analyzer_eval(true);
Geoffrey1014 commented 1 year ago

Maybe CSA actually does a better job. Becuase SA does not know what int a(); returns and whether int a(); 's return changes.

Geoffrey1014 commented 1 year ago

GSA does a better job : https://godbolt.org/z/1Gzrd9dEE

Geoffrey1014 commented 1 year ago

reduced cases: GSA : https://godbolt.org/z/6E5xEdsYW CSA: https://godbolt.org/z/oeE5K1zds

ghost commented 1 year ago

GSA can handle: https://godbolt.org/z/EK63MrcjM