From 3f08aae84f3f6816c119ceecf59eade751132aa3 Mon Sep 17 00:00:00 2001 From: "Ariel J. Bernal" Date: Wed, 27 Mar 2013 18:49:31 +0000 Subject: [PATCH] cpp11-migrate segfaults transforming map::iterator cpp11-migrate segfaults when -use-auto tries to resolve initializing expression resulting in an expression with cleanups. - Skip expressions with cleanups from the initializer - Added test case Fixes PR15550 llvm-svn: 178167 --- .../cpp11-migrate/UseAuto/UseAutoActions.cpp | 9 ++++++++- .../cpp11-migrate/UseAuto/Inputs/test_std_container.h | 3 +++ .../test/cpp11-migrate/UseAuto/iterator.cpp | 8 ++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp index ceb22390a1fd..14986d8dca94 100644 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp +++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp @@ -28,7 +28,14 @@ void UseAutoFixer::run(const MatchFinder::MatchResult &Result) { if (!SM.isFromMainFile(D->getLocStart())) return; - const CXXConstructExpr *Construct = cast(D->getInit()); + const Expr *ExprInit = D->getInit(); + + // Skip expressions with cleanups from the initializer expression. + if (const ExprWithCleanups *E = dyn_cast(ExprInit)) + ExprInit = E->getSubExpr(); + + const CXXConstructExpr *Construct = cast(ExprInit); + assert(Construct->getNumArgs() == 1u && "Expected constructor with single argument"); diff --git a/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h b/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h index c0ea41bfa01f..a856c45fcd24 100644 --- a/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h +++ b/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h @@ -107,6 +107,9 @@ public: const_reverse_iterator rbegin() const { return const_reverse_iterator(); } const_reverse_iterator rend() const { return const_reverse_iterator(); } + + template + iterator find(const K &Key) { return iterator(); } }; #if USE_INLINE_NAMESPACE diff --git a/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp b/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp index ec1e55407594..59c2979b32ea 100644 --- a/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp +++ b/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp @@ -148,5 +148,13 @@ int main(int argc, char **argv) { // CHECK: auto && I2 = Vec.begin(); } + // Passing a string as an argument to introduce a temporary object + // that will create an expression with cleanups. Bugzilla: 15550 + { + std::unordered_map MapFind; + std::unordered_map::iterator I = MapFind.find("foo"); + // CHECK: auto I = MapFind.find("foo"); + } + return 0; }