From 8318304afdfe4d6d689681a73424c73615e95859 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 24 Jan 2009 06:11:36 +0000 Subject: [PATCH] Fix crash ElementRegion::getRValueType() when the RvalueType of the ArrayRegion is a typedef and not (directly) a pointer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62909 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/MemRegion.cpp | 15 ++++++--------- test/Analysis/exercise-ps.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index 2724ed0ada..55c6935b8e 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -108,17 +108,14 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { } QualType ElementRegion::getRValueType(ASTContext& C) const { - QualType T = getArrayRegion()->getRValueType(C); + // Strip off typedefs from the ArrayRegion's RvalueType. + QualType T = getArrayRegion()->getRValueType(C)->getDesugaredType(); - if (isa(T.getTypePtr())) { - ArrayType* AT = cast(T.getTypePtr()); + if (ArrayType* AT = dyn_cast(T.getTypePtr())) return AT->getElementType(); - } - else { - PointerType* PtrT = cast(T.getTypePtr()); - QualType PTy = PtrT->getPointeeType(); - return C.getCanonicalType(PTy); - } + + PointerType* PtrT = cast(T.getTypePtr()); + return C.getCanonicalType(PtrT->getPointeeType()); } //===----------------------------------------------------------------------===// diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c index 6d58e92c31..4aaba8e8dd 100644 --- a/test/Analysis/exercise-ps.c +++ b/test/Analysis/exercise-ps.c @@ -2,7 +2,8 @@ // RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && // RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s // -// Just exercise the analyzer (no assertions). +// Just exercise the analyzer on code that has at one point caused issues +// (i.e., no assertions or crashes). static const char * f1(const char *x, char *y) { @@ -10,3 +11,14 @@ static const char * f1(const char *x, char *y) { *y++ = *x++; } } + +// This following case checks that we properly handle typedefs when getting +// the RvalueType of an ElementRegion. +typedef struct F12_struct {} F12_typedef; +typedef void* void_typedef; +void_typedef f2_helper(); +static void f2(void *buf) { + F12_typedef* x; + x = f2_helper(); + memcpy((&x[1]), (buf), 1); +} -- 2.40.0