From dc49d523db70a1c9005b7c09de80b22ccb1ed6a4 Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Mon, 15 Jul 2013 06:14:07 +0000 Subject: [PATCH] Fix to PR12262 - assertion when substituting explicit template arguments does not substitute a sizeof-pack expression. The solution is proposed by Richard Smith. Differential Revision: http://llvm-reviews.chandlerc.com/D869 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186306 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiate.cpp | 6 + lib/Sema/SemaTemplateInstantiateDecl.cpp | 7 + .../temp.decls/temp.variadic/sizeofpack.cpp | 177 ++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index dd9ceae50d..e86c742679 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -2700,6 +2700,12 @@ LocalInstantiationScope::findInstantiationOf(const Decl *D) { break; } + // If we're performing a partial substitution during template argument + // deduction, we may not have values for template parameters yet. + if (isa(D) || isa(D) || + isa(D)) + return 0; + // If we didn't find the decl, then we either have a sema bug, or we have a // forward reference to a label declaration. Return null to indicate that // we have an uninstantiated label. diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 14185c37ad..420ccb167f 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3588,6 +3588,13 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, return cast((*Found->get())[PackIdx]); } + // If we're performing a partial substitution during template argument + // deduction, we may not have values for template parameters yet. They + // just map to themselves. + if (isa(D) || isa(D) || + isa(D)) + return D; + // If we didn't find the decl, then we must have a label decl that hasn't // been found yet. Lazily instantiate it and return it now. assert(isa(D)); diff --git a/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp new file mode 100644 index 0000000000..6a63b029de --- /dev/null +++ b/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp @@ -0,0 +1,177 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// expected-no-diagnostics + +namespace pr12262 { + +template +void abc1(int (*xxx)[sizeof ... (Ts) + 1]); + +void qq1 () { + abc1(0); + abc1(0); +} + + +template class array {}; + + +template +array make_array1(Types&&... args); + +void qq2 () { + array<1> arr = make_array1(1); + array<3> arr2 = make_array1(1,array<5>(),0.1); +} + + +template +int make_array(array&, Types... args); + +void qq3 () { + array<1> a1; + int aa1 = make_array(a1,1); + array<2> a2; + int aa2 = make_array(a2, 0L, "abc"); +} + + +template +struct AAA { + template + static array make_array(Types ... args); +}; + +void qq4 () { + array<2> arr2 = AAA::make_array(1,2); +} + +} + + +namespace pr12439 { + +template +struct X { + template + using get_t = decltype(sizeof...(Members)); + + template + get_t get(); +}; + +template +template +X::get_t X::get() +{ + return 0; +} + +} + + +namespace pr13272 { + +template +struct enable_if { }; + +template struct enable_if { + typedef T type; +}; + +class Exception {}; + +template +void cxx_throw(typename enable_if<(sizeof...(Args) > 0), const char *>::type fmt, Args&&... args) { + return; +} + +void test() { + cxx_throw("Youpi",1); +} + +} + + +namespace pr13817 { + +template +struct zod; + +template <> +struct zod<1> {}; + +template +zod make_zod(Ts ...) { + return zod(); +} + +int main(int argc, char *argv[]) +{ + make_zod(1); + return 0; +} + +} + + +namespace pr14273 { + +template +struct myType +{ }; + +template +struct Counter +{ + static const int count = 1 + Counter::count; +}; + +template +struct Counter +{ + static const int count = 1; +}; + +template +myType* make_array_with_type(const Args&... args) +{ + return 0; +} + +void func(void) +{ + make_array_with_type(1,2,3); +} + +} + + +namespace pr15112 +{ + template + struct enable_if + { }; + template + struct enable_if + { typedef _Tp type; }; + + typedef __typeof__(sizeof(int)) size_t; + + template + struct is_array_of { static const bool value = true; }; + + struct cpu { using value_type = void; }; + + template + struct coords_alias { typedef T type; }; + + template + using coords = typename coords_alias::type; + + template + typename enable_if::value, + coords>::type + mkcoords(Args... args); + + auto c1 = mkcoords(0ul, 0ul, 0ul); +} -- 2.40.0