re PR c++/68309 (ICE: Segmentation fault)
authorJason Merrill <jason@redhat.com>
Mon, 14 Dec 2015 20:54:17 +0000 (15:54 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 14 Dec 2015 20:54:17 +0000 (15:54 -0500)
PR c++/68309
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.

From-SVN: r231632

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 f21f69cbea9d452c9c0f62f5df11776efa857e56..e7b2d6822bb34cb6489a106f02147367f9379280 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 e8bcba51162f427cce89b989806d5ebd58f51887..69c18871cfced7e52ae31f99d7aeddc414fbd3be 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 60cc94c2aac4c8d766db5d00164fa80ee7786152..a45e6df9e8b0b1bb2927b41a1c03e954e2704daf 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 81ede08e7c7c7ad0830a7c367e2181af870187df..510353bf4f787fac7b3efaf8f6d523291aa8fe0f 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 85598301e9b922446ce93c63a2f54ba0ea52547e..53e72e66f335f4c2836d330a9ab999d1fe23d3dd 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.  */
@@ -581,6 +585,35 @@ hash_table<Descriptor, Allocator>::hash_table (size_t size, bool ggc, bool
   m_size_prime_index = size_prime_index;
 }
 
+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 ()
 {
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); }