-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang][analyzer] use unqualified canonical type during merging equivalence class #95729
[clang][analyzer] use unqualified canonical type during merging equivalence class #95729
Conversation
…alence class Fixes: llvm#95658 Unqualified canonical type should be used instead of normal QualType for type equality comparison
@llvm/pr-subscribers-clang Author: Congcong Cai (HerrCai0907) ChangesFixes: #95658 Full diff: https://github.com/llvm/llvm-project/pull/95729.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index c6f87b45ab887..d8c257dbd731e 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2333,7 +2333,8 @@ inline ProgramStateRef EquivalenceClass::merge(RangeSet::Factory &F,
//
// The moment we introduce symbolic casts, this restriction can be
// lifted.
- if (getType() != Other.getType())
+ if (getType()->getCanonicalTypeUnqualified() !=
+ Other.getType()->getCanonicalTypeUnqualified())
return State;
SymbolSet Members = getClassMembers(State);
diff --git a/clang/test/Analysis/errno-stdlibraryfunctions.c b/clang/test/Analysis/errno-stdlibraryfunctions.c
index a28efb764edfd..657aa37a42670 100644
--- a/clang/test/Analysis/errno-stdlibraryfunctions.c
+++ b/clang/test/Analysis/errno-stdlibraryfunctions.c
@@ -75,6 +75,30 @@ void errno_mkdtemp(char *template) {
}
}
+typedef char* CHAR_PTR;
+void errno_mkdtemp2(CHAR_PTR template) {
+ CHAR_PTR Dir = mkdtemp(template);
+ if (Dir == NULL) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ } else {
+ clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}
+
+typedef char const* CONST_CHAR_PTR;
+void errno_mkdtemp3(CHAR_PTR template) {
+ CONST_CHAR_PTR Dir = mkdtemp(template);
+ if (Dir == NULL) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ } else {
+ clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}
+
void errno_getcwd(char *Buf, size_t Sz) {
char *Path = getcwd(Buf, Sz);
if (Sz == 0) {
|
@llvm/pr-subscribers-clang-static-analyzer-1 Author: Congcong Cai (HerrCai0907) ChangesFixes: #95658 Full diff: https://github.com/llvm/llvm-project/pull/95729.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index c6f87b45ab887..d8c257dbd731e 100644
--- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -2333,7 +2333,8 @@ inline ProgramStateRef EquivalenceClass::merge(RangeSet::Factory &F,
//
// The moment we introduce symbolic casts, this restriction can be
// lifted.
- if (getType() != Other.getType())
+ if (getType()->getCanonicalTypeUnqualified() !=
+ Other.getType()->getCanonicalTypeUnqualified())
return State;
SymbolSet Members = getClassMembers(State);
diff --git a/clang/test/Analysis/errno-stdlibraryfunctions.c b/clang/test/Analysis/errno-stdlibraryfunctions.c
index a28efb764edfd..657aa37a42670 100644
--- a/clang/test/Analysis/errno-stdlibraryfunctions.c
+++ b/clang/test/Analysis/errno-stdlibraryfunctions.c
@@ -75,6 +75,30 @@ void errno_mkdtemp(char *template) {
}
}
+typedef char* CHAR_PTR;
+void errno_mkdtemp2(CHAR_PTR template) {
+ CHAR_PTR Dir = mkdtemp(template);
+ if (Dir == NULL) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ } else {
+ clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}
+
+typedef char const* CONST_CHAR_PTR;
+void errno_mkdtemp3(CHAR_PTR template) {
+ CONST_CHAR_PTR Dir = mkdtemp(template);
+ if (Dir == NULL) {
+ clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
+ if (errno) {} // no warning
+ } else {
+ clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
+ if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
+ }
+}
+
void errno_getcwd(char *Buf, size_t Sz) {
char *Path = getcwd(Buf, Sz);
if (Sz == 0) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome. I have one remark though.
It would be nice to see tests that does not depend on the errno, as this eqclass merging is a major vore feature, unlike the errno modeling which is an optional feature. If have something in mind, you could add that test in addition you already propose.
Again, cool stuff!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, thanks for fixing this bug!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excellent quality. Thank for fixing this.
Do you need us to merge this, or you have merge rights?
Yes. |
Should I fix the other type comparison in static analysis? It looks like not consider this case at lots of position. |
I think you are right. And in most cases within CSA, we should usually compare canonical types. |
Fixes: #95658
Unqualified canonical type should be used instead of normal QualType for type equality comparison