diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-05-09 23:02:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2017-05-09 23:02:10 +0000 |
commit | dc3427730894f036d18da71faee4ae820a1dca04 (patch) | |
tree | 8c3e0201b4c535855855445e2e52a24115db2df7 /test/PCH | |
parent | 96411f068fe4dbc3bc60f29c27101f660619fc75 (diff) |
Don't mark a member as a member specialization until we know we're keeping the specialization.
This improves our behavior in a few ways:
* We now guarantee that if a member is marked as being a member
specialization, there will actually be a member specialization declaration
somewhere on its redeclaration chain. This fixes a crash in modules builds
where we would try to check that there was a visible declaration of the
member specialization and be surprised to not find any declaration of it at
all.
* We don't set the source location of the in-class declaration of the member
specialization to the out-of-line declaration's location until we have
actually finished merging them. This fixes some very silly looking
diagnostics, where we'd point a "previous declaration is here" note at the
same declaration we're complaining about. Ideally we wouldn't mess with the
prior declaration's location at all, but too much code assumes that the
first declaration of an entity is a reasonable thing to use as an indication
of where it was declared, and that's not really true for a member
specialization unless we fake it like this.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@302596 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/PCH')
-rw-r--r-- | test/PCH/cxx-templates.cpp | 8 | ||||
-rw-r--r-- | test/PCH/cxx-templates.h | 3 |
2 files changed, 11 insertions, 0 deletions
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp index d50eee0623..e241701f50 100644 --- a/test/PCH/cxx-templates.cpp +++ b/test/PCH/cxx-templates.cpp @@ -108,3 +108,11 @@ namespace cyclic_module_load { template int local_extern::f<int[]>(); // expected-note {{in instantiation of}} #endif template int local_extern::g<int[]>(); + +namespace MemberSpecializationLocation { +#ifndef NO_ERRORS + // expected-note@cxx-templates.h:* {{previous}} + template<> float A<int>::n; // expected-error {{redeclaration of 'n' with a different type}} +#endif + int k = A<int>::n; +} diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h index c4a8447276..68b252e797 100644 --- a/test/PCH/cxx-templates.h +++ b/test/PCH/cxx-templates.h @@ -358,3 +358,6 @@ namespace rdar15468709c { } } +namespace MemberSpecializationLocation { + template<typename T> struct A { static int n; }; +} |