<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/122403>122403</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang] unexpected result of comparsion between unknownSpaceRegion and stackSpaceRegion
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          mzyKi
      </td>
    </tr>
</table>

<pre>
    I ran clang-analyzer-unix.Stream on the following testcase

```c
#include <stdio.h>
char *get_str(char *Input);

void check_f_leak() {
  FILE *fp = fopen("test", "rb");
  if (NULL == fp) {
    return;
  }
  char str[64];
  if (get_str(str) != str) {
    fclose(fp);
  }
}
```
It show no warning and if I change the testcase like this:

```c
#include <stdio.h>
char *get_str(char *Input);

void check_f_leak_2() {
  FILE *fp = fopen("test", "rb");
  if (NULL == fp) {
    return;
  }
  char str[64];
  if (get_str(str) != NULL) {
    fclose(fp);
  }
}
```
It will show:
```bash
/Workspace/test.c:24:1: warning: Opened stream never closed. Potential resource leak [clang-analyzer-unix.Stream]
   24 | }
      | ^
/Workspace/test.c:16:14: note: Stream opened here
   16 |   FILE *fp = fopen("test", "rb");
      |              ^~~~~~~~~~~~~~~~~~~
/Workspace/test.c:17:15: note: 'fp' is not equal to NULL
   17 |   if (NULL == fp) {
      |               ^~
/Workspace/test.c:17:3: note: Taking false branch
   17 |   if (NULL == fp) {
      |   ^
/Workspace/test.c:21:7: note: Assuming the condition is false
   21 |   if (get_str(str) != NULL) {
      |       ^~~~~~~~~~~~~~~~~~~~
/Workspace/test.c:21:3: note: Taking false branch
   21 |   if (get_str(str) != NULL) {
      |   ^
/Workspace/test.c:24:1: note: Opened stream never closed. Potential resource leak
   24 | }
      | ^
```
In my expectation,the first case should be the same as the second case and branch in the if statement.If we don't know the definition of `get_str`,we should not know the result of `get_str(str) != NULL` and it shall be an `unknownval`.  
After,I used `lldb` to track the cause of this phenomenon, I found the result value of comparison is bound in SimpleSValBuilder.cpp:958
```cpp
    if (LeftMS != RightMS &&
        ((LeftMS != UnknownMS && RightMS != UnknownMS) ||
         (isa<StackSpaceRegion>(LeftMS) || isa<StackSpaceRegion>(RightMS)))) {
      switch (op) {
      default:
        return UnknownVal();
      case BO_EQ:
        return makeTruthVal(false, resultTy);
      case BO_NE:
        return makeTruthVal(true, resultTy);
      }
    }
```
I think ```LeftMS != UnknownMS && RightMS != UnknownMS``` seems to have some logic error.About the expression`get_str(str) != str`, I dump `LeftMS` is `UnknownSpaceRegion` and `RightMS` is `StackLocalSpaceRegion`. But `LeftMS != UnknownMS ` is `false`.**I am not sure whether this s as expected.**

In my later PR, I fix false negative in first case. But I still have question about `LeftMS != UnknownMS && RightMS != UnknownMS`, I‘d really appreciate any suggestion from anyone familiar with this.




</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUV19v4joW_zTm5agoOEDggQdKQULbvffudO7dx8okJ8SLY2dsB9p52M--OnZCYabTqTrSShdZgYTz5-fzO38c4Zzca8QFm9yyyd1AtL4ydlF_ff6HHOxM8bzYghUaciX0_kZooZ6_or1ptXwaPniLogajwVcIpVHKnKTeg0fnc-GQJUta0ySunG54KnWu2gKBpSvnC2mGFUvXLFnmlbDA-HKP_tF5y_isf7LVTesZn7P0Npo8GllAXmF-eCwfFYoD4zPG58AyEgDYbO_XpFg2wNI7KE2DOohwgsY4Z3wFjHO7C787wwCyBMZnv_15f096QbW5tAtg0bdW9_IsuwvfAShhntxOx2xyd23vZUPhOgfGR2S7vzsbL3NlHDI-C16vnXTXPpYsWW49uMqcQBs4Casp8EIX5HNLgPQeAy09GaDkgZ5Ix9Ll_4-ZR_635Ib8_CI5J6lUYKiLd__vTrgqxHvzb2MPrhE5Mr6hzQ9zli75mKXLEUuXPav08_cGNRa0DSo4jUe0EPAUQ_jDeNReCgUWnWltjkCBBza5_XHRUiDCvvgYWLY6R4s-4X6yfgPjaEoXAgraeKTvvhdEoBVajPZG02Dv47z3iK4-bLL-73eftwBndJlcAmY8IyYzkI6eAX5phQJvIvURe9Z5_nnuvYIxgPwZpvQS0mdxoCouhXIIOyt0Xn0YyNsEUpIvs0vfS-faOjTvCiE3upBeGk3BCXC6ZBld4Xh_8VyG51Xu3gpUAPu-QP0ywJ-E7VybPZIPFOZ76u6yk2ionwGfGsy9IE4YX4VxK63zEDq7q0yrCtjFhu9EjSBc_I1EZZSi4RBjBTJObFmC88JjjdoPtyWcEAqyn3k4aHMKMgWWUsdcMCWwadLHdJowvjqdnVMJnZUsulb5bxReJWGaxKFFs0woRXsQmrRaTdb0USg2TYYALFkuS4-W8dUWWocFCSlV7MiEN-CtyA8xeUXrkHzTrIOmQm1q1CFusIXStLq4BHkUqg3iuakbYaWLWb8LclLDg6wbhQ9_CXXbSlWgHeZNw9LlfDK7GqFN0xEZU-8eS__Ph36vn-S-irdTWj3jAKEDfiP8Z9z6WfxC-_r_mMIrWi8WyaR0gqWrBy_ywwPl8CfcU-Kk67OvF1V4S7jzTO24X1dF407S5xW5NN_1oQJL0Sofp18PLs7ofgt_CRVPB5fNPiTr7e-P63-9qlqLA362ra-icuxOfNXR-fn5B9Z-W7_HmrftW8ZeqvWViU_5pg9wfvZRUnt9cIi1o9yuxBHBmRpBmb3MAa01drjcmdaHTManxqJzxNqPy-1cs7CFoq0bOEMkX9LRfQfiMg26AmXTpM-Fs3RImXuTC3WtMITb1sNbETibiOxNkyHjSzpOAjVR48G1FuFUoa_Qxjp21NJiF8SiE49HztgglfBo4Y9PXZXLp246aNwLL49IpfzSMiPELThPh7QQ3y8tutDmRIjrrxFIINias1nC5rMCLAqlnkE0jcVcCk9N7hlcu993PktranpmNEIpaqmksHCSvgqbH3bH9bAGxSIt5ulcDHAxytLpOBsnyXhQLbJRUZY7keF4no925SxHXsyyLOM8yeZiOhrIBU_4JBmNkmQ0Sfl4OOIiS2b5DuflNBuPUzZOsBZSDZU61kNj9wPpXIuLEefjJB0osUPlwosi5-FoSSe1yd3ALkjhZtfuHRsnSjrvXkx46VV4u4wakztodc_jxaCI3ZdyGHboT4ga2u-yMaSi-6ZTDVqrFpX3TXix4RvGN3vpq3Y3zE3N-IaQdF83jTX_wdwzvgk7c4xvus0dF_x_AQAA___oAW7q">