[PATCH] D89055: [analyzer] Wrong type cast occures during pointer dereferencing after type punning
Denys Petrov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 5 02:55:16 PST 2021
ASDenysPetrov updated this revision to Diff 321693.
ASDenysPetrov added a comment.
Updated. Rolled the fix over the evalCast refactoring.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D89055/new/
https://reviews.llvm.org/D89055
Files:
clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
clang/test/Analysis/casts.c
clang/test/Analysis/string.c
Index: clang/test/Analysis/string.c
===================================================================
--- clang/test/Analysis/string.c
+++ clang/test/Analysis/string.c
@@ -363,6 +363,20 @@
strcpy(x, y); // no-warning
}
+// PR37503
+void *get_void_ptr();
+char ***type_punned_ptr;
+void strcpy_no_assertion(char c) {
+ *(unsigned char **)type_punned_ptr = (unsigned char *)(get_void_ptr());
+ strcpy(**type_punned_ptr, &c); // no-crash
+}
+
+// PR49007
+char f(char ***c, int *i) {
+ *(void **)c = i + 1;
+ return (**c)[0]; // no-crash
+}
+
//===----------------------------------------------------------------------===
// stpcpy()
//===----------------------------------------------------------------------===
Index: clang/test/Analysis/casts.c
===================================================================
--- clang/test/Analysis/casts.c
+++ clang/test/Analysis/casts.c
@@ -245,3 +245,8 @@
return a * a;
}
+void no_crash_reinterpret_char_as_uchar(char ***a, int *b) {
+ *(unsigned char **)a = (unsigned char *)b;
+ if (**a == 0) // no-crash
+ ;
+}
Index: clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -731,8 +731,8 @@
// pointers as well.
// FIXME: We really need a single good function to perform casts for us
// correctly every time we need it.
+ const MemRegion *R = V.getRegion();
if (CastTy->isPointerType() && !CastTy->isVoidPointerType()) {
- const MemRegion *R = V.getRegion();
if (const auto *SR = dyn_cast<SymbolicRegion>(R)) {
QualType SRTy = SR->getSymbol()->getType();
if (!hasSameUnqualifiedPointeeType(SRTy, CastTy)) {
@@ -741,6 +741,13 @@
}
}
}
+ // Next fixes pointer dereference using type different from its initial
+ // one. See PR37503 and PR49007 for details.
+ if (const auto *ER = dyn_cast<ElementRegion>(R)) {
+ R = StateMgr.getStoreManager().castRegion(ER, CastTy);
+ return loc::MemRegionVal(R);
+ }
+
return V;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D89055.321693.patch
Type: text/x-patch
Size: 2193 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210205/34339211/attachment.bin>
More information about the cfe-commits
mailing list