diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index a36a239e0de2..2feea594b8aa 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/lib/Analysis/BasicStore.cpp @@ -203,7 +203,6 @@ SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base, SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, SVal Offset) { - if (Base.isUnknownOrUndef()) return Base; @@ -233,6 +232,17 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, case loc::MemRegionKind: { const MemRegion *R = cast(BaseL).getRegion(); + + if (isa(R)) { + // Basic example: + // char buf[100]; + // char *q = &buf[1]; // p points to ElementRegion(buf,Unknown) + // &q[10] + assert(cast(R)->getIndex().isUnknown()); + return Base; + } + + if (const TypedRegion *TR = dyn_cast(R)) { BaseR = TR; break; @@ -244,7 +254,7 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, break; } - + case loc::ConcreteIntKind: // While these seem funny, this can happen through casts. // FIXME: What we should return is the field offset. For example, diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index f221f8b989f1..4e7f0ad5b32d 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/test/Analysis/misc-ps.m @@ -100,3 +100,11 @@ void handle_sizeof_void(unsigned flag) { *p = 1; // no-warning } +// PR 3422 +void pr3422_helper(char *p); +void pr3422() { + char buf[100]; + char *q = &buf[10]; + pr3422_helper(&q[1]); +} +