<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">