diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-07-18 04:57:57 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-07-18 04:57:57 +0000 |
commit | 88237bf587581026dcfc8386abf055cb201aa487 (patch) | |
tree | 3b287e353c369399f7f167add4fae413a3633af3 | |
parent | 517bb844016064f303416f09f1aeb123e32c0f66 (diff) |
Teach CFG construction about destructors resulting from references to array types. Fixes crash in <rdar://problem/11671507>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160424 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/CFG.cpp | 9 | ||||
-rw-r--r-- | test/Analysis/cxx-for-range-cfg.cpp | 16 |
2 files changed, 20 insertions, 5 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index e3cd74b1e4..e141ed9a44 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -776,13 +776,12 @@ void CFGBuilder::addAutomaticObjDtors(LocalScope::const_iterator B, // If this destructor is marked as a no-return destructor, we need to // create a new block for the destructor which does not have as a successor // anything built thus far: control won't flow out of this block. - QualType Ty; - if ((*I)->getType()->isReferenceType()) { + QualType Ty = (*I)->getType(); + if (Ty->isReferenceType()) { Ty = getReferenceInitTemporaryType(*Context, (*I)->getInit()); - } else { - Ty = Context->getBaseElementType((*I)->getType()); } - + Ty = Context->getBaseElementType(Ty); + const CXXDestructorDecl *Dtor = Ty->getAsCXXRecordDecl()->getDestructor(); if (cast<FunctionType>(Dtor->getType())->getNoReturnAttr()) Block = createNoReturnBlock(); diff --git a/test/Analysis/cxx-for-range-cfg.cpp b/test/Analysis/cxx-for-range-cfg.cpp new file mode 100644 index 0000000000..e258c7a1e2 --- /dev/null +++ b/test/Analysis/cxx-for-range-cfg.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -Wall -fsyntax-only %s -std=c++11 -verify + +// The rdar11671507_vector<int *>[]> would previously crash CFG construction +// because of the temporary array of vectors. +template <typename T> +class rdar11671507_vector { +public: + rdar11671507_vector(); + ~rdar11671507_vector(); + T *Base; + T *End; +}; + +void rdar11671507(rdar11671507_vector<int*> v, rdar11671507_vector<int*> w) { + for (auto &vec : (rdar11671507_vector<int *>[]){ v, w }) {} // expected-warning {{unused}} +} |