diff options
author | Balazs Benics <benicsbalazs@gmail.com> | 2024-04-19 16:26:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-19 16:26:07 +0200 |
commit | 7d8616ed500f01b201667020c9be545d686950be (patch) | |
tree | c677fdf59f194aca1576f38c4721793a3665f180 | |
parent | 58764ddccda99039174ca572c6a94393c290f8ac (diff) | |
download | llvm-7d8616ed500f01b201667020c9be545d686950be.zip llvm-7d8616ed500f01b201667020c9be545d686950be.tar.gz llvm-7d8616ed500f01b201667020c9be545d686950be.tar.bz2 |
[analyzer] Fix stores through label locations (#89265)
Interestingly, this case crashed from the very beginning of the project,
at least starting by clang-3.
As a "fix" I just do the same thing as we do for concrete integers. It
might not be the best we could do, but arguably, it's still better than
crashing.
Fixes #89185
-rw-r--r-- | clang/docs/ReleaseNotes.rst | 2 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 7 | ||||
-rw-r--r-- | clang/test/Analysis/gh-issue-89185.c | 14 |
3 files changed, 20 insertions, 3 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 193bbd6..e0a6d2f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -695,6 +695,8 @@ Static Analyzer - Support C++23 static operator calls. (#GH84972) - Fixed a crash in ``security.cert.env.InvalidPtr`` checker when accidentally matched user-defined ``strerror`` and similar library functions. (GH#88181) +- Fixed a crash when storing through an address that refers to the address of + a label. (GH#89185) New features ^^^^^^^^^^^^ diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index ebba181..ba29c12 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -2358,11 +2358,12 @@ StoreRef RegionStoreManager::killBinding(Store ST, Loc L) { RegionBindingsRef RegionStoreManager::bind(RegionBindingsConstRef B, Loc L, SVal V) { - if (L.getAs<loc::ConcreteInt>()) + // We only care about region locations. + auto MemRegVal = L.getAs<loc::MemRegionVal>(); + if (!MemRegVal) return B; - // If we get here, the location should be a region. - const MemRegion *R = L.castAs<loc::MemRegionVal>().getRegion(); + const MemRegion *R = MemRegVal->getRegion(); // Check if the region is a struct region. if (const TypedValueRegion* TR = dyn_cast<TypedValueRegion>(R)) { diff --git a/clang/test/Analysis/gh-issue-89185.c b/clang/test/Analysis/gh-issue-89185.c new file mode 100644 index 0000000..8a907f1 --- /dev/null +++ b/clang/test/Analysis/gh-issue-89185.c @@ -0,0 +1,14 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +void clang_analyzer_dump(char); +void clang_analyzer_dump_ptr(char*); + +// https://github.com/llvm/llvm-project/issues/89185 +void binding_to_label_loc() { + char *b = &&MyLabel; +MyLabel: + *b = 0; // no-crash + clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}} + clang_analyzer_dump(*b); // expected-warning {{Unknown}} + // FIXME: We should never reach here, as storing to a label is invalid. +} |