re PR c++/48069 (FAIL: g++.old-deja/g++.pt/spec26.C)
[gcc.git] / gcc / tree.c
index 26622789bf611b7e716f544c00bd6a8234f0ced7..d923ac89a766146369c8957efa1ad8d587e0fee6 100644 (file)
@@ -1,7 +1,7 @@
 /* Language-independent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+   2011 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -4577,6 +4577,25 @@ free_lang_data_in_decl (tree decl)
     }
   else if (TREE_CODE (decl) == TYPE_DECL)
     DECL_INITIAL (decl) = NULL_TREE;
+  else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL
+           && DECL_INITIAL (decl)
+           && TREE_CODE (DECL_INITIAL (decl)) == BLOCK)
+    {
+      /* Strip builtins from the translation-unit BLOCK.  We still have
+        targets without builtin_decl support and also builtins are
+        shared nodes and thus we can't use TREE_CHAIN in multiple
+        lists.  */
+      tree *nextp = &BLOCK_VARS (DECL_INITIAL (decl));
+      while (*nextp)
+        {
+          tree var = *nextp;
+          if (TREE_CODE (var) == FUNCTION_DECL
+              && DECL_BUILT_IN (var))
+           *nextp = TREE_CHAIN (var);
+         else
+           nextp = &TREE_CHAIN (var);
+        }
+    }
 }
 
 
@@ -5509,7 +5528,8 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
         DECL_DLLIMPORT_P (node) = 1;
     }
   else if (TREE_CODE (node) == FUNCTION_DECL
-          && DECL_DECLARED_INLINE_P (node))
+          && DECL_DECLARED_INLINE_P (node)
+          && flag_keep_inline_dllexport)
     /* An exported function, even if inline, must be emitted.  */
     DECL_EXTERNAL (node) = 0;
 
@@ -5961,12 +5981,18 @@ type_hash_eq (const void *va, const void *vb)
       || TREE_TYPE (a->type) != TREE_TYPE (b->type)
       || !attribute_list_equal (TYPE_ATTRIBUTES (a->type),
                                 TYPE_ATTRIBUTES (b->type))
-      || TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
-      || TYPE_MODE (a->type) != TYPE_MODE (b->type)
       || (TREE_CODE (a->type) != COMPLEX_TYPE
           && TYPE_NAME (a->type) != TYPE_NAME (b->type)))
     return 0;
 
+  /* Be careful about comparing arrays before and after the element type
+     has been completed; don't compare TYPE_ALIGN unless both types are
+     complete.  */
+  if (COMPLETE_TYPE_P (a->type) && COMPLETE_TYPE_P (b->type)
+      && (TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type)
+         || TYPE_MODE (a->type) != TYPE_MODE (b->type)))
+    return 0;
+
   switch (TREE_CODE (a->type))
     {
     case VOID_TYPE:
@@ -6007,15 +6033,16 @@ type_hash_eq (const void *va, const void *vb)
       return TYPE_OFFSET_BASETYPE (a->type) == TYPE_OFFSET_BASETYPE (b->type);
 
     case METHOD_TYPE:
-      return (TYPE_METHOD_BASETYPE (a->type) == TYPE_METHOD_BASETYPE (b->type)
-             && (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type)
-                 || (TYPE_ARG_TYPES (a->type)
-                     && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST
-                     && TYPE_ARG_TYPES (b->type)
-                     && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST
-                     && type_list_equal (TYPE_ARG_TYPES (a->type),
-                                         TYPE_ARG_TYPES (b->type)))));
-
+      if (TYPE_METHOD_BASETYPE (a->type) == TYPE_METHOD_BASETYPE (b->type)
+         && (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type)
+             || (TYPE_ARG_TYPES (a->type)
+                 && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST
+                 && TYPE_ARG_TYPES (b->type)
+                 && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST
+                 && type_list_equal (TYPE_ARG_TYPES (a->type),
+                                     TYPE_ARG_TYPES (b->type)))))
+        break;
+      return 0;
     case ARRAY_TYPE:
       return TYPE_DOMAIN (a->type) == TYPE_DOMAIN (b->type);
 
@@ -10939,7 +10966,7 @@ lhd_gcc_personality (void)
 tree
 get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
 {
-  tree type = TREE_TYPE (binfo);
+  tree type = BINFO_TYPE (binfo);
 
   while (true)
     {
@@ -10947,7 +10974,7 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
       tree fld;
       int i;
 
-      if (type == expected_type)
+      if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (expected_type))
          return binfo;
       if (offset < 0)
        return NULL_TREE;