4.3.2-2
This commit is contained in:
parent
1af11d046b
commit
cd9cbfcd14
@ -1,2 +1,2 @@
|
||||
gcc-4.3.2-20080829.tar.bz2
|
||||
gcc-4.3.2-20080905.tar.bz2
|
||||
fastjar-0.95.tar.gz
|
||||
|
@ -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
|
@ -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;
|
@ -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
@ -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;
|
||||
}
|
||||
|
@ -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" } }
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
@ -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);
|
@ -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
117
gcc43-pr37189.patch
Normal 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);
|
||||
+}
|
@ -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
355
gcc43-x86_64-va_start.patch
Normal 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;
|
||||
+}
|
174
gcc43.spec
174
gcc43.spec
@ -1,6 +1,9 @@
|
||||
%define DATE 20080829
|
||||
%define DATE 20080905
|
||||
%define SVNREV 140029
|
||||
%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 multilib_64_archs sparc64 ppc64 s390x x86_64
|
||||
%define include_gappletviewer 1
|
||||
@ -37,6 +40,10 @@ Release: %{gcc_release}
|
||||
# restrictions.
|
||||
License: GPLv3+ and GPLv2+ with exceptions
|
||||
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
|
||||
Source1: libgcc_post_upgrade.c
|
||||
Source2: README.libgcjwebplugin.so
|
||||
@ -44,7 +51,7 @@ Source3: protoize.1
|
||||
%define fastjar_ver 0.95
|
||||
Source4: http://download.savannah.nongnu.org/releases/fastjar/fastjar-%{fastjar_ver}.tar.gz
|
||||
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 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
|
||||
@ -103,27 +110,27 @@ Requires: glibc >= 2.3.90-35
|
||||
%endif
|
||||
Requires: libgcc >= %{version}-%{release}
|
||||
Requires: libgomp = %{version}-%{release}
|
||||
Obsoletes: gcc3
|
||||
Obsoletes: egcs
|
||||
#Obsoletes: gcc3
|
||||
#Obsoletes: egcs
|
||||
%ifarch sparc
|
||||
Obsoletes: gcc-sparc32
|
||||
Obsoletes: gcc-c++-sparc32
|
||||
#Obsoletes: gcc-sparc32
|
||||
#Obsoletes: gcc-c++-sparc32
|
||||
%endif
|
||||
%ifarch ppc
|
||||
Obsoletes: gcc-ppc32
|
||||
Obsoletes: gcc-c++-ppc32
|
||||
#Obsoletes: gcc-ppc32
|
||||
#Obsoletes: gcc-c++-ppc32
|
||||
%endif
|
||||
Obsoletes: gcc-chill
|
||||
#Obsoletes: gcc-chill
|
||||
%if !%{build_ada}
|
||||
Obsoletes: gcc-gnat < %{version}-%{release}
|
||||
Obsoletes: libgnat < %{version}-%{release}
|
||||
%endif
|
||||
%ifarch sparc sparc64
|
||||
Obsoletes: egcs64
|
||||
#Obsoletes: egcs64
|
||||
%endif
|
||||
Obsoletes: gcc34
|
||||
Obsoletes: gcc35
|
||||
Obsoletes: gcc4
|
||||
#Obsoletes: gcc34
|
||||
#Obsoletes: gcc35
|
||||
#Obsoletes: gcc4
|
||||
Prereq: /sbin/install-info
|
||||
AutoReq: true
|
||||
|
||||
@ -143,18 +150,8 @@ Patch13: gcc43-i386-libgomp.patch
|
||||
Patch14: gcc43-rh251682.patch
|
||||
Patch15: gcc43-sparc-config-detection.patch
|
||||
Patch16: gcc43-libgomp-omp_h-multilib.patch
|
||||
Patch17: gcc43-fortran-debug1.patch
|
||||
Patch18: gcc43-fortran-debug2.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
|
||||
Patch17: gcc43-x86_64-va_start.patch
|
||||
Patch18: gcc43-pr37189.patch
|
||||
|
||||
# On ARM EABI systems, we do want -gnueabi to be part of the
|
||||
# target triple.
|
||||
@ -190,10 +187,10 @@ Group: Development/Languages
|
||||
Requires: gcc = %{version}-%{release}
|
||||
Requires: libstdc++ = %{version}-%{release}
|
||||
Requires: libstdc++-devel = %{version}-%{release}
|
||||
Obsoletes: gcc3-c++
|
||||
Obsoletes: gcc34-c++
|
||||
Obsoletes: gcc35-c++
|
||||
Obsoletes: gcc4-c++
|
||||
#Obsoletes: gcc3-c++
|
||||
#Obsoletes: gcc34-c++
|
||||
#Obsoletes: gcc35-c++
|
||||
#Obsoletes: gcc4-c++
|
||||
Autoreq: true
|
||||
|
||||
%description c++
|
||||
@ -204,8 +201,8 @@ including templates and exception handling.
|
||||
%package -n libstdc++
|
||||
Summary: GNU Standard C++ Library
|
||||
Group: System Environment/Libraries
|
||||
Obsoletes: libstdc++3
|
||||
Obsoletes: libstdc++34
|
||||
#Obsoletes: libstdc++3
|
||||
#Obsoletes: libstdc++34
|
||||
Autoreq: true
|
||||
|
||||
%description -n libstdc++
|
||||
@ -216,8 +213,8 @@ C++ Library.
|
||||
Summary: Header files and libraries for C++ development
|
||||
Group: Development/Libraries
|
||||
Requires: libstdc++ = %{version}-%{release}, %{_prefix}/%{_lib}/libstdc++.so.6
|
||||
Obsoletes: libstdc++3-devel
|
||||
Obsoletes: libstdc++34-devel
|
||||
#Obsoletes: libstdc++3-devel
|
||||
#Obsoletes: libstdc++34-devel
|
||||
Autoreq: true
|
||||
|
||||
%description -n libstdc++-devel
|
||||
@ -230,7 +227,7 @@ Summary: Objective-C support for GCC
|
||||
Group: Development/Languages
|
||||
Requires: gcc = %{version}-%{release}
|
||||
Requires: libobjc = %{version}-%{release}
|
||||
Obsoletes: gcc3-objc
|
||||
#Obsoletes: gcc3-objc
|
||||
Autoreq: true
|
||||
|
||||
%description objc
|
||||
@ -263,9 +260,9 @@ Requires: gcc = %{version}-%{release}
|
||||
Requires: libgfortran = %{version}-%{release}
|
||||
BuildRequires: gmp-devel >= 4.1.2-8, mpfr-devel >= 2.2.1
|
||||
Prereq: /sbin/install-info
|
||||
Obsoletes: gcc3-g77
|
||||
Obsoletes: gcc-g77
|
||||
Obsoletes: gcc4-gfortran
|
||||
#Obsoletes: gcc3-g77
|
||||
#Obsoletes: gcc-g77
|
||||
#Obsoletes: gcc4-gfortran
|
||||
Autoreq: true
|
||||
|
||||
%description gfortran
|
||||
@ -275,7 +272,7 @@ programs with the GNU Compiler Collection.
|
||||
%package -n libgfortran
|
||||
Summary: Fortran 95 runtime
|
||||
Group: System Environment/Libraries
|
||||
Obsoletes: libf2c
|
||||
#Obsoletes: libf2c
|
||||
Autoreq: true
|
||||
|
||||
%description -n libgfortran
|
||||
@ -320,10 +317,10 @@ Requires: gcc = %{version}-%{release}
|
||||
Requires: libgcj = %{version}-%{release}
|
||||
Requires: libgcj-devel = %{version}-%{release}
|
||||
Requires: /usr/share/java/eclipse-ecj.jar
|
||||
Obsoletes: gcc3-java
|
||||
Obsoletes: gcc34-java
|
||||
Obsoletes: gcc35-java
|
||||
Obsoletes: gcc4-java
|
||||
#Obsoletes: gcc3-java
|
||||
#Obsoletes: gcc34-java
|
||||
#Obsoletes: gcc35-java
|
||||
#Obsoletes: gcc4-java
|
||||
Prereq: /sbin/install-info
|
||||
Autoreq: true
|
||||
|
||||
@ -348,10 +345,10 @@ BuildRequires: alsa-lib-devel
|
||||
BuildRequires: libXtst-devel
|
||||
BuildRequires: libXt-devel
|
||||
%endif
|
||||
Obsoletes: gcc-libgcj
|
||||
Obsoletes: libgcj3
|
||||
Obsoletes: libgcj34
|
||||
Obsoletes: libgcj4
|
||||
#Obsoletes: gcc-libgcj
|
||||
#Obsoletes: libgcj3
|
||||
#Obsoletes: libgcj34
|
||||
#Obsoletes: libgcj4
|
||||
Autoreq: true
|
||||
|
||||
%description -n libgcj
|
||||
@ -364,9 +361,9 @@ Group: Development/Languages
|
||||
Requires: libgcj = %{version}-%{release}, %{_prefix}/%{_lib}/libgcj.so.9
|
||||
Requires: zlib-devel, %{_prefix}/%{_lib}/libz.so
|
||||
Requires: /bin/awk
|
||||
Obsoletes: libgcj3-devel
|
||||
Obsoletes: libgcj34-devel
|
||||
Obsoletes: libgcj4-devel
|
||||
#Obsoletes: libgcj3-devel
|
||||
#Obsoletes: libgcj34-devel
|
||||
#Obsoletes: libgcj4-devel
|
||||
Autoreq: 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
|
||||
Group: System Environment/Libraries
|
||||
Requires: libgcj = %{version}-%{release}
|
||||
Obsoletes: libgcj4-src
|
||||
#Obsoletes: libgcj4-src
|
||||
Autoreq: true
|
||||
|
||||
%description -n libgcj-src
|
||||
@ -389,7 +386,7 @@ Summary: The C Preprocessor.
|
||||
Group: Development/Languages
|
||||
Prereq: /sbin/install-info
|
||||
%ifarch ia64
|
||||
Obsoletes: gnupro
|
||||
#Obsoletes: gnupro
|
||||
%endif
|
||||
Autoreq: true
|
||||
|
||||
@ -419,7 +416,7 @@ macros.
|
||||
Summary: Ada 95 support for GCC
|
||||
Group: Development/Languages
|
||||
Requires: gcc = %{version}-%{release}, libgnat = %{version}-%{release}
|
||||
Obsoletes: gnat-devel, gcc3-gnat
|
||||
#Obsoletes: gnat-devel, gcc3-gnat
|
||||
Prereq: /sbin/install-info
|
||||
Autoreq: true
|
||||
|
||||
@ -430,7 +427,7 @@ the documents and Ada 95 compiler.
|
||||
%package -n libgnat
|
||||
Summary: GNU Ada 95 runtime shared libraries
|
||||
Group: System Environment/Libraries
|
||||
Obsoletes: gnat libgnat3
|
||||
#Obsoletes: gnat libgnat3
|
||||
Autoreq: true
|
||||
|
||||
%description -n libgnat
|
||||
@ -455,18 +452,8 @@ which are required to run programs compiled with the GNAT.
|
||||
%patch14 -p0 -b .rh251682~
|
||||
%patch15 -p0 -b .sparc-config-detection~
|
||||
%patch16 -p0 -b .libgomp-omp_h-multilib~
|
||||
%patch17 -p0 -b .fortran-debug1~
|
||||
%patch18 -p0 -b .fortran-debug2~
|
||||
%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~
|
||||
%patch17 -p0 -b .x86_64-va_start~
|
||||
%patch18 -p0 -b .pr37189~
|
||||
|
||||
tar xzf %{SOURCE4}
|
||||
|
||||
@ -489,6 +476,38 @@ perl -pi -e 's/^check: check-recursive/ifeq (\$(MULTISUBDIR),)\ncheck: check-rec
|
||||
|
||||
./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
|
||||
if [ -d libstdc++-v3/config/abi/post/powerpc64-linux-gnu ]; then
|
||||
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}
|
||||
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 !%{bootstrap_java}
|
||||
# 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}
|
||||
|
||||
if [ ! -f /usr/lib/locale/de_DE/LC_CTYPE ]; then
|
||||
export LOCPATH=`pwd`/locale:/usr/lib/locale
|
||||
fi
|
||||
|
||||
%if %{build_java}
|
||||
export PATH=`pwd`/../fastjar-%{fastjar_ver}/obj-%{gcc_target_platform}${PATH:+:$PATH}
|
||||
%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 $RPM_BUILD_ROOT%{_prefix}/lib/{32,64}/libiberty.a
|
||||
rm -f $RPM_BUILD_ROOT%{_prefix}/%{_lib}/libssp*
|
||||
rm -f $RPM_BUILD_ROOT%{_prefix}/bin/gnative2ascii
|
||||
|
||||
%ifarch %{multilib_64_archs}
|
||||
# Remove libraries for the other arch on multilib arches
|
||||
@ -1692,6 +1702,18 @@ fi
|
||||
%doc rpm.doc/changelogs/libmudflap/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
|
||||
- update from gcc-4_3-branch
|
||||
- 4.3.2 release
|
||||
|
Loading…
Reference in New Issue
Block a user