Author: ioeric Date: Fri Dec 8 02:06:16 2017 New Revision: 320139 URL: http://llvm.org/viewvc/llvm-project?rev=320139&view=rev Log: [change-namespace] Fix crash when injected base-class name is used in friend declarations.
Reviewers: hokein Subscribers: klimek, cfe-commits Differential Revision: https://reviews.llvm.org/D41001 Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Modified: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp?rev=320139&r1=320138&r2=320139&view=diff ============================================================================== --- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp (original) +++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp Fri Dec 8 02:06:16 2017 @@ -552,6 +552,10 @@ void ChangeNamespaceTool::run( if (Loc.getTypeLocClass() == TypeLoc::Elaborated) { NestedNameSpecifierLoc NestedNameSpecifier = Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc(); + // This happens for friend declaration of a base class with injected class + // name. + if (!NestedNameSpecifier.getNestedNameSpecifier()) + return; const Type *SpecifierType = NestedNameSpecifier.getNestedNameSpecifier()->getAsType(); if (SpecifierType && SpecifierType->isRecordType()) Modified: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp?rev=320139&r1=320138&r2=320139&view=diff ============================================================================== --- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp (original) +++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp Fri Dec 8 02:06:16 2017 @@ -2154,6 +2154,60 @@ TEST_F(ChangeNamespaceTest, DefaultMoveC EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); } +TEST_F(ChangeNamespaceTest, InjectedClassNameInFriendDecl) { + OldNamespace = "d"; + NewNamespace = "e"; + std::string Code = "namespace a{\n" + "template <typename T>\n" + "class Base {\n" + " public:\n" + " void f() {\n" + " T t;\n" + " t.priv();\n" + " }\n" + "};\n" + "} // namespace a\n" + "namespace d {\n" + "class D : public a::Base<D> {\n" + " private:\n" + " friend class Base<D>;\n" + " void priv() {}\n" + " Base b;\n" + "};\n" + "\n" + "void f() {\n" + " D d;\n" + " a:: Base<D> b;\n" + " b.f();\n" + "}\n" + "} // namespace d\n"; + std::string Expected = "namespace a{\n" + "template <typename T>\n" + "class Base {\n" + " public:\n" + " void f() {\n" + " T t;\n" + " t.priv();\n" + " }\n" + "};\n" + "} // namespace a\n" + "\n" + "namespace e {\n" + "class D : public a::Base<D> {\n" + " private:\n" + " friend class Base<D>;\n" + " void priv() {}\n" + " a::Base b;\n" + "};\n" + "\n" + "void f() {\n" + " D d;\n" + " a::Base<D> b;\n" + " b.f();\n" + "}\n" + "} // namespace e\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} } // anonymous namespace } // namespace change_namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits