r186306 - Fix to PR12262 - assertion when substituting explicit template arguments
Serge Pavlov
sepavloff at gmail.com
Sun Jul 14 23:14:08 PDT 2013
Author: sepavloff
Date: Mon Jul 15 01:14:07 2013
New Revision: 186306
URL: http://llvm.org/viewvc/llvm-project?rev=186306&view=rev
Log:
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
Added:
cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=186306&r1=186305&r2=186306&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Jul 15 01:14:07 2013
@@ -2700,6 +2700,12 @@ LocalInstantiationScope::findInstantiati
break;
}
+ // If we're performing a partial substitution during template argument
+ // deduction, we may not have values for template parameters yet.
+ if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
+ isa<TemplateTemplateParmDecl>(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.
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=186306&r1=186305&r2=186306&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Jul 15 01:14:07 2013
@@ -3588,6 +3588,13 @@ NamedDecl *Sema::FindInstantiatedDecl(So
return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[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<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
+ isa<TemplateTemplateParmDecl>(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<LabelDecl>(D));
Added: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp?rev=186306&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp Mon Jul 15 01:14:07 2013
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+namespace pr12262 {
+
+template<typename T, typename... Ts>
+void abc1(int (*xxx)[sizeof ... (Ts) + 1]);
+
+void qq1 () {
+ abc1<int>(0);
+ abc1<int,double>(0);
+}
+
+
+template <unsigned N> class array {};
+
+
+template<typename T, typename... Types>
+array<sizeof...(Types)> make_array1(Types&&... args);
+
+void qq2 () {
+ array<1> arr = make_array1<int>(1);
+ array<3> arr2 = make_array1<int>(1,array<5>(),0.1);
+}
+
+
+template<typename T, typename... Types>
+int make_array(array<sizeof...(Types)>&, Types... args);
+
+void qq3 () {
+ array<1> a1;
+ int aa1 = make_array<int>(a1,1);
+ array<2> a2;
+ int aa2 = make_array<int>(a2, 0L, "abc");
+}
+
+
+template<typename ... Ts>
+struct AAA {
+ template<typename T, typename... Types>
+ static array<sizeof...(Types)> make_array(Types ... args);
+};
+
+void qq4 () {
+ array<2> arr2 = AAA<int, int>::make_array<int>(1,2);
+}
+
+}
+
+
+namespace pr12439 {
+
+template<class... Members>
+struct X {
+ template<int Idx>
+ using get_t = decltype(sizeof...(Members));
+
+ template<int i>
+ get_t<i> get();
+};
+
+template<class... Members>
+template<int i>
+X<Members...>::get_t<i> X<Members...>::get()
+{
+ return 0;
+}
+
+}
+
+
+namespace pr13272 {
+
+template<bool B, class T = void>
+struct enable_if { };
+
+template<class T> struct enable_if<true, T> {
+ typedef T type;
+};
+
+class Exception {};
+
+template<class Ex, typename... Args>
+void cxx_throw(typename enable_if<(sizeof...(Args) > 0), const char *>::type fmt, Args&&... args) {
+ return;
+}
+
+void test() {
+ cxx_throw<Exception>("Youpi",1);
+}
+
+}
+
+
+namespace pr13817 {
+
+template <unsigned>
+struct zod;
+
+template <>
+struct zod<1> {};
+
+template <typename T, typename ... Ts>
+zod<sizeof...(Ts)> make_zod(Ts ...) {
+ return zod<sizeof...(Ts)>();
+}
+
+int main(int argc, char *argv[])
+{
+ make_zod<int>(1);
+ return 0;
+}
+
+}
+
+
+namespace pr14273 {
+
+template<typename T, int i>
+struct myType
+{ };
+
+template<typename T, typename... Args>
+struct Counter
+{
+ static const int count = 1 + Counter<Args...>::count;
+};
+
+template<typename T>
+struct Counter<T>
+{
+ static const int count = 1;
+};
+
+template<typename Arg, typename... Args>
+myType<Arg, sizeof...(Args)>* make_array_with_type(const Args&... args)
+{
+ return 0;
+}
+
+void func(void)
+{
+ make_array_with_type<char>(1,2,3);
+}
+
+}
+
+
+namespace pr15112
+{
+ template<bool, typename _Tp = void>
+ struct enable_if
+ { };
+ template<typename _Tp>
+ struct enable_if<true,_Tp>
+ { typedef _Tp type; };
+
+ typedef __typeof__(sizeof(int)) size_t;
+
+ template <size_t n, typename T, typename... Args>
+ struct is_array_of { static const bool value = true; };
+
+ struct cpu { using value_type = void; };
+
+ template <size_t Order, typename T>
+ struct coords_alias { typedef T type; };
+
+ template <size_t Order, typename MemoryTag>
+ using coords = typename coords_alias<Order, MemoryTag>::type;
+
+ template <typename MemTag, typename... Args>
+ typename enable_if<is_array_of<sizeof...(Args), size_t, Args...>::value,
+ coords<sizeof...(Args), MemTag>>::type
+ mkcoords(Args... args);
+
+ auto c1 = mkcoords<cpu>(0ul, 0ul, 0ul);
+}
More information about the cfe-commits
mailing list