Skip to content

Commit 0851d7b

Browse files
authored
[clang][analyzer] use unqualified canonical type during merging equivalence class (#95729)
Fixes: #95658 Unqualified canonical type should be used instead of normal QualType for type equality comparison
1 parent 964c92d commit 0851d7b

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2333,7 +2333,8 @@ inline ProgramStateRef EquivalenceClass::merge(RangeSet::Factory &F,
23332333
//
23342334
// The moment we introduce symbolic casts, this restriction can be
23352335
// lifted.
2336-
if (getType() != Other.getType())
2336+
if (getType()->getCanonicalTypeUnqualified() !=
2337+
Other.getType()->getCanonicalTypeUnqualified())
23372338
return State;
23382339

23392340
SymbolSet Members = getClassMembers(State);

clang/test/Analysis/equality_tracking.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,22 @@ void zeroImpliesEquality(int a, int b) {
2828
clang_analyzer_eval(b != a); // expected-warning{{TRUE}}
2929
}
3030

31+
typedef int I32_A;
32+
typedef int I32_B;
33+
void zeroImpliesEqualityWithTypedef(I32_A a, I32_B b) {
34+
clang_analyzer_eval((a - b) == 0); // expected-warning{{UNKNOWN}}
35+
if ((a - b) == 0) {
36+
clang_analyzer_eval(b != a); // expected-warning{{FALSE}}
37+
clang_analyzer_eval(b == a); // expected-warning{{TRUE}}
38+
clang_analyzer_eval(!(a != b)); // expected-warning{{TRUE}}
39+
clang_analyzer_eval(!(b == a)); // expected-warning{{FALSE}}
40+
return;
41+
}
42+
clang_analyzer_eval((a - b) == 0); // expected-warning{{FALSE}}
43+
clang_analyzer_eval(b == a); // expected-warning{{FALSE}}
44+
clang_analyzer_eval(b != a); // expected-warning{{TRUE}}
45+
}
46+
3147
void zeroImpliesReversedEqual(int a, int b) {
3248
clang_analyzer_eval((b - a) == 0); // expected-warning{{UNKNOWN}}
3349
if ((b - a) == 0) {

clang/test/Analysis/errno-stdlibraryfunctions.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,30 @@ void errno_mkdtemp(char *template) {
7575
}
7676
}
7777

78+
typedef char* CHAR_PTR;
79+
void errno_mkdtemp2(CHAR_PTR template) {
80+
CHAR_PTR Dir = mkdtemp(template);
81+
if (Dir == NULL) {
82+
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
83+
if (errno) {} // no warning
84+
} else {
85+
clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
86+
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
87+
}
88+
}
89+
90+
typedef char const* CONST_CHAR_PTR;
91+
void errno_mkdtemp3(CHAR_PTR template) {
92+
CONST_CHAR_PTR Dir = mkdtemp(template);
93+
if (Dir == NULL) {
94+
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
95+
if (errno) {} // no warning
96+
} else {
97+
clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
98+
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
99+
}
100+
}
101+
78102
void errno_getcwd(char *Buf, size_t Sz) {
79103
char *Path = getcwd(Buf, Sz);
80104
if (Sz == 0) {

0 commit comments

Comments
 (0)