[PATCH] D41001: [change-namespace] Fix crash when injected base-class name is used in friend declarations.

Eric Liu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 8 00:56:41 PST 2017


ioeric created this revision.
Herald added subscribers: cfe-commits, klimek.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41001

Files:
  change-namespace/ChangeNamespace.cpp
  unittests/change-namespace/ChangeNamespaceTests.cpp


Index: unittests/change-namespace/ChangeNamespaceTests.cpp
===================================================================
--- unittests/change-namespace/ChangeNamespaceTests.cpp
+++ unittests/change-namespace/ChangeNamespaceTests.cpp
@@ -2154,6 +2154,60 @@
   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
Index: change-namespace/ChangeNamespace.cpp
===================================================================
--- change-namespace/ChangeNamespace.cpp
+++ change-namespace/ChangeNamespace.cpp
@@ -552,6 +552,10 @@
     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())


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D41001.126097.patch
Type: text/x-patch
Size: 3251 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171208/78bbdcf4/attachment.bin>


More information about the cfe-commits mailing list