Hi rsmith,

Fixes multiple crashes where a non-canonical decl would be used as
key.

http://reviews.llvm.org/D7830

Files:
  lib/AST/VTableBuilder.cpp
  test/Modules/Inputs/merge-vtable-codegen/a.h
  test/Modules/Inputs/merge-vtable-codegen/a.modulemap
  test/Modules/Inputs/merge-vtable-codegen/b.h
  test/Modules/Inputs/merge-vtable-codegen/b.modulemap
  test/Modules/Inputs/merge-vtable-codegen/c.h
  test/Modules/Inputs/merge-vtable-codegen/c.modulemap
  test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap
  test/Modules/merge-vtable-codegen.cpp

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/AST/VTableBuilder.cpp
===================================================================
--- lib/AST/VTableBuilder.cpp
+++ lib/AST/VTableBuilder.cpp
@@ -138,6 +138,7 @@
   /// the subobject with the given base offset. 
   OverriderInfo getOverrider(const CXXMethodDecl *MD, 
                              CharUnits BaseOffset) const {
+    MD = MD->getCanonicalDecl();
     assert(OverridersMap.count(std::make_pair(MD, BaseOffset)) && 
            "Did not find overrider!");
     
@@ -1697,7 +1698,7 @@
     assert(MethodVTableIndices.empty());
     for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
          E = MethodInfoMap.end(); I != E; ++I) {
-      const CXXMethodDecl *MD = I->first;
+      const CXXMethodDecl *MD = I->first->getCanonicalDecl();
       const MethodInfo &MI = I->second;
       if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
         MethodVTableIndices[GlobalDecl(DD, Dtor_Complete)]
@@ -2196,6 +2197,7 @@
     // We only want virtual member functions.
     if (!MD->isVirtual())
       continue;
+    MD = MD->getCanonicalDecl();
 
     std::string MethodName =
       PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
@@ -2557,7 +2559,7 @@
     assert(MethodVFTableLocations.empty());
     for (MethodInfoMapTy::const_iterator I = MethodInfoMap.begin(),
          E = MethodInfoMap.end(); I != E; ++I) {
-      const CXXMethodDecl *MD = I->first;
+      const CXXMethodDecl *MD = I->first->getCanonicalDecl();
       const MethodInfo &MI = I->second;
       // Skip the methods that the MostDerivedClass didn't override
       // and the entries shadowed by return adjusting thunks.
Index: test/Modules/Inputs/merge-vtable-codegen/a.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/merge-vtable-codegen/a.h
@@ -0,0 +1,8 @@
+#ifndef A_H
+#define A_H
+
+struct A {
+  virtual void x();
+};
+
+#endif
Index: test/Modules/Inputs/merge-vtable-codegen/a.modulemap
===================================================================
--- /dev/null
+++ test/Modules/Inputs/merge-vtable-codegen/a.modulemap
@@ -0,0 +1,3 @@
+module "a" {
+  textual header "a.h"
+}
Index: test/Modules/Inputs/merge-vtable-codegen/b.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/merge-vtable-codegen/b.h
@@ -0,0 +1,10 @@
+#ifndef B_H
+#define B_H
+
+#include "a.h"
+
+void b(A* p) {
+  p->x();
+}
+
+#endif
Index: test/Modules/Inputs/merge-vtable-codegen/b.modulemap
===================================================================
--- /dev/null
+++ test/Modules/Inputs/merge-vtable-codegen/b.modulemap
@@ -0,0 +1,7 @@
+module "b" {
+  header "b.h"
+  use "a"
+}
+
+extern module "a" "a.modulemap"
+
Index: test/Modules/Inputs/merge-vtable-codegen/c.h
===================================================================
--- /dev/null
+++ test/Modules/Inputs/merge-vtable-codegen/c.h
@@ -0,0 +1,6 @@
+#ifndef C_H
+#define C_H
+
+#include "a.h"
+
+#endif
Index: test/Modules/Inputs/merge-vtable-codegen/c.modulemap
===================================================================
--- /dev/null
+++ test/Modules/Inputs/merge-vtable-codegen/c.modulemap
@@ -0,0 +1,6 @@
+module "c" {
+  header "c.h"
+  use "a"
+}
+
+extern module "a" "a.modulemap"
\ No newline at end of file
Index: test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap
===================================================================
--- /dev/null
+++ test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap
@@ -0,0 +1,8 @@
+module "merge-vtable-codegen" {
+  export *
+  use "b"
+  use "c"
+}
+
+extern module "b" "b.modulemap"
+extern module "c" "c.modulemap"
\ No newline at end of file
Index: test/Modules/merge-vtable-codegen.cpp
===================================================================
--- /dev/null
+++ test/Modules/merge-vtable-codegen.cpp
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+
+// First, build two modules that both re-export the same header.
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=b -o %t/b.pcm -fmodule-maps \
+// RUN:     -emit-module %S/Inputs/merge-vtable-codegen/b.modulemap \
+// RUN:     -I %S/Inputs/merge-vtable-codegen
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-name=c -o %t/c.pcm -fmodule-maps \
+// RUN:     -emit-module %S/Inputs/merge-vtable-codegen/c.modulemap \
+// RUN:     -I %S/Inputs/merge-vtable-codegen
+
+// Use the two modules in a single compile.
+// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodule-file=%t/b.pcm -fmodule-file=%t/c.pcm \
+// RUN:     -emit-llvm -o %t/test.o %s -fmodule-name=merge-vtable-codegen \
+// RUN:     -fmodule-map-file=%S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap
+
+// Note that order is important:
+// Module 'c' just reexports A, while module 'b' defines a method that uses a
+// virtual method of A.
+#include "Inputs/merge-vtable-codegen/c.h"
+#include "Inputs/merge-vtable-codegen/b.h"
+
+void t() {
+  b(nullptr);
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to