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

2017-12-08 Thread Eric Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL320139: [change-namespace] Fix crash when injected 
base-class name is used in friend… (authored by ioeric).

Repository:
  rL LLVM

https://reviews.llvm.org/D41001

Files:
  clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
  clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp


Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
===
--- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
+++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
@@ -552,6 +552,10 @@
 if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
   NestedNameSpecifierLoc NestedNameSpecifier =
   Loc.castAs().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())
Index: 
clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
===
--- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
+++ clang-tools-extra/trunk/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 \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 {\n"
+ " private:\n"
+ "  friend class Base;\n"
+ "  void priv() {}\n"
+ "  Base b;\n"
+ "};\n"
+ "\n"
+ "void f() {\n"
+ "  D d;\n"
+ "  a:: Base b;\n"
+ "  b.f();\n"
+ "}\n"
+ "}  // namespace d\n";
+  std::string Expected = "namespace a{\n"
+ "template \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 {\n"
+ " private:\n"
+ "  friend class Base;\n"
+ "  void priv() {}\n"
+ "  a::Base b;\n"
+ "};\n"
+ "\n"
+ "void f() {\n"
+ "  D d;\n"
+ "  a::Base b;\n"
+ "  b.f();\n"
+ "}\n"
+ "}  // namespace e\n";
+  EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
+}
 
 } // anonymous namespace
 } // namespace change_namespace


Index: clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
===
--- clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
+++ clang-tools-extra/trunk/change-namespace/ChangeNamespace.cpp
@@ -552,6 +552,10 @@
 if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
   NestedNameSpecifierLoc NestedNameSpecifier =
   Loc.castAs().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())
Index: clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
===
--- clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
+++ clang-tools-extra/trunk/unittests/change-namespace/ChangeNamespaceTests.cpp
@@ -2154,6 +2154,60 @@
   EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code));
 }
 
+TEST_F(ChangeNamespaceTest, InjectedClassNameInFriendDecl) {
+  OldNames

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

2017-12-08 Thread Haojian Wu via Phabricator via cfe-commits
hokein accepted this revision.
hokein added a comment.
This revision is now accepted and ready to land.

LGTM.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D41001



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


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

2017-12-08 Thread Eric Liu via Phabricator via cfe-commits
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 \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 {\n"
+ " private:\n"
+ "  friend class Base;\n"
+ "  void priv() {}\n"
+ "  Base b;\n"
+ "};\n"
+ "\n"
+ "void f() {\n"
+ "  D d;\n"
+ "  a:: Base b;\n"
+ "  b.f();\n"
+ "}\n"
+ "}  // namespace d\n";
+  std::string Expected = "namespace a{\n"
+ "template \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 {\n"
+ " private:\n"
+ "  friend class Base;\n"
+ "  void priv() {}\n"
+ "  a::Base b;\n"
+ "};\n"
+ "\n"
+ "void f() {\n"
+ "  D d;\n"
+ "  a::Base 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().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())


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 \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 {\n"
+ " private:\n"
+ "  friend class Base;\n"
+ "  void priv() {}\n"
+ "  Base b;\n"
+ "};\n"
+ "\n"
+ "void f() {\n"
+ "  D d;\n"
+ "  a:: Base b;\n"
+ "  b.f();\n"
+ "}\n"
+ "}  // namespace d\n";
+  std::string Expected = "namespace a{\n"
+ "template \n"
+ "class Base {\n"
+ " public:\n"
+ "  void f() {\n"
+