diff options
63 files changed, 1131 insertions, 280 deletions
diff --git a/ChangeLog.melt b/ChangeLog.melt index 1dac39b28c5..fe03270b35d 100644 --- a/ChangeLog.melt +++ b/ChangeLog.melt @@ -1,3 +1,6 @@ +2009-03-08 Basile Starynkevitch <basile@starynkevitch.net> + MELT branch merged with trunk r144708 + 2009-03-04 Basile Starynkevitch <basile@starynkevitch.net> MELT branch merged with trunk r144598 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6eb37db88f2..ac3f3fb3af0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,118 @@ +2009-03-07 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + PR middle-end/38028 + * function.c (assign_parm_setup_stack): Use STACK_SLOT_ALIGNMENT to + determine alignment passed to assign_stack_local. + (assign_parms_unsplit_complex): Likewise. + * except.c (sjlj_build_landing_pads): Likewise. + +2009-03-06 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/39360 + * tree-flow.h (add_referenced_var): Return bool instead of void. + * tree-dfa.c (add_referenced_var): Return result of + referenced_var_check_and_insert call. + * tree-inline.c (expand_call_inline): Call add_referenced_var instead + of referenced_var_check_and_insert. + + PR debug/39372 + * dwarf2out.c (add_abstract_origin_attribute): Return + origin_die. + (gen_variable_die): Emit DW_AT_location on abstract static variable's + DIE, don't emit it if abstract origin already has it. + * tree-cfg.c (remove_useless_stmts_bind): GIMPLE_BINDs with any + BLOCK_NONLOCALIZED_VARS in its gimple_bind_block aren't useless. + +2009-03-06 Jan-Benedict Glaw <jbglaw@lug-owl.de> + + * genpreds.c: (needs_variable): Fix parentheses at variable name + detection. + (write_tm_constrs_h): Indent generated code. + +2009-03-06 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + * doc/extend.texi (Function Attributes): Add documentation + for isr attributes. + +2009-03-06 Jakub Jelinek <jakub@redhat.com> + + PR debug/39387 + * dwarf2out.c (dwarf2out_imported_module_or_decl_1): For IMPORTED_DECL + take locus from its DECL_SOURCE_LOCATION instead of input_location. + +2009-03-05 Bernd Schmidt <bernd.schmidt@analog.com> + + * config/bfin/bfin.c (bfin_discover_loop): When retrying fails, mark + the loop as bad. + +2009-03-05 Jakub Jelinek <jakub@redhat.com> + + PR debug/39379 + * tree-cfg.c (remove_useless_stmts_bind): Don't remove GIMPLE_BINDs + with blocks containing IMPORTED_DECLs in BLOCK_VARS. + +2009-03-05 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.md (R8_REG, R9_REG): New constants. + * config/i386/i386.h (CONDITIONAL_REGISTER_USAGE): Use named + constants instead of magic numbers. + (HARD_REGNO_CALLER_SAVE_MODE): Ditto. + (QI_REG_P): Ditto. + * config/i386/i386.c (x86_64_int_parameter_registers): Ditto. + (x86_64_ms_abi_int_parameter_registers): Ditto. + (x86_64_int_return_registers): Ditto. + (ix86_maybe_switch_abi): Ditto. + (ix86_expand_call): Ditto for clobbered_registers array. + (ix86_hard_regno_mode_ok): Ditto. + (x86_extended_QIreg_mentioned_p): Ditto. + +2009-03-05 J"orn Rennecke <joern.rennecke@arc.com> + + PR tree-optimization/39349 + * cse.c (cse_insn): Fix loop to stop at VOIDmode. + + * combine.c (gen_lowpart_for_combine): Use omode when generating + clobber. + +2009-03-04 J"orn Rennecke <joern.rennecke@arc.com> + + PR rtl-optimization/39235 + * loop-iv.c (get_simple_loop_desc): Use XCNEW. + +2009-03-04 Zdenek Dvorak <ook@ucw.cz> + + * graphite.c (nb_reductions_in_loop): Update simple_iv arguments. + +2009-03-04 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/39362 + * tree-ssa-sccvn.c (visit_use): Stores and copies from SSA_NAMEs + that occur in abnormal PHIs should be varying. + +2009-03-04 Zdenek Dvorak <ook@ucw.cz> + + * tree-scalar-evolution.c (analyze_scalar_evolution_in_loop): + Extend comments. + (simple_iv): Take loop as an argument instead of statement. + * tree-scalar-evolution.h (simple_iv): Declaration changed. + * tree-ssa-loop-niter.c (number_of_iterations_exit): Update calls + to simple_iv. + * tree-ssa-loop-ivopts.c (determine_biv_step, find_givs_in_stmt_scev): + Ditto. + * tree-parloops.c (loop_parallel_p, canonicalize_loop_ivs): Ditto. + * matrix-reorg.c (analyze_transpose): Ditto. + * tree-data-ref.c (dr_analyze_innermost): Ditto. + * tree-vect-analyze.c (vect_analyze_data_refs): Ditto. + * tree-predcom.c (ref_at_iteration): Ditto. + * tree-ssa-loop-prefetch.c (idx_analyze_ref): Ditto. + +2009-03-04 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/39358 + * tree-ssa-structalias.c (do_sd_constraint): Fix check for + escaped_id and callused_id. + (solve_graph): Likewise. + 2009-03-04 Richard Guenther <rguenther@suse.de> PR tree-optimization/39339 @@ -63,10 +178,10 @@ * config/i386/i386.md (ST?_REG, MM?_REG): New constants. (*call_1_rex64_ms_sysv): Use named constants instead of magic - numbers to describe clobbbered registers. + numbers to describe clobbered registers. (*call_value_0_rex64_ms_sysv): Ditto. - * config/i386/mmx.md (emms): Ditto. - (femms): Ditto. + * config/i386/mmx.md (mmx_emms): Ditto. + (mmx_femms): Ditto. 2009-03-02 Richard Sandiford <rdsandiford@googlemail.com> @@ -274,7 +389,7 @@ PR tree-optimization/39259 * tree-inline.c (initialize_cfun): Remove asserts for calls_setjmp and - alls_alloca function flags. + calls_alloca function flags. (copy_bb): Set calls_setjmp and alls_alloca function flags if such calls are detected. @@ -667,7 +782,7 @@ PR target/39149 * config/i386/i386.c (override_options): Correct warning - messages for -malign-loops, -malign-jumps and -malign-functions. + messages for -malign-loops, -malign-jumps and -malign-functions. 2009-02-13 H.J. Lu <hongjiu.lu@intel.com> diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 6f61d0a2636..1c6be43b888 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20090304 +20090308 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 5465899f298..08156973305 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -25,6 +25,7 @@ 2009-02-25 Laurent GUERBY <laurent@guerby.net> + PR ada/39221 * a-teioed.adb (Expand): Fix Result overflow. 2009-02-25 Laurent GUERBY <laurent@guerby.net> diff --git a/gcc/combine.c b/gcc/combine.c index 3aca075aae1..a9026636e3e 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -9973,7 +9973,7 @@ gen_lowpart_for_combine (enum machine_mode omode, rtx x) } fail: - return gen_rtx_CLOBBER (imode, const0_rtx); + return gen_rtx_CLOBBER (omode, const0_rtx); } /* Simplify a comparison between *POP0 and *POP1 where CODE is the diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index ec5dd57dde7..f4f9d45e321 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -4362,6 +4362,12 @@ bfin_discover_loop (loop_info loop, basic_block tail_bb, rtx tail_insn) break; } } + if (!retry) + { + if (dump_file) + fprintf (dump_file, ";; No forwarder blocks found\n"); + loop->bad = 1; + } } } } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 120ab156fb1..e7dd5bebaec 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1533,24 +1533,8 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] = -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */ }; -static int const x86_64_int_parameter_registers[6] = -{ - 5 /*RDI*/, 4 /*RSI*/, 1 /*RDX*/, 2 /*RCX*/, - FIRST_REX_INT_REG /*R8 */, FIRST_REX_INT_REG + 1 /*R9 */ -}; - -static int const x86_64_ms_abi_int_parameter_registers[4] = -{ - 2 /*RCX*/, 1 /*RDX*/, - FIRST_REX_INT_REG /*R8 */, FIRST_REX_INT_REG + 1 /*R9 */ -}; - -static int const x86_64_int_return_registers[4] = -{ - 0 /*RAX*/, 1 /*RDX*/, 5 /*RDI*/, 4 /*RSI*/ -}; - /* The "default" register map used in 64bit mode. */ + int const dbx64_register_map[FIRST_PSEUDO_REGISTER] = { 0, 1, 2, 3, 4, 5, 6, 7, /* general regs */ @@ -1634,6 +1618,23 @@ rtx ix86_compare_op0 = NULL_RTX; rtx ix86_compare_op1 = NULL_RTX; rtx ix86_compare_emitted = NULL_RTX; +/* Define parameter passing and return registers. */ + +static int const x86_64_int_parameter_registers[6] = +{ + DI_REG, SI_REG, DX_REG, CX_REG, R8_REG, R9_REG +}; + +static int const x86_64_ms_abi_int_parameter_registers[4] = +{ + CX_REG, DX_REG, R8_REG, R9_REG +}; + +static int const x86_64_int_return_registers[4] = +{ + AX_REG, DX_REG, DI_REG, SI_REG +}; + /* Define the structure for the machine field in struct function. */ struct stack_local_entry GTY(()) @@ -4617,7 +4618,7 @@ static void ix86_maybe_switch_abi (void) { if (TARGET_64BIT && - call_used_regs[4 /*RSI*/] == (cfun->machine->call_abi == MS_ABI)) + call_used_regs[SI_REG] == (cfun->machine->call_abi == MS_ABI)) reinit_regs (); } @@ -18684,8 +18685,12 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, by SYSV calls. */ if (ix86_cfun_abi () == MS_ABI && function_call_abi == SYSV_ABI) { - static int clobbered_registers[] = {27, 28, 45, 46, 47, 48, 49, 50, 51, - 52, SI_REG, DI_REG}; + static int clobbered_registers[] = { + XMM6_REG, XMM7_REG, XMM8_REG, + XMM9_REG, XMM10_REG, XMM11_REG, + XMM12_REG, XMM13_REG, XMM14_REG, + XMM15_REG, SI_REG, DI_REG + }; unsigned int i; rtx vec[ARRAY_SIZE (clobbered_registers) + 2]; rtx unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), @@ -25757,7 +25762,7 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode) { /* Take care for QImode values - they can be in non-QI regs, but then they do cause partial register stalls. */ - if (regno < 4 || TARGET_64BIT) + if (regno <= BX_REG || TARGET_64BIT) return 1; if (!TARGET_PARTIAL_REG_STALL) return 1; @@ -26869,7 +26874,7 @@ x86_extended_QIreg_mentioned_p (rtx insn) extract_insn_cached (insn); for (i = 0; i < recog_data.n_operands; i++) if (REG_P (recog_data.operand[i]) - && REGNO (recog_data.operand[i]) >= 4) + && REGNO (recog_data.operand[i]) > BX_REG) return true; return false; } diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 5bdf379bca0..f2f4448d15e 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -938,10 +938,10 @@ do { \ && ((cfun && cfun->machine->call_abi == MS_ABI) \ || (!cfun && DEFAULT_ABI == MS_ABI))) \ { \ - call_used_regs[4 /*RSI*/] = 0; \ - call_used_regs[5 /*RDI*/] = 0; \ - call_used_regs[27 /*XMM6*/] = 0; \ - call_used_regs[28 /*XMM7*/] = 0; \ + call_used_regs[SI_REG] = 0; \ + call_used_regs[DI_REG] = 0; \ + call_used_regs[XMM6_REG] = 0; \ + call_used_regs[XMM7_REG] = 0; \ for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++) \ call_used_regs[i] = 0; \ } \ @@ -1073,7 +1073,7 @@ do { \ : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \ : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false) \ : (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode \ - : (MODE) == QImode && (REGNO) >= 4 && !TARGET_64BIT ? SImode \ + : (MODE) == QImode && (REGNO) > BX_REG && !TARGET_64BIT ? SImode \ : (MODE)) /* Specify the registers used for certain standard purposes. @@ -1310,7 +1310,7 @@ enum reg_class #define SMALL_REGISTER_CLASSES 1 -#define QI_REG_P(X) (REG_P (X) && REGNO (X) < 4) +#define QI_REG_P(X) (REG_P (X) && REGNO (X) <= BX_REG) #define GENERAL_REGNO_P(N) \ ((N) <= STACK_POINTER_REGNUM || REX_INT_REGNO_P (N)) @@ -1508,7 +1508,8 @@ enum reg_class prologue and apilogue. This is not possible without ACCUMULATE_OUTGOING_ARGS. */ -#define ACCUMULATE_OUTGOING_ARGS (TARGET_ACCUMULATE_OUTGOING_ARGS || ix86_cfun_abi () == MS_ABI) +#define ACCUMULATE_OUTGOING_ARGS \ + (TARGET_ACCUMULATE_OUTGOING_ARGS || ix86_cfun_abi () == MS_ABI) /* If defined, a C expression whose value is nonzero when we want to use PUSH instructions to pass outgoing arguments. */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9c6ae1c12a6..761a5e70c68 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -291,6 +291,8 @@ (MM5_REG 34) (MM6_REG 35) (MM7_REG 36) + (R8_REG 37) + (R9_REG 38) (R10_REG 39) (R11_REG 40) (R13_REG 42) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9d1ab5a6211..368843fd3a0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,50 @@ +2009-03-07 Jason Merrill <jason@redhat.com> + + PR c++/39367 + * init.c (build_new_1): Don't use a VLA type. + (build_vec_init): Handle getting a pointer for BASE. + +2009-03-06 H.J. Lu <hongjiu.lu@intel.com> + + PR c++/37520 + * cp-tree.h: Check NO_DOT_IN_LABEL before NO_DOLLAR_IN_LABEL + when mangling symbols. + +2009-03-06 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/33492 + * error.c (dump_expr): Don't try to print THROW_EXPRs in full. + +2009-03-06 Alexandre Oliva <aoliva@redhat.com> + + * decl.c (record_builtin_java_type): Use canonicalized integer + types. + +2009-03-04 Jason Merrill <jason@redhat.com> + + PR c++/38908 + * class.c (is_really_empty_class): New fn. + * cp-tree.h: Declare it. + * cp-objcp-common.c (cp_expr_size): Use it. + + PR c++/13549 + * semantics.c (perform_koenig_lookup): Handle TEMPLATE_ID_EXPR. + * parser.c (cp_parser_postfix_expression): Call it for + TEMPLATE_ID_EXPR. + * tree.c (is_overloaded_fn): Look through TEMPLATE_ID_EXPR. + (get_first_fn): Likewise. + + PR c++/9634 + PR c++/29469 + PR c++/29607 + Implement DR 224. + * decl.c (make_typename_type): Do look inside currently open classes. + * parser.c (cp_parser_lookup_name): Likewise. + (cp_parser_template_name): Likewise. + * pt.c (dependent_scope_p): New function. + * cp-tree.h: Declare it. + * class.c (currently_open_class): Return fast if T isn't a class. + 2009-02-26 H.J. Lu <hongjiu.lu@intel.com> PR c++/37789 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 13fa99027aa..b8553effc03 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5787,6 +5787,9 @@ currently_open_class (tree t) { int i; + if (!CLASS_TYPE_P (t)) + return false; + /* We start looking from 1 because entry 0 is from global scope, and has no type. */ for (i = current_class_depth; i > 0; --i) @@ -6458,7 +6461,7 @@ is_empty_class (tree type) if (type == error_mark_node) return 0; - if (! MAYBE_CLASS_TYPE_P (type)) + if (! CLASS_TYPE_P (type)) return 0; /* In G++ 3.2, whether or not a class was empty was determined by @@ -6498,6 +6501,37 @@ contains_empty_class_p (tree type) return false; } +/* Returns true if TYPE contains no actual data, just various + possible combinations of empty classes. */ + +bool +is_really_empty_class (tree type) +{ + if (is_empty_class (type)) + return true; + if (CLASS_TYPE_P (type)) + { + tree field; + tree binfo; + tree base_binfo; + int i; + + for (binfo = TYPE_BINFO (type), i = 0; + BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i) + if (!is_really_empty_class (BINFO_TYPE (base_binfo))) + return false; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && !DECL_ARTIFICIAL (field) + && !is_really_empty_class (TREE_TYPE (field))) + return false; + return true; + } + else if (TREE_CODE (type) == ARRAY_TYPE) + return is_really_empty_class (TREE_TYPE (type)); + return false; +} + /* Note that NAME was looked up while the current class was being defined and that the result of that lookup was DECL. */ diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 7d2e870bc80..fefafb1ac7e 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -101,7 +101,7 @@ cp_expr_size (const_tree exp) constructed, this is a valid transformation. */ || CP_AGGREGATE_TYPE_P (type)) /* This would be wrong for a type with virtual bases. */ - return (is_empty_class (type) + return (is_really_empty_class (type) ? size_zero_node : CLASSTYPE_SIZE_UNIT (type)); else diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 46ff9222b97..0b1d7c61cdc 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3660,20 +3660,8 @@ extern GTY(()) VEC(tree,gc) *local_classes; at a particular location, we can index into the string at any other location that provides distinguishing characters). */ -/* Define NO_DOLLAR_IN_LABEL in your favorite tm file if your assembler - doesn't allow '$' in symbol names. */ -#ifndef NO_DOLLAR_IN_LABEL - -#define JOINER '$' - -#define AUTO_TEMP_NAME "_$tmp_" -#define VFIELD_BASE "$vf" -#define VFIELD_NAME "_vptr$" -#define VFIELD_NAME_FORMAT "_vptr$%s" -#define ANON_AGGRNAME_FORMAT "$_%d" - -#else /* NO_DOLLAR_IN_LABEL */ - +/* Define NO_DOT_IN_LABEL in your favorite tm file if your assembler + doesn't allow '.' in symbol names. */ #ifndef NO_DOT_IN_LABEL #define JOINER '.' @@ -3687,6 +3675,18 @@ extern GTY(()) VEC(tree,gc) *local_classes; #else /* NO_DOT_IN_LABEL */ +#ifndef NO_DOLLAR_IN_LABEL + +#define JOINER '$' + +#define AUTO_TEMP_NAME "_$tmp_" +#define VFIELD_BASE "$vf" +#define VFIELD_NAME "_vptr$" +#define VFIELD_NAME_FORMAT "_vptr$%s" +#define ANON_AGGRNAME_FORMAT "$_%d" + +#else /* NO_DOLLAR_IN_LABEL */ + #define IN_CHARGE_NAME "__in_chrg" #define AUTO_TEMP_NAME "__tmp_" #define TEMP_NAME_P(ID_NODE) \ @@ -3709,8 +3709,8 @@ extern GTY(()) VEC(tree,gc) *local_classes; sizeof (ANON_AGGRNAME_PREFIX) - 1)) #define ANON_AGGRNAME_FORMAT "__anon_%d" -#endif /* NO_DOT_IN_LABEL */ #endif /* NO_DOLLAR_IN_LABEL */ +#endif /* NO_DOT_IN_LABEL */ #define THIS_NAME "this" @@ -4240,6 +4240,7 @@ extern void finish_struct_1 (tree); extern int resolves_to_fixed_type_p (tree, int *); extern void init_class_processing (void); extern int is_empty_class (tree); +extern bool is_really_empty_class (tree); extern void pushclass (tree); extern void popclass (void); extern void push_nested_class (tree); @@ -4594,6 +4595,7 @@ extern struct tinst_level *current_instantiation(void); extern tree maybe_get_template_decl_from_type_decl (tree); extern int processing_template_parmlist; extern bool dependent_type_p (tree); +extern bool dependent_scope_p (tree); extern bool any_dependent_template_arguments_p (const_tree); extern bool dependent_template_p (tree); extern bool dependent_template_id_p (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 551764dc29c..4ed342514b8 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2977,12 +2977,6 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); gcc_assert (TYPE_P (context)); - /* When the CONTEXT is a dependent type, NAME could refer to a - dependent base class of CONTEXT. So we cannot peek inside it, - even if CONTEXT is a currently open scope. */ - if (dependent_type_p (context)) - return build_typename_type (context, name, fullname, tag_type); - if (!MAYBE_CLASS_TYPE_P (context)) { if (complain & tf_error) @@ -2990,11 +2984,23 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; } + /* When the CONTEXT is a dependent type, NAME could refer to a + dependent base class of CONTEXT. But look inside it anyway + if CONTEXT is a currently open scope, in case it refers to a + member of the current instantiation or a non-dependent base; + lookup will stop when we hit a dependent base. */ + if (!dependent_scope_p (context)) + /* We should only set WANT_TYPE when we're a nested typename type. + Then we can give better diagnostics if we find a non-type. */ + t = lookup_field (context, name, 0, /*want_type=*/true); + else + t = NULL_TREE; + + if (!t && dependent_type_p (context)) + return build_typename_type (context, name, fullname, tag_type); + want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR; - /* We should only set WANT_TYPE when we're a nested typename type. - Then we can give better diagnostics if we find a non-type. */ - t = lookup_field (context, name, 0, /*want_type=*/true); if (!t) { if (complain & tf_error) @@ -3162,10 +3168,18 @@ record_builtin_java_type (const char* name, int size) { tree type, decl; if (size > 0) - type = make_signed_type (size); + type = build_nonstandard_integer_type (size, 0); else if (size > -32) - { /* "__java_char" or ""__java_boolean". */ - type = make_unsigned_type (-size); + { + tree stype; + /* "__java_char" or ""__java_boolean". */ + type = build_nonstandard_integer_type (-size, 1); + /* Get the signed type cached and attached to the unsigned type, + so it doesn't get garbage-collected at "random" times, + causing potential codegen differences out of different UIDs + and different alias set numbers. */ + stype = build_nonstandard_integer_type (-size, 0); + TREE_CHAIN (type) = stype; /*if (size == -1) TREE_SET_CODE (type, BOOLEAN_TYPE);*/ } else diff --git a/gcc/cp/error.c b/gcc/cp/error.c index e2cb8bf0ecc..5eb8f28b4c9 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1508,8 +1508,9 @@ dump_expr (tree t, int flags) break; case THROW_EXPR: - pp_cxx_identifier (cxx_pp, "throw"); - dump_expr (TREE_OPERAND (t, 0), flags); + /* While waiting for caret diagnostics, avoid printing + __cxa_allocate_exception, __cxa_throw, and the like. */ + pp_cxx_identifier (cxx_pp, "<throw-expression>"); break; case PTRMEM_CST: diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 85c496bbaf2..8e3e4895264 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1787,23 +1787,14 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, /* True iff this is a call to "operator new[]" instead of just "operator new". */ bool array_p = false; - /* True iff ARRAY_P is true and the bound of the array type is - not necessarily a compile time constant. For example, VLA_P is - true for "new int[f()]". */ - bool vla_p = false; - /* The type being allocated. If ARRAY_P is true, this will be an - ARRAY_TYPE. */ - tree full_type; - /* If ARRAY_P is true, the element type of the array. This is an - never ARRAY_TYPE; for something like "new int[3][4]", the + /* If ARRAY_P is true, the element type of the array. This is never + an ARRAY_TYPE; for something like "new int[3][4]", the ELT_TYPE is "int". If ARRAY_P is false, this is the same type as - FULL_TYPE. */ + TYPE. */ tree elt_type; /* The type of the new-expression. (This type is always a pointer type.) */ tree pointer_type; - /* A pointer type pointing to the FULL_TYPE. */ - tree full_pointer_type; tree outer_nelts = NULL_TREE; tree alloc_call, alloc_expr; /* The address returned by the call to "operator new". This node is @@ -1834,35 +1825,15 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, if (nelts) { - tree index; - outer_nelts = nelts; array_p = true; - - /* ??? The middle-end will error on us for building a VLA outside a - function context. Methinks that's not it's purvey. So we'll do - our own VLA layout later. */ - vla_p = true; - index = convert (sizetype, nelts); - index = size_binop (MINUS_EXPR, index, size_one_node); - index = build_index_type (index); - full_type = build_cplus_array_type (type, NULL_TREE); - /* We need a copy of the type as build_array_type will return a shared copy - of the incomplete array type. */ - full_type = build_distinct_type_copy (full_type); - TYPE_DOMAIN (full_type) = index; - SET_TYPE_STRUCTURAL_EQUALITY (full_type); } - else + else if (TREE_CODE (type) == ARRAY_TYPE) { - full_type = type; - if (TREE_CODE (type) == ARRAY_TYPE) - { - array_p = true; - nelts = array_type_nelts_top (type); - outer_nelts = nelts; - type = TREE_TYPE (type); - } + array_p = true; + nelts = array_type_nelts_top (type); + outer_nelts = nelts; + type = TREE_TYPE (type); } /* If our base type is an array, then make sure we know how many elements @@ -1897,21 +1868,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, size = size_in_bytes (elt_type); if (array_p) - { - size = size_binop (MULT_EXPR, size, convert (sizetype, nelts)); - if (vla_p) - { - tree n, bitsize; - - /* Do our own VLA layout. Setting TYPE_SIZE/_UNIT is - necessary in order for the <INIT_EXPR <*foo> <CONSTRUCTOR - ...>> to be valid. */ - TYPE_SIZE_UNIT (full_type) = size; - n = convert (bitsizetype, nelts); - bitsize = size_binop (MULT_EXPR, TYPE_SIZE (elt_type), n); - TYPE_SIZE (full_type) = bitsize; - } - } + size = size_binop (MULT_EXPR, size, convert (sizetype, nelts)); alloc_fn = NULL_TREE; @@ -2139,8 +2096,9 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, } /* Now use a pointer to the type we've actually allocated. */ - full_pointer_type = build_pointer_type (full_type); - data_addr = fold_convert (full_pointer_type, data_addr); + data_addr = fold_convert (pointer_type, data_addr); + /* Any further uses of alloc_node will want this type, too. */ + alloc_node = fold_convert (pointer_type, alloc_node); /* Now initialize the allocated object. Note that we preevaluate the initialization expression, apart from the actual constructor call or @@ -2152,8 +2110,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, bool stable; bool explicit_value_init_p = false; - init_expr = cp_build_indirect_ref (data_addr, NULL, complain); - if (init == void_zero_node) { init = NULL_TREE; @@ -2170,7 +2126,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, return error_mark_node; } init_expr - = build_vec_init (init_expr, + = build_vec_init (data_addr, cp_build_binary_op (input_location, MINUS_EXPR, outer_nelts, integer_one_node, @@ -2187,6 +2143,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, } else { + init_expr = cp_build_indirect_ref (data_addr, NULL, complain); + if (TYPE_NEEDS_CONSTRUCTING (type) && !explicit_value_init_p) { init_expr = build_special_member_call (init_expr, @@ -2198,8 +2156,8 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, else if (explicit_value_init_p) { /* Something like `new int()'. */ - init_expr = build2 (INIT_EXPR, full_type, - init_expr, build_value_init (full_type)); + init_expr = build2 (INIT_EXPR, type, + init_expr, build_value_init (type)); } else { @@ -2240,7 +2198,7 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, functions that we use for finding allocation functions. */ cleanup = (build_op_delete_call (dcode, - fold_convert (full_pointer_type, alloc_node), + alloc_node, size, globally_qualified_p, placement_allocation_fn_p ? alloc_call : NULL_TREE, @@ -2323,9 +2281,6 @@ build_new_1 (tree placement, tree type, tree nelts, tree init, if (init_preeval_expr) rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval); - /* Convert to the final type. */ - rval = build_nop (pointer_type, rval); - /* A new-expression is never an lvalue. */ gcc_assert (!lvalue_p (rval)); @@ -2665,9 +2620,10 @@ get_temp_regvar (tree type, tree init) /* `build_vec_init' returns tree structure that performs initialization of a vector of aggregate types. - BASE is a reference to the vector, of ARRAY_TYPE. + BASE is a reference to the vector, of ARRAY_TYPE, or a pointer + to the first element, of POINTER_TYPE. MAXINDEX is the maximum index of the array (one less than the - number of elements). It is only used if + number of elements). It is only used if BASE is a pointer or TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE. INIT is the (possibly NULL) initializer. @@ -2692,7 +2648,7 @@ build_vec_init (tree base, tree maxindex, tree init, tree size; tree itype = NULL_TREE; tree iterator; - /* The type of the array. */ + /* The type of BASE. */ tree atype = TREE_TYPE (base); /* The type of an element in the array. */ tree type = TREE_TYPE (atype); @@ -2708,7 +2664,7 @@ build_vec_init (tree base, tree maxindex, tree init, int num_initialized_elts = 0; bool is_global; - if (TYPE_DOMAIN (atype)) + if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype)) maxindex = array_type_nelts (atype); if (maxindex == NULL_TREE || maxindex == error_mark_node) @@ -2717,7 +2673,7 @@ build_vec_init (tree base, tree maxindex, tree init, if (explicit_value_init_p) gcc_assert (!init); - inner_elt_type = strip_array_types (atype); + inner_elt_type = strip_array_types (type); if (init && (from_array == 2 ? (!CLASS_TYPE_P (inner_elt_type) @@ -2734,15 +2690,20 @@ build_vec_init (tree base, tree maxindex, tree init, brace-enclosed initializers. In this case, digest_init and store_constructor will handle the semantics for us. */ + gcc_assert (TREE_CODE (atype) == ARRAY_TYPE); stmt_expr = build2 (INIT_EXPR, atype, base, init); return stmt_expr; } maxindex = cp_convert (ptrdiff_type_node, maxindex); - ptype = build_pointer_type (type); size = size_in_bytes (type); - if (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE) - base = cp_convert (ptype, decay_conversion (base)); + if (TREE_CODE (atype) == ARRAY_TYPE) + { + ptype = build_pointer_type (type); + base = cp_convert (ptype, decay_conversion (base)); + } + else + ptype = atype; /* The code we are generating looks like: ({ @@ -2954,10 +2915,13 @@ build_vec_init (tree base, tree maxindex, tree init, stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt); - /* Now convert make the result have the correct type. */ - atype = build_pointer_type (atype); - stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); - stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain); + /* Now make the result have the correct type. */ + if (TREE_CODE (atype) == ARRAY_TYPE) + { + atype = build_pointer_type (atype); + stmt_expr = build1 (NOP_EXPR, atype, stmt_expr); + stmt_expr = cp_build_indirect_ref (stmt_expr, NULL, complain); + } current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps; return stmt_expr; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 80a767ebe2d..5c5c912b587 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4732,7 +4732,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, } koenig_p = false; - if (idk == CP_ID_KIND_UNQUALIFIED) + if (idk == CP_ID_KIND_UNQUALIFIED + || idk == CP_ID_KIND_TEMPLATE_ID) { if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE) { @@ -10323,7 +10324,7 @@ cp_parser_template_name (cp_parser* parser, && !template_keyword_p && parser->scope && TYPE_P (parser->scope) && check_dependency_p - && dependent_type_p (parser->scope) + && dependent_scope_p (parser->scope) /* Do not do this for dtors (or ctors), since they never need the template keyword before their name. */ && !constructor_name_p (identifier, parser->scope)) @@ -17023,35 +17024,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name, cannot look up the name if the scope is not a class type; it might, for example, be a template type parameter. */ dependent_p = (TYPE_P (parser->scope) - && !(parser->in_declarator_p - && currently_open_class (parser->scope)) - && dependent_type_p (parser->scope)); + && dependent_scope_p (parser->scope)); if ((check_dependency || !CLASS_TYPE_P (parser->scope)) - && dependent_p) - { - if (tag_type) - { - tree type; - - /* The resolution to Core Issue 180 says that `struct - A::B' should be considered a type-name, even if `A' - is dependent. */ - type = make_typename_type (parser->scope, name, tag_type, - /*complain=*/tf_error); - decl = TYPE_NAME (type); - } - else if (is_template - && (cp_parser_next_token_ends_template_argument_p (parser) - || cp_lexer_next_token_is (parser->lexer, - CPP_CLOSE_PAREN))) - decl = make_unbound_class_template (parser->scope, - name, NULL_TREE, - /*complain=*/tf_error); - else - decl = build_qualified_name (/*type=*/NULL_TREE, - parser->scope, name, - is_template); - } + && dependent_p) + /* Defer lookup. */ + decl = error_mark_node; else { tree pushed_scope = NULL_TREE; @@ -17072,14 +17049,42 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /*complain=*/true); /* If we have a single function from a using decl, pull it out. */ - if (decl - && TREE_CODE (decl) == OVERLOAD + if (TREE_CODE (decl) == OVERLOAD && !really_overloaded_fn (decl)) decl = OVL_FUNCTION (decl); if (pushed_scope) pop_scope (pushed_scope); } + + /* If the scope is a dependent type and either we deferred lookup or + we did lookup but didn't find the name, rememeber the name. */ + if (decl == error_mark_node && TYPE_P (parser->scope) + && dependent_type_p (parser->scope)) + { + if (tag_type) + { + tree type; + + /* The resolution to Core Issue 180 says that `struct + A::B' should be considered a type-name, even if `A' + is dependent. */ + type = make_typename_type (parser->scope, name, tag_type, + /*complain=*/tf_error); + decl = TYPE_NAME (type); + } + else if (is_template + && (cp_parser_next_token_ends_template_argument_p (parser) + || cp_lexer_next_token_is (parser->lexer, + CPP_CLOSE_PAREN))) + decl = make_unbound_class_template (parser->scope, + name, NULL_TREE, + /*complain=*/tf_error); + else + decl = build_qualified_name (/*type=*/NULL_TREE, + parser->scope, name, + is_template); + } parser->qualifying_scope = parser->scope; parser->object_scope = NULL_TREE; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index dacc8689f38..8ae4ed511cc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -16067,6 +16067,16 @@ dependent_type_p (tree type) return TYPE_DEPENDENT_P (type); } +/* Returns TRUE if SCOPE is a dependent scope, in which we can't do any + lookup. In other words, a dependent type that is not the current + instantiation. */ + +bool +dependent_scope_p (tree scope) +{ + return dependent_type_p (scope) && !currently_open_class (scope); +} + /* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */ static bool @@ -16088,7 +16098,7 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) An id-expression is type-dependent if it contains a nested-name-specifier that contains a class-name that names a dependent type. */ - /* The suggested resolution to Core Issue 2 implies that if the + /* The suggested resolution to Core Issue 224 implies that if the qualifying type is the current class, then we must peek inside it. */ if (DECL_P (name) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 840b0e0d394..5f01a83c463 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1801,6 +1801,13 @@ perform_koenig_lookup (tree fn, tree args) { tree identifier = NULL_TREE; tree functions = NULL_TREE; + tree tmpl_args = NULL_TREE; + + if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) + { + tmpl_args = TREE_OPERAND (fn, 1); + fn = TREE_OPERAND (fn, 0); + } /* Find the name of the overloaded function. */ if (TREE_CODE (fn) == IDENTIFIER_NODE) @@ -1820,7 +1827,8 @@ perform_koenig_lookup (tree fn, tree args) Do Koenig lookup -- unless any of the arguments are type-dependent. */ - if (!any_type_dependent_arguments_p (args)) + if (!any_type_dependent_arguments_p (args) + && !any_dependent_template_arguments_p (tmpl_args)) { fn = lookup_arg_dependent (identifier, functions, args); if (!fn) @@ -1828,6 +1836,9 @@ perform_koenig_lookup (tree fn, tree args) fn = unqualified_fn_lookup_error (identifier); } + if (fn && tmpl_args) + fn = build_nt (TEMPLATE_ID_EXPR, fn, tmpl_args); + return fn; } diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 456abfc9443..82f3b89e402 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1175,8 +1175,9 @@ is_overloaded_fn (tree x) x = TREE_OPERAND (x, 1); if (BASELINK_P (x)) x = BASELINK_FUNCTIONS (x); - if (TREE_CODE (x) == TEMPLATE_ID_EXPR - || DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x)) + if (TREE_CODE (x) == TEMPLATE_ID_EXPR) + x = TREE_OPERAND (x, 0); + if (DECL_FUNCTION_TEMPLATE_P (OVL_CURRENT (x)) || (TREE_CODE (x) == OVERLOAD && OVL_CHAIN (x))) return 2; return (TREE_CODE (x) == FUNCTION_DECL @@ -1202,6 +1203,8 @@ get_first_fn (tree from) from = TREE_OPERAND (from, 1); if (BASELINK_P (from)) from = BASELINK_FUNCTIONS (from); + if (TREE_CODE (from) == TEMPLATE_ID_EXPR) + from = TREE_OPERAND (from, 0); return OVL_CURRENT (from); } diff --git a/gcc/cse.c b/gcc/cse.c index 91cb108e94c..bab0908c984 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -4483,7 +4483,8 @@ cse_insn (rtx insn) enum machine_mode wider_mode; for (wider_mode = GET_MODE_WIDER_MODE (mode); - GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD + wider_mode != VOIDmode + && GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD && src_related == 0; wider_mode = GET_MODE_WIDER_MODE (wider_mode)) { diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index f901db32fda..3d93010a54a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2436,6 +2436,11 @@ to run as a thread. The compiler omits generate prologue/epilogue sequences and replaces the return instruction with a @code{sleep} instruction. This attribute is available only on fido. +@item isr +@cindex interrupt service routines on ARM +Use this attribute on ARM to write Interrupt Service Routines. This is an +alias to the @code{interrupt} attribute above. + @item kspisusp @cindex User stack pointer in interrupts on the Blackfin When used together with @code{interrupt_handler}, @code{exception_handler} diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 848926b6383..63301a57178 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -5128,7 +5128,7 @@ static void add_byte_size_attribute (dw_die_ref, tree); static void add_bit_offset_attribute (dw_die_ref, tree); static void add_bit_size_attribute (dw_die_ref, tree); static void add_prototyped_attribute (dw_die_ref, tree); -static void add_abstract_origin_attribute (dw_die_ref, tree); +static dw_die_ref add_abstract_origin_attribute (dw_die_ref, tree); static void add_pure_or_virtual_attribute (dw_die_ref, tree); static void add_src_coords_attributes (dw_die_ref, tree); static void add_name_and_src_coords_attributes (dw_die_ref, tree); @@ -12479,7 +12479,7 @@ add_prototyped_attribute (dw_die_ref die, tree func_type) by looking in either the type declaration or object declaration equate table. */ -static inline void +static inline dw_die_ref add_abstract_origin_attribute (dw_die_ref die, tree origin) { dw_die_ref origin_die = NULL; @@ -12517,7 +12517,8 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin) here. */ if (origin_die) - add_AT_die_ref (die, DW_AT_abstract_origin, origin_die); + add_AT_die_ref (die, DW_AT_abstract_origin, origin_die); + return origin_die; } /* We do not currently support the pure_virtual attribute. */ @@ -13885,6 +13886,7 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) tree decl_or_origin = decl ? decl : origin; dw_die_ref var_die; dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL; + dw_die_ref origin_die; int declaration = (DECL_EXTERNAL (decl_or_origin) /* If DECL is COMDAT and has not actually been emitted, we cannot take its address; there @@ -14018,8 +14020,9 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) var_die = new_die (DW_TAG_variable, context_die, decl); + origin_die = NULL; if (origin != NULL) - add_abstract_origin_attribute (var_die, origin); + origin_die = add_abstract_origin_attribute (var_die, origin); /* Loop unrolling can create multiple blocks that refer to the same static variable, so we must test for the DW_AT_declaration flag. @@ -14082,7 +14085,17 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die) if (decl && (DECL_ABSTRACT (decl) || declaration)) equate_decl_number_to_die (decl, var_die); - if (! declaration && ! DECL_ABSTRACT (decl_or_origin)) + if (! declaration + && (! DECL_ABSTRACT (decl_or_origin) + /* Local static vars are shared between all clones/inlines, + so emit DW_AT_location on the abstract DIE if DECL_RTL is + already set. */ + || (TREE_CODE (decl_or_origin) == VAR_DECL + && TREE_STATIC (decl_or_origin) + && DECL_RTL_SET_P (decl_or_origin))) + /* When abstract origin already has DW_AT_location attribute, no need + to add it again. */ + && (origin_die == NULL || get_AT (origin_die, DW_AT_location) == NULL)) { if (TREE_CODE (decl_or_origin) == VAR_DECL && TREE_STATIC (decl_or_origin) && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin))) @@ -15490,7 +15503,10 @@ dwarf2out_imported_module_or_decl_1 (tree decl, lexical_block_die, lexical_block); - xloc = expand_location (input_location); + if (TREE_CODE (decl) == IMPORTED_DECL) + xloc = expand_location (DECL_SOURCE_LOCATION (decl)); + else + xloc = expand_location (input_location); add_AT_file (imported_die, DW_AT_decl_file, lookup_filename (xloc.file)); add_AT_unsigned (imported_die, DW_AT_decl_line, xloc.line); if (name) diff --git a/gcc/except.c b/gcc/except.c index c762edc022e..2913fc8f31f 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2017,11 +2017,13 @@ sjlj_build_landing_pads (void) if (sjlj_find_directly_reachable_regions (lp_info)) { rtx dispatch_label = gen_label_rtx (); - + int align = STACK_SLOT_ALIGNMENT (sjlj_fc_type_node, + TYPE_MODE (sjlj_fc_type_node), + TYPE_ALIGN (sjlj_fc_type_node)); crtl->eh.sjlj_fc = assign_stack_local (TYPE_MODE (sjlj_fc_type_node), int_size_in_bytes (sjlj_fc_type_node), - TYPE_ALIGN (sjlj_fc_type_node)); + align); sjlj_assign_call_site_values (dispatch_label, lp_info); sjlj_mark_call_sites (lp_info); diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 6502f1a0802..e91e90b2860 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,8 @@ +2009-03-06 Alexandre Oliva <aoliva@redhat.com> + + * simplify.c (gfc_simplify_transfer): Zero-initialize the + buffer. + 2009-02-27 Tobias Burnus <burnus@net-b.de> PR fortran/39309 diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 6893a88c433..7be4671acfb 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4541,6 +4541,7 @@ gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size) /* Allocate the buffer to store the binary version of the source. */ buffer_size = MAX (source_size, result_size); buffer = (unsigned char*)alloca (buffer_size); + memset (buffer, 0, buffer_size); /* Now write source to the buffer. */ gfc_target_encode_expr (source, buffer, buffer_size); diff --git a/gcc/function.c b/gcc/function.c index 471b91f8eb5..0cbcbd3e054 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2967,10 +2967,13 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm, if (data->stack_parm == 0) { + int align = STACK_SLOT_ALIGNMENT (data->passed_type, + GET_MODE (data->entry_parm), + TYPE_ALIGN (data->passed_type)); data->stack_parm = assign_stack_local (GET_MODE (data->entry_parm), GET_MODE_SIZE (GET_MODE (data->entry_parm)), - TYPE_ALIGN (data->passed_type)); + align); set_mem_attributes (data->stack_parm, parm, 1); } @@ -3032,11 +3035,13 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs) { rtx rmem, imem; HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (parm)); + int align = STACK_SLOT_ALIGNMENT (TREE_TYPE (parm), + DECL_MODE (parm), + TYPE_ALIGN (TREE_TYPE (parm))); /* split_complex_arg put the real and imag parts in pseudos. Move them to memory. */ - tmp = assign_stack_local (DECL_MODE (parm), size, - TYPE_ALIGN (TREE_TYPE (parm))); + tmp = assign_stack_local (DECL_MODE (parm), size, align); set_mem_attributes (tmp, parm, 1); rmem = adjust_address_nv (tmp, inner, 0); imem = adjust_address_nv (tmp, inner, GET_MODE_SIZE (inner)); diff --git a/gcc/genpreds.c b/gcc/genpreds.c index e0fb3f42e52..a1232e9573f 100644 --- a/gcc/genpreds.c +++ b/gcc/genpreds.c @@ -2,7 +2,7 @@ - prototype declarations for operand predicates (tm-preds.h) - function definitions of operand predicates, if defined new-style (insn-preds.c) - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -234,7 +234,7 @@ needs_variable (rtx exp, const char *var) if (q != p && (ISALNUM (q[-1]) || q[-1] == '_')) return false; q += strlen (var); - if (ISALNUM (q[0] || q[0] == '_')) + if (ISALNUM (q[0]) || q[0] == '_') return false; } return true; @@ -1103,7 +1103,7 @@ write_tm_constrs_h (void) "{\n", c->c_name, needs_op ? "op" : "ARG_UNUSED (op)"); if (needs_mode) - puts ("enum machine_mode mode = GET_MODE (op);"); + puts (" enum machine_mode mode = GET_MODE (op);"); if (needs_ival) puts (" HOST_WIDE_INT ival = 0;"); if (needs_hval) diff --git a/gcc/graphite.c b/gcc/graphite.c index 9b36284e680..58b67f4255a 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -2364,7 +2364,7 @@ nb_reductions_in_loop (loop_p loop) scev = analyze_scalar_evolution (loop, PHI_RESULT (phi)); scev = instantiate_parameters (loop, scev); - if (!simple_iv (loop, phi, PHI_RESULT (phi), &iv, true)) + if (!simple_iv (loop, loop, PHI_RESULT (phi), &iv, true)) res++; } diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c index 9d844d8d90c..e02f1649c64 100644 --- a/gcc/loop-iv.c +++ b/gcc/loop-iv.c @@ -2801,7 +2801,9 @@ get_simple_loop_desc (struct loop *loop) if (desc) return desc; - desc = XNEW (struct niter_desc); + /* At least desc->infinite is not always initialized by + find_simple_loop_exit. */ + desc = XCNEW (struct niter_desc); iv_analysis_loop_init (loop); find_simple_exit (loop, desc); loop->aux = desc; diff --git a/gcc/matrix-reorg.c b/gcc/matrix-reorg.c index c1d5ca0caa3..7ea185ced20 100644 --- a/gcc/matrix-reorg.c +++ b/gcc/matrix-reorg.c @@ -930,7 +930,7 @@ analyze_transpose (void **slot, void *data ATTRIBUTE_UNUSED) free (acc_info); continue; } - if (simple_iv (loop, acc_info->stmt, acc_info->offset, &iv, true)) + if (simple_iv (loop, loop, acc_info->offset, &iv, true)) { if (iv.step != NULL) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fc081f5ecc4..1b7a69d10e1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,66 @@ +2009-03-07 Jason Merrill <jason@redhat.com> + + PR c++/39367 + * g++.dg/opt/new1.C: New. + +2009-03-06 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/33492 + * g++.dg/other/error32.C: New. + +2009-03-06 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/39360 + * gcc.c-torture/compile/pr39360.c: New test. + + PR debug/39372 + * g++.dg/debug/dwarf2/static-local-var-in-ctor.C: New test. + +2009-03-05 Jason Merrill <jason@redhat.com> + + PR c++/38908 + * g++.dg/warn/Wuninitialized-3.C: New test. + +2009-03-05 Jakub Jelinek <jakub@redhat.com> + + PR debug/39379 + * g++.dg/debug/dwarf2/imported-module-3.C: New test. + * g++.dg/debug/dwarf2/imported-module-4.C: New test. + +2009-03-04 Jason Merrill <jason@redhat.com> + + PR c++/13549 + * g++.dg/template/koenig7.C: New test. + +2009-03-04 Nathan Sidwell <nathan@codesourcery.com> + + * g++.dg/torture/predcom-1.C: New test. + +2009-03-04 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/39362 + * g++.dg/torture/pr39362.C: New testcase. + +2009-03-04 Jason Merrill <jason@redhat.com> + Giovanni Bajo <giovannibajo@gcc.gnu.org> + + PR c++/9634 + PR c++/29469 + PR c++/29607 + * g++.dg/template/dependent-name5.C: New test. + +2009-03-04 Steve Ellcey <sje@cup.hp.com> + + PR testsuite/39357 + * gcc.dg/vect-iv-6.c (dg-require-effective-target): Change from + vect_int to vect_int_mult. + +2009-03-04 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/39358 + * g++.dg/warn/Wstrict-aliasing-bogus-escape-2.C: New testcase. + * g++.dg/warn/Wstrict-aliasing-bogus-escape-3.C: Likewise. + 2009-03-04 Richard Guenther <rguenther@suse.de> PR tree-optimization/39339 @@ -19,8 +82,7 @@ 2009-03-03 Ira Rosen <irar@il.ibm.com> PR tree-optimization/39248 - * gcc.dg/vect/vect-complex-1.c: Add attribute aligned - to the arrays. + * gcc.dg/vect/vect-complex-1.c: Add attribute aligned to the arrays. * gcc.dg/vect/vect-iv-6.c: Don't expect to fail to vectorize on targets without vector misalignment support. * lib/target-supports.exp @@ -62,7 +124,7 @@ 2009-02-26 H.J. Lu <hongjiu.lu@intel.com> PR c++/37789 - * other/pr37789.C: New. + * g++.dg/other/pr37789.C: New. 2009-02-26 Paul Thomas <pault@gcc.gnu.org> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-3.C b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-3.C new file mode 100644 index 00000000000..d62a506f49b --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-3.C @@ -0,0 +1,17 @@ +// PR debug/39379 +// { dg-do compile } +// { dg-options "-g -dA" } +// { dg-final { scan-assembler "DW_TAG_imported" } } + +namespace A +{ + int v; +} + +int +main () +{ + using namespace A; + v++; + return v - 1; +} diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-4.C b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-4.C new file mode 100644 index 00000000000..6e9b52e1f19 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/imported-module-4.C @@ -0,0 +1,21 @@ +// PR debug/39379 +// { dg-do compile } +// { dg-options "-g -dA" } +// { dg-final { scan-assembler "DW_TAG_imported" } } + +namespace A +{ + int v; +} + +int +f () +{ + int i; + { + using namespace A; + v++; + i = v - 1; + } + return i; +} diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C b/gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C new file mode 100644 index 00000000000..a1bf6b53cd4 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/static-local-var-in-ctor.C @@ -0,0 +1,37 @@ +// PR debug/39372 +// { dg-do compile } +// { dg-options "-O0 -g -dA" } +// { dg-final { scan-assembler "DW_OP_addr\[^\n\r\]*\[\n\r\]*\[^\n\r\]*staticvar1" } } +// { dg-final { scan-assembler "DW_OP_addr\[^\n\r\]*\[\n\r\]*\[^\n\r\]*staticvar2" } } + +extern void f (int *); + +struct A +{ + A(int i); + void foo(int i); +}; + +A::A(int i) +{ + static int *staticvar1 = new int(i); + f (staticvar1); +} + +void A::foo(int i) +{ + static int *staticvar2 = new int(i); + f (staticvar2); +} + +void f (int *) +{ +} + +int +main (void) +{ + A a(42); + a.foo(42); + return 0; +} diff --git a/gcc/testsuite/g++.dg/opt/new1.C b/gcc/testsuite/g++.dg/opt/new1.C new file mode 100644 index 00000000000..dbcc0f8517a --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/new1.C @@ -0,0 +1,71 @@ +// PR c++/39367 +// { dg-options "-O" } + +class QScriptEnginePrivate; +class QScriptClassInfo; +namespace QScript { + enum Type { InvalidType }; +}; +class QScriptValueImpl { +public: + inline QScriptValueImpl(); + QScript::Type m_type; +}; +namespace QScript { + namespace Ecma { + class Core { + public: + inline QScriptEnginePrivate *engine() const { } + inline QScriptClassInfo *classInfo() const { } + QScriptValueImpl publicPrototype; + }; + class Boolean: public Core { + void newBoolean(QScriptValueImpl *result, bool value = false); + }; + } + template <typename T> class Buffer { + public: + inline void reserve(int num); + inline void resize(int s); + T *m_data; + int m_capacity; + int m_size; + }; +} +template <typename T> void QScript::Buffer<T>::resize(int s) { + if (m_capacity < s) + reserve (s << 1); +} +template <typename T> void QScript::Buffer<T>::reserve(int x) { + T *new_data = new T[m_capacity]; + for (int i=0; i<m_size; ++i) + new_data[i] = m_data[i]; +} +class QScriptObject { +public: + inline void reset(); + QScript::Buffer<QScriptValueImpl> m_values; +}; +class QScriptEnginePrivate { +public: + inline QScriptObject *allocObject() { return 0; } + inline void newObject(QScriptValueImpl *o, const QScriptValueImpl &proto, + QScriptClassInfo *oc = 0); +}; +inline void QScriptEnginePrivate::newObject(QScriptValueImpl *o, + const QScriptValueImpl &proto, + QScriptClassInfo *oc) +{ + QScriptObject *od = allocObject(); + od->reset(); +} +inline QScriptValueImpl::QScriptValueImpl() : m_type(QScript::InvalidType) { } +inline void QScriptObject::reset() { m_values.resize(0); } +namespace QScript { + namespace Ecma { + void Boolean::newBoolean(QScriptValueImpl *result, bool value) + { + engine()->newObject(result, publicPrototype, classInfo()); + } + } +} diff --git a/gcc/testsuite/g++.dg/other/error32.C b/gcc/testsuite/g++.dg/other/error32.C new file mode 100644 index 00000000000..35c64c4eab9 --- /dev/null +++ b/gcc/testsuite/g++.dg/other/error32.C @@ -0,0 +1,8 @@ +// PR c++/33492 +// { dg-options "" } + +void foo() +{ + if (throw 0) // { dg-error "could not convert .\\<throw-expression\\>. to .bool." } + ; +} diff --git a/gcc/testsuite/g++.dg/template/dependent-name5.C b/gcc/testsuite/g++.dg/template/dependent-name5.C new file mode 100644 index 00000000000..681060c7002 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/dependent-name5.C @@ -0,0 +1,45 @@ +// PR c++/9634, c++/29469, c++/29607 +// Contributed by: Giovanni Bajo <giovannibajo at gcc dot gnu dot org> +// DR224: Make sure that a name is *truly* semantically dependent. + +struct D { + typedef int K; +}; + +template <typename T> +struct A +{ + typedef int Bar; + + template <typename> + struct N {}; + + typedef Bar type1; + typedef A::Bar type2; + typedef A<T>::Bar type3; + typedef A<T*>::Bar type4; // { dg-error "" } + typedef typename A<T*>::Bar type5; + + typedef N<int> type6; + typedef A::N<int> type7; + typedef A<T>::N<int> type8; + typedef A<T*>::template N<int> type9; // { dg-error "" } + typedef typename A<T*>::template N<int> type10; + + typedef D Bar2; + struct N2 { typedef int K; }; + + // Check that A::N2 is still considered dependent (because it + // could be specialized), while A::Bar2 (being just ::D) is not. + typedef A::Bar2 type11; + typedef type11::K k3; + + typedef A::N2 type12; + typedef typename type12::K k2; + typedef type12::K k1; // { dg-error "" } + + // Check that A::Bar2 is not considered dependent even if we use + // the typename keyword. + typedef typename A::Bar2 type13; + typedef type13::K k4; +}; diff --git a/gcc/testsuite/g++.dg/template/koenig7.C b/gcc/testsuite/g++.dg/template/koenig7.C new file mode 100644 index 00000000000..07f2fcad33d --- /dev/null +++ b/gcc/testsuite/g++.dg/template/koenig7.C @@ -0,0 +1,11 @@ +// PR c++/13549 +// We need to do arg-dep lookup for g<T>(j) at instantiation time because +// g<T> is dependent, even though (j) is not; at that point we can find +// g(h). + +template <typename T> int g(int); +class h{}; +template <typename T> int l(){h j; return g<T>(j);} +template <typename T> int g(const h&); +class j{}; +int jj(){return l<j>();} diff --git a/gcc/testsuite/g++.dg/torture/pr39362.C b/gcc/testsuite/g++.dg/torture/pr39362.C new file mode 100644 index 00000000000..fb23439f595 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr39362.C @@ -0,0 +1,105 @@ +/* { dg-do compile } */ + +void *fastMalloc (int n); +void fastFree (void *p); +template <class T> struct C +{ + void deref () { delete static_cast <T *>(this); } +}; +template <typename T> +struct D +{ + D (T *ptr) : m_ptr (ptr) { } + ~D () { if (T * ptr = m_ptr) ptr->deref (); } + T *operator-> () const; + T *m_ptr; + typedef T *UnspecifiedBoolType; + operator UnspecifiedBoolType () const; +}; +template <typename T> struct E +{ + static void destruct (T * begin, T * end) + { + for (T * cur = begin; cur != end; ++cur) + cur->~T (); + } +}; +template <typename T> class F; +template <typename T> struct G +{ + static void destruct (T * begin, T * end) + { + E <T>::destruct (begin, end); + } + static void uninitializedFill (T * dst, T * dstEnd, const T & val) + { + F<T>::uninitializedFill (dst, dstEnd, val); + } +}; +template <typename T> struct H +{ + void allocateBuffer (int newCapacity) + { + m_buffer = static_cast <T *>(fastMalloc (newCapacity * sizeof (T))); + } + void deallocateBuffer (T * bufferToDeallocate) + { + if (m_buffer == bufferToDeallocate) + fastFree (bufferToDeallocate); + } + T *buffer () { } + int capacity () const { } + T *m_buffer; +}; +template <typename T, int cap> class I; +template <typename T> struct I <T, 0> : H <T> +{ + I (int capacity) { allocateBuffer (capacity); } + ~I () { deallocateBuffer (buffer ()); } + using H <T>::allocateBuffer; + H <T>::buffer; +}; +template <typename T, int cap = 0> struct J +{ + typedef T *iterator; + ~J () { if (m_size) shrink (0); } + J (const J &); + int capacity () const { m_buffer.capacity (); } + T & operator[](int i) { } + iterator begin () { } + iterator end () { return begin () + m_size; } + void shrink (int size); + template <typename U> void append (const U &); + int m_size; + I <T, cap> m_buffer; +}; +template <typename T, int cap> +J <T, cap>::J (const J & other) : m_buffer (other.capacity ()) +{ +} +template <typename T, int cap> +void J <T, cap>::shrink (int size) +{ + G <T>::destruct (begin () + size, end ()); + m_size = size; +} +struct A : public C <A> +{ + virtual ~A (); + typedef J <D <A> > B; + virtual A *firstChild () const; + virtual A *nextSibling () const; + virtual const B & children (int length); + B m_children; +}; +const A::B & +A::children (int length) +{ + for (D <A> obj = firstChild (); obj; obj = obj->nextSibling ()) + { + B children = obj->children (2); + for (unsigned i = 0; i <length; ++i) + m_children.append (children[i]); + } +} + diff --git a/gcc/testsuite/g++.dg/torture/predcom-1.C b/gcc/testsuite/g++.dg/torture/predcom-1.C new file mode 100644 index 00000000000..c668cac606d --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/predcom-1.C @@ -0,0 +1,29 @@ +/* Test for ICE in predictive commoning with empty loop header block + on arm-none-linux-gnueabi. */ + +struct Foo +{ + double *ptr; + + Foo (double *ptr_) + : ptr (ptr_) + { + } + + Foo PostInc () + { + return Foo (ptr++); + } +}; + +bool Baz (Foo first, double *last) +{ + Foo prev (first.ptr); + + first.ptr++; + + while (first.ptr != last) + if (*first.PostInc ().ptr < *prev.PostInc ().ptr) + return false; +} + diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-escape-2.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-escape-2.C new file mode 100644 index 00000000000..29414e00e36 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-escape-2.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wstrict-aliasing" } */ + +#include<list> + +struct A +{ + virtual ~A(); +}; + +A* foo(); + +void bar(std::list<int> x) +{ + std::list<int> y = x; + if (*y.rbegin()) + delete foo(); +} + diff --git a/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-escape-3.C b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-escape-3.C new file mode 100644 index 00000000000..de6b2c47735 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wstrict-aliasing-bogus-escape-3.C @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wstrict-aliasing" } */ + +struct Node_base {}; + +struct Node : Node_base +{ + int data; +}; + +struct List +{ + Node_base node, *prev; + + List() : prev(&node) { xyz(); } + + void xyz(); + + int back() { return static_cast<Node*>(prev)->data; } +}; + +struct A +{ + virtual ~A(); +}; + +A* foo(); + +void bar() +{ + List y; + if (y.back()) + delete foo(); +} + diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-3.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-3.C new file mode 100644 index 00000000000..dc3be3f67fa --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-3.C @@ -0,0 +1,17 @@ +// PR C++/38908 +// { dg-options "-Wuninitialized -O" } + +struct empty {}; + +struct dfs_visitor { + dfs_visitor() { } + empty m_vis; +}; + +void bar(const dfs_visitor&); +void foo(void) +{ + dfs_visitor vis; + dfs_visitor vis2 = vis; + bar (vis2); +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr39360.c b/gcc/testsuite/gcc.c-torture/compile/pr39360.c new file mode 100644 index 00000000000..0bd63114431 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr39360.c @@ -0,0 +1,16 @@ +/* PR middle-end/39360 */ + +static int a[] = { 1 }; + +static inline void +bar (int **x) +{ + static int *c[2] = { 0, a }; + *x = c[1]; +} + +int +foo (int **x) +{ + bar (x); +} diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-6.c b/gcc/testsuite/gcc.dg/vect/vect-iv-6.c index a0863cfe064..f9fa57813ff 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-iv-6.c +++ b/gcc/testsuite/gcc.dg/vect/vect-iv-6.c @@ -1,4 +1,4 @@ -/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_int_mult } */ #include <stdio.h> #include <stdarg.h> #include "tree-vect.h" diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 5632a8930bc..9c5b2e6c58c 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1796,9 +1796,21 @@ remove_useless_stmts_bind (gimple_stmt_iterator *gsi, struct rus_data *data ATTR || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block)) != FUNCTION_DECL))) { - gsi_insert_seq_before (gsi, body_seq, GSI_SAME_STMT); - gsi_remove (gsi, false); - data->repeat = true; + tree var = NULL_TREE; + /* Even if there are no gimple_bind_vars, there might be other + decls in BLOCK_VARS rendering the GIMPLE_BIND not useless. */ + if (block && !BLOCK_NUM_NONLOCALIZED_VARS (block)) + for (var = BLOCK_VARS (block); var; var = TREE_CHAIN (var)) + if (TREE_CODE (var) == IMPORTED_DECL) + break; + if (var || (block && BLOCK_NUM_NONLOCALIZED_VARS (block))) + gsi_next (gsi); + else + { + gsi_insert_seq_before (gsi, body_seq, GSI_SAME_STMT); + gsi_remove (gsi, false); + data->repeat = true; + } } else gsi_next (gsi); diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index bc9737dd951..7c062602a1a 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -698,7 +698,7 @@ dr_analyze_innermost (struct data_reference *dr) } base = build_fold_addr_expr (base); - if (!simple_iv (loop, stmt, base, &base_iv, false)) + if (!simple_iv (loop, loop_containing_stmt (stmt), base, &base_iv, false)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "failed: evolution of base is not affine.\n"); @@ -709,7 +709,8 @@ dr_analyze_innermost (struct data_reference *dr) offset_iv.base = ssize_int (0); offset_iv.step = ssize_int (0); } - else if (!simple_iv (loop, stmt, poffset, &offset_iv, false)) + else if (!simple_iv (loop, loop_containing_stmt (stmt), + poffset, &offset_iv, false)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "failed: evolution of offset is not affine.\n"); diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index df0be2df134..5241e64c929 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -1,6 +1,6 @@ /* Data flow functions for trees. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009 + Free Software Foundation, Inc. Contributed by Diego Novillo <dnovillo@redhat.com> This file is part of GCC. @@ -639,7 +639,7 @@ set_default_def (tree var, tree def) /* Add VAR to the list of referenced variables if it isn't already there. */ -void +bool add_referenced_var (tree var) { var_ann_t v_ann; @@ -655,7 +655,7 @@ add_referenced_var (tree var) /* Tag's don't have DECL_INITIAL. */ if (MTAG_P (var)) - return; + return true; /* Scan DECL_INITIAL for pointer variables as they may contain address arithmetic referencing the address of other @@ -667,7 +667,11 @@ add_referenced_var (tree var) optimizers. */ && !DECL_EXTERNAL (var)) walk_tree (&DECL_INITIAL (var), find_vars_r, NULL, 0); + + return true; } + + return false; } /* Remove VAR from the list. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 01953b59332..40829675b84 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -768,7 +768,7 @@ extern void dump_referenced_vars (FILE *); extern void dump_variable (FILE *, tree); extern void debug_variable (tree); extern tree get_virtual_var (tree); -extern void add_referenced_var (tree); +extern bool add_referenced_var (tree); extern void remove_referenced_var (tree); extern void mark_symbols_for_renaming (gimple); extern void find_new_referenced_vars (gimple); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 63392e21c4b..917b5267434 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1,5 +1,5 @@ /* Tree inlining. - Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Alexandre Oliva <aoliva@redhat.com> @@ -3383,7 +3383,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) var = TREE_VALUE (t_step); if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var)) { - if (var_ann (var) && referenced_var_check_and_insert (var)) + if (var_ann (var) && add_referenced_var (var)) cfun->local_decls = tree_cons (NULL_TREE, var, cfun->local_decls); } diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index f2d0ff63f17..4e9b102973a 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -385,7 +385,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, tree def = PHI_RESULT (phi); affine_iv iv; - if (is_gimple_reg (def) && !simple_iv (loop, phi, def, &iv, true)) + if (is_gimple_reg (def) && !simple_iv (loop, loop, def, &iv, true)) { struct reduction_info *red; @@ -1380,7 +1380,7 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree *nit) continue; } - ok = simple_iv (loop, phi, res, &iv, true); + ok = simple_iv (loop, loop, res, &iv, true); if (reduction_list) red = reduction_phi (reduction_list, phi); diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 5ce8c3ea066..bd82a8016fb 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1374,7 +1374,7 @@ ref_at_iteration (struct loop *loop, tree ref, int iter) else return NULL_TREE; - ok = simple_iv (loop, first_stmt (loop->header), idx, &iv, true); + ok = simple_iv (loop, loop, idx, &iv, true); if (!ok) return NULL_TREE; iv.base = expand_simple_operations (iv.base); diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index d7f97d705a1..8e12c2b32ab 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -1915,12 +1915,54 @@ analyze_scalar_evolution (struct loop *loop, tree var) } /* Analyze scalar evolution of use of VERSION in USE_LOOP with respect to - WRTO_LOOP (which should be a superloop of both USE_LOOP and definition - of VERSION). + WRTO_LOOP (which should be a superloop of USE_LOOP) FOLDED_CASTS is set to true if resolve_mixers used chrec_convert_aggressive (TODO -- not really, we are way too conservative - at the moment in order to keep things simple). */ + at the moment in order to keep things simple). + + To illustrate the meaning of USE_LOOP and WRTO_LOOP, consider the following + example: + + for (i = 0; i < 100; i++) -- loop 1 + { + for (j = 0; j < 100; j++) -- loop 2 + { + k1 = i; + k2 = j; + + use2 (k1, k2); + + for (t = 0; t < 100; t++) -- loop 3 + use3 (k1, k2); + + } + use1 (k1, k2); + } + + Both k1 and k2 are invariants in loop3, thus + analyze_scalar_evolution_in_loop (loop3, loop3, k1) = k1 + analyze_scalar_evolution_in_loop (loop3, loop3, k2) = k2 + + As they are invariant, it does not matter whether we consider their + usage in loop 3 or loop 2, hence + analyze_scalar_evolution_in_loop (loop2, loop3, k1) = + analyze_scalar_evolution_in_loop (loop2, loop2, k1) = i + analyze_scalar_evolution_in_loop (loop2, loop3, k2) = + analyze_scalar_evolution_in_loop (loop2, loop2, k2) = [0,+,1]_2 + + Similarly for their evolutions with respect to loop 1. The values of K2 + in the use in loop 2 vary independently on loop 1, thus we cannot express + the evolution with respect to loop 1: + analyze_scalar_evolution_in_loop (loop1, loop3, k1) = + analyze_scalar_evolution_in_loop (loop1, loop2, k1) = [0,+,1]_1 + analyze_scalar_evolution_in_loop (loop1, loop3, k2) = + analyze_scalar_evolution_in_loop (loop1, loop2, k2) = dont_know + + The value of k2 in the use in loop 1 is known, though: + analyze_scalar_evolution_in_loop (loop1, loop1, k1) = [0,+,1]_1 + analyze_scalar_evolution_in_loop (loop1, loop1, k2) = 100 + */ static tree analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop, @@ -1929,6 +1971,25 @@ analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop, bool val = false; tree ev = version, tmp; + /* We cannot just do + + tmp = analyze_scalar_evolution (use_loop, version); + ev = resolve_mixers (wrto_loop, tmp); + + as resolve_mixers would query the scalar evolution with respect to + wrto_loop. For example, in the situation described in the function + comment, suppose that wrto_loop = loop1, use_loop = loop3 and + version = k2. Then + + analyze_scalar_evolution (use_loop, version) = k2 + + and resolve_mixers (loop1, k2) finds that the value of k2 in loop 1 + is 100, which is a wrong result, since we are interested in the + value in loop 3. + + Instead, we need to proceed from use_loop to wrto_loop loop by loop, + each time checking that there is no evolution in the inner loop. */ + if (folded_casts) *folded_casts = false; while (1) @@ -2743,17 +2804,31 @@ scev_reset (void) } } -/* Checks whether OP behaves as a simple affine iv of LOOP in STMT and returns - its base and step in IV if possible. If ALLOW_NONCONSTANT_STEP is true, we - want step to be invariant in LOOP. Otherwise we require it to be an - integer constant. IV->no_overflow is set to true if we are sure the iv cannot - overflow (e.g. because it is computed in signed arithmetics). */ +/* Checks whether use of OP in USE_LOOP behaves as a simple affine iv with + respect to WRTO_LOOP and returns its base and step in IV if possible + (see analyze_scalar_evolution_in_loop for more details on USE_LOOP + and WRTO_LOOP). If ALLOW_NONCONSTANT_STEP is true, we want step to be + invariant in LOOP. Otherwise we require it to be an integer constant. + + IV->no_overflow is set to true if we are sure the iv cannot overflow (e.g. + because it is computed in signed arithmetics). Consequently, adding an + induction variable + + for (i = IV->base; ; i += IV->step) + + is only safe if IV->no_overflow is false, or TYPE_OVERFLOW_UNDEFINED is + false for the type of the induction variable, or you can prove that i does + not wrap by some other argument. Otherwise, this might introduce undefined + behavior, and + + for (i = iv->base; ; i = (type) ((unsigned type) i + (unsigned type) iv->step)) + + must be used instead. */ bool -simple_iv (struct loop *loop, gimple stmt, tree op, affine_iv *iv, - bool allow_nonconstant_step) +simple_iv (struct loop *wrto_loop, struct loop *use_loop, tree op, + affine_iv *iv, bool allow_nonconstant_step) { - basic_block bb = gimple_bb (stmt); tree type, ev; bool folded_casts; @@ -2766,13 +2841,13 @@ simple_iv (struct loop *loop, gimple stmt, tree op, affine_iv *iv, && TREE_CODE (type) != POINTER_TYPE) return false; - ev = analyze_scalar_evolution_in_loop (loop, bb->loop_father, op, + ev = analyze_scalar_evolution_in_loop (wrto_loop, use_loop, op, &folded_casts); - if (chrec_contains_undetermined (ev)) + if (chrec_contains_undetermined (ev) + || chrec_contains_symbols_defined_in_loop (ev, wrto_loop->num)) return false; - if (tree_does_not_contain_chrecs (ev) - && !chrec_contains_symbols_defined_in_loop (ev, loop->num)) + if (tree_does_not_contain_chrecs (ev)) { iv->base = ev; iv->step = build_int_cst (TREE_TYPE (ev), 0); @@ -2781,22 +2856,16 @@ simple_iv (struct loop *loop, gimple stmt, tree op, affine_iv *iv, } if (TREE_CODE (ev) != POLYNOMIAL_CHREC - || CHREC_VARIABLE (ev) != (unsigned) loop->num) + || CHREC_VARIABLE (ev) != (unsigned) wrto_loop->num) return false; iv->step = CHREC_RIGHT (ev); - if (allow_nonconstant_step) - { - if (tree_contains_chrecs (iv->step, NULL) - || chrec_contains_symbols_defined_in_loop (iv->step, loop->num)) - return false; - } - else if (TREE_CODE (iv->step) != INTEGER_CST) + if ((!allow_nonconstant_step && TREE_CODE (iv->step) != INTEGER_CST) + || tree_contains_chrecs (iv->step, NULL)) return false; iv->base = CHREC_LEFT (ev); - if (tree_contains_chrecs (iv->base, NULL) - || chrec_contains_symbols_defined_in_loop (iv->base, loop->num)) + if (tree_contains_chrecs (iv->base, NULL)) return false; iv->no_overflow = !folded_casts && TYPE_OVERFLOW_UNDEFINED (type); diff --git a/gcc/tree-scalar-evolution.h b/gcc/tree-scalar-evolution.h index 072f25d2963..06324972ca5 100644 --- a/gcc/tree-scalar-evolution.h +++ b/gcc/tree-scalar-evolution.h @@ -36,7 +36,7 @@ extern void scev_analysis (void); unsigned int scev_const_prop (void); bool expression_expensive_p (tree); -extern bool simple_iv (struct loop *, gimple, tree, affine_iv *, bool); +extern bool simple_iv (struct loop *, struct loop *, tree, affine_iv *, bool); /* Returns the basic block preceding LOOP or ENTRY_BLOCK_PTR when the loop is function's body. */ diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index b1813d373dc..c7bfa07be80 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -884,7 +884,7 @@ determine_biv_step (gimple phi) if (!is_gimple_reg (name)) return NULL_TREE; - if (!simple_iv (loop, phi, name, &iv, true)) + if (!simple_iv (loop, loop, name, &iv, true)) return NULL_TREE; return integer_zerop (iv.step) ? NULL_TREE : iv.step; @@ -990,7 +990,7 @@ find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv) if (TREE_CODE (lhs) != SSA_NAME) return false; - if (!simple_iv (loop, stmt, lhs, iv, true)) + if (!simple_iv (loop, loop_containing_stmt (stmt), lhs, iv, true)) return false; iv->base = expand_simple_operations (iv->base); diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 13b10c9f1c4..c67e638d58a 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -1781,9 +1781,9 @@ number_of_iterations_exit (struct loop *loop, edge exit, && !POINTER_TYPE_P (type)) return false; - if (!simple_iv (loop, stmt, op0, &iv0, false)) + if (!simple_iv (loop, loop_containing_stmt (stmt), op0, &iv0, false)) return false; - if (!simple_iv (loop, stmt, op1, &iv1, false)) + if (!simple_iv (loop, loop_containing_stmt (stmt), op1, &iv1, false)) return false; /* We don't want to see undefined signed overflow warnings while diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c index 6da4bf232aa..d0e460cf92e 100644 --- a/gcc/tree-ssa-loop-prefetch.c +++ b/gcc/tree-ssa-loop-prefetch.c @@ -364,7 +364,8 @@ idx_analyze_ref (tree base, tree *index, void *data) || TREE_CODE (base) == ALIGN_INDIRECT_REF) return false; - if (!simple_iv (ar_data->loop, ar_data->stmt, *index, &iv, false)) + if (!simple_iv (ar_data->loop, loop_containing_stmt (ar_data->stmt), + *index, &iv, false)) return false; ibase = iv.base; step = iv.step; diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index bc4fd7cc868..dc55676c4a3 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2367,14 +2367,19 @@ visit_use (tree use) VN_INFO (lhs)->expr = NULL_TREE; } - if (TREE_CODE (lhs) == SSA_NAME - /* We can substitute SSA_NAMEs that are live over - abnormal edges with their constant value. */ - && !(gimple_assign_copy_p (stmt) - && is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) - && !(simplified - && is_gimple_min_invariant (simplified)) - && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) + if ((TREE_CODE (lhs) == SSA_NAME + /* We can substitute SSA_NAMEs that are live over + abnormal edges with their constant value. */ + && !(gimple_assign_copy_p (stmt) + && is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) + && !(simplified + && is_gimple_min_invariant (simplified)) + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)) + /* Stores or copies from SSA_NAMEs that are live over + abnormal edges are a problem. */ + || (gimple_assign_single_p (stmt) + && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))) changed = defs_to_varying (stmt); else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs)) { diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 07fd9ed2a85..732bc6f7938 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -1524,8 +1524,8 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c, of a variable can also reach all other fields of the variable we simply have to expand the solution to contain all sub-fields if one sub-field is contained. */ - if (c->rhs.var == escaped_id - || c->rhs.var == callused_id) + if (c->rhs.var == find (escaped_id) + || c->rhs.var == find (callused_id)) { bitmap vars = NULL; /* In a first pass record all variables we need to add all @@ -1594,9 +1594,10 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c, /* Merging the solution from ESCAPED needlessly increases the set. Use ESCAPED as representative instead. Same for CALLUSED. */ - else if (get_varinfo (t)->id == escaped_id - || get_varinfo (t)->id == callused_id) - flag |= bitmap_set_bit (sol, get_varinfo (t)->id); + else if (get_varinfo (t)->id == find (escaped_id)) + flag |= bitmap_set_bit (sol, escaped_id); + else if (get_varinfo (t)->id == find (callused_id)) + flag |= bitmap_set_bit (sol, callused_id); else if (add_graph_edge (graph, lhs, t)) flag |= bitmap_ior_into (sol, get_varinfo (t)->solution); } @@ -2516,8 +2517,8 @@ solve_graph (constraint_graph_t graph) if (!solution_empty /* Do not propagate the ESCAPED/CALLUSED solutions. */ - && i != escaped_id - && i != callused_id) + && i != find (escaped_id) + && i != find (callused_id)) { bitmap_iterator bi; diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c index a4460b49168..0b947143c68 100644 --- a/gcc/tree-vect-analyze.c +++ b/gcc/tree-vect-analyze.c @@ -3622,7 +3622,8 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo) } outer_base = build_fold_addr_expr (outer_base); - if (!simple_iv (loop, stmt, outer_base, &base_iv, false)) + if (!simple_iv (loop, loop_containing_stmt (stmt), outer_base, + &base_iv, false)) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "failed: evolution of base is not affine.\n"); @@ -3642,7 +3643,8 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo) offset_iv.base = ssize_int (0); offset_iv.step = ssize_int (0); } - else if (!simple_iv (loop, stmt, poffset, &offset_iv, false)) + else if (!simple_iv (loop, loop_containing_stmt (stmt), poffset, + &offset_iv, false)) { if (vect_print_dump_info (REPORT_DETAILS)) fprintf (vect_dump, "evolution of offset is not affine.\n"); diff --git a/libcpp/po/ChangeLog b/libcpp/po/ChangeLog index 354082b7a01..55a2ed12f50 100644 --- a/libcpp/po/ChangeLog +++ b/libcpp/po/ChangeLog @@ -1,3 +1,7 @@ +2009-03-04 Joseph Myers <joseph@codesourcery.com> + + * es.po: Update. + 2009-02-13 Joseph S. Myers <joseph@codesourcery.com> * zh_CN.po: Update. diff --git a/libcpp/po/es.po b/libcpp/po/es.po index 8e45e979d69..b96ef24b2d0 100644 --- a/libcpp/po/es.po +++ b/libcpp/po/es.po @@ -1,14 +1,14 @@ -# Mensajes en español para cpplib-4.3.0 -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# Mensajes en español para cpplib-4.4-b20081121 +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is distributed under the same license as the gcc package. -# Cristian Othón Martínez Vera <cfuga@itam.mx>, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008. +# Cristian Othón Martínez Vera <cfuga@itam.mx>, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009. # msgid "" msgstr "" -"Project-Id-Version: cpplib-4.3.0\n" +"Project-Id-Version: cpplib 4.4-b20081121\n" "Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n" "POT-Creation-Date: 2008-11-18 20:02+0000\n" -"PO-Revision-Date: 2008-03-18 12:01-0600\n" +"PO-Revision-Date: 2009-03-03 23:45-0600\n" "Last-Translator: Cristian Othón Martínez Vera <cfuga@itam.mx>\n" "Language-Team: Spanish <es@li.org>\n" "MIME-Version: 1.0\n" @@ -160,9 +160,9 @@ msgid "#%s is a GCC extension" msgstr "#%s es una extensión de GCC" #: directives.c:352 -#, fuzzy, c-format +#, c-format msgid "#%s is a deprecated GCC extension" -msgstr "#%s es una extensión de GCC" +msgstr "#%s es una extensión de GCC obsoleta" #: directives.c:366 msgid "suggest not using #elif in traditional C" @@ -267,7 +267,7 @@ msgstr "\"%s\" después de # no es un entero positivo" #: directives.c:1042 #, c-format msgid "%s" -msgstr "" +msgstr "%s" #: directives.c:1066 #, c-format @@ -522,14 +522,12 @@ msgid "\"%s\" is not defined" msgstr "\"%s\" no está definido" #: expr.c:756 -#, fuzzy msgid "assertions are a GCC extension" -msgstr "las constantes binarias son una extensión GCC" +msgstr "las aserciones son una extensión GCC" #: expr.c:759 -#, fuzzy msgid "assertions are a deprecated extension" -msgstr "las constantes binarias son una extensión GCC" +msgstr "las aserciones son una extensión obsoleta" #: expr.c:892 expr.c:921 #, c-format @@ -546,9 +544,9 @@ msgid "missing expression between '(' and ')'" msgstr "falta una expresión entre '(' y ')'" #: expr.c:932 -#, fuzzy, c-format +#, c-format msgid "%s with no expression" -msgstr "#if sin expresión" +msgstr "%s sin expresión" #: expr.c:935 #, c-format @@ -565,9 +563,9 @@ msgid " ':' without preceding '?'" msgstr " ':' sin una '?' precedente" #: expr.c:994 -#, fuzzy, c-format +#, c-format msgid "unbalanced stack in %s" -msgstr "pila desbalanceada en #if" +msgstr "pila desbalanceada en %s" #: expr.c:1014 #, c-format @@ -830,7 +828,7 @@ msgstr "la función de macro \"%s\" se debe usar con argumentos en C tradicional" #: macro.c:1016 #, c-format msgid "invoking macro %s argument %d: empty macro arguments are undefined in ISO C90 and ISO C++98" -msgstr "" +msgstr "al invocar el macro %s argumento %d: los argumentos de macro vacíos están indefinidos en ISO C90 y en ISO C++98" #: macro.c:1453 #, c-format |