Geoffrey1014 / SA_Bugs

record bugs of static analyzers
3 stars 1 forks source link

GSA evaluates __analyzer_eval(((a())<(0))||((a())==(0))); to be TRUE, but function a() is a unknown function #64

Open Geoffrey1014 opened 1 year ago

Geoffrey1014 commented 1 year ago

date: 2023-1-10 commit: args: -fanalyzer -O0 test:

#include "stdint.h"
#include <stdbool.h>
int a(); 

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

report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109196 fix: original:

Geoffrey1014 commented 1 year ago

GSA evaluates __analyzer_eval(((a())<(0))||((a())==(0))); to be TRUE, but function a() is a unknown function.

But if I delete for(;;), every evaluation expression is evaluated to be UNKNOWN.

See it live: https://godbolt.org/z/7e5bKdvde , https://godbolt.org/z/sj4bq4Krx

Input:

#include "stdint.h"
#include <stdbool.h>
int a(); 

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

Output:

<source>: In function 'b':
<source>:9:7: warning: UNKNOWN
    9 |       __analyzer_eval((a() <= 0)==true);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:10:7: warning: TRUE
   10 |       __analyzer_eval(((a())<(0))||((a())==(0)));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:11:7: warning: UNKNOWN
   11 |       __analyzer_eval(((a())+0)<=((0)+0));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:12:7: warning: UNKNOWN
   12 |       __analyzer_eval(((a())+0)<=((0)+1));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:13:7: warning: UNKNOWN
   13 |       __analyzer_eval(((a())+1)<=((0)+1));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:14:7: warning: UNKNOWN
   14 |       __analyzer_eval(((a())+0)<=((0)+2));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:15:7: warning: UNKNOWN
   15 |       __analyzer_eval(((a())+1)<=((0)+2));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:7: warning: UNKNOWN
   16 |       __analyzer_eval(((a())+2)<=((0)+2));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:17:7: warning: UNKNOWN
   17 |       __analyzer_eval(((a())-0)<=((0)-0));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:18:7: warning: UNKNOWN
   18 |       __analyzer_eval((!(a() <= 0))==false);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:7: warning: FALSE
   19 |       __analyzer_eval((((a())>=(0))&&((a())!=(0)))==false);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:20:7: warning: TRUE
   20 |       __analyzer_eval(true);
      |       ^~~~~~~~~~~~~~~~~~~~~
<source>:10:7: warning: UNKNOWN
   10 |       __analyzer_eval(((a())<(0))||((a())==(0)));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:11:7: warning: UNKNOWN
   11 |       __analyzer_eval(((a())+0)<=((0)+0));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:12:7: warning: UNKNOWN
   12 |       __analyzer_eval(((a())+0)<=((0)+1));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:13:7: warning: UNKNOWN
   13 |       __analyzer_eval(((a())+1)<=((0)+1));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:14:7: warning: UNKNOWN
   14 |       __analyzer_eval(((a())+0)<=((0)+2));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:15:7: warning: UNKNOWN
   15 |       __analyzer_eval(((a())+1)<=((0)+2));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:16:7: warning: UNKNOWN
   16 |       __analyzer_eval(((a())+2)<=((0)+2));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:17:7: warning: UNKNOWN
   17 |       __analyzer_eval(((a())-0)<=((0)-0));
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:18:7: warning: UNKNOWN
   18 |       __analyzer_eval((!(a() <= 0))==false);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:19:7: warning: UNKNOWN
   19 |       __analyzer_eval((((a())>=(0))&&((a())!=(0)))==false);
      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>:20:7: warning: TRUE
   20 |       __analyzer_eval(true);
      |       ^~~~~~~~~~~~~~~~~~~~~
Compiler returned: 0
ghost commented 1 year ago

CSA clang_analyzer_eval(((a())<(0))||((a())==(0))); is True and False. It is right. See it live: https://godbolt.org/z/Tavqj1sMh.