PR c++/68309
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Dec 2015 20:54:17 +0000 (20:54 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Dec 2015 20:54:17 +0000 (20:54 +0000)
gcc/
* hash-table.h: Add copy constructor.
* hash-map.h: Add copy constructor.
gcc/cp/
* pt.c (instantiate_decl): Copy local_specializations for nested
function.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231632 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/hash-map.h
gcc/hash-table.h
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic3.C [new file with mode: 0644]

index f21f69c..e7b2d68 100644 (file)
@@ -1,3 +1,9 @@
+2015-12-14  Jason Merrill  <jason@redhat.com>
+
+       PR c++/68309
+       * hash-table.h: Add copy constructor.
+       * hash-map.h: Add copy constructor.
+
 2015-12-14  Tom de Vries  <tom@codesourcery.com>
 
        PR other/68882
index e8bcba5..69c1887 100644 (file)
@@ -1,3 +1,9 @@
+2015-12-14  Jason Merrill  <jason@redhat.com>
+
+       PR c++/68309
+       * pt.c (instantiate_decl): Copy local_specializations for nested
+       function.
+
 2015-12-09  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/60218
index 60cc94c..a45e6df 100644 (file)
@@ -21725,8 +21725,13 @@ instantiate_decl (tree d, int defer_ok,
         template from within the body of another.  */
       saved_local_specializations = local_specializations;
 
-      /* Set up the list of local specializations.  */
-      local_specializations = new hash_map<tree, tree>;
+      /* Set up the list of local specializations, copying the current
+        list if there is one.  */
+      if (local_specializations)
+       local_specializations
+         = new hash_map<tree, tree> (*local_specializations);
+      else
+       local_specializations = new hash_map<tree, tree>;
 
       /* Set up context.  */
       if (DECL_OMP_DECLARE_REDUCTION_P (code_pattern)
index 81ede08..510353b 100644 (file)
@@ -111,6 +111,11 @@ public:
                     CXX_MEM_STAT_INFO)
     : m_table (n, ggc, gather_mem_stats, HASH_MAP_ORIGIN PASS_MEM_STAT) {}
 
+  hash_map (const hash_map &h, bool ggc = false,
+           bool gather_mem_stats = GATHER_STATISTICS CXX_MEM_STAT_INFO)
+    : m_table (h.m_table, ggc, gather_mem_stats,
+              HASH_MAP_ORIGIN PASS_MEM_STAT) {}
+
   /* Create a hash_map in ggc memory.  */
   static hash_map *create_ggc (size_t size,
                               bool gather_mem_stats = GATHER_STATISTICS
index 8559830..53e72e6 100644 (file)
@@ -365,6 +365,10 @@ public:
                       bool gather_mem_stats = GATHER_STATISTICS,
                       mem_alloc_origin origin = HASH_TABLE_ORIGIN
                       CXX_MEM_STAT_INFO);
+  hash_table (const hash_table &, bool ggc = false,
+             bool gather_mem_stats = GATHER_STATISTICS,
+             mem_alloc_origin origin = HASH_TABLE_ORIGIN
+             CXX_MEM_STAT_INFO);
   ~hash_table ();
 
   /* Create a hash_table in gc memory.  */
@@ -582,6 +586,35 @@ hash_table<Descriptor, Allocator>::hash_table (size_t size, bool ggc, bool
 }
 
 template<typename Descriptor, template<typename Type> class Allocator>
+hash_table<Descriptor, Allocator>::hash_table (const hash_table &h, bool ggc,
+                                              bool gather_mem_stats,
+                                              mem_alloc_origin origin
+                                              MEM_STAT_DECL) :
+  m_n_elements (h.m_n_elements), m_n_deleted (h.m_n_deleted),
+  m_searches (0), m_collisions (0), m_ggc (ggc),
+  m_gather_mem_stats (gather_mem_stats)
+{
+  size_t size = h.m_size;
+
+  if (m_gather_mem_stats)
+    hash_table_usage.register_descriptor (this, origin, ggc
+                                         FINAL_PASS_MEM_STAT);
+
+  value_type *nentries = alloc_entries (size PASS_MEM_STAT);
+  for (size_t i = 0; i < size; ++i)
+    {
+      value_type &entry = h.m_entries[i];
+      if (is_deleted (entry))
+       mark_deleted (nentries[i]);
+      else if (!is_empty (entry))
+       nentries[i] = entry;
+    }
+  m_entries = nentries;
+  m_size = size;
+  m_size_prime_index = h.m_size_prime_index;
+}
+
+template<typename Descriptor, template<typename Type> class Allocator>
 hash_table<Descriptor, Allocator>::~hash_table ()
 {
   for (size_t i = m_size - 1; i < m_size; i--)
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic3.C
new file mode 100644 (file)
index 0000000..76b6b3f
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/68309
+// { dg-do compile { target c++11 } }
+
+template <class... Ts> void f(Ts...);
+template <class T> T g(T);
+template <typename... Ts> void print(Ts... args) {
+  [&] { f(g<decltype(args)>(args)...); }();
+}
+int main() { print(5.2); }