summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-07-06 23:47:19 +0000
committerTed Kremenek <kremenek@apple.com>2009-07-06 23:47:19 +0000
commit97213bac53fd78f80f0aefd381d129886324bfbf (patch)
treee09e68192b89c92f95b56856a035bfb9d8b1d567
parent446bff93f5d8f3089375dbc0203c00be08009065 (diff)
downloadbcm5719-llvm-97213bac53fd78f80f0aefd381d129886324bfbf.tar.gz
bcm5719-llvm-97213bac53fd78f80f0aefd381d129886324bfbf.zip
NewCastRegion: Handle casts *from* pointers to incomplete structs to other types.
llvm-svn: 74884
-rw-r--r--clang/lib/Analysis/Store.cpp28
-rw-r--r--clang/test/Analysis/misc-ps.m6
2 files changed, 25 insertions, 9 deletions
diff --git a/clang/lib/Analysis/Store.cpp b/clang/lib/Analysis/Store.cpp
index 4ca02085225..bc5d6c25a96 100644
--- a/clang/lib/Analysis/Store.cpp
+++ b/clang/lib/Analysis/Store.cpp
@@ -35,6 +35,16 @@ StoreManager::MakeElementRegion(const GRState *state, const MemRegion *region,
ValMgr.getContext()));
}
+static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
+ if (const RecordType *RT = Ty->getAsRecordType()) {
+ const RecordDecl *D = RT->getDecl();
+ if (!D->getDefinition(Ctx))
+ return false;
+ }
+
+ return true;
+}
+
StoreManager::CastResult
StoreManager::NewCastRegion(const GRState *state, const MemRegion* R,
QualType CastToTy) {
@@ -53,7 +63,7 @@ StoreManager::NewCastRegion(const GRState *state, const MemRegion* R,
// Now assume we are casting from pointer to pointer. Other cases should
// already be handled.
QualType PointeeTy = CastToTy->getAsPointerType()->getPointeeType();
-
+
// Process region cast according to the kind of the region being cast.
switch (R->getKind()) {
case MemRegion::BEG_TYPED_REGIONS:
@@ -96,15 +106,15 @@ StoreManager::NewCastRegion(const GRState *state, const MemRegion* R,
// the cast-to pointee type is of smaller size. In other cases, we return
// the original VarRegion.
- // If the pointee type is incomplete, do not compute its size, and return
- // the original region.
- if (const RecordType *RT = PointeeTy->getAsRecordType()) {
- const RecordDecl *D = RT->getDecl();
- if (!D->getDefinition(Ctx))
- return CastResult(state, R);
- }
-
+ // If the pointee or object type is incomplete, do compute their sizes,
+ // and return the original region.
QualType ObjTy = cast<TypedRegion>(R)->getValueType(Ctx);
+
+ if (!IsCompleteType(Ctx, PointeeTy) || !IsCompleteType(Ctx, ObjTy)) {
+ state = setCastType(state, R, ToTy);
+ break;
+ }
+
uint64_t PointeeTySize = Ctx.getTypeSize(PointeeTy);
uint64_t ObjTySize = Ctx.getTypeSize(ObjTy);
diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m
index d4d2e6272f5..59578819f2f 100644
--- a/clang/test/Analysis/misc-ps.m
+++ b/clang/test/Analysis/misc-ps.m
@@ -306,4 +306,10 @@ const float *string_literal_test2() {
return (const float*) "hello";
}
+// Test that we handle casts *from* incomplete struct types.
+extern const struct _FooAssertStruct _cmd;
+void test_cast_from_incomplete_struct_aux(volatile const void *x);
+void test_cast_from_incomplete_struct() {
+ test_cast_from_incomplete_struct_aux(&_cmd);
+}
OpenPOWER on IntegriCloud