summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-08-03 21:41:46 +0000
committerTed Kremenek <kremenek@apple.com>2009-08-03 21:41:46 +0000
commit0bb32e3e5d7524022642a8055da3ffe32ea5952a (patch)
tree19238a0bfea6cb944ec4d0483c687455bbda9e0e /clang
parenta1d8bcd33ec766e4d38ccda65d1244e187821296 (diff)
downloadbcm5719-llvm-0bb32e3e5d7524022642a8055da3ffe32ea5952a.tar.gz
bcm5719-llvm-0bb32e3e5d7524022642a8055da3ffe32ea5952a.zip
Handle disgusting corner case where a byte is loaded from the address of a function.
llvm-svn: 78000
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Analysis/RegionStore.cpp4
-rw-r--r--clang/test/Analysis/misc-ps.m9
2 files changed, 12 insertions, 1 deletions
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp
index 543783d924f..c47aaa20e07 100644
--- a/clang/lib/Analysis/RegionStore.cpp
+++ b/clang/lib/Analysis/RegionStore.cpp
@@ -882,6 +882,9 @@ RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
MR = MRMgr.getElementRegion(T, idx, MR, Ctx);
}
+ if (isa<CodeTextRegion>(MR))
+ return SValuator::CastResult(state, UnknownVal());
+
// FIXME: Perhaps this method should just take a 'const MemRegion*' argument
// instead of 'Loc', and have the other Loc cases handled at a higher level.
const TypedRegion *R = cast<TypedRegion>(MR);
@@ -1000,7 +1003,6 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state,
if (R->getIndex().isZeroConstant()) {
if (const TypedRegion *superTR = dyn_cast<TypedRegion>(superR)) {
ASTContext &Ctx = getContext();
-
if (IsAnyPointerOrIntptr(superTR->getValueType(Ctx), Ctx)) {
QualType valTy = R->getValueType(Ctx);
if (IsAnyPointerOrIntptr(valTy, Ctx)) {
diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m
index c4fa7a8a1d0..5cfcd714cdb 100644
--- a/clang/test/Analysis/misc-ps.m
+++ b/clang/test/Analysis/misc-ps.m
@@ -499,3 +499,12 @@ void test_cast_const_voidptr() {
char *p = &x[1];
const void* q = p;
}
+
+// Reduced from a crash when analyzing Wine. This test handles loads from
+// function addresses.
+typedef long (*FARPROC)();
+FARPROC test_load_func(FARPROC origfun) {
+ if (!*(unsigned char*) origfun)
+ return origfun;
+ return 0;
+}
OpenPOWER on IntegriCloud