summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-08-14 20:30:52 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-08-14 20:30:52 +0000
commit462b6fc6dcd7dee1321fb933d4978fc0122a78ad (patch)
tree196f6432510dde7cbb895fbc4f7a729dad783dff /clang
parent015ebbc8c70866662685d1d367cd7bc4a4aa7265 (diff)
downloadbcm5719-llvm-462b6fc6dcd7dee1321fb933d4978fc0122a78ad.tar.gz
bcm5719-llvm-462b6fc6dcd7dee1321fb933d4978fc0122a78ad.zip
[modules] Turn off a broken optimization: we need to pick up implicit special
members from all redefinitions of a class that have them, in case the special member is defined in one module but only declared in another. llvm-svn: 215675
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp7
-rw-r--r--clang/test/Modules/Inputs/templates-left.h6
-rw-r--r--clang/test/Modules/Inputs/templates-top.h13
-rw-r--r--clang/test/Modules/templates-2.mm36
4 files changed, 60 insertions, 2 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index dcb747fe8d7..38837e2c067 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1301,8 +1301,11 @@ void ASTDeclReader::MergeDefinitionData(
// If the new definition has new special members, let the name lookup
// code know that it needs to look in the new definition too.
- if ((MergeDD.DeclaredSpecialMembers & ~DD.DeclaredSpecialMembers) &&
- DD.Definition != MergeDD.Definition) {
+ //
+ // FIXME: We only need to do this if the merged definition declares members
+ // that this definition did not declare, or if it defines members that this
+ // definition did not define.
+ if (MergeDD.DeclaredSpecialMembers && DD.Definition != MergeDD.Definition) {
Reader.MergedLookups[DD.Definition].push_back(MergeDD.Definition);
DD.Definition->setHasExternalVisibleStorage();
}
diff --git a/clang/test/Modules/Inputs/templates-left.h b/clang/test/Modules/Inputs/templates-left.h
index 2bd79be9458..7ca5cc52a12 100644
--- a/clang/test/Modules/Inputs/templates-left.h
+++ b/clang/test/Modules/Inputs/templates-left.h
@@ -60,3 +60,9 @@ template<typename T> void testDelayUpdates(DelayUpdates<T> *p = 0) {}
void outOfLineInlineUseLeftF(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::f);
void outOfLineInlineUseLeftG(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::g);
void outOfLineInlineUseLeftH(void (OutOfLineInline<int>::*)() = &OutOfLineInline<int>::h);
+
+namespace EmitDefaultedSpecialMembers {
+ inline void f() {
+ SmallString<256> SS;
+ };
+}
diff --git a/clang/test/Modules/Inputs/templates-top.h b/clang/test/Modules/Inputs/templates-top.h
index 1216266f34f..b1e0548d41e 100644
--- a/clang/test/Modules/Inputs/templates-top.h
+++ b/clang/test/Modules/Inputs/templates-top.h
@@ -40,3 +40,16 @@ template<typename T> struct OutOfLineInline {
template<typename T> inline void OutOfLineInline<T>::f() {}
template<typename T> inline void OutOfLineInline<T>::g() {}
template<typename T> inline void OutOfLineInline<T>::h() {}
+
+namespace EmitDefaultedSpecialMembers {
+ template<typename T> struct SmallVectorImpl {
+ SmallVectorImpl() {}
+ ~SmallVectorImpl() {} // non-trivial dtor
+ };
+ template<typename T, unsigned N> struct SmallVector : SmallVectorImpl<T> {
+ // trivial dtor
+ };
+ template<unsigned N> struct SmallString : SmallVector<char, N> {
+ // trivial dtor
+ };
+}
diff --git a/clang/test/Modules/templates-2.mm b/clang/test/Modules/templates-2.mm
new file mode 100644
index 00000000000..b7ceafbbc5b
--- /dev/null
+++ b/clang/test/Modules/templates-2.mm
@@ -0,0 +1,36 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -verify %s -Wno-objc-root-class
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++11 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs -emit-llvm %s -o - -Wno-objc-root-class | FileCheck %s
+// expected-no-diagnostics
+
+@import templates_top;
+
+struct TestEmitDefaultedSpecialMembers {
+ EmitDefaultedSpecialMembers::SmallVector<char, 256> V;
+};
+
+@import templates_left;
+
+void testEmitDefaultedSpecialMembers() {
+ EmitDefaultedSpecialMembers::SmallString<256> V;
+ // CHECK: call {{.*}} @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EEC1Ev(
+ // CHECK: call {{.*}} @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EED1Ev(
+}
+
+// CHECK-LABEL: define {{.*}} @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EEC1Ev(
+// CHECK: call {{.*}} @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EEC2Ev(
+
+// CHECK-LABEL: define {{.*}} @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EED1Ev(
+// CHECK: call {{.*}} @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EED2Ev(
+
+// CHECK-LABEL: define linkonce_odr void @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EED2Ev(
+// CHECK: call void @_ZN27EmitDefaultedSpecialMembers11SmallVectorIcLj256EED2Ev(
+// CHECK-LABEL: define linkonce_odr void @_ZN27EmitDefaultedSpecialMembers11SmallVectorIcLj256EED2Ev(
+// CHECK: call void @_ZN27EmitDefaultedSpecialMembers15SmallVectorImplIcED2Ev(
+// CHECK-LABEL: define linkonce_odr void @_ZN27EmitDefaultedSpecialMembers15SmallVectorImplIcED2Ev(
+
+// CHECK-LABEL: define linkonce_odr void @_ZN27EmitDefaultedSpecialMembers11SmallStringILj256EEC2Ev(
+// CHECK: call void @_ZN27EmitDefaultedSpecialMembers11SmallVectorIcLj256EEC2Ev(
+// CHECK-LABEL: define linkonce_odr void @_ZN27EmitDefaultedSpecialMembers11SmallVectorIcLj256EEC2Ev(
+// CHECK: call void @_ZN27EmitDefaultedSpecialMembers15SmallVectorImplIcEC2Ev(
+// CHECK-LABEL: define linkonce_odr void @_ZN27EmitDefaultedSpecialMembers15SmallVectorImplIcEC2Ev(
OpenPOWER on IntegriCloud