From 13d2d6cfd6a0032402c98b4fa237526c5b40e3fb Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 6 Oct 2009 21:27:51 +0000 Subject: [PATCH] Test explicit specialization for all of the various cases where explicit specializations can occur. Also, fix a minor recovery bug where we should allow declarations coming from the parser to be NULL. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83416 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplate.cpp | 2 +- test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp | 97 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index d12ec9318a..02c3e43b33 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -257,7 +257,7 @@ bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) { /// the parameter D to reference the templated declaration and return a pointer /// to the template declaration. Otherwise, do nothing to D and return null. TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) { - if (TemplateDecl *Temp = dyn_cast(D.getAs())) { + if (TemplateDecl *Temp = dyn_cast_or_null(D.getAs())) { D = DeclPtrTy::make(Temp->getTemplatedDecl()); return Temp; } diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp new file mode 100644 index 0000000000..f3d0709ef8 --- /dev/null +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp @@ -0,0 +1,97 @@ +// RUN: clang-cc -fsyntax-only %s + +// This test creates cases where implicit instantiations of various entities +// would cause a diagnostic, but provides expliict specializations for those +// entities that avoid the diagnostic. The intent is to verify that +struct NonDefaultConstructible { + NonDefaultConstructible(int); +}; + + +// C++ [temp.expl.spec]p1: +// An explicit specialization of any of the following: + +// -- function template +template void f0(T) { + T t; +} + +template<> void f0(NonDefaultConstructible) { } + +void test_f0(NonDefaultConstructible NDC) { + f0(NDC); +} + +// -- class template +template +struct X0 { + static T member; + + void f1(T t) { + t = 17; + } + + struct Inner : public T { }; + + template + struct InnerTemplate : public T { }; + + template + void ft1(T t, U u); +}; + +template +template +void X0::ft1(T t, U u) { + t = u; +} + +template T X0::member; + +template<> struct X0 { }; +X0 test_X0; + + +// -- member function of a class template +template<> void X0::f1(void *) { } + +void test_spec(X0 xvp, void *vp) { + xvp.f1(vp); +} + +// -- static data member of a class template +template<> +NonDefaultConstructible X0::member = 17; + +NonDefaultConstructible &get_static_member() { + return X0::member; +} + +// -- member class of a class template +template<> +struct X0::Inner { }; + +X0::Inner inner0; + +// -- member class template of a class template +template<> +template<> +struct X0::InnerTemplate { }; + +X0::InnerTemplate inner_template0; + +// -- member function template of a class template +template<> +template<> +void X0::ft1(void*, const void*) { } + +void test_func_template(X0 xvp, void *vp, const void *cvp) { + xvp.ft1(vp, cvp); +} + +// example from the standard: +template class stream; +template<> class stream { /* ... */ }; +template class Array { /* ... */ }; +template void sort(Array& v) { /* ... */ } +template<> void sort(Array&) ; -- 2.40.0