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