summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorVolodymyr Sapsai <vsapsai@apple.com>2018-05-16 18:28:58 +0000
committerVolodymyr Sapsai <vsapsai@apple.com>2018-05-16 18:28:58 +0000
commit9b973483ed3bec6d0224cd75dd95bc9cc9b7b0a5 (patch)
tree44ea27121dc7179ebab7f6e3e6effce5d328ce87 /clang/test
parentb24957e22a965535d34f8f987c8b4b6ccfcd5f69 (diff)
downloadbcm5719-llvm-9b973483ed3bec6d0224cd75dd95bc9cc9b7b0a5.tar.gz
bcm5719-llvm-9b973483ed3bec6d0224cd75dd95bc9cc9b7b0a5.zip
[Sema] Fix assertion when constructor is disabled with partially specialized template.
The added test case was triggering assertion > Assertion failed: (!SpecializedTemplate.is<SpecializedPartialSpecialization*>() && "Already set to a class template partial specialization!"), function setInstantiationOf, file clang/include/clang/AST/DeclTemplate.h, line 1825. It was happening with ClassTemplateSpecializationDecl `enable_if_not_same<int, int>`. Because this template is specialized for equal types not to have a definition, it wasn't instantiated and its specialization kind remained TSK_Undeclared. And because it was implicit instantiation, we didn't mark the decl as invalid. So when we try to find the best matching partial specialization the second time, we hit the assertion as partial specialization is already set. Fix by reusing stored partial specialization when available, instead of looking for the best match every time. rdar://problem/39524996 Reviewers: rsmith, arphaman Reviewed By: rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D46909 llvm-svn: 332509
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/SemaTemplate/partial-spec-instantiate.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/partial-spec-instantiate.cpp b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
index d5ecd8c1e3b..2fc0517ae3d 100644
--- a/clang/test/SemaTemplate/partial-spec-instantiate.cpp
+++ b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -55,3 +55,46 @@ namespace rdar9169404 {
// expected-no-diagnostics
#endif
}
+
+// rdar://problem/39524996
+namespace rdar39524996 {
+ template <typename T, typename U>
+ struct enable_if_not_same
+ {
+ typedef void type;
+ };
+ template <typename T>
+ struct enable_if_not_same<T, T>;
+
+ template <typename T>
+ struct Wrapper {
+ // Assertion triggered on trying to set twice the same partial specialization
+ // enable_if_not_same<int, int>
+ template <class U>
+ Wrapper(const Wrapper<U>& other,
+ typename enable_if_not_same<U, T>::type* = 0) {}
+
+ explicit Wrapper(int i) {}
+ };
+
+ template <class T>
+ struct Container {
+ // It is important that the struct has implicit copy and move constructors.
+ Container() : x() {}
+
+ template <class U>
+ Container(const Container<U>& other) : x(static_cast<T>(other.x)) {}
+
+ // Implicit constructors are member-wise, so the field triggers instantiation
+ // of T constructors and we instantiate all of them for overloading purposes.
+ T x;
+ };
+
+ void takesWrapperInContainer(const Container< Wrapper<int> >& c);
+ void test() {
+ // Type mismatch triggers initialization with conversion which requires
+ // implicit constructors to be instantiated.
+ Container<int> c;
+ takesWrapperInContainer(c);
+ }
+}
OpenPOWER on IntegriCloud