diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-14 20:30:52 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-08-14 20:30:52 +0000 |
| commit | 462b6fc6dcd7dee1321fb933d4978fc0122a78ad (patch) | |
| tree | 196f6432510dde7cbb895fbc4f7a729dad783dff /clang | |
| parent | 015ebbc8c70866662685d1d367cd7bc4a4aa7265 (diff) | |
| download | bcm5719-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.cpp | 7 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/templates-left.h | 6 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/templates-top.h | 13 | ||||
| -rw-r--r-- | clang/test/Modules/templates-2.mm | 36 |
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( |

