OSDN Git Service

install.texi: document language-specific check- shortcuts
[pf3gnuchains/gcc-fork.git] / gcc / varasm.c
index 2c31af9..79c81fa 100644 (file)
@@ -1198,16 +1198,23 @@ make_decl_rtl (tree decl)
   else if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
     {
       const char *asmspec = name+1;
+      enum machine_mode mode = DECL_MODE (decl);
       reg_number = decode_reg_name (asmspec);
       /* First detect errors in declaring global registers.  */
       if (reg_number == -1)
        error ("register name not specified for %q+D", decl);
       else if (reg_number < 0)
        error ("invalid register name for %q+D", decl);
-      else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
+      else if (mode == BLKmode)
        error ("data type of %q+D isn%'t suitable for a register",
               decl);
-      else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
+      else if (!in_hard_reg_set_p (accessible_reg_set, mode, reg_number))
+       error ("the register specified for %q+D cannot be accessed"
+              " by the current target", decl);
+      else if (!in_hard_reg_set_p (operand_reg_set, mode, reg_number))
+       error ("the register specified for %q+D is not general enough"
+              " to be used as a register variable", decl);
+      else if (!HARD_REGNO_MODE_OK (reg_number, mode))
        error ("register specified for %q+D isn%'t suitable for data type",
                decl);
       /* Now handle properly declared static register variables.  */
@@ -1230,7 +1237,7 @@ make_decl_rtl (tree decl)
             confused with that register and be eliminated.  This usage is
             somewhat suspect...  */
 
-         SET_DECL_RTL (decl, gen_rtx_raw_REG (DECL_MODE (decl), reg_number));
+         SET_DECL_RTL (decl, gen_rtx_raw_REG (mode, reg_number));
          ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number;
          REG_USERVAR_P (DECL_RTL (decl)) = 1;
 
@@ -1242,7 +1249,7 @@ make_decl_rtl (tree decl)
              name = IDENTIFIER_POINTER (DECL_NAME (decl));
              ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, reg_number, name);
 #endif
-             nregs = hard_regno_nregs[reg_number][DECL_MODE (decl)];
+             nregs = hard_regno_nregs[reg_number][mode];
              while (nregs > 0)
                globalize_reg (decl, reg_number + --nregs);
            }
@@ -2109,7 +2116,9 @@ incorporeal_function_p (tree decl)
        return true;
 
       name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-      if (is_builtin_name (name))
+      /* Atomic or sync builtins which have survived this far will be
+        resolved externally and therefore are not incorporeal.  */
+      if (strncmp (name, "__builtin_", 10) == 0)
        return true;
     }
   return false;
@@ -5785,14 +5794,11 @@ void
 assemble_alias (tree decl, tree target)
 {
   tree target_decl;
-  bool is_weakref = false;
 
   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
     {
       tree alias = DECL_ASSEMBLER_NAME (decl);
 
-      is_weakref = true;
-
       ultimate_transparent_alias_target (&target);
 
       if (alias == target)
@@ -5830,12 +5836,6 @@ assemble_alias (tree decl, tree target)
     }
   TREE_USED (decl) = 1;
 
-  /* A quirk of the initial implementation of aliases required that the user
-     add "extern" to all of them.  Which is silly, but now historical.  Do
-     note that the symbol is in fact locally defined.  */
-  if (! is_weakref)
-    DECL_EXTERNAL (decl) = 0;
-
   /* Allow aliases to aliases.  */
   if (TREE_CODE (decl) == FUNCTION_DECL)
     cgraph_get_create_node (decl)->alias = true;
@@ -6911,11 +6911,14 @@ default_binds_local_p_1 (const_tree exp, int shlib)
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
     local_p = true;
-  /* Weakrefs may not bind locally, even though the weakref itself is
-     always static and therefore local.
-     FIXME: We can resolve this more curefuly by looking at the weakref
-     alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)))
+  /* Weakrefs may not bind locally, even though the weakref itself is always
+     static and therefore local.  Similarly, the resolver for ifunc functions
+     might resolve to a non-local function.
+     FIXME: We can resolve the weakref case more curefuly by looking at the
+     weakref alias.  */
+  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+          || (TREE_CODE (exp) == FUNCTION_DECL
+              && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
     local_p = false;
   /* Static variables are always local.  */
   else if (! TREE_PUBLIC (exp))
@@ -7655,7 +7658,7 @@ get_elf_initfini_array_priority_section (int priority,
       sprintf (buf, "%s.%.5u", 
               constructor_p ? ".init_array" : ".fini_array",
               priority);
-      sec = get_section (buf, SECTION_WRITE, NULL_TREE);
+      sec = get_section (buf, SECTION_WRITE | SECTION_NOTYPE, NULL_TREE);
     }
   else
     {
@@ -7663,16 +7666,16 @@ get_elf_initfini_array_priority_section (int priority,
        {
          if (elf_init_array_section == NULL)
            elf_init_array_section
-             = get_unnamed_section (0, output_section_asm_op,
-                                    "\t.section\t.init_array");
+             = get_section (".init_array",
+                            SECTION_WRITE | SECTION_NOTYPE, NULL_TREE);
          sec = elf_init_array_section;
        }
       else
        {
          if (elf_fini_array_section == NULL)
            elf_fini_array_section
-             = get_unnamed_section (0, output_section_asm_op,
-                                    "\t.section\t.fini_array");
+             = get_section (".fini_array",
+                            SECTION_WRITE | SECTION_NOTYPE, NULL_TREE);
          sec = elf_fini_array_section;
        }
     }