This commit is contained in:
Jakub Jelinek 2008-09-05 08:43:54 +00:00
parent 1af11d046b
commit cd9cbfcd14
17 changed files with 572 additions and 3455 deletions

View File

@ -1,2 +1,2 @@
gcc-4.3.2-20080829.tar.bz2 gcc-4.3.2-20080905.tar.bz2
fastjar-0.95.tar.gz fastjar-0.95.tar.gz

View File

@ -1,739 +0,0 @@
2008-05-07 Jakub Jelinek <jakub@redhat.com>
PR debug/35896
* dwarf2out.c (dw_expand_expr, common_check): Removed.
(fortran_common): New function.
(gen_variable_die): Call fortran_common instead of common_check,
adjust for it returning tree instead of rtx. Formatting.
2008-04-26 George Helffrich <george@gcc.gnu.org>
PR fortran/35892
PR fortran/35154
* trans-common.c (create_common): Add decl to function
chain (if inside one) to preserve identifier scope in debug output.
* gfortran.dg/debug/pr35154-stabs.f: New test case for
.stabs functionality.
* gfortran.dg/debug/pr35154-dwarf2.f: New test case for
DWARF functionality.
2008-04-18 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/35724
* trans-common.c (create_common): Revert patch causing regression.
2008-04-01 George Helffrich <george@gcc.gnu.org>
PR fortran/PR35154, fortran/PR23057
* fortran/trans-common.c (create_common): Add decl to function
chain to preserve identifier scope in debug output.
* dbxout.c: Emit .stabs debug info for Fortran COMMON block
variables as base symbol name + offset using N_BCOMM/N_ECOMM.
(is_fortran, dbxout_common_name, dbxout_common_check): New functions.
(dbxout_symbol_location): Transform N_LCSYM to N_GSYM for storage
in common.
(dbxout_syms): Check for COMMON-based symbol and wrap in
N_BCOMM/N_ECOMM stab bracket, including as many symbols as possible
in bracket for efficiency.
* dwarf2out.c: Emit DWARF debug info for Fortran COMMON block
using DW_TAG_common_block + member offset.
(add_pubname_string): New function.
(dw_expand_expr): New function to find block name and offset for
COMMON var.
(common_check): New function to check whether symbol in Fortran COMMON.
(gen_variable_die): If COMMON, use DW_TAG_common_block.
* testsuite/gcc.dg/debug/pr35154.c: New test to check that non-Fortran
use of common is unchanged.
* testsuite/lib/gfortran-dg.exp: New harness to compile Fortran progs
with all combinations of debug options available on target.
* testsuite/gfortran.dg/debug/debug.exp: Ditto.
* testsuite/gfortran.dg/debug/trivial.f: Ditto.
--- gcc/dbxout.c (revision 133800)
+++ gcc/dbxout.c (revision 133801)
@@ -322,10 +322,13 @@ static void dbxout_type_methods (tree);
static void dbxout_range_type (tree);
static void dbxout_type (tree, int);
static bool print_int_cst_bounds_in_octal_p (tree);
+static bool is_fortran (void);
static void dbxout_type_name (tree);
static void dbxout_class_name_qualifiers (tree);
static int dbxout_symbol_location (tree, tree, const char *, rtx);
static void dbxout_symbol_name (tree, const char *, int);
+static void dbxout_common_name (tree, const char *, STAB_CODE_TYPE);
+static const char *dbxout_common_check (tree, int *);
static void dbxout_global_decl (tree);
static void dbxout_type_decl (tree, int);
static void dbxout_handle_pch (unsigned);
@@ -973,6 +976,14 @@ get_lang_number (void)
}
+static bool
+is_fortran (void)
+{
+ unsigned int lang = get_lang_number ();
+
+ return (lang == N_SO_FORTRAN) || (lang == N_SO_FORTRAN90);
+}
+
/* At the beginning of compilation, start writing the symbol table.
Initialize `typevec' and output the standard data types of C. */
@@ -2868,8 +2879,15 @@ dbxout_symbol_location (tree decl, tree
{
if (TREE_PUBLIC (decl))
{
+ int offs;
letter = 'G';
code = N_GSYM;
+ if (NULL != dbxout_common_check (decl, &offs))
+ {
+ letter = 'V';
+ addr = 0;
+ number = offs;
+ }
}
else
{
@@ -2915,7 +2933,17 @@ dbxout_symbol_location (tree decl, tree
if (DECL_INITIAL (decl) == 0
|| (!strcmp (lang_hooks.name, "GNU C++")
&& DECL_INITIAL (decl) == error_mark_node))
- code = N_LCSYM;
+ {
+ int offs;
+ code = N_LCSYM;
+ if (NULL != dbxout_common_check (decl, &offs))
+ {
+ addr = 0;
+ number = offs;
+ letter = 'V';
+ code = N_GSYM;
+ }
+ }
else if (DECL_IN_TEXT_SECTION (decl))
/* This is not quite right, but it's the closest
of all the codes that Unix defines. */
@@ -3004,9 +3032,17 @@ dbxout_symbol_location (tree decl, tree
variable, thereby avoiding the need for a register. In such
cases we're forced to lie to debuggers and tell them that
this variable was itself `static'. */
+ int offs;
code = N_LCSYM;
letter = 'V';
- addr = XEXP (XEXP (home, 0), 0);
+ if (NULL == dbxout_common_check (decl, &offs))
+ addr = XEXP (XEXP (home, 0), 0);
+ else
+ {
+ addr = 0;
+ number = offs;
+ code = N_GSYM;
+ }
}
else if (GET_CODE (home) == CONCAT)
{
@@ -3091,6 +3127,115 @@ dbxout_symbol_name (tree decl, const cha
stabstr_C (letter);
}
+
+/* Output the common block name for DECL in a stabs.
+
+ Symbols in global common (.comm) get wrapped with an N_BCOMM/N_ECOMM pair
+ around each group of symbols in the same .comm area. The N_GSYM stabs
+ that are emitted only contain the offset in the common area. This routine
+ emits the N_BCOMM and N_ECOMM stabs. */
+
+static void
+dbxout_common_name (tree decl, const char *name, STAB_CODE_TYPE op)
+{
+ dbxout_begin_complex_stabs ();
+ stabstr_S (name);
+ dbxout_finish_complex_stabs (decl, op, NULL_RTX, NULL, 0);
+}
+
+/* Check decl to determine whether it is a VAR_DECL destined for storage in a
+ common area. If it is, the return value will be a non-null string giving
+ the name of the common storage block it will go into. If non-null, the
+ value is the offset into the common block for that symbol's storage. */
+
+static const char *
+dbxout_common_check (tree decl, int *value)
+{
+ rtx home;
+ rtx sym_addr;
+ const char *name = NULL;
+
+ /* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
+ it does not have a value (the offset into the common area), or if it
+ is thread local (as opposed to global) then it isn't common, and shouldn't
+ be handled as such.
+
+ ??? DECL_THREAD_LOCAL_P check prevents problems with improper .stabs
+ for thread-local symbols. Can be handled via same mechanism as used
+ in dwarf2out.c. */
+ if (TREE_CODE (decl) != VAR_DECL
+ || !TREE_PUBLIC(decl)
+ || !TREE_STATIC(decl)
+ || !DECL_HAS_VALUE_EXPR_P(decl)
+ || DECL_THREAD_LOCAL_P (decl)
+ || !is_fortran ())
+ return NULL;
+
+ home = DECL_RTL (decl);
+ if (home == NULL_RTX || GET_CODE (home) != MEM)
+ return NULL;
+
+ sym_addr = dbxout_expand_expr (DECL_VALUE_EXPR (decl));
+ if (sym_addr == NULL_RTX || GET_CODE (sym_addr) != MEM)
+ return NULL;
+
+ sym_addr = XEXP (sym_addr, 0);
+ if (GET_CODE (sym_addr) == CONST)
+ sym_addr = XEXP (sym_addr, 0);
+ if ((GET_CODE (sym_addr) == SYMBOL_REF || GET_CODE (sym_addr) == PLUS)
+ && DECL_INITIAL (decl) == 0)
+ {
+
+ /* We have a sym that will go into a common area, meaning that it
+ will get storage reserved with a .comm/.lcomm assembler pseudo-op.
+
+ Determine name of common area this symbol will be an offset into,
+ and offset into that area. Also retrieve the decl for the area
+ that the symbol is offset into. */
+ tree cdecl = NULL;
+
+ switch (GET_CODE (sym_addr))
+ {
+ case PLUS:
+ if (GET_CODE (XEXP (sym_addr, 0)) == CONST_INT)
+ {
+ name =
+ targetm.strip_name_encoding(XSTR (XEXP (sym_addr, 1), 0));
+ *value = INTVAL (XEXP (sym_addr, 0));
+ cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 1));
+ }
+ else
+ {
+ name =
+ targetm.strip_name_encoding(XSTR (XEXP (sym_addr, 0), 0));
+ *value = INTVAL (XEXP (sym_addr, 1));
+ cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 0));
+ }
+ break;
+
+ case SYMBOL_REF:
+ name = targetm.strip_name_encoding(XSTR (sym_addr, 0));
+ *value = 0;
+ cdecl = SYMBOL_REF_DECL (sym_addr);
+ break;
+
+ default:
+ error ("common symbol debug info is not structured as "
+ "symbol+offset");
+ }
+
+ /* Check area common symbol is offset into. If this is not public, then
+ it is not a symbol in a common block. It must be a .lcomm symbol, not
+ a .comm symbol. */
+ if (cdecl == NULL || !TREE_PUBLIC(cdecl))
+ name = NULL;
+ }
+ else
+ name = NULL;
+
+ return name;
+}
+
/* Output definitions of all the decls in a chain. Return nonzero if
anything was output */
@@ -3098,11 +3243,38 @@ int
dbxout_syms (tree syms)
{
int result = 0;
+ const char *comm_prev = NULL;
+ tree syms_prev = NULL;
+
while (syms)
{
+ int temp, copen, cclos;
+ const char *comm_new;
+
+ /* Check for common symbol, and then progression into a new/different
+ block of common symbols. Emit closing/opening common bracket if
+ necessary. */
+ comm_new = dbxout_common_check (syms, &temp);
+ copen = comm_new != NULL
+ && (comm_prev == NULL || strcmp (comm_new, comm_prev));
+ cclos = comm_prev != NULL
+ && (comm_new == NULL || strcmp (comm_new, comm_prev));
+ if (cclos)
+ dbxout_common_name (syms_prev, comm_prev, N_ECOMM);
+ if (copen)
+ {
+ dbxout_common_name (syms, comm_new, N_BCOMM);
+ syms_prev = syms;
+ }
+ comm_prev = comm_new;
+
result += dbxout_symbol (syms, 1);
syms = TREE_CHAIN (syms);
}
+
+ if (comm_prev != NULL)
+ dbxout_common_name (syms_prev, comm_prev, N_ECOMM);
+
return result;
}
--- gcc/dwarf2out.c (revision 133800)
+++ gcc/dwarf2out.c (revision 133801)
@@ -4429,6 +4429,7 @@ static void output_compilation_unit_head
static void output_comp_unit (dw_die_ref, int);
static const char *dwarf2_name (tree, int);
static void add_pubname (tree, dw_die_ref);
+static void add_pubname_string (const char *, dw_die_ref);
static void add_pubtype (tree, dw_die_ref);
static void output_pubnames (VEC (pubname_entry,gc) *);
static void add_arange (tree, dw_die_ref);
@@ -7659,18 +7660,23 @@ dwarf2_name (tree decl, int scope)
/* Add a new entry to .debug_pubnames if appropriate. */
static void
-add_pubname (tree decl, dw_die_ref die)
+add_pubname_string (const char *str, dw_die_ref die)
{
pubname_entry e;
- if (! TREE_PUBLIC (decl))
- return;
-
e.die = die;
- e.name = xstrdup (dwarf2_name (decl, 1));
+ e.name = xstrdup (str);
VEC_safe_push (pubname_entry, gc, pubname_table, &e);
}
+static void
+add_pubname (tree decl, dw_die_ref die)
+{
+
+ if (TREE_PUBLIC (decl))
+ add_pubname_string (dwarf2_name (decl, 1), die);
+}
+
/* Add a new entry to .debug_pubtypes if appropriate. */
static void
@@ -10914,6 +10920,57 @@ secname_for_decl (const_tree decl)
return secname;
}
+/* Check whether decl is a Fortran COMMON symbol. If not, NULL_RTX is returned.
+ If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the
+ value is the offset into the common block for the symbol. */
+
+static tree
+fortran_common (tree decl, HOST_WIDE_INT *value)
+{
+ tree val_expr, cvar;
+ enum machine_mode mode;
+ HOST_WIDE_INT bitsize, bitpos;
+ tree offset;
+ int volatilep = 0, unsignedp = 0;
+
+ /* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
+ it does not have a value (the offset into the common area), or if it
+ is thread local (as opposed to global) then it isn't common, and shouldn't
+ be handled as such. */
+ if (TREE_CODE (decl) != VAR_DECL
+ || !TREE_PUBLIC (decl)
+ || !TREE_STATIC (decl)
+ || !DECL_HAS_VALUE_EXPR_P (decl)
+ || !is_fortran ())
+ return NULL_TREE;
+
+ val_expr = DECL_VALUE_EXPR (decl);
+ if (TREE_CODE (val_expr) != COMPONENT_REF)
+ return NULL_TREE;
+
+ cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, true);
+
+ if (cvar == NULL_TREE
+ || TREE_CODE (cvar) != VAR_DECL
+ || DECL_ARTIFICIAL (cvar)
+ || !TREE_PUBLIC (cvar))
+ return NULL_TREE;
+
+ *value = 0;
+ if (offset != NULL)
+ {
+ if (!host_integerp (offset, 0))
+ return NULL_TREE;
+ *value = tree_low_cst (offset, 0);
+ }
+ if (bitpos != 0)
+ *value += bitpos / BITS_PER_UNIT;
+
+ return cvar;
+}
+
+
/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
data attribute for a variable or a parameter. We generate the
DW_AT_const_value attribute only in those cases where the given variable
@@ -12811,9 +12868,10 @@ gen_subprogram_die (tree decl, dw_die_re
static void
gen_variable_die (tree decl, dw_die_ref context_die)
{
+ HOST_WIDE_INT off;
+ tree com_decl;
+ dw_die_ref var_die;
tree origin = decl_ultimate_origin (decl);
- dw_die_ref var_die = new_die (DW_TAG_variable, context_die, decl);
-
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (DECL_EXTERNAL (decl)
/* If DECL is COMDAT and has not actually been
@@ -12837,6 +12895,37 @@ gen_variable_die (tree decl, dw_die_ref
&& DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
|| class_or_namespace_scope_p (context_die));
+ com_decl = fortran_common (decl, &off);
+
+ /* Symbol in common gets emitted as a child of the common block, in the form
+ of a data member.
+
+ ??? This creates a new common block die for every common block symbol.
+ Better to share same common block die for all symbols in that block. */
+ if (com_decl)
+ {
+ tree field;
+ dw_die_ref com_die;
+ const char *cnam = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
+ dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
+
+ field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
+ var_die = new_die (DW_TAG_common_block, context_die, decl);
+ add_name_and_src_coords_attributes (var_die, field);
+ add_AT_flag (var_die, DW_AT_external, 1);
+ add_AT_loc (var_die, DW_AT_location, loc);
+ com_die = new_die (DW_TAG_member, var_die, decl);
+ add_name_and_src_coords_attributes (com_die, decl);
+ add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
+ TREE_THIS_VOLATILE (decl), context_die);
+ add_AT_loc (com_die, DW_AT_data_member_location,
+ int_loc_descriptor (off));
+ add_pubname_string (cnam, var_die); /* ??? needed? */
+ return;
+ }
+
+ var_die = new_die (DW_TAG_variable, context_die, decl);
+
if (origin != NULL)
add_abstract_origin_attribute (var_die, origin);
@@ -13812,8 +13901,13 @@ decls_for_scope (tree stmt, dw_die_ref c
add_child_die (context_die, die);
/* Do not produce debug information for static variables since
these might be optimized out. We are called for these later
- in varpool_analyze_pending_decls. */
- if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
+ in varpool_analyze_pending_decls.
+
+ But *do* produce it for Fortran COMMON variables because,
+ even though they are static, their names can differ depending
+ on the scope, which we need to preserve. */
+ if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
+ && !(is_fortran () && TREE_PUBLIC (decl)))
;
else
gen_decl_die (decl, context_die);
@@ -14137,6 +14231,16 @@ gen_decl_die (tree decl, dw_die_ref cont
if (debug_info_level <= DINFO_LEVEL_TERSE)
break;
+ /* If this is the global definition of the Fortran COMMON block, we don't
+ need to do anything. Syntactically, the block itself has no identity,
+ just its constituent identifiers. */
+ if (TREE_CODE (decl) == VAR_DECL
+ && TREE_PUBLIC (decl)
+ && TREE_STATIC (decl)
+ && is_fortran ()
+ && !DECL_HAS_VALUE_EXPR_P (decl))
+ break;
+
/* Output any DIEs that are needed to specify the type of this data
object. */
if (TREE_CODE (decl) == RESULT_DECL && DECL_BY_REFERENCE (decl))
@@ -14203,7 +14307,15 @@ dwarf2out_global_decl (tree decl)
/* Output DWARF2 information for file-scope tentative data object
declarations, file-scope (extern) function declarations (which had no
corresponding body) and file-scope tagged type declarations and
- definitions which have not yet been forced out. */
+ definitions which have not yet been forced out.
+
+ Ignore the global decl of any Fortran COMMON blocks which also wind up here
+ though they have already been described in the local scope for the
+ procedures using them. */
+ if (TREE_CODE (decl) == VAR_DECL
+ && TREE_PUBLIC (decl) && TREE_STATIC (decl) && is_fortran ())
+ return;
+
if (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl))
dwarf2out_decl (decl);
}
--- gcc/fortran/trans-common.c (revision 134695)
+++ gcc/fortran/trans-common.c (revision 134696)
@@ -687,7 +687,11 @@ create_common (gfc_common_head *com, seg
/* This is a fake variable just for debugging purposes. */
TREE_ASM_WRITTEN (var_decl) = 1;
- if (com)
+ /* To preserve identifier names in COMMON, chain to procedure
+ scope unless at top level in a module definition. */
+ if (com
+ && s->sym->ns->proc_name
+ && s->sym->ns->proc_name->attr.flavor == FL_MODULE)
var_decl = pushdecl_top_level (var_decl);
else
gfc_add_decl_to_function (var_decl);
--- gcc/testsuite/gfortran.dg/debug/pr35154-stabs.f (revision 0)
+++ gcc/testsuite/gfortran.dg/debug/pr35154-stabs.f (revision 134696)
@@ -0,0 +1,35 @@
+C Test program for common block debugging. G. Helffrich 11 July 2004.
+C { dg-do compile }
+C { dg-skip-if "No stabs" { mmix-*-* *-*-netware* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-sysv5* *-*-vxworks* } { "*" } { "" } }
+C { dg-skip-if "No stabs" {*-*-* } { "*" } { "-gstabs" } }
+ common i,j
+ common /label/l,m
+ i = 1
+ j = 2
+ k = 3
+ l = 4
+ m = 5
+ call sub
+ end
+ subroutine sub
+ common /label/l,m
+ logical first
+ save n
+ data first /.true./
+ if (first) then
+ n = 0
+ first = .false.
+ endif
+ n = n + 1
+ l = l + 1
+ return
+ end
+
+C { dg-final { scan-assembler ".stabs.*\"__BLNK__\",226" } }
+C { dg-final { scan-assembler ".stabs.*\"i:V.*\",.*,0" } }
+C { dg-final { scan-assembler ".stabs.*\"j:V.*\",.*,4" } }
+C { dg-final { scan-assembler ".stabs.*\"__BLNK__\",228" } }
+C { dg-final { scan-assembler ".stabs.*\"label_\",226" } }
+C { dg-final { scan-assembler ".stabs.*\"l:V.*\",.*,0" } }
+C { dg-final { scan-assembler ".stabs.*\"m:V.*\",.*,4" } }
+C { dg-final { scan-assembler ".stabs.*\"label_\",228" } }
--- gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f (revision 0)
+++ gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f (revision 134696)
@@ -0,0 +1,37 @@
+C Test program for common block debugging. G. Helffrich 11 July 2004.
+C { dg-do compile }
+C { dg-skip-if "DWARF-2 only" { "*-*-*" } { "*" } { "-gdwarf-2" } }
+C { dg-options "-dA" }
+ common i,j
+ common /label/l,m
+ i = 1
+ j = 2
+ k = 3
+ l = 4
+ m = 5
+ call sub
+ end
+ subroutine sub
+ common /label/l,m
+ logical first
+ save n
+ data first /.true./
+ if (first) then
+ n = 0
+ first = .false.
+ endif
+ n = n + 1
+ l = l + 1
+ return
+ end
+
+C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
+C { dg-final { scan-assembler "DW_AT_name: \"__BLNK__\"" } }
+C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
+C { dg-final { scan-assembler "\"i.*\".*DW_AT_name" } }
+C { dg-final { scan-assembler "\"j.*\".*DW_AT_name" } }
+C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
+C { dg-final { scan-assembler "DW_AT_name: \"label\"" } }
+C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
+C { dg-final { scan-assembler "\"l.*\".*DW_AT_name" } }
+C { dg-final { scan-assembler "\"m.*\".*DW_AT_name" } }
--- gcc/testsuite/gcc.dg/debug/pr35154.c (revision 0)
+++ gcc/testsuite/gcc.dg/debug/pr35154.c (revision 133801)
@@ -0,0 +1,34 @@
+/* Test to make sure that stabs for C symbols that go into .comm have the
+ proper structure. These should be lettered G for the struct that gives
+ the name to the .comm, and should be V or S for .lcomm symbols. */
+
+static char i_outer;
+struct {
+ char f1;
+ char f2;
+} opta;
+struct {
+ char f1;
+ char f2;
+} optb;
+
+int
+main()
+{
+ static char i_inner[2];
+ i_inner[0] = 'a'; i_inner[1] = 'b';
+ opta.f1 = 'c';
+ opta.f2 = 'd';
+ optb.f1 = 'C';
+ optb.f2 = 'D';
+ i_outer = 'e';
+/* { dg-do compile } */
+/* { dg-skip-if "No stabs" { mmix-*-* *-*-netware* alpha*-*-* hppa*64*-*-* ia64-*-* *-*-sysv5* *-*-vxworks* } { "*" } { "" } } */
+/* { dg-skip-if "stabs only" { *-*-* } { "*" } { "-gstabs" } } */
+ return 0;
+}
+
+/* { dg-final { scan-assembler ".stabs.*i_inner:V" } } */
+/* { dg-final { scan-assembler ".stabs.*i_outer:S" } } */
+/* { dg-final { scan-assembler ".stabs.*opta:G" } } */
+/* { dg-final { scan-assembler ".stabs.*optb:G" } } */
--- gcc/testsuite/lib/gfortran-dg.exp (revision 133800)
+++ gcc/testsuite/lib/gfortran-dg.exp (revision 133801)
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -107,3 +107,57 @@ proc gfortran-dg-runtest { testcases def
}
}
}
+
+proc gfortran-dg-debug-runtest { target_compile trivial opt_opts testcases } {
+ global srcdir subdir DEBUG_TORTURE_OPTIONS
+
+ if ![info exists DEBUG_TORTURE_OPTIONS] {
+ set DEBUG_TORTURE_OPTIONS ""
+ set type_list [list "-gstabs" "-gstabs+" "-gxcoff" "-gxcoff+" "-gcoff" "-gdwarf-2" ]
+ foreach type $type_list {
+ set comp_output [$target_compile \
+ "$srcdir/$subdir/$trivial" "trivial.S" assembly \
+ "additional_flags=$type"]
+ if { [string match "exit status *" $comp_output] } {
+ continue
+ }
+ if { [string match \
+ "* target system does not support the * debug format*" \
+ $comp_output]
+ } {
+ continue
+ }
+ foreach level {1 "" 3} {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
+ foreach opt $opt_opts {
+ lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}" \
+ "$opt" ]
+ }
+ }
+ }
+ }
+
+ verbose -log "Using options $DEBUG_TORTURE_OPTIONS"
+
+ global runtests
+
+ foreach test $testcases {
+ # If we're only testing specific files and this isn't one of
+ # them, skip it.
+ if ![runtest_file_p $runtests $test] {
+ continue
+ }
+
+ set nshort [file tail [file dirname $test]]/[file tail $test]
+
+ foreach flags $DEBUG_TORTURE_OPTIONS {
+ set doit 1
+ # gcc-specific checking removed here
+
+ if { $doit } {
+ verbose -log "Testing $nshort, $flags" 1
+ dg-test $test $flags ""
+ }
+ }
+ }
+}
--- gcc/testsuite/gfortran.dg/debug/debug.exp (revision 0)
+++ gcc/testsuite/gfortran.dg/debug/debug.exp (revision 133801)
@@ -0,0 +1,41 @@
+# Copyright (C) 2008 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gfortran-dg.exp
+load_lib gfortran.exp
+
+# Debugging testsuite proc
+proc gfortran-debug-dg-test { prog do_what extra_tool_flags } {
+ return [gfortran-dg-test $prog $do_what $extra_tool_flags]
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+
+gfortran_init
+
+gfortran-dg-debug-runtest gfortran_target_compile trivial.f "" \
+ [lsort [glob -nocomplain $srcdir/$subdir/*.\[fS\]]]
+
+# All done.
+dg-finish
--- gcc/testsuite/gfortran.dg/debug/trivial.f (revision 0)
+++ gcc/testsuite/gfortran.dg/debug/trivial.f (revision 133801)
@@ -0,0 +1,2 @@
+ program trivial
+ end

View File

@ -1,457 +0,0 @@
2008-08-26 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (gen_const_die): New function.
(size_of_die, value_format, output_die): Output larger
dw_val_class_vec using DW_FORM_block2 or DW_FORM_block4.
(native_encode_initializer): New function.
(tree_add_const_value_attribute): Call it.
(gen_decl_die, dwarf2out_decl): Handle CONST_DECLs if is_fortran ().
* trans-decl.c (check_constant_initializer,
gfc_emit_parameter_debug_info): New functions.
(gfc_generate_module_vars, gfc_generate_function_code): Emit
PARAMETERs and unreferenced variables with initializers into
debug info.
--- gcc/fortran/trans-decl.c.jj 2008-08-26 21:43:36.000000000 +0200
+++ gcc/fortran/trans-decl.c 2008-08-26 22:54:24.000000000 +0200
@@ -3232,6 +3232,135 @@ gfc_trans_use_stmts (gfc_namespace * ns)
}
+/* Return true if expr is a constant initializer that gfc_conv_initializer
+ will handle. */
+
+static bool
+check_constant_initializer (gfc_expr *expr, gfc_typespec *ts, bool array,
+ bool pointer)
+{
+ gfc_constructor *c;
+ gfc_component *cm;
+
+ if (pointer)
+ return true;
+ else if (array)
+ {
+ if (expr->expr_type == EXPR_CONSTANT || expr->expr_type == EXPR_NULL)
+ return true;
+ else if (expr->expr_type == EXPR_STRUCTURE)
+ return check_constant_initializer (expr, ts, false, false);
+ else if (expr->expr_type != EXPR_ARRAY)
+ return false;
+ for (c = expr->value.constructor; c; c = c->next)
+ {
+ if (c->iterator)
+ return false;
+ if (c->expr->expr_type == EXPR_STRUCTURE)
+ {
+ if (!check_constant_initializer (c->expr, ts, false, false))
+ return false;
+ }
+ else if (c->expr->expr_type != EXPR_CONSTANT)
+ return false;
+ }
+ return true;
+ }
+ else switch (ts->type)
+ {
+ case BT_DERIVED:
+ if (expr->expr_type != EXPR_STRUCTURE)
+ return false;
+ cm = expr->ts.derived->components;
+ for (c = expr->value.constructor; c; c = c->next, cm = cm->next)
+ {
+ if (!c->expr || cm->allocatable)
+ continue;
+ if (!check_constant_initializer (c->expr, &cm->ts,
+ cm->dimension,
+ cm->pointer))
+ return false;
+ }
+ return true;
+ default:
+ return expr->expr_type == EXPR_CONSTANT;
+ }
+}
+
+/* Emit debug info for parameters and unreferenced variables with
+ initializers. */
+
+static void
+gfc_emit_parameter_debug_info (gfc_symbol *sym)
+{
+ tree decl;
+
+ if (sym->attr.flavor != FL_PARAMETER
+ && (sym->attr.flavor != FL_VARIABLE || sym->attr.referenced))
+ return;
+
+ if (sym->backend_decl != NULL
+ || sym->value == NULL
+ || sym->attr.use_assoc
+ || sym->attr.dummy
+ || sym->attr.result
+ || sym->attr.function
+ || sym->attr.intrinsic
+ || sym->attr.pointer
+ || sym->attr.allocatable
+ || sym->attr.cray_pointee
+ || sym->attr.threadprivate
+ || sym->attr.is_bind_c
+ || sym->attr.subref_array_pointer
+ || sym->attr.assign)
+ return;
+
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ gfc_conv_const_charlen (sym->ts.cl);
+ if (sym->ts.cl->backend_decl == NULL
+ || TREE_CODE (sym->ts.cl->backend_decl) != INTEGER_CST)
+ return;
+ }
+ else if (sym->ts.type == BT_DERIVED && sym->ts.derived->attr.alloc_comp)
+ return;
+
+ if (sym->as)
+ {
+ int n;
+
+ if (sym->as->type != AS_EXPLICIT)
+ return;
+ for (n = 0; n < sym->as->rank; n++)
+ if (sym->as->lower[n]->expr_type != EXPR_CONSTANT
+ || sym->as->upper[n] == NULL
+ || sym->as->upper[n]->expr_type != EXPR_CONSTANT)
+ return;
+ }
+
+ if (!check_constant_initializer (sym->value, &sym->ts,
+ sym->attr.dimension, false))
+ return;
+
+ /* Create the decl for the variable or constant. */
+ decl = build_decl (sym->attr.flavor == FL_PARAMETER ? CONST_DECL : VAR_DECL,
+ gfc_sym_identifier (sym), gfc_sym_type (sym));
+ if (sym->attr.flavor == FL_PARAMETER)
+ TREE_READONLY (decl) = 1;
+ gfc_set_decl_location (decl, &sym->declared_at);
+ if (sym->attr.dimension)
+ GFC_DECL_PACKED_ARRAY (decl) = 1;
+ DECL_CONTEXT (decl) = sym->ns->proc_name->backend_decl;
+ TREE_STATIC (decl) = 1;
+ TREE_USED (decl) = 1;
+ if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
+ TREE_PUBLIC (decl) = 1;
+ DECL_INITIAL (decl)
+ = gfc_conv_initializer (sym->value, &sym->ts, TREE_TYPE (decl),
+ sym->attr.dimension, 0);
+ debug_hooks->global_decl (decl);
+}
+
/* Generate all the required code for module variables. */
void
@@ -3252,6 +3381,7 @@ gfc_generate_module_vars (gfc_namespace
cur_module = NULL;
gfc_trans_use_stmts (ns);
+ gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
}
@@ -3787,6 +3917,7 @@ gfc_generate_function_code (gfc_namespac
}
gfc_trans_use_stmts (ns);
+ gfc_traverse_ns (ns, gfc_emit_parameter_debug_info);
}
void
--- gcc/dwarf2out.c.jj 2008-08-26 21:43:31.000000000 +0200
+++ gcc/dwarf2out.c 2008-08-26 21:43:42.000000000 +0200
@@ -5093,6 +5093,7 @@ static void gen_unspecified_parameters_d
static void gen_formal_types_die (tree, dw_die_ref);
static void gen_subprogram_die (tree, dw_die_ref);
static void gen_variable_die (tree, dw_die_ref);
+static void gen_const_die (tree, dw_die_ref);
static void gen_label_die (tree, dw_die_ref);
static void gen_lexical_block_die (tree, dw_die_ref, int);
static void gen_inlined_subroutine_die (tree, dw_die_ref, int);
@@ -7564,8 +7565,10 @@ size_of_die (dw_die_ref die)
size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */
break;
case dw_val_class_vec:
- size += 1 + (a->dw_attr_val.v.val_vec.length
- * a->dw_attr_val.v.val_vec.elt_size); /* block */
+ size += constant_size (a->dw_attr_val.v.val_vec.length
+ * a->dw_attr_val.v.val_vec.elt_size)
+ + a->dw_attr_val.v.val_vec.length
+ * a->dw_attr_val.v.val_vec.elt_size; /* block */
break;
case dw_val_class_flag:
size += 1;
@@ -7764,7 +7767,18 @@ value_format (dw_attr_ref a)
case dw_val_class_long_long:
return DW_FORM_block1;
case dw_val_class_vec:
- return DW_FORM_block1;
+ switch (constant_size (a->dw_attr_val.v.val_vec.length
+ * a->dw_attr_val.v.val_vec.elt_size))
+ {
+ case 1:
+ return DW_FORM_block1;
+ case 2:
+ return DW_FORM_block2;
+ case 4:
+ return DW_FORM_block4;
+ default:
+ gcc_unreachable ();
+ }
case dw_val_class_flag:
return DW_FORM_flag;
case dw_val_class_die_ref:
@@ -8056,7 +8070,8 @@ output_die (dw_die_ref die)
unsigned int i;
unsigned char *p;
- dw2_asm_output_data (1, len * elt_size, "%s", name);
+ dw2_asm_output_data (constant_size (len * elt_size),
+ len * elt_size, "%s", name);
if (elt_size > sizeof (HOST_WIDE_INT))
{
elt_size /= 2;
@@ -11762,6 +11777,150 @@ add_location_or_const_value_attribute (d
tree_add_const_value_attribute (die, decl);
}
+/* Helper function for tree_add_const_value_attribute. Natively encode
+ initializer INIT into an array. Return true if successful. */
+
+static bool
+native_encode_initializer (tree init, unsigned char *array, int size)
+{
+ tree type;
+
+ if (init == NULL_TREE)
+ return false;
+
+ STRIP_NOPS (init);
+ switch (TREE_CODE (init))
+ {
+ case STRING_CST:
+ type = TREE_TYPE (init);
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree enttype = TREE_TYPE (type);
+ enum machine_mode mode = TYPE_MODE (enttype);
+
+ if (GET_MODE_CLASS (mode) != MODE_INT || GET_MODE_SIZE (mode) != 1)
+ return false;
+ if (int_size_in_bytes (type) != size)
+ return false;
+ if (size > TREE_STRING_LENGTH (init))
+ {
+ memcpy (array, TREE_STRING_POINTER (init),
+ TREE_STRING_LENGTH (init));
+ memset (array + TREE_STRING_LENGTH (init),
+ '\0', size - TREE_STRING_LENGTH (init));
+ }
+ else
+ memcpy (array, TREE_STRING_POINTER (init), size);
+ return true;
+ }
+ return false;
+ case CONSTRUCTOR:
+ type = TREE_TYPE (init);
+ if (int_size_in_bytes (type) != size)
+ return false;
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ HOST_WIDE_INT min_index;
+ unsigned HOST_WIDE_INT cnt;
+ int curpos = 0, fieldsize;
+ constructor_elt *ce;
+
+ if (TYPE_DOMAIN (type) == NULL_TREE
+ || !host_integerp (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0))
+ return false;
+
+ fieldsize = int_size_in_bytes (TREE_TYPE (type));
+ if (fieldsize <= 0)
+ return false;
+
+ min_index = tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0);
+ memset (array, '\0', size);
+ for (cnt = 0;
+ VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (init), cnt, ce);
+ cnt++)
+ {
+ tree val = ce->value;
+ tree index = ce->index;
+ int pos = curpos;
+ if (index && TREE_CODE (index) == RANGE_EXPR)
+ pos = (tree_low_cst (TREE_OPERAND (index, 0), 0) - min_index)
+ * fieldsize;
+ else if (index)
+ pos = tree_low_cst (index, 0) * fieldsize;
+
+ if (val)
+ {
+ STRIP_NOPS (val);
+ if (!native_encode_initializer (val, array + pos, fieldsize))
+ return false;
+ }
+ curpos = pos + fieldsize;
+ if (index && TREE_CODE (index) == RANGE_EXPR)
+ {
+ int count = tree_low_cst (TREE_OPERAND (index, 1), 0)
+ - tree_low_cst (TREE_OPERAND (index, 0), 0);
+ while (count > 0)
+ {
+ if (val)
+ memcpy (array + curpos, array + pos, fieldsize);
+ curpos += fieldsize;
+ }
+ }
+ gcc_assert (curpos <= size);
+ }
+ return true;
+ }
+ else if (TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE)
+ {
+ tree field = NULL_TREE;
+ unsigned HOST_WIDE_INT cnt;
+ constructor_elt *ce;
+
+ if (int_size_in_bytes (type) != size)
+ return false;
+
+ if (TREE_CODE (type) == RECORD_TYPE)
+ field = TYPE_FIELDS (type);
+
+ for (cnt = 0;
+ VEC_iterate (constructor_elt, CONSTRUCTOR_ELTS (init), cnt, ce);
+ cnt++, field = field ? TREE_CHAIN (field) : 0)
+ {
+ tree val = ce->value;
+ int pos, fieldsize;
+
+ if (ce->index != 0)
+ field = ce->index;
+
+ if (val)
+ STRIP_NOPS (val);
+
+ if (field == NULL_TREE || DECL_BIT_FIELD (field))
+ return false;
+
+ if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
+ && TYPE_DOMAIN (TREE_TYPE (field))
+ && ! TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (field))))
+ return false;
+ else if (DECL_SIZE_UNIT (field) == NULL_TREE
+ || !host_integerp (DECL_SIZE_UNIT (field), 0))
+ return false;
+ fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 0);
+ pos = int_byte_position (field);
+ gcc_assert (pos + fieldsize <= size);
+ if (val
+ && !native_encode_initializer (val, array + pos, fieldsize))
+ return false;
+ }
+ return true;
+ }
+ return false;
+ default:
+ return native_encode_expr (init, array, size) == size;
+ }
+}
+
/* If we don't have a copy of this variable in memory for some reason (such
as a C++ member constant that doesn't have an out-of-line definition),
we should tell the debugger about the constant value. */
@@ -11781,6 +11940,19 @@ tree_add_const_value_attribute (dw_die_r
rtl = rtl_for_decl_init (init, type);
if (rtl)
add_const_value_attribute (var_die, rtl);
+ /* If the host and target are sane, try harder. */
+ else if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
+ && initializer_constant_valid_p (init, type))
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (init));
+ if (size > 0 && (int) size == size)
+ {
+ unsigned char *array = GGC_CNEWVEC (unsigned char, size);
+
+ if (native_encode_initializer (init, array, size))
+ add_AT_vec (var_die, DW_AT_const_value, size, 1, array);
+ }
+ }
}
/* Convert the CFI instructions for the current function into a
@@ -13743,6 +13914,24 @@ gen_variable_die (tree decl, dw_die_ref
tree_add_const_value_attribute (var_die, decl);
}
+/* Generate a DIE to represent a named constant. */
+
+static void
+gen_const_die (tree decl, dw_die_ref context_die)
+{
+ dw_die_ref const_die;
+ tree type = TREE_TYPE (decl);
+
+ const_die = new_die (DW_TAG_constant, context_die, decl);
+ add_name_and_src_coords_attributes (const_die, decl);
+ add_type_attribute (const_die, type, 1, 0, context_die);
+ if (TREE_PUBLIC (decl))
+ add_AT_flag (const_die, DW_AT_external, 1);
+ if (DECL_ARTIFICIAL (decl))
+ add_AT_flag (const_die, DW_AT_artificial, 1);
+ tree_add_const_value_attribute (const_die, decl);
+}
+
/* Generate a DIE to represent a label identifier. */
static void
@@ -14883,8 +15072,20 @@ gen_decl_die (tree decl, dw_die_ref cont
break;
case CONST_DECL:
- /* The individual enumerators of an enum type get output when we output
- the Dwarf representation of the relevant enum type itself. */
+ if (!is_fortran ())
+ {
+ /* The individual enumerators of an enum type get output when we output
+ the Dwarf representation of the relevant enum type itself. */
+ break;
+ }
+
+ /* Emit its type. */
+ gen_type_die (TREE_TYPE (decl), context_die);
+
+ /* And its containing namespace. */
+ context_die = declare_in_namespace (decl, context_die);
+
+ gen_const_die (decl, context_die);
break;
case FUNCTION_DECL:
@@ -15229,6 +15430,15 @@ dwarf2out_decl (tree decl)
return;
break;
+ case CONST_DECL:
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+ if (!is_fortran ())
+ return;
+ if (TREE_STATIC (decl) && decl_function_context (decl))
+ context_die = lookup_decl_die (DECL_CONTEXT (decl));
+ break;
+
case NAMESPACE_DECL:
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;

View File

@ -1,73 +0,0 @@
2008-08-28 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (descr_info_loc): Handle VAR_DECL.
* trans.h (struct lang_type): Add span.
(GFC_TYPE_ARRAY_SPAN): Define.
* trans-decl.c (gfc_get_symbol_decl): For subref array pointers,
copy TREE_STATIC from decl to span instead of setting it
unconditionally, set DECL_ARTIFICIAL, fix type of initializer
and set GFC_TYPE_ARRAY_SPAN on decl's type.
* trans-types.c (gfc_get_array_descr_info): If
GFC_TYPE_ARRAY_SPAN is non-NULL, use it as element size.
--- gcc/fortran/trans.h.jj 2008-08-26 21:43:04.000000000 +0200
+++ gcc/fortran/trans.h 2008-08-28 09:58:01.000000000 +0200
@@ -605,6 +605,7 @@ struct lang_type GTY(())
tree offset;
tree dtype;
tree dataptr_type;
+ tree span;
};
struct lang_decl GTY(())
@@ -657,6 +658,7 @@ struct lang_decl GTY(())
#define GFC_TYPE_ARRAY_DTYPE(node) (TYPE_LANG_SPECIFIC(node)->dtype)
#define GFC_TYPE_ARRAY_DATAPTR_TYPE(node) \
(TYPE_LANG_SPECIFIC(node)->dataptr_type)
+#define GFC_TYPE_ARRAY_SPAN(node) (TYPE_LANG_SPECIFIC(node)->span)
/* Build an expression with void type. */
#define build1_v(code, arg) build1(code, void_type_node, arg)
--- gcc/fortran/trans-decl.c.jj 2008-08-26 22:54:24.000000000 +0200
+++ gcc/fortran/trans-decl.c 2008-08-28 10:54:28.000000000 +0200
@@ -1105,10 +1105,12 @@ gfc_get_symbol_decl (gfc_symbol * sym)
span = build_decl (VAR_DECL, create_tmp_var_name ("span"),
gfc_array_index_type);
gfc_finish_var_decl (span, sym);
- TREE_STATIC (span) = 1;
- DECL_INITIAL (span) = build_int_cst (NULL_TREE, 0);
+ TREE_STATIC (span) = TREE_STATIC (decl);
+ DECL_ARTIFICIAL (span) = 1;
+ DECL_INITIAL (span) = build_int_cst (gfc_array_index_type, 0);
GFC_DECL_SPAN (decl) = span;
+ GFC_TYPE_ARRAY_SPAN (TREE_TYPE (decl)) = span;
}
sym->backend_decl = decl;
--- gcc/fortran/trans-types.c.jj 2008-08-26 21:43:04.000000000 +0200
+++ gcc/fortran/trans-types.c 2008-08-28 10:23:39.000000000 +0200
@@ -2289,7 +2289,10 @@ gfc_get_array_descr_info (const_tree typ
else
info->base_decl = base_decl = build_decl (VAR_DECL, NULL_TREE, ptype);
- elem_size = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (etype));
+ if (GFC_TYPE_ARRAY_SPAN (type))
+ elem_size = GFC_TYPE_ARRAY_SPAN (type);
+ else
+ elem_size = fold_convert (gfc_array_index_type, TYPE_SIZE_UNIT (etype));
field = TYPE_FIELDS (TYPE_MAIN_VARIANT (type));
data_off = byte_position (field);
field = TREE_CHAIN (field);
--- gcc/dwarf2out.c.jj 2008-08-26 21:43:42.000000000 +0200
+++ gcc/dwarf2out.c 2008-08-28 10:35:38.000000000 +0200
@@ -12232,6 +12232,8 @@ descr_info_loc (tree val, tree base_decl
case NOP_EXPR:
case CONVERT_EXPR:
return descr_info_loc (TREE_OPERAND (val, 0), base_decl);
+ case VAR_DECL:
+ return loc_descriptor_from_tree_1 (val, 0);
case INTEGER_CST:
if (host_integerp (val, 0))
return int_loc_descriptor (tree_low_cst (val, 0));

File diff suppressed because it is too large Load Diff

View File

@ -1,82 +0,0 @@
2008-08-21 Jakub Jelinek <jakub@redhat.com>
* trans-decl.c (gfc_build_qualified_array): Build non-flat
array type for debug info purposes.
* dwarf2out.c (add_bound_info): If lookup_decl_die failed, try
loc_descriptor_from_tree_1.
--- gcc/fortran/trans-decl.c.jj 2008-08-21 11:56:09.000000000 +0200
+++ gcc/fortran/trans-decl.c 2008-08-21 23:07:01.000000000 +0200
@@ -703,6 +703,50 @@ gfc_build_qualified_array (tree decl, gf
TYPE_DOMAIN (type) = range;
layout_type (type);
}
+
+ if (nest || write_symbols == NO_DEBUG)
+ return;
+
+ if (TYPE_NAME (type) != NULL_TREE
+ && GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1) != NULL_TREE
+ && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, sym->as->rank - 1)) == VAR_DECL)
+ {
+ tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
+
+ for (dim = 0; dim < sym->as->rank - 1; dim++)
+ {
+ gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE);
+ gtype = TREE_TYPE (gtype);
+ }
+ gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE);
+ if (TYPE_MAX_VALUE (TYPE_DOMAIN (gtype)) == NULL)
+ TYPE_NAME (type) = NULL_TREE;
+ }
+
+ if (TYPE_NAME (type) == NULL_TREE)
+ {
+ tree gtype = TREE_TYPE (type), rtype, type_decl;
+
+ for (dim = sym->as->rank - 1; dim >= 0; dim--)
+ {
+ rtype = build_range_type (gfc_array_index_type,
+ GFC_TYPE_ARRAY_LBOUND (type, dim),
+ GFC_TYPE_ARRAY_UBOUND (type, dim));
+ gtype = build_array_type (gtype, rtype);
+ /* Ensure the bound variables aren't optimized out at -O0. */
+ if (!optimize)
+ {
+ if (GFC_TYPE_ARRAY_LBOUND (type, dim)
+ && TREE_CODE (GFC_TYPE_ARRAY_LBOUND (type, dim)) == VAR_DECL)
+ DECL_IGNORED_P (GFC_TYPE_ARRAY_LBOUND (type, dim)) = 0;
+ if (GFC_TYPE_ARRAY_UBOUND (type, dim)
+ && TREE_CODE (GFC_TYPE_ARRAY_UBOUND (type, dim)) == VAR_DECL)
+ DECL_IGNORED_P (GFC_TYPE_ARRAY_UBOUND (type, dim)) = 0;
+ }
+ }
+ TYPE_NAME (type) = type_decl = build_decl (TYPE_DECL, NULL, gtype);
+ DECL_ORIGINAL_TYPE (type_decl) = gtype;
+ }
}
--- gcc/dwarf2out.c.jj 2008-08-21 13:15:41.000000000 +0200
+++ gcc/dwarf2out.c 2008-08-21 18:27:30.000000000 +0200
@@ -11943,6 +11943,7 @@ add_bound_info (dw_die_ref subrange_die,
case RESULT_DECL:
{
dw_die_ref decl_die = lookup_decl_die (bound);
+ dw_loc_descr_ref loc;
/* ??? Can this happen, or should the variable have been bound
first? Probably it can, since I imagine that we try to create
@@ -11951,6 +11952,11 @@ add_bound_info (dw_die_ref subrange_die,
later parameter. */
if (decl_die != NULL)
add_AT_die_ref (subrange_die, bound_attr, decl_die);
+ else
+ {
+ loc = loc_descriptor_from_tree_1 (bound, 0);
+ add_AT_location_description (subrange_die, bound_attr, loc);
+ }
break;
}

View File

@ -1,112 +0,0 @@
2008-08-22 Jakub Jelinek <jakub@redhat.com>
PR fortran/23057
* dwarf2out.c (gen_variable_die): Represent Fortran COMMON vars
as DW_TAG_variable children of DW_TAG_common_block rather than
DW_TAG_member children. Put DW_AT_external to individual
DW_TAG_variable DIEs, not to DW_TAG_common_block.
* gfortran.dg/debug/pr35154-dwarf2.f: Adjust for replacement
of DW_TAG_member with DW_TAG_variable.
--- gcc/dwarf2out.c.jj 2008-08-21 18:27:30.000000000 +0200
+++ gcc/dwarf2out.c 2008-08-22 12:12:56.000000000 +0200
@@ -13540,43 +13540,66 @@ gen_variable_die (tree decl, dw_die_ref
{
tree field;
dw_die_ref com_die;
+ dw_loc_descr_ref loc;
- if (lookup_decl_die (decl))
- return;
+ com_die = lookup_decl_die (decl);
+ if (com_die)
+ {
+ if (get_AT (com_die, DW_AT_location) == NULL)
+ {
+ loc = loc_descriptor_from_tree (com_decl);
+ if (loc)
+ {
+ if (off)
+ add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst,
+ off, 0));
+ add_AT_loc (com_die, DW_AT_location, loc);
+ remove_AT (com_die, DW_AT_declaration);
+ }
+ }
+ return;
+ }
field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
var_die = lookup_decl_die (com_decl);
+ loc = loc_descriptor_from_tree (com_decl);
if (var_die == NULL)
{
const char *cnam
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
- dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
var_die = new_die (DW_TAG_common_block, context_die, decl);
add_name_and_src_coords_attributes (var_die, com_decl);
- add_AT_flag (var_die, DW_AT_external, 1);
if (loc)
- add_AT_loc (var_die, DW_AT_location, loc);
+ {
+ add_AT_loc (var_die, DW_AT_location, loc);
+ /* Avoid sharing the same loc descriptor between
+ DW_TAG_common_block and DW_TAG_variable. */
+ loc = loc_descriptor_from_tree (com_decl);
+ }
else if (DECL_EXTERNAL (decl))
add_AT_flag (var_die, DW_AT_declaration, 1);
add_pubname_string (cnam, var_die); /* ??? needed? */
equate_decl_number_to_die (com_decl, var_die);
}
- else if (get_AT (var_die, DW_AT_location) == NULL)
+ else if (get_AT (var_die, DW_AT_location) == NULL && loc)
{
- dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
-
- if (loc)
- {
- add_AT_loc (var_die, DW_AT_location, loc);
- remove_AT (var_die, DW_AT_declaration);
- }
+ add_AT_loc (var_die, DW_AT_location, loc);
+ loc = loc_descriptor_from_tree (com_decl);
+ remove_AT (var_die, DW_AT_declaration);
}
- com_die = new_die (DW_TAG_member, var_die, decl);
+ com_die = new_die (DW_TAG_variable, var_die, decl);
add_name_and_src_coords_attributes (com_die, decl);
add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
TREE_THIS_VOLATILE (decl), context_die);
- add_AT_loc (com_die, DW_AT_data_member_location,
- int_loc_descriptor (off));
+ add_AT_flag (com_die, DW_AT_external, 1);
+ if (loc)
+ {
+ if (off)
+ add_loc_descr (&loc, new_loc_descr (DW_OP_plus_uconst, off, 0));
+ add_AT_loc (com_die, DW_AT_location, loc);
+ }
+ else if (DECL_EXTERNAL (decl))
+ add_AT_flag (com_die, DW_AT_declaration, 1);
equate_decl_number_to_die (decl, com_die);
return;
}
--- gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f.jj 2008-04-27 12:42:44.000000000 +0200
+++ gcc/testsuite/gfortran.dg/debug/pr35154-dwarf2.f 2008-08-22 10:56:44.000000000 +0200
@@ -27,11 +27,11 @@ C { dg-options "-dA" }
C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
C { dg-final { scan-assembler "DW_AT_name: \"__BLNK__\"" } }
-C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
+C { dg-final { scan-assembler "(DIE.*DW_TAG_variable)" } }
C { dg-final { scan-assembler "\"i.*\".*DW_AT_name" } }
C { dg-final { scan-assembler "\"j.*\".*DW_AT_name" } }
C { dg-final { scan-assembler "(DIE.*DW_TAG_common_block)" } }
C { dg-final { scan-assembler "DW_AT_name: \"label\"" } }
-C { dg-final { scan-assembler "(DIE.*DW_TAG_member)" } }
+C { dg-final { scan-assembler "(DIE.*DW_TAG_variable)" } }
C { dg-final { scan-assembler "\"l.*\".*DW_AT_name" } }
C { dg-final { scan-assembler "\"m.*\".*DW_AT_name" } }

View File

@ -1,91 +0,0 @@
2008-08-22 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (loc_by_reference): New function.
(add_location_or_const_value_attribute): Use it.
--- gcc/dwarf2out.c.jj 2008-08-22 12:12:56.000000000 +0200
+++ gcc/dwarf2out.c 2008-08-22 13:39:21.000000000 +0200
@@ -10971,6 +10971,32 @@ fortran_common (tree decl, HOST_WIDE_INT
return cvar;
}
+/* Dereference a location expression LOC if DECL is passed by invisible
+ reference. */
+
+static dw_loc_descr_ref
+loc_by_reference (dw_loc_descr_ref loc, tree decl)
+{
+ HOST_WIDE_INT size;
+ enum dwarf_location_atom op;
+
+ if (loc == NULL)
+ return NULL;
+
+ if ((TREE_CODE (decl) != PARM_DECL && TREE_CODE (decl) != RESULT_DECL)
+ || !DECL_BY_REFERENCE (decl))
+ return loc;
+
+ size = int_size_in_bytes (TREE_TYPE (decl));
+ if (size > DWARF2_ADDR_SIZE || size == -1)
+ return 0;
+ else if (size == DWARF2_ADDR_SIZE)
+ op = DW_OP_deref;
+ else
+ op = DW_OP_deref_size;
+ add_loc_descr (&loc, new_loc_descr (op, size, 0));
+ return loc;
+}
/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
data attribute for a variable or a parameter. We generate the
@@ -11029,8 +11055,8 @@ add_location_or_const_value_attribute (d
else
initialized = VAR_INIT_STATUS_INITIALIZED;
- list = new_loc_list (loc_descriptor (varloc, initialized),
- node->label, node->next->label, secname, 1);
+ descr = loc_by_reference (loc_descriptor (varloc, initialized), decl);
+ list = new_loc_list (descr, node->label, node->next->label, secname, 1);
node = node->next;
for (; node->next; node = node->next)
@@ -11041,8 +11067,9 @@ add_location_or_const_value_attribute (d
enum var_init_status initialized =
NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
varloc = NOTE_VAR_LOCATION (node->var_loc_note);
- add_loc_descr_to_loc_list (&list,
- loc_descriptor (varloc, initialized),
+ descr = loc_by_reference (loc_descriptor (varloc, initialized),
+ decl);
+ add_loc_descr_to_loc_list (&list, descr,
node->label, node->next->label, secname);
}
@@ -11063,8 +11090,9 @@ add_location_or_const_value_attribute (d
current_function_funcdef_no);
endname = ggc_strdup (label_id);
}
- add_loc_descr_to_loc_list (&list,
- loc_descriptor (varloc, initialized),
+ descr = loc_by_reference (loc_descriptor (varloc, initialized),
+ decl);
+ add_loc_descr_to_loc_list (&list, descr,
node->label, endname, secname);
}
@@ -11094,6 +11122,7 @@ add_location_or_const_value_attribute (d
descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note), status);
if (descr)
{
+ descr = loc_by_reference (descr, decl);
add_AT_location_description (die, attr, descr);
return;
}
@@ -11104,6 +11133,7 @@ add_location_or_const_value_attribute (d
descr = loc_descriptor_from_tree (decl);
if (descr)
{
+ descr = loc_by_reference (descr, decl);
add_AT_location_description (die, attr, descr);
return;
}

View File

@ -1,17 +0,0 @@
2008-08-22 Jakub Jelinek <jakub@redhat.com>
PR fortran/24790
* trans-decl.c (create_function_arglist): Set DECL_BY_REFERENCE on
PARM_DECLs with pointer or reference type.
--- gcc/fortran/trans-decl.c.jj 2008-08-21 23:07:01.000000000 +0200
+++ gcc/fortran/trans-decl.c 2008-08-22 14:47:59.000000000 +0200
@@ -1588,6 +1588,8 @@ create_function_arglist (gfc_symbol * sy
DECL_ARG_TYPE (parm) = TREE_VALUE (typelist);
/* All implementation args are read-only. */
TREE_READONLY (parm) = 1;
+ if (POINTER_TYPE_P (type) && f->sym->attr.flavor != FL_PROCEDURE)
+ DECL_BY_REFERENCE (parm) = 1;
gfc_finish_decl (parm);

View File

@ -1,82 +0,0 @@
2008-08-22 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (add_subscript_info): Stop on Fortran TYPE_STRING_FLAG
types.
(gen_array_type_die): Emit DW_TAG_string_type for Fortran character
types.
--- gcc/dwarf2out.c.jj 2008-08-22 13:39:21.000000000 +0200
+++ gcc/dwarf2out.c 2008-08-22 17:49:10.000000000 +0200
@@ -11418,6 +11418,9 @@ add_subscript_info (dw_die_ref type_die,
{
tree domain = TYPE_DOMAIN (type);
+ if (TYPE_STRING_FLAG (type) && is_fortran () && dimension_number > 0)
+ break;
+
/* Arrays come in three flavors: Unspecified bounds, fixed bounds,
and (in GNU C only) variable bounds. Handle all three forms
here. */
@@ -11940,6 +11943,39 @@ gen_array_type_die (tree type, dw_die_re
dw_die_ref array_die;
tree element_type;
+ /* Emit DW_TAG_string_type for Fortran character types (with kind 1 only, as
+ DW_TAG_string_type doesn't have DW_AT_type attribute). */
+ if (TYPE_STRING_FLAG (type)
+ && TREE_CODE (type) == ARRAY_TYPE
+ && is_fortran ()
+ && TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (char_type_node))
+ {
+ HOST_WIDE_INT size;
+
+ array_die = new_die (DW_TAG_string_type, scope_die, type);
+ add_name_attribute (array_die, type_tag (type));
+ equate_type_number_to_die (type, array_die);
+ size = int_size_in_bytes (type);
+ if (size >= 0)
+ add_AT_unsigned (array_die, DW_AT_byte_size, size);
+ else if (TYPE_DOMAIN (type) != NULL_TREE
+ && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE
+ && DECL_P (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+ {
+ tree szdecl = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
+ dw_loc_descr_ref loc = loc_descriptor_from_tree (szdecl);
+
+ size = int_size_in_bytes (TREE_TYPE (szdecl));
+ if (loc && size > 0)
+ {
+ add_AT_loc (array_die, DW_AT_string_length, loc);
+ if (size != DWARF2_ADDR_SIZE)
+ add_AT_unsigned (array_die, DW_AT_byte_size, size);
+ }
+ }
+ return;
+ }
+
/* ??? The SGI dwarf reader fails for array of array of enum types unless
the inner array type comes before the outer array type. Thus we must
call gen_type_die before we call new_die. See below also. */
@@ -11962,7 +11998,8 @@ gen_array_type_die (tree type, dw_die_re
/* For Fortran multidimensional arrays use DW_ORD_col_major ordering. */
if (is_fortran ()
&& TREE_CODE (type) == ARRAY_TYPE
- && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
+ && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE
+ && !TYPE_STRING_FLAG (TREE_TYPE (type)))
add_AT_unsigned (array_die, DW_AT_ordering, DW_ORD_col_major);
#if 0
@@ -11994,7 +12031,11 @@ gen_array_type_die (tree type, dw_die_re
add_subscript_info. */
#ifndef MIPS_DEBUGGING_INFO
while (TREE_CODE (element_type) == ARRAY_TYPE)
- element_type = TREE_TYPE (element_type);
+ {
+ if (TYPE_STRING_FLAG (element_type) && is_fortran ())
+ break;
+ element_type = TREE_TYPE (element_type);
+ }
gen_type_die (element_type, context_die);
#endif

View File

@ -1,48 +0,0 @@
2008-08-22 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (gen_formal_parameter_die, gen_variable_die): For
DECL_BY_REFERENCE decls don't pass TREE_READONLY and
TREE_THIS_VOLATILE to add_type_attribute.
--- gcc/dwarf2out.c.jj 2008-08-22 17:49:10.000000000 +0200
+++ gcc/dwarf2out.c 2008-08-22 18:04:15.000000000 +0200
@@ -13033,11 +13033,13 @@ gen_formal_parameter_die (tree node, dw_
tree type = TREE_TYPE (node);
add_name_and_src_coords_attributes (parm_die, node);
if (DECL_BY_REFERENCE (node))
- type = TREE_TYPE (type);
- add_type_attribute (parm_die, type,
- TREE_READONLY (node),
- TREE_THIS_VOLATILE (node),
- context_die);
+ add_type_attribute (parm_die, TREE_TYPE (type), 0, 0,
+ context_die);
+ else
+ add_type_attribute (parm_die, type,
+ TREE_READONLY (node),
+ TREE_THIS_VOLATILE (node),
+ context_die);
if (DECL_ARTIFICIAL (node))
add_AT_flag (parm_die, DW_AT_artificial, 1);
}
@@ -13714,14 +13716,15 @@ gen_variable_die (tree decl, dw_die_ref
else
{
tree type = TREE_TYPE (decl);
+
+ add_name_and_src_coords_attributes (var_die, decl);
if ((TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == RESULT_DECL)
&& DECL_BY_REFERENCE (decl))
- type = TREE_TYPE (type);
-
- add_name_and_src_coords_attributes (var_die, decl);
- add_type_attribute (var_die, type, TREE_READONLY (decl),
- TREE_THIS_VOLATILE (decl), context_die);
+ add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
+ else
+ add_type_attribute (var_die, type, TREE_READONLY (decl),
+ TREE_THIS_VOLATILE (decl), context_die);
if (TREE_PUBLIC (decl))
add_AT_flag (var_die, DW_AT_external, 1);

View File

@ -1,144 +0,0 @@
2008-08-25 Jakub Jelinek <jakub@redhat.com>
* gfortran.h (gfc_use_list): Add where field.
* module.c (use_locus): New static variable.
(gfc_match_use): Set it.
(gfc_use_module): Copy it to gfc_use_list's where field.
* trans-decl.c (gfc_generate_module_vars): Call gfc_trans_use_stmts.
(gfc_trans_use_stmts): Set backend locus before calling the debug
hook. Allow non-VAR_DECLs to be created even for non-external
module. Don't emit anything so far for renames from different
modules.
--- gcc/fortran/gfortran.h.jj 2008-08-22 20:11:22.000000000 +0200
+++ gcc/fortran/gfortran.h 2008-08-25 13:03:42.000000000 +0200
@@ -1131,6 +1131,7 @@ typedef struct gfc_use_list
const char *module_name;
int only_flag;
struct gfc_use_rename *rename;
+ locus where;
/* Next USE statement. */
struct gfc_use_list *next;
}
--- gcc/fortran/module.c.jj 2008-08-22 20:11:22.000000000 +0200
+++ gcc/fortran/module.c 2008-08-25 13:10:57.000000000 +0200
@@ -188,6 +188,8 @@ static int symbol_number; /* Counter for
/* Tells mio_expr_ref to make symbols for unused equivalence members. */
static bool in_load_equiv;
+static locus use_locus;
+
/*****************************************************************/
@@ -546,6 +548,8 @@ gfc_match_use (void)
}
}
+ use_locus = gfc_current_locus;
+
m = gfc_match_name (module_name);
if (m != MATCH_YES)
return m;
@@ -5044,6 +5048,7 @@ gfc_use_module (void)
use_stmt->module_name = gfc_get_string (module_name);
use_stmt->only_flag = only_flag;
use_stmt->rename = gfc_rename_list;
+ use_stmt->where = use_locus;
gfc_rename_list = NULL;
use_stmt->next = gfc_current_ns->use_stmts;
gfc_current_ns->use_stmts = use_stmt;
--- gcc/fortran/trans-decl.c.jj 2008-08-25 12:44:00.000000000 +0200
+++ gcc/fortran/trans-decl.c 2008-08-25 13:16:17.000000000 +0200
@@ -3151,26 +3151,7 @@ gfc_create_module_variable (gfc_symbol *
}
}
-
-/* Generate all the required code for module variables. */
-
-void
-gfc_generate_module_vars (gfc_namespace * ns)
-{
- module_namespace = ns;
- cur_module = gfc_find_module (ns->proc_name->name);
-
- /* Check if the frontend left the namespace in a reasonable state. */
- gcc_assert (ns->proc_name && !ns->proc_name->tlink);
-
- /* Generate COMMON blocks. */
- gfc_trans_common (ns);
-
- /* Create decls for all the module variables. */
- gfc_traverse_ns (ns, gfc_create_module_variable);
-
- cur_module = NULL;
-}
+/* Emit debug information for USE statements. */
static void
gfc_trans_use_stmts (gfc_namespace * ns)
@@ -3190,6 +3171,7 @@ gfc_trans_use_stmts (gfc_namespace * ns)
void_type_node);
DECL_EXTERNAL (entry->namespace_decl) = 1;
}
+ gfc_set_backend_locus (&use_stmt->where);
if (!use_stmt->only_flag)
(*debug_hooks->imported_module_or_decl) (entry->namespace_decl,
NULL_TREE,
@@ -3214,9 +3196,14 @@ gfc_trans_use_stmts (gfc_namespace * ns)
rent->local_name[0]
? rent->local_name : rent->use_name);
gcc_assert (st && st->n.sym->attr.use_assoc);
- if (st->n.sym->backend_decl && DECL_P (st->n.sym->backend_decl))
+ if (st->n.sym->backend_decl
+ && DECL_P (st->n.sym->backend_decl)
+ && st->n.sym->module
+ && strcmp (st->n.sym->module, use_stmt->module_name) == 0)
{
- gcc_assert (DECL_EXTERNAL (entry->namespace_decl));
+ gcc_assert (DECL_EXTERNAL (entry->namespace_decl)
+ || (TREE_CODE (st->n.sym->backend_decl)
+ != VAR_DECL));
decl = copy_node (st->n.sym->backend_decl);
DECL_CONTEXT (decl) = entry->namespace_decl;
DECL_EXTERNAL (decl) = 1;
@@ -3236,6 +3223,7 @@ gfc_trans_use_stmts (gfc_namespace * ns)
local_name = get_identifier (rent->local_name);
else
local_name = NULL_TREE;
+ gfc_set_backend_locus (&rent->where);
(*debug_hooks->imported_module_or_decl) (decl, local_name,
ns->proc_name->backend_decl,
!use_stmt->only_flag);
@@ -3243,6 +3231,30 @@ gfc_trans_use_stmts (gfc_namespace * ns)
}
}
+
+/* Generate all the required code for module variables. */
+
+void
+gfc_generate_module_vars (gfc_namespace * ns)
+{
+ module_namespace = ns;
+ cur_module = gfc_find_module (ns->proc_name->name);
+
+ /* Check if the frontend left the namespace in a reasonable state. */
+ gcc_assert (ns->proc_name && !ns->proc_name->tlink);
+
+ /* Generate COMMON blocks. */
+ gfc_trans_common (ns);
+
+ /* Create decls for all the module variables. */
+ gfc_traverse_ns (ns, gfc_create_module_variable);
+
+ cur_module = NULL;
+
+ gfc_trans_use_stmts (ns);
+}
+
+
static void
gfc_generate_contained_functions (gfc_namespace * parent)
{

117
gcc43-pr37189.patch Normal file
View File

@ -0,0 +1,117 @@
2008-09-03 Jakub Jelinek <jakub@redhat.com>
PR c++/37189
* cp-tree.h (defer_mark_used_calls, deferred_mark_used_calls): New
extern decls.
* decl2.c (mark_used): If defer_mark_used_calls, push decl into
deferred_mark_used_calls vector and exit early.
* decl.c (defer_mark_used_calls, deferred_mark_used_calls): New
variables.
(finish_function): Set defer_mark_used_calls for the duration of the
function. Call mark_used on any queued decls.
PR c++/37189
* g++.dg/gomp/pr37189.C: New test.
--- gcc/cp/decl2.c (revision 139954)
+++ gcc/cp/decl2.c (revision 139955)
@@ -3776,6 +3776,15 @@ mark_used (tree decl)
/* If we don't need a value, then we don't need to synthesize DECL. */
if (skip_evaluation)
return;
+
+ /* If within finish_function, defer the rest until that function
+ finishes, otherwise it might recurse. */
+ if (defer_mark_used_calls)
+ {
+ VEC_safe_push (tree, gc, deferred_mark_used_calls, decl);
+ return;
+ }
+
/* Normally, we can wait until instantiation-time to synthesize
DECL. However, if DECL is a static data member initialized with
a constant, we need the value right now because a reference to
--- gcc/cp/decl.c (revision 139954)
+++ gcc/cp/decl.c (revision 139955)
@@ -227,6 +227,11 @@ struct named_label_entry GTY(())
function, two inside the body of a function in a local class, etc.) */
int function_depth;
+/* To avoid unwanted recursion, finish_function defers all mark_used calls
+ encountered during its execution until it finishes. */
+bool defer_mark_used_calls;
+VEC(tree, gc) *deferred_mark_used_calls;
+
/* States indicating how grokdeclarator() should handle declspecs marked
with __attribute__((deprecated)). An object declared as
__attribute__((deprecated)) suppresses warnings of uses of other
@@ -12033,6 +12038,9 @@ finish_function (int flags)
if (fndecl == NULL_TREE)
return error_mark_node;
+ gcc_assert (!defer_mark_used_calls);
+ defer_mark_used_calls = true;
+
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
&& DECL_VIRTUAL_P (fndecl)
&& !processing_template_decl)
@@ -12232,6 +12240,17 @@ finish_function (int flags)
cxx_pop_function_context and then reset via pop_function_context. */
current_function_decl = NULL_TREE;
+ defer_mark_used_calls = false;
+ if (deferred_mark_used_calls)
+ {
+ unsigned int i;
+ tree decl;
+
+ for (i = 0; VEC_iterate (tree, deferred_mark_used_calls, i, decl); i++)
+ mark_used (decl);
+ VEC_free (tree, gc, deferred_mark_used_calls);
+ }
+
return fndecl;
}
--- gcc/cp/cp-tree.h (revision 139954)
+++ gcc/cp/cp-tree.h (revision 139955)
@@ -4381,6 +4381,9 @@ extern void initialize_artificial_var (
extern tree check_var_type (tree, tree);
extern tree reshape_init (tree, tree);
+extern bool defer_mark_used_calls;
+extern GTY(()) VEC(tree, gc) *deferred_mark_used_calls;
+
/* in decl2.c */
extern bool check_java_method (tree);
extern tree build_memfn_type (tree, tree, cp_cv_quals);
--- gcc/testsuite/g++.dg/gomp/pr37189.C (revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr37189.C (revision 139955)
@@ -0,0 +1,27 @@
+// PR c++/37189
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+struct S
+{
+ S () {}
+ S (S const &) {}
+};
+
+struct T
+{
+ S s;
+};
+
+void
+bar (T &)
+{
+}
+
+int
+foo ()
+{
+ T t;
+ #pragma omp task
+ bar (t);
+}

View File

@ -1,522 +0,0 @@
2008-08-29 Jakub Jelinek <jakub@redhat.com>
PR middle-end/37248
PR middle-end/36449
* fold-const.c (make_bit_field_ref): Change bitpos and bitsize
arguments to HOST_WIDE_INT.
(fold_truthop): Change first_bit and end_bit to HOST_WIDE_INT.
* g++.dg/opt/pr36449.C: New test.
2008-08-29 Jakub Jelinek <jakub@redhat.com>
Revert:
2008-06-11 Richard Guenther <rguenther@suse.de>
PR middle-end/36449
* fold-const.c (fold_truthop): Remove code generating
BIT_FIELD_REFs of structure bases.
(fold_binary): Likewise.
(make_bit_field_ref): Remove.
(optimize_bit_field_compare): Remove.
(all_ones_mask_p): Remove.
--- gcc/fold-const.c (revision 136662)
+++ gcc/fold-const.c (revision 136661)
@@ -109,9 +109,12 @@ static int twoval_comparison_p (tree, tr
static tree eval_subst (tree, tree, tree, tree, tree);
static tree pedantic_omit_one_operand (tree, tree, tree);
static tree distribute_bit_expr (enum tree_code, tree, tree, tree);
+static tree make_bit_field_ref (tree, tree, HOST_WIDE_INT, HOST_WIDE_INT, int);
+static tree optimize_bit_field_compare (enum tree_code, tree, tree, tree);
static tree decode_field_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
enum machine_mode *, int *, int *,
tree *, tree *);
+static int all_ones_mask_p (const_tree, int);
static tree sign_bit_p (tree, const_tree);
static int simple_operand_p (const_tree);
static tree range_binop (enum tree_code, tree, tree, int, tree, int);
@@ -3848,6 +3851,202 @@ distribute_real_division (enum tree_code
return NULL_TREE;
}
+/* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
+ starting at BITPOS. The field is unsigned if UNSIGNEDP is nonzero. */
+
+static tree
+make_bit_field_ref (tree inner, tree type, HOST_WIDE_INT bitsize,
+ HOST_WIDE_INT bitpos, int unsignedp)
+{
+ tree result;
+
+ if (bitpos == 0)
+ {
+ tree size = TYPE_SIZE (TREE_TYPE (inner));
+ if ((INTEGRAL_TYPE_P (TREE_TYPE (inner))
+ || POINTER_TYPE_P (TREE_TYPE (inner)))
+ && host_integerp (size, 0)
+ && tree_low_cst (size, 0) == bitsize)
+ return fold_convert (type, inner);
+ }
+
+ result = build3 (BIT_FIELD_REF, type, inner,
+ size_int (bitsize), bitsize_int (bitpos));
+
+ BIT_FIELD_REF_UNSIGNED (result) = unsignedp;
+
+ return result;
+}
+
+/* Optimize a bit-field compare.
+
+ There are two cases: First is a compare against a constant and the
+ second is a comparison of two items where the fields are at the same
+ bit position relative to the start of a chunk (byte, halfword, word)
+ large enough to contain it. In these cases we can avoid the shift
+ implicit in bitfield extractions.
+
+ For constants, we emit a compare of the shifted constant with the
+ BIT_AND_EXPR of a mask and a byte, halfword, or word of the operand being
+ compared. For two fields at the same position, we do the ANDs with the
+ similar mask and compare the result of the ANDs.
+
+ CODE is the comparison code, known to be either NE_EXPR or EQ_EXPR.
+ COMPARE_TYPE is the type of the comparison, and LHS and RHS
+ are the left and right operands of the comparison, respectively.
+
+ If the optimization described above can be done, we return the resulting
+ tree. Otherwise we return zero. */
+
+static tree
+optimize_bit_field_compare (enum tree_code code, tree compare_type,
+ tree lhs, tree rhs)
+{
+ HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
+ tree type = TREE_TYPE (lhs);
+ tree signed_type, unsigned_type;
+ int const_p = TREE_CODE (rhs) == INTEGER_CST;
+ enum machine_mode lmode, rmode, nmode;
+ int lunsignedp, runsignedp;
+ int lvolatilep = 0, rvolatilep = 0;
+ tree linner, rinner = NULL_TREE;
+ tree mask;
+ tree offset;
+
+ /* Get all the information about the extractions being done. If the bit size
+ if the same as the size of the underlying object, we aren't doing an
+ extraction at all and so can do nothing. We also don't want to
+ do anything if the inner expression is a PLACEHOLDER_EXPR since we
+ then will no longer be able to replace it. */
+ linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &offset, &lmode,
+ &lunsignedp, &lvolatilep, false);
+ if (linner == lhs || lbitsize == GET_MODE_BITSIZE (lmode) || lbitsize < 0
+ || offset != 0 || TREE_CODE (linner) == PLACEHOLDER_EXPR)
+ return 0;
+
+ if (!const_p)
+ {
+ /* If this is not a constant, we can only do something if bit positions,
+ sizes, and signedness are the same. */
+ rinner = get_inner_reference (rhs, &rbitsize, &rbitpos, &offset, &rmode,
+ &runsignedp, &rvolatilep, false);
+
+ if (rinner == rhs || lbitpos != rbitpos || lbitsize != rbitsize
+ || lunsignedp != runsignedp || offset != 0
+ || TREE_CODE (rinner) == PLACEHOLDER_EXPR)
+ return 0;
+ }
+
+ /* See if we can find a mode to refer to this field. We should be able to,
+ but fail if we can't. */
+ nmode = get_best_mode (lbitsize, lbitpos,
+ const_p ? TYPE_ALIGN (TREE_TYPE (linner))
+ : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
+ TYPE_ALIGN (TREE_TYPE (rinner))),
+ word_mode, lvolatilep || rvolatilep);
+ if (nmode == VOIDmode)
+ return 0;
+
+ /* Set signed and unsigned types of the precision of this mode for the
+ shifts below. */
+ signed_type = lang_hooks.types.type_for_mode (nmode, 0);
+ unsigned_type = lang_hooks.types.type_for_mode (nmode, 1);
+
+ /* Compute the bit position and size for the new reference and our offset
+ within it. If the new reference is the same size as the original, we
+ won't optimize anything, so return zero. */
+ nbitsize = GET_MODE_BITSIZE (nmode);
+ nbitpos = lbitpos & ~ (nbitsize - 1);
+ lbitpos -= nbitpos;
+ if (nbitsize == lbitsize)
+ return 0;
+
+ if (BYTES_BIG_ENDIAN)
+ lbitpos = nbitsize - lbitsize - lbitpos;
+
+ /* Make the mask to be used against the extracted field. */
+ mask = build_int_cst_type (unsigned_type, -1);
+ mask = const_binop (LSHIFT_EXPR, mask, size_int (nbitsize - lbitsize), 0);
+ mask = const_binop (RSHIFT_EXPR, mask,
+ size_int (nbitsize - lbitsize - lbitpos), 0);
+
+ if (! const_p)
+ /* If not comparing with constant, just rework the comparison
+ and return. */
+ return fold_build2 (code, compare_type,
+ fold_build2 (BIT_AND_EXPR, unsigned_type,
+ make_bit_field_ref (linner,
+ unsigned_type,
+ nbitsize, nbitpos,
+ 1),
+ mask),
+ fold_build2 (BIT_AND_EXPR, unsigned_type,
+ make_bit_field_ref (rinner,
+ unsigned_type,
+ nbitsize, nbitpos,
+ 1),
+ mask));
+
+ /* Otherwise, we are handling the constant case. See if the constant is too
+ big for the field. Warn and return a tree of for 0 (false) if so. We do
+ this not only for its own sake, but to avoid having to test for this
+ error case below. If we didn't, we might generate wrong code.
+
+ For unsigned fields, the constant shifted right by the field length should
+ be all zero. For signed fields, the high-order bits should agree with
+ the sign bit. */
+
+ if (lunsignedp)
+ {
+ if (! integer_zerop (const_binop (RSHIFT_EXPR,
+ fold_convert (unsigned_type, rhs),
+ size_int (lbitsize), 0)))
+ {
+ warning (0, "comparison is always %d due to width of bit-field",
+ code == NE_EXPR);
+ return constant_boolean_node (code == NE_EXPR, compare_type);
+ }
+ }
+ else
+ {
+ tree tem = const_binop (RSHIFT_EXPR, fold_convert (signed_type, rhs),
+ size_int (lbitsize - 1), 0);
+ if (! integer_zerop (tem) && ! integer_all_onesp (tem))
+ {
+ warning (0, "comparison is always %d due to width of bit-field",
+ code == NE_EXPR);
+ return constant_boolean_node (code == NE_EXPR, compare_type);
+ }
+ }
+
+ /* Single-bit compares should always be against zero. */
+ if (lbitsize == 1 && ! integer_zerop (rhs))
+ {
+ code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
+ rhs = build_int_cst (type, 0);
+ }
+
+ /* Make a new bitfield reference, shift the constant over the
+ appropriate number of bits and mask it with the computed mask
+ (in case this was a signed field). If we changed it, make a new one. */
+ lhs = make_bit_field_ref (linner, unsigned_type, nbitsize, nbitpos, 1);
+ if (lvolatilep)
+ {
+ TREE_SIDE_EFFECTS (lhs) = 1;
+ TREE_THIS_VOLATILE (lhs) = 1;
+ }
+
+ rhs = const_binop (BIT_AND_EXPR,
+ const_binop (LSHIFT_EXPR,
+ fold_convert (unsigned_type, rhs),
+ size_int (lbitpos), 0),
+ mask, 0);
+
+ return build2 (code, compare_type,
+ build2 (BIT_AND_EXPR, unsigned_type, lhs, mask),
+ rhs);
+}
+
/* Subroutine for fold_truthop: decode a field reference.
If EXP is a comparison reference, we return the innermost reference.
@@ -3939,6 +4138,27 @@ decode_field_reference (tree exp, HOST_W
return inner;
}
+/* Return nonzero if MASK represents a mask of SIZE ones in the low-order
+ bit positions. */
+
+static int
+all_ones_mask_p (const_tree mask, int size)
+{
+ tree type = TREE_TYPE (mask);
+ unsigned int precision = TYPE_PRECISION (type);
+ tree tmask;
+
+ tmask = build_int_cst_type (signed_type_for (type), -1);
+
+ return
+ tree_int_cst_equal (mask,
+ const_binop (RSHIFT_EXPR,
+ const_binop (LSHIFT_EXPR, tmask,
+ size_int (precision - size),
+ 0),
+ size_int (precision - size), 0));
+}
+
/* Subroutine for fold: determine if VAL is the INTEGER_CONST that
represents the sign bit of EXP's type. If EXP represents a sign
or zero extension, also test VAL against the unextended type.
@@ -5264,16 +5484,16 @@ fold_truthop (enum tree_code code, tree
tree ll_inner, lr_inner, rl_inner, rr_inner;
HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
- HOST_WIDE_INT xll_bitpos, xrl_bitpos;
- HOST_WIDE_INT lnbitsize, lnbitpos;
+ HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
+ HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
- enum machine_mode lnmode;
+ enum machine_mode lnmode, rnmode;
tree ll_mask, lr_mask, rl_mask, rr_mask;
tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
tree l_const, r_const;
- tree lntype, result;
- int first_bit, end_bit;
+ tree lntype, rntype, result;
+ HOST_WIDE_INT first_bit, end_bit;
int volatilep;
tree orig_lhs = lhs, orig_rhs = rhs;
enum tree_code orig_code = code;
@@ -5510,6 +5730,118 @@ fold_truthop (enum tree_code code, tree
}
}
+ /* If the right sides are not constant, do the same for it. Also,
+ disallow this optimization if a size or signedness mismatch occurs
+ between the left and right sides. */
+ if (l_const == 0)
+ {
+ if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
+ || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp
+ /* Make sure the two fields on the right
+ correspond to the left without being swapped. */
+ || ll_bitpos - rl_bitpos != lr_bitpos - rr_bitpos)
+ return 0;
+
+ first_bit = MIN (lr_bitpos, rr_bitpos);
+ end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
+ rnmode = get_best_mode (end_bit - first_bit, first_bit,
+ TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode,
+ volatilep);
+ if (rnmode == VOIDmode)
+ return 0;
+
+ rnbitsize = GET_MODE_BITSIZE (rnmode);
+ rnbitpos = first_bit & ~ (rnbitsize - 1);
+ rntype = lang_hooks.types.type_for_size (rnbitsize, 1);
+ xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
+ xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
+ }
+
+ lr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, lr_mask),
+ size_int (xlr_bitpos), 0);
+ rr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, rr_mask),
+ size_int (xrr_bitpos), 0);
+
+ /* Make a mask that corresponds to both fields being compared.
+ Do this for both items being compared. If the operands are the
+ same size and the bits being compared are in the same position
+ then we can do this by masking both and comparing the masked
+ results. */
+ ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
+ lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask, 0);
+ if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
+ {
+ lhs = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
+ ll_unsignedp || rl_unsignedp);
+ if (! all_ones_mask_p (ll_mask, lnbitsize))
+ lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);
+
+ rhs = make_bit_field_ref (lr_inner, rntype, rnbitsize, rnbitpos,
+ lr_unsignedp || rr_unsignedp);
+ if (! all_ones_mask_p (lr_mask, rnbitsize))
+ rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
+
+ return build2 (wanted_code, truth_type, lhs, rhs);
+ }
+
+ /* There is still another way we can do something: If both pairs of
+ fields being compared are adjacent, we may be able to make a wider
+ field containing them both.
+
+ Note that we still must mask the lhs/rhs expressions. Furthermore,
+ the mask must be shifted to account for the shift done by
+ make_bit_field_ref. */
+ if ((ll_bitsize + ll_bitpos == rl_bitpos
+ && lr_bitsize + lr_bitpos == rr_bitpos)
+ || (ll_bitpos == rl_bitpos + rl_bitsize
+ && lr_bitpos == rr_bitpos + rr_bitsize))
+ {
+ tree type;
+
+ lhs = make_bit_field_ref (ll_inner, lntype, ll_bitsize + rl_bitsize,
+ MIN (ll_bitpos, rl_bitpos), ll_unsignedp);
+ rhs = make_bit_field_ref (lr_inner, rntype, lr_bitsize + rr_bitsize,
+ MIN (lr_bitpos, rr_bitpos), lr_unsignedp);
+
+ ll_mask = const_binop (RSHIFT_EXPR, ll_mask,
+ size_int (MIN (xll_bitpos, xrl_bitpos)), 0);
+ lr_mask = const_binop (RSHIFT_EXPR, lr_mask,
+ size_int (MIN (xlr_bitpos, xrr_bitpos)), 0);
+
+ /* Convert to the smaller type before masking out unwanted bits. */
+ type = lntype;
+ if (lntype != rntype)
+ {
+ if (lnbitsize > rnbitsize)
+ {
+ lhs = fold_convert (rntype, lhs);
+ ll_mask = fold_convert (rntype, ll_mask);
+ type = rntype;
+ }
+ else if (lnbitsize < rnbitsize)
+ {
+ rhs = fold_convert (lntype, rhs);
+ lr_mask = fold_convert (lntype, lr_mask);
+ type = lntype;
+ }
+ }
+
+ if (! all_ones_mask_p (ll_mask, ll_bitsize + rl_bitsize))
+ lhs = build2 (BIT_AND_EXPR, type, lhs, ll_mask);
+
+ if (! all_ones_mask_p (lr_mask, lr_bitsize + rr_bitsize))
+ rhs = build2 (BIT_AND_EXPR, type, rhs, lr_mask);
+
+ return build2 (wanted_code, truth_type, lhs, rhs);
+ }
+
+ return 0;
+ }
+
/* Handle the case of comparisons with constants. If there is something in
common between the masks, those bits of the constants must be the same.
If not, the condition is always false. Test for this to avoid generating
@@ -5531,7 +5863,19 @@ fold_truthop (enum tree_code code, tree
}
}
- return NULL_TREE;
+ /* Construct the expression we will return. First get the component
+ reference we will make. Unless the mask is all ones the width of
+ that field, perform the mask operation. Then compare with the
+ merged constant. */
+ result = make_bit_field_ref (ll_inner, lntype, lnbitsize, lnbitpos,
+ ll_unsignedp || rl_unsignedp);
+
+ ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask, 0);
+ if (! all_ones_mask_p (ll_mask, lnbitsize))
+ result = build2 (BIT_AND_EXPR, lntype, result, ll_mask);
+
+ return build2 (wanted_code, truth_type, result,
+ const_binop (BIT_IOR_EXPR, l_const, r_const, 0));
}
/* Optimize T, which is a comparison of a MIN_EXPR or MAX_EXPR with a
@@ -11912,6 +12256,18 @@ fold_binary (enum tree_code code, tree t
return omit_one_operand (type, rslt, arg0);
}
+ /* If this is a comparison of a field, we may be able to simplify it. */
+ if ((TREE_CODE (arg0) == COMPONENT_REF
+ || TREE_CODE (arg0) == BIT_FIELD_REF)
+ /* Handle the constant case even without -O
+ to make sure the warnings are given. */
+ && (optimize || TREE_CODE (arg1) == INTEGER_CST))
+ {
+ t1 = optimize_bit_field_compare (code, type, arg0, arg1);
+ if (t1)
+ return t1;
+ }
+
/* Optimize comparisons of strlen vs zero to a compare of the
first character of the string vs zero. To wit,
strlen(ptr) == 0 => *ptr == 0
--- gcc/testsuite/g++.dg/opt/pr36449.C.jj 2008-08-26 11:03:24.000000000 +0200
+++ gcc/testsuite/g++.dg/opt/pr36449.C 2008-08-26 11:00:53.000000000 +0200
@@ -0,0 +1,70 @@
+// PR middle-end/36449
+// { dg-do run }
+// { dg-options "-O3" }
+
+extern "C" void exit (int);
+extern "C" void abort ();
+
+struct R
+{
+ short a;
+ short b;
+};
+
+struct S
+{
+ R e;
+ long f;
+ long g;
+};
+
+struct T
+{
+ short c;
+ short d;
+};
+
+struct U
+{
+ long h[0x1ffffff + 1];
+ T i;
+};
+
+U *j;
+
+void __attribute__((noinline))
+bar ()
+{
+ exit (0);
+}
+
+void __attribute__((noinline))
+foo ()
+{
+ S s;
+
+ s.e.a = 36;
+ s.e.b = 38;
+ if (s.e.a == j->i.c && s.e.b == j->i.d)
+ bar ();
+}
+
+int
+main ()
+{
+ try
+ {
+ j = new U;
+ }
+ catch (...)
+ {
+ return 0;
+ }
+ j->i.c = 36;
+ j->i.d = 38;
+ j->h[0] = 1;
+ j->h[1] = 2;
+ j->h[2] = 3;
+ foo ();
+ abort ();
+}

355
gcc43-x86_64-va_start.patch Normal file
View File

@ -0,0 +1,355 @@
2008-09-02 H.J. Lu <hongjiu.lu@intel.com>
Jakub Jelinek <jakub@redhat.com>
* config/i386/i386.c (X86_64_VARARGS_SIZE): Removed.
(setup_incoming_varargs_64): Set/check ix86_varargs_gpr_size and
ix86_varargs_fpr_size. Use ix86_varargs_gpr_size instead of
REGPARM_MAX. Don't set ix86_save_varrargs_registers.
(ix86_va_start): Check ix86_varargs_gpr_size and
ix86_varargs_fpr_size instead of cfun->va_list_gpr_size and
cfun->va_list_fpr_size, respectively. Subtract 8*REGPARM_MAX
from frame pointer if ix86_varargs_gpr_size == 0.
(ix86_compute_frame_layout): Updated.
* config/i386/i386.h (ix86_save_varrargs_registers): Removed.
(ix86_varargs_gpr_size): Define.
(ix86_varargs_fpr_size): Likewise.
(machine_function): Remove save_varrargs_registers.
Add varargs_gpr_size and varargs_fpr_size.
* gcc.target/i386/amd64-abi-3.c: New test.
* gcc.target/i386/amd64-abi-4.c: Likewise.
* gcc.target/i386/amd64-abi-5.c: Likewise.
* gcc.target/i386/amd64-abi-6.c: Likewise.
--- gcc/config/i386/i386.h (revision 139909)
+++ gcc/config/i386/i386.h (revision 139910)
@@ -2440,7 +2440,8 @@ struct machine_function GTY(())
struct stack_local_entry *stack_locals;
const char *some_ld_name;
rtx force_align_arg_pointer;
- int save_varrargs_registers;
+ int varargs_gpr_size;
+ int varargs_fpr_size;
int accesses_prev_frame;
int optimize_mode_switching[MAX_386_ENTITIES];
int needs_cld;
@@ -2463,7 +2464,8 @@ struct machine_function GTY(())
};
#define ix86_stack_locals (cfun->machine->stack_locals)
-#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
+#define ix86_varargs_gpr_size (cfun->machine->varargs_gpr_size)
+#define ix86_varargs_fpr_size (cfun->machine->varargs_fpr_size)
#define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching)
#define ix86_current_function_needs_cld (cfun->machine->needs_cld)
#define ix86_tls_descriptor_calls_expanded_in_cfun \
--- gcc/config/i386/i386.c (revision 139909)
+++ gcc/config/i386/i386.c (revision 139910)
@@ -1616,9 +1616,6 @@ rtx ix86_compare_op0 = NULL_RTX;
rtx ix86_compare_op1 = NULL_RTX;
rtx ix86_compare_emitted = NULL_RTX;
-/* Size of the register save area. */
-#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
-
/* Define the structure for the machine field in struct function. */
struct stack_local_entry GTY(())
@@ -4976,11 +4973,22 @@ setup_incoming_varargs_64 (CUMULATIVE_AR
alias_set_type set;
int i;
- if (! cfun->va_list_gpr_size && ! cfun->va_list_fpr_size)
+ /* GPR size of varargs save area. */
+ if (cfun->va_list_gpr_size)
+ ix86_varargs_gpr_size = REGPARM_MAX * UNITS_PER_WORD;
+ else
+ ix86_varargs_gpr_size = 0;
+
+ /* FPR size of varargs save area. We don't need it if we don't pass
+ anything in SSE registers. */
+ if (cum->sse_nregs && cfun->va_list_fpr_size)
+ ix86_varargs_fpr_size = SSE_REGPARM_MAX * 16;
+ else
+ ix86_varargs_fpr_size = 0;
+
+ if (! ix86_varargs_gpr_size && ! ix86_varargs_fpr_size)
return;
- /* Indicate to allocate space on the stack for varargs save area. */
- ix86_save_varrargs_registers = 1;
/* We need 16-byte stack alignment to save SSE registers. If user
asked for lower preferred_stack_boundary, lets just hope that he knows
what he is doing and won't varargs SSE values.
@@ -5006,7 +5014,7 @@ setup_incoming_varargs_64 (CUMULATIVE_AR
x86_64_int_parameter_registers[i]));
}
- if (cum->sse_nregs && cfun->va_list_fpr_size)
+ if (ix86_varargs_fpr_size)
{
/* Now emit code to save SSE registers. The AX parameter contains number
of SSE parameter registers used to call this function. We use
@@ -5041,7 +5049,7 @@ setup_incoming_varargs_64 (CUMULATIVE_AR
tmp_reg = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (VOIDmode, tmp_reg,
plus_constant (save_area,
- 8 * REGPARM_MAX + 127)));
+ ix86_varargs_gpr_size + 127)));
mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127));
MEM_NOTRAP_P (mem) = 1;
set_mem_alias_set (mem, set);
@@ -5145,7 +5153,7 @@ ix86_va_start (tree valist, rtx nextarg)
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
- if (cfun->va_list_fpr_size)
+ if (TARGET_SSE && cfun->va_list_fpr_size)
{
type = TREE_TYPE (fpr);
t = build2 (GIMPLE_MODIFY_STMT, type, fpr,
@@ -5164,12 +5172,15 @@ ix86_va_start (tree valist, rtx nextarg)
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- if (cfun->va_list_gpr_size || cfun->va_list_fpr_size)
+ if (ix86_varargs_gpr_size || ix86_varargs_fpr_size)
{
/* Find the register save area.
Prologue of the function save it right above stack frame. */
type = TREE_TYPE (sav);
t = make_tree (type, frame_pointer_rtx);
+ if (!ix86_varargs_gpr_size)
+ t = build2 (POINTER_PLUS_EXPR, type, t,
+ size_int (-8 * REGPARM_MAX));
t = build2 (GIMPLE_MODIFY_STMT, type, sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -6079,13 +6090,8 @@ ix86_compute_frame_layout (struct ix86_f
offset += frame->nregs * UNITS_PER_WORD;
/* Va-arg area */
- if (ix86_save_varrargs_registers)
- {
- offset += X86_64_VARARGS_SIZE;
- frame->va_arg_size = X86_64_VARARGS_SIZE;
- }
- else
- frame->va_arg_size = 0;
+ frame->va_arg_size = ix86_varargs_gpr_size + ix86_varargs_fpr_size;
+ offset += frame->va_arg_size;
/* Align start of frame for local function. */
frame->padding1 = ((offset + stack_alignment_needed - 1)
--- gcc/testsuite/gcc.target/i386/amd64-abi-3.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/amd64-abi-3.c (revision 139910)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mno-sse" } */
+/* { dg-final { scan-assembler "subq\[\\t \]*\\\$88,\[\\t \]*%rsp" } } */
+/* { dg-final { scan-assembler-not "subq\[\\t \]*\\\$216,\[\\t \]*%rsp" } } */
+
+#include <stdarg.h>
+
+void foo (va_list va_arglist);
+
+void
+test (int a1, ...)
+{
+ va_list va_arglist;
+ va_start (va_arglist, a1);
+ foo (va_arglist);
+ va_end (va_arglist);
+}
--- gcc/testsuite/gcc.target/i386/amd64-abi-5.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/amd64-abi-5.c (revision 139910)
@@ -0,0 +1,64 @@
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2" } */
+
+#include <stdarg.h>
+#include <assert.h>
+
+int n1 = 30;
+double n2 = 324;
+double n3 = 39494.94;
+double n4 = 407;
+double n5 = 32.304;
+double n6 = 394.14;
+double n7 = 4.07;
+double n8 = 32.4;
+double n9 = 314.194;
+double n10 = 0.1407;
+
+int e1;
+double e2;
+double e3;
+double e4;
+double e5;
+double e6;
+double e7;
+double e8;
+double e9;
+double e10;
+
+static void
+__attribute__((noinline))
+test (int a1, ...)
+{
+ e1 = a1;
+ va_list va_arglist;
+ va_start (va_arglist, a1);
+ e2 = va_arg (va_arglist, double);
+ e3 = va_arg (va_arglist, double);
+ e4 = va_arg (va_arglist, double);
+ e5 = va_arg (va_arglist, double);
+ e6 = va_arg (va_arglist, double);
+ e7 = va_arg (va_arglist, double);
+ e8 = va_arg (va_arglist, double);
+ e9 = va_arg (va_arglist, double);
+ e10 = va_arg (va_arglist, double);
+ va_end (va_arglist);
+}
+
+int
+main ()
+{
+ test (n1, n2, n3, n4, n5, n6, n7, n8, n9, n10);
+ assert (n1 == e1);
+ assert (n2 == e2);
+ assert (n3 == e3);
+ assert (n4 == e4);
+ assert (n5 == e5);
+ assert (n6 == e6);
+ assert (n7 == e7);
+ assert (n8 == e8);
+ assert (n9 == e9);
+ assert (n10 == e10);
+ return 0;
+}
--- gcc/testsuite/gcc.target/i386/amd64-abi-4.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/amd64-abi-4.c (revision 139910)
@@ -0,0 +1,47 @@
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mno-sse" } */
+
+#include <stdarg.h>
+#include <assert.h>
+
+int n1 = 30;
+int n2 = 324;
+void *n3 = (void *) &n2;
+int n4 = 407;
+
+int e1;
+int e2;
+void *e3;
+int e4;
+
+static void
+__attribute__((noinline))
+foo (va_list va_arglist)
+{
+ e2 = va_arg (va_arglist, int);
+ e3 = va_arg (va_arglist, void *);
+ e4 = va_arg (va_arglist, int);
+}
+
+static void
+__attribute__((noinline))
+test (int a1, ...)
+{
+ e1 = a1;
+ va_list va_arglist;
+ va_start (va_arglist, a1);
+ foo (va_arglist);
+ va_end (va_arglist);
+}
+
+int
+main ()
+{
+ test (n1, n2, n3, n4);
+ assert (n1 == e1);
+ assert (n2 == e2);
+ assert (n3 == e3);
+ assert (n4 == e4);
+ return 0;
+}
--- gcc/testsuite/gcc.target/i386/amd64-abi-6.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/amd64-abi-6.c (revision 139910)
@@ -0,0 +1,71 @@
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2" } */
+
+#include <stdarg.h>
+#include <assert.h>
+
+int n1 = 30;
+double n2 = 324;
+double n3 = 39494.94;
+double n4 = 407;
+double n5 = 32.304;
+double n6 = 394.14;
+double n7 = 4.07;
+double n8 = 32.4;
+double n9 = 314.194;
+double n10 = 0.1407;
+
+int e1;
+double e2;
+double e3;
+double e4;
+double e5;
+double e6;
+double e7;
+double e8;
+double e9;
+double e10;
+
+static void
+__attribute__((noinline))
+foo (va_list va_arglist)
+{
+ e2 = va_arg (va_arglist, double);
+ e3 = va_arg (va_arglist, double);
+ e4 = va_arg (va_arglist, double);
+ e5 = va_arg (va_arglist, double);
+ e6 = va_arg (va_arglist, double);
+ e7 = va_arg (va_arglist, double);
+ e8 = va_arg (va_arglist, double);
+ e9 = va_arg (va_arglist, double);
+ e10 = va_arg (va_arglist, double);
+}
+
+static void
+__attribute__((noinline))
+test (int a1, ...)
+{
+ va_list va_arglist;
+ e1 = a1;
+ va_start (va_arglist, a1);
+ foo (va_arglist);
+ va_end (va_arglist);
+}
+
+int
+main ()
+{
+ test (n1, n2, n3, n4, n5, n6, n7, n8, n9, n10);
+ assert (n1 == e1);
+ assert (n2 == e2);
+ assert (n3 == e3);
+ assert (n4 == e4);
+ assert (n5 == e5);
+ assert (n6 == e6);
+ assert (n7 == e7);
+ assert (n8 == e8);
+ assert (n9 == e9);
+ assert (n10 == e10);
+ return 0;
+}

View File

@ -1,6 +1,9 @@
%define DATE 20080829 %define DATE 20080905
%define SVNREV 140029
%define gcc_version 4.3.2 %define gcc_version 4.3.2
%define gcc_release 1 # Note, gcc_release must be integer, if you want to add suffixes to
# %{release}, append them after %{gcc_release} on Release: line.
%define gcc_release 2
%define _unpackaged_files_terminate_build 0 %define _unpackaged_files_terminate_build 0
%define multilib_64_archs sparc64 ppc64 s390x x86_64 %define multilib_64_archs sparc64 ppc64 s390x x86_64
%define include_gappletviewer 1 %define include_gappletviewer 1
@ -37,6 +40,10 @@ Release: %{gcc_release}
# restrictions. # restrictions.
License: GPLv3+ and GPLv2+ with exceptions License: GPLv3+ and GPLv2+ with exceptions
Group: Development/Languages Group: Development/Languages
# The source for this package was pulled from upstream's vcs. Use the
# following commands to generate the tarball:
# svn export svn://gcc.gnu.org/svn/gcc/branches/redhat/gcc-4_3-branch@%{SVNREV} gcc-%{version}-%{DATE}
# tar cf - gcc-%{version}-%{DATE} | bzip2 -9 > gcc-%{version}-%{DATE}.tar.bz2
Source0: gcc-%{version}-%{DATE}.tar.bz2 Source0: gcc-%{version}-%{DATE}.tar.bz2
Source1: libgcc_post_upgrade.c Source1: libgcc_post_upgrade.c
Source2: README.libgcjwebplugin.so Source2: README.libgcjwebplugin.so
@ -44,7 +51,7 @@ Source3: protoize.1
%define fastjar_ver 0.95 %define fastjar_ver 0.95
Source4: http://download.savannah.nongnu.org/releases/fastjar/fastjar-%{fastjar_ver}.tar.gz Source4: http://download.savannah.nongnu.org/releases/fastjar/fastjar-%{fastjar_ver}.tar.gz
URL: http://gcc.gnu.org URL: http://gcc.gnu.org
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n))
# Need binutils with -pie support >= 2.14.90.0.4-4 # Need binutils with -pie support >= 2.14.90.0.4-4
# Need binutils which can omit dot symbols and overlap .opd on ppc64 >= 2.15.91.0.2-4 # Need binutils which can omit dot symbols and overlap .opd on ppc64 >= 2.15.91.0.2-4
# Need binutils which handle -msecure-plt on ppc >= 2.16.91.0.2-2 # Need binutils which handle -msecure-plt on ppc >= 2.16.91.0.2-2
@ -103,27 +110,27 @@ Requires: glibc >= 2.3.90-35
%endif %endif
Requires: libgcc >= %{version}-%{release} Requires: libgcc >= %{version}-%{release}
Requires: libgomp = %{version}-%{release} Requires: libgomp = %{version}-%{release}
Obsoletes: gcc3 #Obsoletes: gcc3
Obsoletes: egcs #Obsoletes: egcs
%ifarch sparc %ifarch sparc
Obsoletes: gcc-sparc32 #Obsoletes: gcc-sparc32
Obsoletes: gcc-c++-sparc32 #Obsoletes: gcc-c++-sparc32
%endif %endif
%ifarch ppc %ifarch ppc
Obsoletes: gcc-ppc32 #Obsoletes: gcc-ppc32
Obsoletes: gcc-c++-ppc32 #Obsoletes: gcc-c++-ppc32
%endif %endif
Obsoletes: gcc-chill #Obsoletes: gcc-chill
%if !%{build_ada} %if !%{build_ada}
Obsoletes: gcc-gnat < %{version}-%{release} Obsoletes: gcc-gnat < %{version}-%{release}
Obsoletes: libgnat < %{version}-%{release} Obsoletes: libgnat < %{version}-%{release}
%endif %endif
%ifarch sparc sparc64 %ifarch sparc sparc64
Obsoletes: egcs64 #Obsoletes: egcs64
%endif %endif
Obsoletes: gcc34 #Obsoletes: gcc34
Obsoletes: gcc35 #Obsoletes: gcc35
Obsoletes: gcc4 #Obsoletes: gcc4
Prereq: /sbin/install-info Prereq: /sbin/install-info
AutoReq: true AutoReq: true
@ -143,18 +150,8 @@ Patch13: gcc43-i386-libgomp.patch
Patch14: gcc43-rh251682.patch Patch14: gcc43-rh251682.patch
Patch15: gcc43-sparc-config-detection.patch Patch15: gcc43-sparc-config-detection.patch
Patch16: gcc43-libgomp-omp_h-multilib.patch Patch16: gcc43-libgomp-omp_h-multilib.patch
Patch17: gcc43-fortran-debug1.patch Patch17: gcc43-x86_64-va_start.patch
Patch18: gcc43-fortran-debug2.patch Patch18: gcc43-pr37189.patch
Patch19: gcc43-fortran-debug3.patch
Patch20: gcc43-fortran-debug4.patch
Patch21: gcc43-fortran-debug5.patch
Patch22: gcc43-fortran-debug6.patch
Patch23: gcc43-fortran-debug7.patch
Patch24: gcc43-fortran-debug8.patch
Patch25: gcc43-fortran-debug9.patch
Patch26: gcc43-fortran-debug10.patch
Patch27: gcc43-fortran-debug11.patch
Patch28: gcc43-pr37248.patch
# On ARM EABI systems, we do want -gnueabi to be part of the # On ARM EABI systems, we do want -gnueabi to be part of the
# target triple. # target triple.
@ -190,10 +187,10 @@ Group: Development/Languages
Requires: gcc = %{version}-%{release} Requires: gcc = %{version}-%{release}
Requires: libstdc++ = %{version}-%{release} Requires: libstdc++ = %{version}-%{release}
Requires: libstdc++-devel = %{version}-%{release} Requires: libstdc++-devel = %{version}-%{release}
Obsoletes: gcc3-c++ #Obsoletes: gcc3-c++
Obsoletes: gcc34-c++ #Obsoletes: gcc34-c++
Obsoletes: gcc35-c++ #Obsoletes: gcc35-c++
Obsoletes: gcc4-c++ #Obsoletes: gcc4-c++
Autoreq: true Autoreq: true
%description c++ %description c++
@ -204,8 +201,8 @@ including templates and exception handling.
%package -n libstdc++ %package -n libstdc++
Summary: GNU Standard C++ Library Summary: GNU Standard C++ Library
Group: System Environment/Libraries Group: System Environment/Libraries
Obsoletes: libstdc++3 #Obsoletes: libstdc++3
Obsoletes: libstdc++34 #Obsoletes: libstdc++34
Autoreq: true Autoreq: true
%description -n libstdc++ %description -n libstdc++
@ -216,8 +213,8 @@ C++ Library.
Summary: Header files and libraries for C++ development Summary: Header files and libraries for C++ development
Group: Development/Libraries Group: Development/Libraries
Requires: libstdc++ = %{version}-%{release}, %{_prefix}/%{_lib}/libstdc++.so.6 Requires: libstdc++ = %{version}-%{release}, %{_prefix}/%{_lib}/libstdc++.so.6
Obsoletes: libstdc++3-devel #Obsoletes: libstdc++3-devel
Obsoletes: libstdc++34-devel #Obsoletes: libstdc++34-devel
Autoreq: true Autoreq: true
%description -n libstdc++-devel %description -n libstdc++-devel
@ -230,7 +227,7 @@ Summary: Objective-C support for GCC
Group: Development/Languages Group: Development/Languages
Requires: gcc = %{version}-%{release} Requires: gcc = %{version}-%{release}
Requires: libobjc = %{version}-%{release} Requires: libobjc = %{version}-%{release}
Obsoletes: gcc3-objc #Obsoletes: gcc3-objc
Autoreq: true Autoreq: true
%description objc %description objc
@ -263,9 +260,9 @@ Requires: gcc = %{version}-%{release}
Requires: libgfortran = %{version}-%{release} Requires: libgfortran = %{version}-%{release}
BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1 BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1
Prereq: /sbin/install-info Prereq: /sbin/install-info
Obsoletes: gcc3-g77 #Obsoletes: gcc3-g77
Obsoletes: gcc-g77 #Obsoletes: gcc-g77
Obsoletes: gcc4-gfortran #Obsoletes: gcc4-gfortran
Autoreq: true Autoreq: true
%description gfortran %description gfortran
@ -275,7 +272,7 @@ programs with the GNU Compiler Collection.
%package -n libgfortran %package -n libgfortran
Summary: Fortran 95 runtime Summary: Fortran 95 runtime
Group: System Environment/Libraries Group: System Environment/Libraries
Obsoletes: libf2c #Obsoletes: libf2c
Autoreq: true Autoreq: true
%description -n libgfortran %description -n libgfortran
@ -320,10 +317,10 @@ Requires: gcc = %{version}-%{release}
Requires: libgcj = %{version}-%{release} Requires: libgcj = %{version}-%{release}
Requires: libgcj-devel = %{version}-%{release} Requires: libgcj-devel = %{version}-%{release}
Requires: /usr/share/java/eclipse-ecj.jar Requires: /usr/share/java/eclipse-ecj.jar
Obsoletes: gcc3-java #Obsoletes: gcc3-java
Obsoletes: gcc34-java #Obsoletes: gcc34-java
Obsoletes: gcc35-java #Obsoletes: gcc35-java
Obsoletes: gcc4-java #Obsoletes: gcc4-java
Prereq: /sbin/install-info Prereq: /sbin/install-info
Autoreq: true Autoreq: true
@ -348,10 +345,10 @@ BuildRequires: alsa-lib-devel
BuildRequires: libXtst-devel BuildRequires: libXtst-devel
BuildRequires: libXt-devel BuildRequires: libXt-devel
%endif %endif
Obsoletes: gcc-libgcj #Obsoletes: gcc-libgcj
Obsoletes: libgcj3 #Obsoletes: libgcj3
Obsoletes: libgcj34 #Obsoletes: libgcj34
Obsoletes: libgcj4 #Obsoletes: libgcj4
Autoreq: true Autoreq: true
%description -n libgcj %description -n libgcj
@ -364,9 +361,9 @@ Group: Development/Languages
Requires: libgcj = %{version}-%{release}, %{_prefix}/%{_lib}/libgcj.so.9 Requires: libgcj = %{version}-%{release}, %{_prefix}/%{_lib}/libgcj.so.9
Requires: zlib-devel, %{_prefix}/%{_lib}/libz.so Requires: zlib-devel, %{_prefix}/%{_lib}/libz.so
Requires: /bin/awk Requires: /bin/awk
Obsoletes: libgcj3-devel #Obsoletes: libgcj3-devel
Obsoletes: libgcj34-devel #Obsoletes: libgcj34-devel
Obsoletes: libgcj4-devel #Obsoletes: libgcj4-devel
Autoreq: false Autoreq: false
Autoprov: false Autoprov: false
@ -378,7 +375,7 @@ package to compile your Java programs using the GCC Java compiler (gcj).
Summary: Java library sources from GCC4 preview Summary: Java library sources from GCC4 preview
Group: System Environment/Libraries Group: System Environment/Libraries
Requires: libgcj = %{version}-%{release} Requires: libgcj = %{version}-%{release}
Obsoletes: libgcj4-src #Obsoletes: libgcj4-src
Autoreq: true Autoreq: true
%description -n libgcj-src %description -n libgcj-src
@ -389,7 +386,7 @@ Summary: The C Preprocessor.
Group: Development/Languages Group: Development/Languages
Prereq: /sbin/install-info Prereq: /sbin/install-info
%ifarch ia64 %ifarch ia64
Obsoletes: gnupro #Obsoletes: gnupro
%endif %endif
Autoreq: true Autoreq: true
@ -419,7 +416,7 @@ macros.
Summary: Ada 95 support for GCC Summary: Ada 95 support for GCC
Group: Development/Languages Group: Development/Languages
Requires: gcc = %{version}-%{release}, libgnat = %{version}-%{release} Requires: gcc = %{version}-%{release}, libgnat = %{version}-%{release}
Obsoletes: gnat-devel, gcc3-gnat #Obsoletes: gnat-devel, gcc3-gnat
Prereq: /sbin/install-info Prereq: /sbin/install-info
Autoreq: true Autoreq: true
@ -430,7 +427,7 @@ the documents and Ada 95 compiler.
%package -n libgnat %package -n libgnat
Summary: GNU Ada 95 runtime shared libraries Summary: GNU Ada 95 runtime shared libraries
Group: System Environment/Libraries Group: System Environment/Libraries
Obsoletes: gnat libgnat3 #Obsoletes: gnat libgnat3
Autoreq: true Autoreq: true
%description -n libgnat %description -n libgnat
@ -455,18 +452,8 @@ which are required to run programs compiled with the GNAT.
%patch14 -p0 -b .rh251682~ %patch14 -p0 -b .rh251682~
%patch15 -p0 -b .sparc-config-detection~ %patch15 -p0 -b .sparc-config-detection~
%patch16 -p0 -b .libgomp-omp_h-multilib~ %patch16 -p0 -b .libgomp-omp_h-multilib~
%patch17 -p0 -b .fortran-debug1~ %patch17 -p0 -b .x86_64-va_start~
%patch18 -p0 -b .fortran-debug2~ %patch18 -p0 -b .pr37189~
%patch19 -p0 -b .fortran-debug3~
%patch20 -p0 -b .fortran-debug4~
%patch21 -p0 -b .fortran-debug5~
%patch22 -p0 -b .fortran-debug6~
%patch23 -p0 -b .fortran-debug7~
%patch24 -p0 -b .fortran-debug8~
%patch25 -p0 -b .fortran-debug9~
%patch26 -p0 -b .fortran-debug10~
%patch27 -p0 -b .fortran-debug11~
%patch28 -p0 -b .pr37248~
tar xzf %{SOURCE4} tar xzf %{SOURCE4}
@ -489,6 +476,38 @@ perl -pi -e 's/^check: check-recursive/ifeq (\$(MULTISUBDIR),)\ncheck: check-rec
./contrib/gcc_update --touch ./contrib/gcc_update --touch
# To make rpmlint happy (argh), fix up names in ChangeLog entries to valid UTF-8
LC_ALL=C sed -i \
-e 's/D\(o\|\xf6\)nmez/D\xc3\xb6nmez/' \
-e 's/\(Av\|\x81\xc1v\|\xc1v\|\xef\xbf\xbdv\?\|\x81\xc3\x81v\|\xc3v\)ila/\xc3\x81vila/' \
-e 's/Esp\(in\|\x81\xedn\|\xedn\|\xef\xbf\xbdn\?\|\xef\xbf\xbd\xadn\|\x81\xc3\xadn\)dola/Esp\xc3\xadndola/' \
-e 's/Schl\(u\|\xef\xbf\xbd\|\xfcu\?\|\x81\xfc\|\x81\xc3\xbc\|\xc3\xaf\xc2\xbf\xc2\xbd\|\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xc2\xbc\)ter/Schl\xc3\xbcter/' \
-e 's/Humi\(e\|\xe8\)res/Humi\xc3\xa8res/' \
-e 's/L\(ow\|\xc3\xaf\xc2\xbf\xc2\xbd\|oew\|\xf6w\)is/L\xc3\xb6wis/' \
-e 's/G\xfctlein/G\xc3\xbctlein/' \
-e 's/G\xe1[b]or/G\xc3\xa1bor/' \
-e 's/L\xf3ki/L\xc3\xb3ki/' \
-e 's/Fautr\xc3 /Fautr\xc3\xa9 /' \
-e 's/S\xe9[b]astian/S\xc3\xa9bastian/' \
-e 's/Th\xef\xbf\xbd[d]ore/Th\xc3\xa9odore/' \
-e 's/Cors\xc3\xc2\xa9pius/Cors\xc3\xa9pius/' \
-e 's/K\xfchl/K\xc3\xbchl/' \
-e 's/R\xf6nnerup/R\xc3\xb6nnerup/' \
-e 's/L\xf8vset/L\xc3\xb8vset/' \
-e 's/Ph\x81\xfb\x81\xf4ng-Th\x81\xe5o/Ph\xc3\xbb\xc3\xb4ng-Th\xc3\xa5o/' \
-e 's/V\x81\xf5/V\xc3\xb5/' \
-e 's/J\xf6nsson/J\xc3\xb6nsson/' \
-e 's/V\xef\xbf\xbdis\xef\xbf\xbdnen/V\xc3\xa4is\xc3\xa4nen/' \
-e 's/J\xef\xbf\xbdrg/J\xc3\xb6rg/' \
-e 's/M\xef\xbf\xbdsli/M\xc3\xb6sli/' \
-e 's/R\xe4ty/R\xc3\xa4ty/' \
-e 's/2003\xc2\xad-/2003-/' \
-e 's/\xc2\xa0/ /g' \
-e 's/ \xa0/ /g' \
-e 's/\xa0 //' \
`find . -name \*ChangeLog\*`
LC_ALL=C sed -i -e 's/\xa0/ /' gcc/doc/options.texi
%ifarch ppc %ifarch ppc
if [ -d libstdc++-v3/config/abi/post/powerpc64-linux-gnu ]; then if [ -d libstdc++-v3/config/abi/post/powerpc64-linux-gnu ]; then
mkdir -p libstdc++-v3/config/abi/post/powerpc64-linux-gnu/64 mkdir -p libstdc++-v3/config/abi/post/powerpc64-linux-gnu/64
@ -523,12 +542,6 @@ rm -fr obj-%{gcc_target_platform}
mkdir obj-%{gcc_target_platform} mkdir obj-%{gcc_target_platform}
cd obj-%{gcc_target_platform} cd obj-%{gcc_target_platform}
if [ ! -f /usr/lib/locale/de_DE/LC_CTYPE ]; then
mkdir locale
localedef -f ISO-8859-1 -i de_DE locale/de_DE
export LOCPATH=`pwd`/locale:/usr/lib/locale
fi
%if %{build_java} %if %{build_java}
%if !%{bootstrap_java} %if !%{bootstrap_java}
# If we don't have gjavah in $PATH, try to build it with the old gij # If we don't have gjavah in $PATH, try to build it with the old gij
@ -738,10 +751,6 @@ perl -pi -e \
cd obj-%{gcc_target_platform} cd obj-%{gcc_target_platform}
if [ ! -f /usr/lib/locale/de_DE/LC_CTYPE ]; then
export LOCPATH=`pwd`/locale:/usr/lib/locale
fi
%if %{build_java} %if %{build_java}
export PATH=`pwd`/../fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}${PATH:+:$PATH} export PATH=`pwd`/../fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}${PATH:+:$PATH}
%if !%{bootstrap_java} %if !%{bootstrap_java}
@ -1073,6 +1082,7 @@ rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/{libffi*,libiberty.a}
rm -f $FULLEPATH/install-tools/{mkheaders,fixincl} rm -f $FULLEPATH/install-tools/{mkheaders,fixincl}
rm -f $RPM_BUILD_ROOT%{_prefix}/lib/{32,64}/libiberty.a rm -f $RPM_BUILD_ROOT%{_prefix}/lib/{32,64}/libiberty.a
rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libssp* rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libssp*
rm -f $RPM_BUILD_ROOT%{_prefix}/bin/gnative2ascii
%ifarch %{multilib_64_archs} %ifarch %{multilib_64_archs}
# Remove libraries for the other arch on multilib arches # Remove libraries for the other arch on multilib arches
@ -1692,6 +1702,18 @@ fi
%doc rpm.doc/changelogs/libmudflap/ChangeLog* %doc rpm.doc/changelogs/libmudflap/ChangeLog*
%changelog %changelog
* Fri Sep 5 2008 Jakub Jelinek <jakub@redhat.com> 4.3.2-2
- update from gcc-4_3-branch
- PRs c++/37348, c/37261, fortran/36371, fortran/37193, middle-end/36449,
target/36332, target/37168
- make ChangeLog files and gcc.info valid UTF-8, remove gnative2ascii from
gcc-gnat, comment out most of the Obsoletes (#225778)
- on x86_64 decrease frame size in varargs functions that don't need saving
gpr or fpr registers
- fix ICE on implicitly determined firstprivate where copy ctor or dtor
needs synthetization (PR c++/37189)
- document how to recrease the tarball
* Fri Aug 29 2008 Jakub Jelinek <jakub@redhat.com> 4.3.2-1 * Fri Aug 29 2008 Jakub Jelinek <jakub@redhat.com> 4.3.2-1
- update from gcc-4_3-branch - update from gcc-4_3-branch
- 4.3.2 release - 4.3.2 release

View File

@ -1,2 +1,2 @@
69f70d92142466361146326f840a6185 gcc-4.3.2-20080829.tar.bz2 373bfd18d804b93123d89b793967fb3b gcc-4.3.2-20080905.tar.bz2
92a70f9e56223b653bce0f58f90cf950 fastjar-0.95.tar.gz 92a70f9e56223b653bce0f58f90cf950 fastjar-0.95.tar.gz