From 4db15d75ec50a9eb20ebd8fa95a1fda5c7a635e3 Mon Sep 17 00:00:00 2001
From: Jan Hubicka <jh@suse.cz>
Date: Thu, 4 Sep 2008 12:30:26 +0200
Subject: [PATCH] re PR tree-optimization/37345 (Segfault in
 decl_function_context (TYPE_MAIN_VARIANT))

	PR tree-optimization/37345
	PR tree-optimization/37358
	PR tree-optimization/37357
	* tree.c (build_function_type_skip_args): Build distinct type copy;
	set TYPE_CONTEXT.
	(build_function_decl_skip_args): Set type of new decl not orig decl;
	clear DECL_VINDEX for methods turned into functions.

From-SVN: r139980
---
 gcc/ChangeLog                          | 10 ++++++++++
 gcc/testsuite/ChangeLog                |  7 +++++++
 gcc/testsuite/g++.dg/torture/pr37345.C | 15 +++++++++++++++
 gcc/tree.c                             | 14 ++++++++++++--
 4 files changed, 44 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/torture/pr37345.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d3d023ebc44b..eba838bab8e0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2008-09-04  Jan Hubicka  <jh@suse.cz>
+
+	PR tree-optimization/37345
+	PR tree-optimization/37358
+	PR tree-optimization/37357
+	* tree.c (build_function_type_skip_args): Build distinct type copy;
+	set TYPE_CONTEXT.
+	(build_function_decl_skip_args): Set type of new decl not orig decl;
+	clear DECL_VINDEX for methods turned into functions.
+
 2008-09-04  Nick Clifton  <nickc@redhat.com>
 
 	* configure.ac (HAVE_GAS_LCOMM_WITH_ALIGNMENT): New assembler
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7348b958eee3..40bf497a77fd 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2008-09-03  Jan Hubicka  <jh@suse.cz>
+
+	PR tree-optimization/37345
+	PR tree-optimization/37358
+	PR tree-optimization/37357
+	* g++.dg/torture/pr37345.c: New file.
+
 2008-09-03  Tobias Grosser  <grosser@fim.uni-passau.de>
 
 	* lib/target-supports.exp (check_effective_target_fgraphite): Fix test.
diff --git a/gcc/testsuite/g++.dg/torture/pr37345.C b/gcc/testsuite/g++.dg/torture/pr37345.C
new file mode 100644
index 000000000000..5b49f53069d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr37345.C
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+class EbmlElement {                                                                                                                                                    
+    virtual EbmlElement * Clone() const;                                                                                                                               
+};                                                                                                                                                                     
+class KaxTracks : public EbmlElement {                                                                                                                                 
+public:                                                                                                                                                                
+    EbmlElement * Clone() const {                                                                                                                                      
+        return new KaxTracks(*this);                                                                                                                                   
+    }                                                                                                                                                                  
+};                                                                                                                                                                     
+KaxTracks kax_tracks;                                                                                                                                                  
+void finish_file(void)                                                                                                                                                 
+{                                                                                                                                                                      
+  kax_tracks.Clone();                                                                                                                                                  
+} 
diff --git a/gcc/tree.c b/gcc/tree.c
index 95680bacb612..71267bdb82c5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -5925,7 +5925,12 @@ build_function_type_skip_args (tree orig_type, bitmap args_to_skip)
       TYPE_ARG_TYPES (new_type) = new_reversed;
     }
   else
-    new_type = build_function_type (TREE_TYPE (orig_type), new_reversed);
+    {
+      new_type
+        = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
+							 new_reversed));
+      TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
+    }
 
   /* This is a new type, not a copy of an old type.  Need to reassociate
      variants.  We can handle everything except the main variant lazily.  */
@@ -5959,7 +5964,12 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip)
   new_type = TREE_TYPE (orig_decl);
   if (prototype_p (new_type))
     new_type = build_function_type_skip_args (new_type, args_to_skip);
-  TREE_TYPE (orig_decl) = new_type;
+  TREE_TYPE (new_decl) = new_type;
+
+  /* For declarations setting DECL_VINDEX (i.e. methods)
+     we expect first argument to be THIS pointer.   */
+  if (bitmap_bit_p (args_to_skip, 0))
+    DECL_VINDEX (new_decl) = NULL_TREE;
   return new_decl;
 }
 
-- 
GitLab