summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2015-02-24 09:06:28 +0000
committerManuel Klimek <klimek@google.com>2015-02-24 09:06:28 +0000
commit7906f139c3adf797c8f1a8ec3a287682dec0176b (patch)
treeb6a66de5eb3c55738a71b1f3214214ab04971d61
parentcf51397c4872807e10d5ed3a55999693406eb2ae (diff)
downloadbcm5719-llvm-7906f139c3adf797c8f1a8ec3a287682dec0176b.tar.gz
bcm5719-llvm-7906f139c3adf797c8f1a8ec3a287682dec0176b.zip
Fix codegen for virtual methods that are (re-) exported from multiple modules.
Fixes multiple crashes where a non-canonical decl would be used as key in a lookup. llvm-svn: 230314
-rw-r--r--clang/lib/AST/VTableBuilder.cpp6
-rw-r--r--clang/test/Modules/Inputs/merge-vtable-codegen/a.h8
-rw-r--r--clang/test/Modules/Inputs/merge-vtable-codegen/b.h17
-rw-r--r--clang/test/Modules/Inputs/merge-vtable-codegen/c.h6
-rw-r--r--clang/test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap11
-rw-r--r--clang/test/Modules/merge-vtable-codegen.cpp24
6 files changed, 71 insertions, 1 deletions
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index ddb1f057ac8..c0777e08c9f 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -411,7 +411,8 @@ void FinalOverriders::dump(raw_ostream &Out, BaseSubobject Base,
for (const auto *MD : RD->methods()) {
if (!MD->isVirtual())
continue;
-
+ MD = MD->getCanonicalDecl();
+
OverriderInfo Overrider = getOverrider(MD, Base.getBaseOffset());
Out << " ";
@@ -695,6 +696,7 @@ void VCallAndVBaseOffsetBuilder::AddVCallOffsets(BaseSubobject Base,
for (const auto *MD : RD->methods()) {
if (!MD->isVirtual())
continue;
+ MD = MD->getCanonicalDecl();
CharUnits OffsetOffset = getCurrentOffsetOffset();
@@ -1514,6 +1516,7 @@ void ItaniumVTableBuilder::AddMethods(
for (const auto *MD : RD->methods()) {
if (!MD->isVirtual())
continue;
+ MD = MD->getCanonicalDecl();
// Get the final overrider.
FinalOverriders::OverriderInfo Overrider =
@@ -2196,6 +2199,7 @@ void ItaniumVTableBuilder::dumpLayout(raw_ostream &Out) {
// We only want virtual member functions.
if (!MD->isVirtual())
continue;
+ MD = MD->getCanonicalDecl();
std::string MethodName =
PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual,
diff --git a/clang/test/Modules/Inputs/merge-vtable-codegen/a.h b/clang/test/Modules/Inputs/merge-vtable-codegen/a.h
new file mode 100644
index 00000000000..c2885379aa4
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-vtable-codegen/a.h
@@ -0,0 +1,8 @@
+#ifndef A_H
+#define A_H
+
+struct A {
+ virtual void x();
+};
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-vtable-codegen/b.h b/clang/test/Modules/Inputs/merge-vtable-codegen/b.h
new file mode 100644
index 00000000000..770e46077f9
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-vtable-codegen/b.h
@@ -0,0 +1,17 @@
+#ifndef B_H
+#define B_H
+
+#include "a.h"
+
+class B : virtual public A {
+ virtual void x() {}
+};
+
+void b(A* p) {
+ p->x();
+ // Instantiating a class that virtually inherits 'A'
+ // triggers calculation of the vtable offsets in 'A'.
+ B b;
+}
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-vtable-codegen/c.h b/clang/test/Modules/Inputs/merge-vtable-codegen/c.h
new file mode 100644
index 00000000000..40cbbb047cb
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-vtable-codegen/c.h
@@ -0,0 +1,6 @@
+#ifndef C_H
+#define C_H
+
+#include "a.h"
+
+#endif
diff --git a/clang/test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap b/clang/test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap
new file mode 100644
index 00000000000..1edaa07101f
--- /dev/null
+++ b/clang/test/Modules/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap
@@ -0,0 +1,11 @@
+module "a" {
+ textual header "a.h"
+}
+
+module "b" {
+ header "b.h"
+}
+
+module "c" {
+ header "c.h"
+}
diff --git a/clang/test/Modules/merge-vtable-codegen.cpp b/clang/test/Modules/merge-vtable-codegen.cpp
new file mode 100644
index 00000000000..7372073891c
--- /dev/null
+++ b/clang/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/merge-vtable-codegen.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/merge-vtable-codegen.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: -fmodule-map-file=%S/Inputs/merge-vtable-codegen/merge-vtable-codegen.modulemap \
+// RUN: -emit-llvm -o %t/test.o %s
+
+// 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);
+}
OpenPOWER on IntegriCloud