diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2008-07-08 13:47:18 +0000 |
---|---|---|
committer | H.J. Lu <hongjiu.lu@intel.com> | 2008-07-08 13:47:18 +0000 |
commit | f3bf5946fbbcb67f3a59afce01f09decebf431d0 (patch) | |
tree | 843cf7e02d9f4325008f3ba5f18010e2874607f3 | |
parent | 2b75b1686ad266868cad5b7e43e17360027a9e92 (diff) |
Merged with trunk at revision 137380.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ix86/avx@137624 138bc75d-0d04-0410-961f-82ee72b054a4
103 files changed, 2733 insertions, 606 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2bf1fd6e510..4a126ecef43 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,180 @@ +2008-07-08 Martin Jambor <mjambor@suse.cz> + + * ipa-cp.c (ipcp_init_cloned_node): Call ipa_check_create_node_params + instead of ipa_create_node_params. + (ipcp_driver): Allocate infos with ipa_check_create_node_params and + ipa_check_create_edge_args, free them with + free_all_ipa_structures_after_ipa_cp, call ipa_register_cgraph_hooks. + + * ipa-prop.c: Include flags.h and tree-inline.h. + (ipa_node_params_vector): New variable. + (ipa_edge_args_vector): New variable. + (edge_removal_hook_holder): New variable. + (node_removal_hook_holder): New variable. + (edge_duplication_hook_holder): New variable. + (node_duplication_hook_holder): New variable. + (ipa_detect_param_modifications): Check for presence of modified flags. + (ipa_compute_jump_functions): Check for presence of jump functions. + (ipa_free_edge_args_substructures): New function. + (ipa_create_node_params): Removed. + (ipa_free_all_edge_args): Changed to deallocate the on-the-side vector. + (ipa_free_node_params_substructures): New function. + (ipa_free_all_node_params): Changed to deallocate the on-the-side + vector. + (ipa_edge_removal_hook): New function. + (ipa_node_removal_hook): New function. + (duplicate_array): New function. + (ipa_edge_duplication_hook): New function. + (ipa_node_duplication_hook): New function. + (ipa_register_cgraph_hooks): New function. + (ipa_unregister_cgraph_hooks): New function. + (free_all_ipa_structures_after_ipa_cp): New function. + + * ipa-prop.h: Include vec.h. + (ipa_node_params_t): New typedef with vector types for it. + (ipa_edge_args_t): New typedef with vector types for it. + (IPA_NODE_REF): Changed to access an on-the-side vector. + (IPA_EDGE_REF): Changed to access an on-the-side vector. + (ipa_check_create_node_params): New function. + (ipa_check_create_edge_args): New function. + + * Makefile.in (IPA_PROP_H): New variable for ipa-prop.h. Converted + all users. + +2008-07-07 Tom Tromey <tromey@redhat.com> + + * configure, config.in: Rebuilt. + * configure.ac: Don't check for scandir or alphasort. + +2008-07-07 Joseph Myers <joseph@codesourcery.com> + + * config/arm/arm.c (arm_init_neon_builtins): Register built-in + types immediately after creating them. + +2008-07-07 Joseph Myers <joseph@codesourcery.com> + + * config/arm/aout.h (DOLLARS_IN_IDENTIFIERS): Remove. + +2008-07-07 Fernando Pereira <fernando@cs.ucla.edu> + + * tree-ssa-structalias.c (compute_points_to_sets): Add call to + dump_constraint_graph. + (dump_constraint_edge): New function. + (dump_constraint_graph): New function. + (debug_constraint_graph): New function. + (dump_constraint): Removed useless comparison. + * tree-ssa-structalias.h (dump_constraint_edge): Declare. + (dump_constraint_graph): Declare. + (debug_constraint_graph): Declare. + * tree-dump.c (struct dump_option_value_info): Declare + TDF_GRAPH. + +2008-07-07 Kai Tietz <kai.tietz@onevision.com> + + * config/i386/i386.c (is_va_list_char_pointer): New. + (ix86_va_start): Replace compare with ms_va_list_type_node + by is_va_list_char_pointer. + (ix86_gimplify_va_arg): Likewise. + +2008-07-07 Martin Jambor <mjambor@suse.cz> + + * cgraph.c (cgraph_edge_max_uid): New variable. + (struct cgraph_edge_hook_list): New type. + (struct cgraph_node_hook_list): New type. + (struct cgraph_2edge_hook_list): New type. + (struct cgraph_2node_hook_list): New type. + (first_cgraph_edge_removal_hook): New variable. + (first_cgraph_node_removal_hook): New variable. + (first_cgraph_edge_duplicated_hook): New variable. + (first_cgraph_node_duplicated_hook): New variable. + (cgraph_add_edge_removal_hook): New function. + (cgraph_remove_edge_removal_hook): New function. + (cgraph_call_edge_removal_hooks): New function. + (cgraph_add_node_removal_hook): New function. + (cgraph_remove_node_removal_hook): New function. + (cgraph_call_node_removal_hooks): New function. + (cgraph_add_edge_duplication_hook): New function. + (cgraph_remove_edge_duplication_hook): New function. + (cgraph_call_edge_duplication_hooks): New function. + (cgraph_add_node_duplication_hook): New function. + (cgraph_remove_node_duplication_hook): New function. + (cgraph_call_node_duplication_hooks): New function. + (cgraph_create_edge): Assign to edge uid. + (cgraph_remove_edge): Call edge removal hooks. + (cgraph_node_remove_callees): Call edge removal hooks. + (cgraph_node_remove_callers): Call edge removal hooks. + (cgraph_remove_node): Call node removal hooks. + (cgraph_clone_edge): Call edge duplication hooks. + (cgraph_clone_node): Call node duplication hooks. + + * cgraph.h (cgraph_edge): New field uid. + (cgraph_edge_hook): New type. + (cgraph_node_hook): New type. + (cgraph_2edge_hook): New type. + (cgraph_2node_hook): New type. + +2008-07-07 Andreas Tobler <a.tobler@schweiz.org> + + * config.in: Regenerate. + +2008-07-07 Vladimir Prus <vladimir@codesourcery.com> + + * gcc.c (print_sysroot): New. + (option_map, display_help, process_command): Handle the + -print-sysroot option. + (main): Print the sysroot if requested. + * doc/invoke.texi (Debugging Options): Document -print-sysroot. + +2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + PR target/34780 + * unwind-pe.h (size_of_encoded_value): add attribute unused. + +2008-07-07 Daniel Jacobowitz <dan@codesourcery.com> + + * function.c (assign_parm_remove_parallels): Check mode of + entry_parm. + (assign_parm_setup_block_p): Also check mode of entry_parm. + +2008-07-07 Richard Guenther <rguenther@suse.de> + + * tree-ssa-structalias.h (set_used_smts): Remove. + * tree-ssa-structalias.c (used_smts): Likewise. + (set_used_smts): Likewise. + * tree-ssa-alias.c (compute_flow_sensitive_aliasing): Remove + call to set_used_smts. + +2008-07-07 Richard Guenther <rguenther@suse.de> + + * tree-ssa-structalias.c (struct variable_info): Add is_full_var flag. + (new_var_info): Set it to false. + (solution_set_add): Correctly handle pointers outside a var and + inside a field. + (type_safe): Treat variables with is_full_var properly. + (do_sd_constraint): Likewise. + (do_ds_constraint): Likewise. + (process_constraint): Remove zeroing offset for !use_field_sensitive. + (get_constraint_for_ptr_offset): New function. + (get_constraint_for_component_ref): For addresses at least include + the last field of the variable. Handle is_full_vars properly. + (get_constraint_for_1): Factor common code, handle POINTER_PLUS_EXPR. + (handle_ptr_arith): Remove. + (find_func_aliases): Simplify assignment handling. + (create_function_info_for): For parameter and result varinfos set + is_full_var flag. + (create_variable_info_for): Set is_full_var flag whenever we + just created a single varinfo for a decl. + (init_alias_vars): Initialize use_field_sensitive from + max-fields-for-field-sensitive parameter. + +2008-07-07 Richard Guenther <rguenther@suse.de> + + PR tree-optimization/36713 + * tree-flow-inline.h (is_call_used): New function. + * tree-nrv.c (dest_safe_for_nrv_p): Use it. + * tree-tailcall.c (suitable_for_tail_opt_p): Likewise. + * tree-outof-ssa.c (create_temp): Set call-used flag if required. + 2008-07-07 Maxim Kuvyrkov <maxim@codesourcery.com> * config/m68k/m68k.c (m68k_return_in_memory): Fix arguments types. diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e0e8921cbc2..9c0637d2a77 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20080707 +20080708 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index ef0336607da..a3def27bd52 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -839,6 +839,7 @@ TREE_INLINE_H = tree-inline.h $(VARRAY_H) pointer-set.h REAL_H = real.h $(MACHMODE_H) DBGCNT_H = dbgcnt.h dbgcnt.def EBIMAP_H = ebitmap.h sbitmap.h +IPA_PROP_H = $(TREE_H) vec.h # # Now figure out from those variables how to compile and link. @@ -2007,7 +2008,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \ langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) intl.h $(FUNCTION_H) $(TREE_GIMPLE_H) \ debug.h $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-iterator.h tree-mudflap.h \ - ipa-prop.h value-prof.h $(TARGET_H) $(INTEGRATE_H) + $(IPA_PROP_H) value-prof.h $(TARGET_H) $(INTEGRATE_H) print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(GGC_H) langhooks.h $(REAL_H) tree-iterator.h fixed-value.h $(TREE_FLOW_H) stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ @@ -2520,7 +2521,7 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(TREE_GIMPLE_H) \ $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \ - $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h \ + $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \ gt-cgraphunit.h cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(TREE_GIMPLE_H) \ @@ -2529,14 +2530,14 @@ varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(TREE_GIMPLE_H) \ $(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \ - $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h \ + $(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \ gt-varpool.h ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) ipa-prop.h \ - $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) + langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) \ + $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) tree-inline.h ipa-cp.o : ipa-cp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - langhooks.h $(TARGET_H) $(CGRAPH_H) ipa-prop.h tree-inline.h tree-dump.h \ + langhooks.h $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) tree-inline.h tree-dump.h \ $(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H) $(DIAGNOSTIC_H) matrix-reorg.o : matrix-reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TARGET_H) $(CGRAPH_H) $(TREE_FLOW_H) $(TM_H) tree-pass.h \ diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 17ee8f0a63a..6a80bbed095 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -109,6 +109,9 @@ int cgraph_n_nodes; /* Maximal uid used in cgraph nodes. */ int cgraph_max_uid; +/* Maximal uid used in cgraph edges. */ +int cgraph_edge_max_uid; + /* Maximal pid used for profiling */ int cgraph_max_pid; @@ -132,6 +135,206 @@ static GTY(()) struct cgraph_asm_node *cgraph_asm_last_node; them, to support -fno-toplevel-reorder. */ int cgraph_order; +/* List of hooks trigerred on cgraph_edge events. */ +struct cgraph_edge_hook_list { + cgraph_edge_hook hook; + void *data; + struct cgraph_edge_hook_list *next; +}; + +/* List of hooks trigerred on cgraph_node events. */ +struct cgraph_node_hook_list { + cgraph_node_hook hook; + void *data; + struct cgraph_node_hook_list *next; +}; + +/* List of hooks trigerred on events involving two cgraph_edges. */ +struct cgraph_2edge_hook_list { + cgraph_2edge_hook hook; + void *data; + struct cgraph_2edge_hook_list *next; +}; + +/* List of hooks trigerred on events involving two cgraph_nodes. */ +struct cgraph_2node_hook_list { + cgraph_2node_hook hook; + void *data; + struct cgraph_2node_hook_list *next; +}; + +/* List of hooks triggered when an edge is removed. */ +struct cgraph_edge_hook_list *first_cgraph_edge_removal_hook; +/* List of hooks triggered when a node is removed. */ +struct cgraph_node_hook_list *first_cgraph_node_removal_hook; +/* List of hooks triggered when an edge is duplicated. */ +struct cgraph_2edge_hook_list *first_cgraph_edge_duplicated_hook; +/* List of hooks triggered when a node is duplicated. */ +struct cgraph_2node_hook_list *first_cgraph_node_duplicated_hook; + + +/* Register HOOK to be called with DATA on each removed edge. */ +struct cgraph_edge_hook_list * +cgraph_add_edge_removal_hook (cgraph_edge_hook hook, void *data) +{ + struct cgraph_edge_hook_list *entry; + struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook; + + entry = (struct cgraph_edge_hook_list *) xmalloc (sizeof (*entry)); + entry->hook = hook; + entry->data = data; + entry->next = NULL; + while (*ptr) + ptr = &(*ptr)->next; + *ptr = entry; + return entry; +} + +/* Remove ENTRY from the list of hooks called on removing edges. */ +void +cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry) +{ + struct cgraph_edge_hook_list **ptr = &first_cgraph_edge_removal_hook; + + while (*ptr != entry) + ptr = &(*ptr)->next; + *ptr = entry->next; +} + +/* Call all edge removal hooks. */ +static void +cgraph_call_edge_removal_hooks (struct cgraph_edge *e) +{ + struct cgraph_edge_hook_list *entry = first_cgraph_edge_removal_hook; + while (entry) + { + entry->hook (e, entry->data); + entry = entry->next; + } +} + +/* Register HOOK to be called with DATA on each removed node. */ +struct cgraph_node_hook_list * +cgraph_add_node_removal_hook (cgraph_node_hook hook, void *data) +{ + struct cgraph_node_hook_list *entry; + struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook; + + entry = (struct cgraph_node_hook_list *) xmalloc (sizeof (*entry)); + entry->hook = hook; + entry->data = data; + entry->next = NULL; + while (*ptr) + ptr = &(*ptr)->next; + *ptr = entry; + return entry; +} + +/* Remove ENTRY from the list of hooks called on removing nodes. */ +void +cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry) +{ + struct cgraph_node_hook_list **ptr = &first_cgraph_node_removal_hook; + + while (*ptr != entry) + ptr = &(*ptr)->next; + *ptr = entry->next; +} + +/* Call all node removal hooks. */ +static void +cgraph_call_node_removal_hooks (struct cgraph_node *node) +{ + struct cgraph_node_hook_list *entry = first_cgraph_node_removal_hook; + while (entry) + { + entry->hook (node, entry->data); + entry = entry->next; + } +} + +/* Register HOOK to be called with DATA on each duplicated edge. */ +struct cgraph_2edge_hook_list * +cgraph_add_edge_duplication_hook (cgraph_2edge_hook hook, void *data) +{ + struct cgraph_2edge_hook_list *entry; + struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook; + + entry = (struct cgraph_2edge_hook_list *) xmalloc (sizeof (*entry)); + entry->hook = hook; + entry->data = data; + entry->next = NULL; + while (*ptr) + ptr = &(*ptr)->next; + *ptr = entry; + return entry; +} + +/* Remove ENTRY from the list of hooks called on duplicating edges. */ +void +cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry) +{ + struct cgraph_2edge_hook_list **ptr = &first_cgraph_edge_duplicated_hook; + + while (*ptr != entry) + ptr = &(*ptr)->next; + *ptr = entry->next; +} + +/* Call all edge duplication hooks. */ +static void +cgraph_call_edge_duplication_hooks (struct cgraph_edge *cs1, + struct cgraph_edge *cs2) +{ + struct cgraph_2edge_hook_list *entry = first_cgraph_edge_duplicated_hook; + while (entry) + { + entry->hook (cs1, cs2, entry->data); + entry = entry->next; + } +} + +/* Register HOOK to be called with DATA on each duplicated node. */ +struct cgraph_2node_hook_list * +cgraph_add_node_duplication_hook (cgraph_2node_hook hook, void *data) +{ + struct cgraph_2node_hook_list *entry; + struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook; + + entry = (struct cgraph_2node_hook_list *) xmalloc (sizeof (*entry)); + entry->hook = hook; + entry->data = data; + entry->next = NULL; + while (*ptr) + ptr = &(*ptr)->next; + *ptr = entry; + return entry; +} + +/* Remove ENTRY from the list of hooks called on duplicating nodes. */ +void +cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry) +{ + struct cgraph_2node_hook_list **ptr = &first_cgraph_node_duplicated_hook; + + while (*ptr != entry) + ptr = &(*ptr)->next; + *ptr = entry->next; +} + +/* Call all node duplication hooks. */ +static void +cgraph_call_node_duplication_hooks (struct cgraph_node *node1, + struct cgraph_node *node2) +{ + struct cgraph_2node_hook_list *entry = first_cgraph_node_duplicated_hook; + while (entry) + { + entry->hook (node1, node2, entry->data); + entry = entry->next; + } +} + /* Returns a hash code for P. */ static hashval_t @@ -365,6 +568,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, gcc_assert (freq >= 0); gcc_assert (freq <= CGRAPH_FREQ_MAX); edge->loop_nest = nest; + edge->uid = cgraph_edge_max_uid++; if (caller->call_site_hash) { void **slot; @@ -414,6 +618,7 @@ cgraph_edge_remove_caller (struct cgraph_edge *e) void cgraph_remove_edge (struct cgraph_edge *e) { + cgraph_call_edge_removal_hooks (e); /* Remove from callers list of the callee. */ cgraph_edge_remove_callee (e); @@ -495,7 +700,10 @@ cgraph_node_remove_callees (struct cgraph_node *node) the callees. The callee list of the node can be zapped with one assignment. */ for (e = node->callees; e; e = e->next_callee) - cgraph_edge_remove_callee (e); + { + cgraph_call_edge_removal_hooks (e); + cgraph_edge_remove_callee (e); + } node->callees = NULL; if (node->call_site_hash) { @@ -515,7 +723,10 @@ cgraph_node_remove_callers (struct cgraph_node *node) the callers. The caller list of the node can be zapped with one assignment. */ for (e = node->callers; e; e = e->next_caller) - cgraph_edge_remove_caller (e); + { + cgraph_call_edge_removal_hooks (e); + cgraph_edge_remove_caller (e); + } node->callers = NULL; } @@ -549,6 +760,7 @@ cgraph_remove_node (struct cgraph_node *node) void **slot; bool kill_body = false; + cgraph_call_node_removal_hooks (node); cgraph_node_remove_callers (node); cgraph_node_remove_callees (node); /* Incremental inlining access removed nodes stored in the postorder list. @@ -891,6 +1103,7 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n, if (e->count < 0) e->count = 0; } + cgraph_call_edge_duplication_hooks (e, new); return new; } @@ -942,6 +1155,7 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq, int loop_ne if (new->next_clone) new->next_clone->prev_clone = new; + cgraph_call_node_duplication_hooks (n, new); return new; } diff --git a/gcc/cgraph.h b/gcc/cgraph.h index dda2a1891f5..ee79c9200f1 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -209,6 +209,8 @@ struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_call int frequency; /* Depth of loop nest, 1 means no loop nest. */ int loop_nest; + /* Unique id of the edge. */ + int uid; }; #define CGRAPH_FREQ_BASE 1000 @@ -266,6 +268,7 @@ struct cgraph_asm_node GTY(()) extern GTY(()) struct cgraph_node *cgraph_nodes; extern GTY(()) int cgraph_n_nodes; extern GTY(()) int cgraph_max_uid; +extern GTY(()) int cgraph_edge_max_uid; extern GTY(()) int cgraph_max_pid; extern bool cgraph_global_info_ready; enum cgraph_state @@ -351,6 +354,26 @@ struct cgraph_node *save_inline_function_body (struct cgraph_node *); void record_references_in_initializer (tree); bool cgraph_process_new_functions (void); +typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *); +typedef void (*cgraph_node_hook)(struct cgraph_node *, void *); +typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *, + void *); +typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *, + void *); +struct cgraph_edge_hook_list; +struct cgraph_node_hook_list; +struct cgraph_2edge_hook_list; +struct cgraph_2node_hook_list; +struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *); +void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *); +struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook, + void *); +void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *); +struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *); +void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *); +struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *); +void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *); + /* In cgraphbuild.c */ unsigned int rebuild_cgraph_edges (void); diff --git a/gcc/config.in b/gcc/config.in index ec2c468d402..ec20c1cdab0 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -180,12 +180,6 @@ #endif -/* Define to 1 if you have the `alphasort' function. */ -#ifndef USED_FOR_TARGET -#undef HAVE_ALPHASORT -#endif - - /* Define if your assembler supports cmpb. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_CMPB @@ -1122,12 +1116,6 @@ #endif -/* Define to 1 if you have the `scandir' function. */ -#ifndef USED_FOR_TARGET -#undef HAVE_SCANDIR -#endif - - /* Define to 1 if you have the `setlocale' function. */ #ifndef USED_FOR_TARGET #undef HAVE_SETLOCALE @@ -1518,6 +1506,12 @@ #endif +/* Define to `char *' if <sys/types.h> does not define. */ +#ifndef USED_FOR_TARGET +#undef caddr_t +#endif + + /* Define to `int' if <sys/types.h> doesn't define. */ #ifndef USED_FOR_TARGET #undef gid_t diff --git a/gcc/config/arm/aout.h b/gcc/config/arm/aout.h index cb46a8edc90..59c1bf70e5d 100644 --- a/gcc/config/arm/aout.h +++ b/gcc/config/arm/aout.h @@ -191,9 +191,6 @@ } #endif -/* Arm Assembler barfs on dollars. */ -#define DOLLARS_IN_IDENTIFIERS 0 - #ifndef NO_DOLLAR_IN_LABEL #define NO_DOLLAR_IN_LABEL 1 #endif diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index fa3d06dcd75..0ce531bb802 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15094,6 +15094,24 @@ arm_init_neon_builtins (void) TYPE_PRECISION (neon_float_type_node) = FLOAT_TYPE_SIZE; layout_type (neon_float_type_node); + /* Define typedefs which exactly correspond to the modes we are basing vector + types on. If you change these names you'll need to change + the table used by arm_mangle_type too. */ + (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node, + "__builtin_neon_qi"); + (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node, + "__builtin_neon_hi"); + (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node, + "__builtin_neon_si"); + (*lang_hooks.types.register_builtin_type) (neon_float_type_node, + "__builtin_neon_sf"); + (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node, + "__builtin_neon_di"); + (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node, + "__builtin_neon_poly8"); + (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node, + "__builtin_neon_poly16"); + intQI_pointer_node = build_pointer_type (neon_intQI_type_node); intHI_pointer_node = build_pointer_type (neon_intHI_type_node); intSI_pointer_node = build_pointer_type (neon_intSI_type_node); @@ -15146,12 +15164,32 @@ arm_init_neon_builtins (void) intUSI_type_node = make_unsigned_type (GET_MODE_PRECISION (SImode)); intUDI_type_node = make_unsigned_type (GET_MODE_PRECISION (DImode)); + (*lang_hooks.types.register_builtin_type) (intUQI_type_node, + "__builtin_neon_uqi"); + (*lang_hooks.types.register_builtin_type) (intUHI_type_node, + "__builtin_neon_uhi"); + (*lang_hooks.types.register_builtin_type) (intUSI_type_node, + "__builtin_neon_usi"); + (*lang_hooks.types.register_builtin_type) (intUDI_type_node, + "__builtin_neon_udi"); + /* Opaque integer types for structures of vectors. */ intEI_type_node = make_signed_type (GET_MODE_PRECISION (EImode)); intOI_type_node = make_signed_type (GET_MODE_PRECISION (OImode)); intCI_type_node = make_signed_type (GET_MODE_PRECISION (CImode)); intXI_type_node = make_signed_type (GET_MODE_PRECISION (XImode)); + (*lang_hooks.types.register_builtin_type) (intTI_type_node, + "__builtin_neon_ti"); + (*lang_hooks.types.register_builtin_type) (intEI_type_node, + "__builtin_neon_ei"); + (*lang_hooks.types.register_builtin_type) (intOI_type_node, + "__builtin_neon_oi"); + (*lang_hooks.types.register_builtin_type) (intCI_type_node, + "__builtin_neon_ci"); + (*lang_hooks.types.register_builtin_type) (intXI_type_node, + "__builtin_neon_xi"); + /* Pointers to vector types. */ V8QI_pointer_node = build_pointer_type (V8QI_type_node); V4HI_pointer_node = build_pointer_type (V4HI_type_node); @@ -15195,44 +15233,6 @@ arm_init_neon_builtins (void) build_function_type_list (void_type_node, V2DI_pointer_node, V2DI_type_node, V2DI_type_node, NULL); - /* Define typedefs which exactly correspond to the modes we are basing vector - types on. If you change these names you'll need to change - the table used by arm_mangle_type too. */ - (*lang_hooks.types.register_builtin_type) (neon_intQI_type_node, - "__builtin_neon_qi"); - (*lang_hooks.types.register_builtin_type) (neon_intHI_type_node, - "__builtin_neon_hi"); - (*lang_hooks.types.register_builtin_type) (neon_intSI_type_node, - "__builtin_neon_si"); - (*lang_hooks.types.register_builtin_type) (neon_float_type_node, - "__builtin_neon_sf"); - (*lang_hooks.types.register_builtin_type) (neon_intDI_type_node, - "__builtin_neon_di"); - - (*lang_hooks.types.register_builtin_type) (neon_polyQI_type_node, - "__builtin_neon_poly8"); - (*lang_hooks.types.register_builtin_type) (neon_polyHI_type_node, - "__builtin_neon_poly16"); - (*lang_hooks.types.register_builtin_type) (intUQI_type_node, - "__builtin_neon_uqi"); - (*lang_hooks.types.register_builtin_type) (intUHI_type_node, - "__builtin_neon_uhi"); - (*lang_hooks.types.register_builtin_type) (intUSI_type_node, - "__builtin_neon_usi"); - (*lang_hooks.types.register_builtin_type) (intUDI_type_node, - "__builtin_neon_udi"); - - (*lang_hooks.types.register_builtin_type) (intTI_type_node, - "__builtin_neon_ti"); - (*lang_hooks.types.register_builtin_type) (intEI_type_node, - "__builtin_neon_ei"); - (*lang_hooks.types.register_builtin_type) (intOI_type_node, - "__builtin_neon_oi"); - (*lang_hooks.types.register_builtin_type) (intCI_type_node, - "__builtin_neon_ci"); - (*lang_hooks.types.register_builtin_type) (intXI_type_node, - "__builtin_neon_xi"); - dreg_types[0] = V8QI_type_node; dreg_types[1] = V4HI_type_node; dreg_types[2] = V2SI_type_node; diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 49223db101b..e3dc4595d83 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5522,6 +5522,21 @@ ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode, setup_incoming_varargs_64 (&next_cum); } +/* Checks if TYPE is of kind va_list char *. */ + +static bool +is_va_list_char_pointer (tree type) +{ + tree canonic; + + /* For 32-bit it is always true. */ + if (!TARGET_64BIT) + return true; + canonic = ix86_canonical_va_list_type (type); + return (canonic == ms_va_list_type_node + || (DEFAULT_ABI == MS_ABI && canonic == va_list_type_node)); +} + /* Implement va_start. */ static void @@ -5533,8 +5548,7 @@ ix86_va_start (tree valist, rtx nextarg) tree type; /* Only 64bit target needs something special. */ - if (!TARGET_64BIT || - ix86_canonical_va_list_type (TREE_TYPE (valist)) == ms_va_list_type_node) + if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist))) { std_expand_builtin_va_start (valist, nextarg); return; @@ -5613,8 +5627,7 @@ ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) enum machine_mode nat_mode; /* Only 64bit target needs something special. */ - if (!TARGET_64BIT || - ix86_canonical_va_list_type (TREE_TYPE (valist)) == ms_va_list_type_node) + if (!TARGET_64BIT || is_va_list_char_pointer (TREE_TYPE (valist))) return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); f_gpr = TYPE_FIELDS (TREE_TYPE (sysv_va_list_type_node)); diff --git a/gcc/configure b/gcc/configure index 5d2ceb5308a..beb1b81314b 100755 --- a/gcc/configure +++ b/gcc/configure @@ -10097,10 +10097,8 @@ fi - - for ac_func in times clock kill getrlimit setrlimit atoll atoq \ - sysconf strsignal getrusage nl_langinfo scandir alphasort \ + sysconf strsignal getrusage nl_langinfo \ gettimeofday mbstowcs wcswidth mmap mincore setlocale \ clearerr_unlocked feof_unlocked ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked putchar_unlocked putc_unlocked do @@ -14725,13 +14723,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:14728: $ac_compile\"" >&5) + (eval echo "\"\$as_me:14726: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:14731: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:14729: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:14734: output\"" >&5) + (eval echo "\"\$as_me:14732: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -15786,7 +15784,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 15789 "configure"' > conftest.$ac_ext + echo '#line 15787 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -16406,11 +16404,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16409: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16407: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16413: \$? = $ac_status" >&5 + echo "$as_me:16411: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -16728,11 +16726,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16731: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16729: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16735: \$? = $ac_status" >&5 + echo "$as_me:16733: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -16833,11 +16831,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16836: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16834: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:16840: \$? = $ac_status" >&5 + echo "$as_me:16838: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16888,11 +16886,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16891: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16889: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:16895: \$? = $ac_status" >&5 + echo "$as_me:16893: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -19685,7 +19683,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19688 "configure" +#line 19686 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -19785,7 +19783,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 19788 "configure" +#line 19786 "configure" #include "confdefs.h" #if HAVE_DLFCN_H diff --git a/gcc/configure.ac b/gcc/configure.ac index 1e9e8d87b78..dd62e956e65 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -987,7 +987,7 @@ define(gcc_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked dnl putchar_unlocked putc_unlocked) AC_CHECK_FUNCS(times clock kill getrlimit setrlimit atoll atoq \ - sysconf strsignal getrusage nl_langinfo scandir alphasort \ + sysconf strsignal getrusage nl_langinfo \ gettimeofday mbstowcs wcswidth mmap mincore setlocale \ gcc_UNLOCKED_FUNCS) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5732d984d44..29f5534c377 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -310,7 +310,7 @@ Objective-C and Objective-C++ Dialects}. -p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol -print-multi-directory -print-multi-lib @gol -print-prog-name=@var{program} -print-search-dirs -Q @gol --print-sysroot-headers-suffix @gol +-print-sysroot -print-sysroot-headers-suffix @gol -save-temps -time} @item Optimization Options @@ -5059,6 +5059,14 @@ variable @env{GCC_EXEC_PREFIX} to the directory where you installed them. Don't forget the trailing @samp{/}. @xref{Environment Variables}. +@item -print-sysroot +@opindex print-sysroot +Print the target sysroot directory that will be used during +compilation. This is the target sysroot specified either at configure +time or or using the @option{--sysroot} option, possibly with an extra +suffix that depends on compilation options. If no target sysroot is +specified, the option prints nothing. + @item -print-sysroot-headers-suffix @opindex print-sysroot-headers-suffix Print the suffix added to the target sysroot when searching for diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7b641f077ba..44f61fa2458 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,16 @@ +2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/36670 + * iresolve.c (gfc_resolve_product): Set shape of return + value from array. + (gfc_resolve_sum): Likewise. + +2008-07-07 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/36726 + * f95-lang.c (poplevel): Don't ever add subblocks to + global_binding_level. + 2008-07-02 Janus Weil <janus@gcc.gnu.org> Tobias Burnus <burnus@net-b.de> Paul Thomas <pault@gcc.gnu.org> diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 794cc41a2d0..9dfb4233210 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -435,6 +435,10 @@ poplevel (int keep, int reverse, int functionbody) DECL_INITIAL (current_function_decl) = block_node; BLOCK_VARS (block_node) = 0; } + else if (current_binding_level == global_binding_level) + /* When using gfc_start_block/gfc_finish_block from middle-end hooks, + don't add newly created BLOCKs as sublocks of global_binding_level. */ + ; else if (block_node) { current_binding_level->blocks diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c index 64a24e80007..2c804143ba9 100644 --- a/gcc/fortran/iresolve.c +++ b/gcc/fortran/iresolve.c @@ -1788,6 +1788,7 @@ gfc_resolve_product (gfc_expr *f, gfc_expr *array, gfc_expr *dim, if (dim != NULL) { f->rank = array->rank - 1; + f->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim); gfc_resolve_dim_arg (dim); } @@ -2271,6 +2272,7 @@ gfc_resolve_sum (gfc_expr *f, gfc_expr *array, gfc_expr *dim, gfc_expr *mask) if (dim != NULL) { f->rank = array->rank - 1; + f->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim); gfc_resolve_dim_arg (dim); } diff --git a/gcc/function.c b/gcc/function.c index d8234da3877..69c2f68a4f9 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2364,8 +2364,7 @@ assign_parm_remove_parallels (struct assign_parm_data_one *data) This can be done with register operations rather than on the stack, even if we will store the reconstituted parameter on the stack later. */ - if (GET_CODE (entry_parm) == PARALLEL - && data->passed_mode != BLKmode) + if (GET_CODE (entry_parm) == PARALLEL && GET_MODE (entry_parm) != BLKmode) { rtx parmreg = gen_reg_rtx (GET_MODE (entry_parm)); emit_group_store (parmreg, entry_parm, NULL_TREE, @@ -2421,6 +2420,8 @@ assign_parm_setup_block_p (struct assign_parm_data_one *data) { if (data->nominal_mode == BLKmode) return true; + if (GET_MODE (data->entry_parm) == BLKmode) + return true; #ifdef BLOCK_REG_PADDING /* Only assign_parm_setup_block knows how to deal with register arguments diff --git a/gcc/gcc.c b/gcc/gcc.c index 00533247163..7914e4b6f35 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -155,6 +155,8 @@ static const char *print_prog_name = NULL; static int print_multi_directory; +static int print_sysroot; + /* Flag saying to print the relative path we'd use to find OS libraries given the current compiler flags. */ @@ -1162,6 +1164,7 @@ static const struct option_map option_map[] = {"--print-multi-directory", "-print-multi-directory", 0}, {"--print-multi-os-directory", "-print-multi-os-directory", 0}, {"--print-prog-name", "-print-prog-name=", "aj"}, + {"--print-sysroot", "-print-sysroot", 0}, {"--print-sysroot-headers-suffix", "-print-sysroot-headers-suffix", 0}, {"--profile", "-p", 0}, {"--profile-blocks", "-a", 0}, @@ -3244,6 +3247,7 @@ display_help (void) -print-multi-lib Display the mapping between command line options and\n\ multiple library search directories\n"), stdout); fputs (_(" -print-multi-os-directory Display the relative path to OS libraries\n"), stdout); + fputs (_(" -print-sysroot Display the target libraries directory\n"), stdout); fputs (_(" -print-sysroot-headers-suffix Display the sysroot suffix used to find headers\n"), stdout); fputs (_(" -Wa,<options> Pass comma-separated <options> on to the assembler\n"), stdout); fputs (_(" -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"), stdout); @@ -3686,6 +3690,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" print_multi_lib = 1; else if (! strcmp (argv[i], "-print-multi-directory")) print_multi_directory = 1; + else if (! strcmp (argv[i], "-print-sysroot")) + print_sysroot = 1; else if (! strcmp (argv[i], "-print-multi-os-directory")) print_multi_os_directory = 1; else if (! strcmp (argv[i], "-print-sysroot-headers-suffix")) @@ -4126,6 +4132,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" ; else if (! strcmp (argv[i], "-print-multi-directory")) ; + else if (! strcmp (argv[i], "-print-sysroot")) + ; else if (! strcmp (argv[i], "-print-multi-os-directory")) ; else if (! strcmp (argv[i], "-print-sysroot-headers-suffix")) @@ -6529,6 +6537,18 @@ main (int argc, char **argv) return (0); } + if (print_sysroot) + { + if (target_system_root) + { + if (target_sysroot_suffix) + printf ("%s%s\n", target_system_root, target_sysroot_suffix); + else + printf ("%s\n", target_system_root); + } + return (0); + } + if (print_multi_os_directory) { if (multilib_os_dir == NULL) diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 9e2153141d3..bda0fc261d6 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -153,7 +153,7 @@ static void ipcp_init_cloned_node (struct cgraph_node *orig_node, struct cgraph_node *new_node) { - ipa_create_node_params (new_node); + ipa_check_create_node_params (); IPA_NODE_REF (new_node)->ipcp_orig_node = orig_node; ipa_count_formal_params (new_node); ipa_create_param_decls_array (new_node); @@ -998,8 +998,9 @@ ipcp_driver (void) { if (dump_file) fprintf (dump_file, "\nIPA constant propagation start:\n"); - ipa_create_all_node_params (); - ipa_create_all_edge_args (); + ipa_check_create_node_params (); + ipa_check_create_edge_args (); + ipa_register_cgraph_hooks (); /* 1. Call the init stage to initialize the ipa_node_params and ipa_edge_args structures. */ ipcp_init_stage (); @@ -1025,8 +1026,7 @@ ipcp_driver (void) ipcp_print_profile_data (dump_file); } /* Free all IPCP structures. */ - ipa_free_all_node_params (); - ipa_free_all_edge_args (); + free_all_ipa_structures_after_ipa_cp (); if (dump_file) fprintf (dump_file, "\nIPA constant propagation end\n"); cgraph_remove_unreachable_nodes (true, NULL); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index c5b4c9a80c8..f67d6579e10 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -28,8 +28,21 @@ along with GCC; see the file COPYING3. If not see #include "ipa-prop.h" #include "tree-flow.h" #include "tree-pass.h" +#include "tree-inline.h" #include "flags.h" #include "timevar.h" +#include "flags.h" + +/* Vector where the parameter infos are actually stored. */ +VEC (ipa_node_params_t, heap) *ipa_node_params_vector; +/* Vector where the parameter infos are actually stored. */ +VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector; + +/* Holders of ipa cgraph hooks: */ +struct cgraph_edge_hook_list *edge_removal_hook_holder; +struct cgraph_node_hook_list *node_removal_hook_holder; +struct cgraph_2edge_hook_list *edge_duplication_hook_holder; +struct cgraph_2node_hook_list *node_duplication_hook_holder; /* Initialize worklist to contain all functions. */ struct ipa_func_list * @@ -176,7 +189,7 @@ ipa_detect_param_modifications (struct cgraph_node *mt) tree stmt, parm_tree; struct ipa_node_params *info = IPA_NODE_REF (mt); - if (ipa_get_param_count (info) == 0) + if (ipa_get_param_count (info) == 0 || info->modified_flags) return; count = ipa_get_param_count (info); @@ -244,7 +257,7 @@ ipa_compute_jump_functions (struct cgraph_edge *cs) call_expr_arg_iterator iter; struct ipa_edge_args *args = IPA_EDGE_REF (cs); - if (ipa_get_cs_argument_count (args) == 0) + if (ipa_get_cs_argument_count (args) == 0 || args->jump_functions) return; args->jump_functions = XCNEWVEC (struct ipa_jump_func, ipa_get_cs_argument_count (args)); @@ -316,74 +329,184 @@ ipa_compute_jump_functions (struct cgraph_edge *cs) } } -/* Allocate and initialize ipa_node_params structure for the given cgraph - node. */ +/* Frees all dynamically allocated structures that the argument info points + to. */ void -ipa_create_node_params (struct cgraph_node *node) +ipa_free_edge_args_substructures (struct ipa_edge_args *args) { - node->aux = xcalloc (1, sizeof (struct ipa_node_params)); + if (args->jump_functions) + free (args->jump_functions); + + memset (args, 0, sizeof (*args)); } -/* Allocate and initialize ipa_node_params structure for all - nodes in callgraph. */ +/* Free all ipa_edge structures. */ void -ipa_create_all_node_params (void) +ipa_free_all_edge_args (void) { - struct cgraph_node *node; + int i; + struct ipa_edge_args *args; - for (node = cgraph_nodes; node; node = node->next) - ipa_create_node_params (node); + for (i = 0; + VEC_iterate (ipa_edge_args_t, ipa_edge_args_vector, i, args); + i++) + ipa_free_edge_args_substructures (args); + + VEC_free (ipa_edge_args_t, heap, ipa_edge_args_vector); + ipa_edge_args_vector = NULL; } -/* Allocate and initialize ipa_edge structure. */ +/* Frees all dynamically allocated structures that the param info points + to. */ void -ipa_create_all_edge_args (void) +ipa_free_node_params_substructures (struct ipa_node_params *info) { - struct cgraph_node *node; - struct cgraph_edge *cs; - - for (node = cgraph_nodes; node; node = node->next) - for (cs = node->callees; cs; cs = cs->next_callee) - cs->aux = xcalloc (1, sizeof (struct ipa_edge_args)); + if (info->ipcp_lattices) + free (info->ipcp_lattices); + if (info->param_decls) + free (info->param_decls); + if (info->modified_flags) + free (info->modified_flags); + + memset (info, 0, sizeof (*info)); } -/* Free ipa_edge structure. */ +/* Free all ipa_node_params structures. */ void -ipa_free_all_edge_args (void) +ipa_free_all_node_params (void) { - struct cgraph_node *node; - struct cgraph_edge *cs; + int i; + struct ipa_node_params *info; - for (node = cgraph_nodes; node; node = node->next) - for (cs = node->callees; cs; cs = cs->next_callee) - if (cs->aux) - { - if (IPA_EDGE_REF (cs)->jump_functions) - free (IPA_EDGE_REF (cs)->jump_functions); - free (cs->aux); - cs->aux = NULL; - } + for (i = 0; + VEC_iterate (ipa_node_params_t, ipa_node_params_vector, i, info); + i++) + ipa_free_node_params_substructures (info); + + VEC_free (ipa_node_params_t, heap, ipa_node_params_vector); + ipa_node_params_vector = NULL; +} + +/* Hook that is called by cgraph.c when an edge is removed. */ +static void +ipa_edge_removal_hook (struct cgraph_edge *cs, + void *data __attribute__ ((unused))) +{ + ipa_free_edge_args_substructures (IPA_EDGE_REF (cs)); } -/* Free ipa data structures of ipa_node_params and ipa_edge_args. */ +/* Hook that is called by cgraph.c when a node is removed. */ +static void +ipa_node_removal_hook (struct cgraph_node *node, + void *data __attribute__ ((unused))) +{ + ipa_free_node_params_substructures (IPA_NODE_REF (node)); +} + +/* Helper function to duplicate an array of size N that is at SRC and store a + pointer to it to DST. Nothing is done if SRC is NULL. */ +static void * +duplicate_array (void *src, size_t n) +{ + void *p; + + if (!src) + return NULL; + + p = xcalloc (1, n); + memcpy (p, src, n); + return p; +} + +/* Hook that is called by cgraph.c when a node is duplicated. */ +static void +ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, + void *data) +{ + struct ipa_edge_args *old_args, *new_args; + int arg_count; + + ipa_check_create_edge_args (); + + old_args = IPA_EDGE_REF (src); + new_args = IPA_EDGE_REF (dst); + + arg_count = ipa_get_cs_argument_count (old_args); + ipa_set_cs_argument_count (new_args, arg_count); + new_args->jump_functions = (struct ipa_jump_func *) + duplicate_array (old_args->jump_functions, + sizeof (struct ipa_jump_func) * arg_count); + data = data; /* Suppressing compiler warning. */ +} + +/* Hook that is called by cgraph.c when a node is duplicated. */ +static void +ipa_node_duplication_hook (struct cgraph_node *src, struct cgraph_node *dst, + void *data) +{ + struct ipa_node_params *old_info, *new_info; + int param_count; + + ipa_check_create_node_params (); + old_info = IPA_NODE_REF (src); + new_info = IPA_NODE_REF (dst); + param_count = ipa_get_param_count (old_info); + + ipa_set_param_count (new_info, param_count); + new_info->ipcp_lattices = (struct ipcp_lattice *) + duplicate_array (old_info->ipcp_lattices, + sizeof (struct ipcp_lattice) * param_count); + new_info->param_decls = (tree *) + duplicate_array (old_info->param_decls, sizeof (tree) * param_count); + new_info->modified_flags = (bool *) + duplicate_array (old_info->modified_flags, sizeof (bool) * param_count); + + new_info->ipcp_orig_node = old_info->ipcp_orig_node; + new_info->count_scale = old_info->count_scale; + + data = data; /* Suppressing compiler warning. */ +} + +/* Register our cgraph hooks if they are not already there. */ void -ipa_free_all_node_params (void) +ipa_register_cgraph_hooks (void) { - struct cgraph_node *node; + if (!edge_removal_hook_holder) + edge_removal_hook_holder = + cgraph_add_edge_removal_hook (&ipa_edge_removal_hook, NULL); + if (!node_removal_hook_holder) + node_removal_hook_holder = + cgraph_add_node_removal_hook (&ipa_node_removal_hook, NULL); + if (!edge_duplication_hook_holder) + edge_duplication_hook_holder = + cgraph_add_edge_duplication_hook (&ipa_edge_duplication_hook, NULL); + if (!node_duplication_hook_holder) + node_duplication_hook_holder = + cgraph_add_node_duplication_hook (&ipa_node_duplication_hook, NULL); +} - for (node = cgraph_nodes; node; node = node->next) - { - if (node->aux == NULL) - continue; - if (IPA_NODE_REF (node)->ipcp_lattices) - free (IPA_NODE_REF (node)->ipcp_lattices); - if (IPA_NODE_REF (node)->param_decls) - free (IPA_NODE_REF (node)->param_decls); - if (IPA_NODE_REF (node)->modified_flags) - free (IPA_NODE_REF (node)->modified_flags); - free (node->aux); - node->aux = NULL; - } +/* Unregister our cgraph hooks if they are not already there. */ +static void +ipa_unregister_cgraph_hooks (void) +{ + cgraph_remove_edge_removal_hook (edge_removal_hook_holder); + edge_removal_hook_holder = NULL; + cgraph_remove_node_removal_hook (node_removal_hook_holder); + node_removal_hook_holder = NULL; + cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder); + edge_duplication_hook_holder = NULL; + cgraph_remove_node_duplication_hook (node_duplication_hook_holder); + node_duplication_hook_holder = NULL; +} + +/* Free all ipa_node_params and all ipa_edge_args structures if they are no + longer needed after ipa-cp. */ +void +free_all_ipa_structures_after_ipa_cp (void) +{ + ipa_free_all_edge_args (); + ipa_free_all_node_params (); + ipa_unregister_cgraph_hooks (); } /* Print ipa_tree_map data structures of all functions in the diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index a81418d7f47..e442698bd3a 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #define IPA_PROP_H #include "tree.h" +#include "vec.h" /* The following definitions and interfaces are used by interprocedural analyses. */ @@ -100,14 +101,6 @@ struct ipa_replace_map bool ref_p; }; -/* Return the field in cgraph_node/cgraph_edge struct that points - to ipa_node_params/ipa_edge_args struct. */ -#define IPA_NODE_REF(MT) ((struct ipa_node_params *)(MT)->aux) -#define IPA_EDGE_REF(EDGE) ((struct ipa_edge_args *)(EDGE)->aux) -/* This macro checks validity of index returned by - ipa_get_param_decl_index function. */ -#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1) - /* ipa_node_params stores information related to formal parameters of functions and some other information for interprocedural passes that operate on parameters (such as ipa-cp). */ @@ -229,6 +222,71 @@ ipa_get_ith_jump_func (struct ipa_edge_args *args, int i) return &args->jump_functions[i]; } +/* Vectors need to have typedefs of structures. */ +typedef struct ipa_node_params ipa_node_params_t; +typedef struct ipa_edge_args ipa_edge_args_t; + +/* Types of vectors hodling the infos. */ +DEF_VEC_O (ipa_node_params_t); +DEF_VEC_ALLOC_O (ipa_node_params_t, heap); +DEF_VEC_O (ipa_edge_args_t); +DEF_VEC_ALLOC_O (ipa_edge_args_t, heap); + +/* Vector where the parameter infos are actually stored. */ +extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector; +/* Vector where the parameter infos are actually stored. */ +extern VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector; + +/* Return the associated parameter/argument info corresponding to the given + node/edge. */ +#define IPA_NODE_REF(NODE) (VEC_index (ipa_node_params_t, \ + ipa_node_params_vector, (NODE)->uid)) +#define IPA_EDGE_REF(EDGE) (VEC_index (ipa_edge_args_t, \ + ipa_edge_args_vector, (EDGE)->uid)) +/* This macro checks validity of index returned by + ipa_get_param_decl_index function. */ +#define IS_VALID_JUMP_FUNC_INDEX(I) ((I) != -1) + +/* Creating and freeing ipa_node_params and ipa_edge_args. */ +void ipa_create_all_node_params (void); +void ipa_create_all_edge_args (void); +void ipa_free_edge_args_substructures (struct ipa_edge_args *); +void ipa_free_node_params_substructures (struct ipa_node_params *); +void ipa_free_all_node_params (void); +void ipa_free_all_edge_args (void); +void free_all_ipa_structures_after_ipa_cp (void); +void ipa_register_cgraph_hooks (void); + +/* This function ensures the array of node param infos is big enough to + accomdate a structure for all nodes and realloacates it if not. */ +static inline void +ipa_check_create_node_params (void) +{ + if (!ipa_node_params_vector) + ipa_node_params_vector = VEC_alloc (ipa_node_params_t, heap, + cgraph_max_uid); + + if (VEC_length (ipa_node_params_t, ipa_node_params_vector) + <= (unsigned) cgraph_max_uid) + VEC_safe_grow_cleared (ipa_node_params_t, heap, + ipa_node_params_vector, cgraph_max_uid + 1); +} + +/* This function ensures the array of adge arguments infos is big enough to + accomdate a structure for all edges and realloacates it if not. */ +static inline void +ipa_check_create_edge_args (void) +{ + if (!ipa_edge_args_vector) + ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, heap, + cgraph_edge_max_uid); + + if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector) + <= (unsigned) cgraph_edge_max_uid) + VEC_safe_grow_cleared (ipa_edge_args_t, heap, ipa_edge_args_vector, + cgraph_edge_max_uid + 1); +} + /* A function list element. It is used to create a temporary worklist used in the propagation stage of IPCP. (can be used for more IPA optimizations) */ struct ipa_func_list @@ -251,13 +309,6 @@ void ipa_count_formal_params (struct cgraph_node *); void ipa_create_param_decls_array (struct cgraph_node *); void ipa_detect_param_modifications (struct cgraph_node *); -/* Creating and freeing ipa_node_params and ipa_edge_args. */ -void ipa_create_node_params (struct cgraph_node *); -void ipa_free_all_node_params (void); -void ipa_create_all_node_params (void); -void ipa_create_all_edge_args (void); -void ipa_free_all_edge_args (void); - /* Debugging interface. */ void ipa_print_all_tree_maps (FILE *); void ipa_print_all_params_modified (FILE *); diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index a8ae772a66e..f0f57e76390 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,8 @@ +2008-07-06 Tom Tromey <tromey@redhat.com> + + * Make-lang.in (java/parse.o-warn): Remove. + (java/jcf-io.o-warn): Remove. + 2008-07-05 Tom Tromey <tromey@redhat.com> * jcf-io.c: Don't include fnmatch.h. Don't use JCF_USE_SCANDIR. diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in index cab40afb959..6f0c4179f97 100644 --- a/gcc/java/Make-lang.in +++ b/gcc/java/Make-lang.in @@ -98,12 +98,6 @@ java-warn = $(STRICT_WARN) # String length warnings jvspec.o-warn = -Wno-error -# Bison-1.75 output often yields (harmless) -Wtraditional warnings -java/parse.o-warn = -Wno-error - -# java/jcf-io.c contains a -Wc++compat warning. -java/jcf-io.o-warn = -Wno-error - jc1$(exeext): $(JAVA_OBJS) $(BACKEND) $(LIBDEPS) attribs.o rm -f $@ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 841f216c136..f73e0443f8a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,75 @@ +2008-07-07 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.dg/compat/struct-layout-1_generate.c (vector_types): Add + v32qi, v16hi, v8si, v4di, v8sf, v4df, u32qi, u16hi, u8si, u4di, + u8sf and u4df. + + * gcc.dg/compat/union-m128-1_main.c: Run only on x86. Remove + __x86_64__ check. Include "cpuid.h". + (main): Check SSE2 at runtime. + + * gcc.dg/compat/union-m128-1_x.c: Compile with -msse2. Remove + __x86_64__ check. + * gcc.dg/compat/union-m128-1_y.c: Likewise. + + * gcc.dg/compat/vector-1_x.c: Add 32byte vector tests. + * gcc.dg/compat/vector-1_y.c: Likewise. + * gcc.dg/compat/vector-2_x.c: Likewise. + * gcc.dg/compat/vector-2_y.c: Likewise. + + * gcc.dg/compat/vector-1a_main.c: New. + * gcc.dg/compat/vector-1a_x.c: Likewise. + * gcc.dg/compat/vector-1a_y.c: Likewise. + * gcc.dg/compat/vector-2a_main.c: Likewise. + * gcc.dg/compat/vector-2a_x.c: Likewise. + * gcc.dg/compat/vector-2a_y.c: Likewise. + + * gcc.dg/compat/vector-defs.h (v32qi): New. + (v16hi): Likewise. + (v8si): Likewise. + (v4di): Likewise. + (v8sf): Likewise. + (v4df): Likewise. + (u32qi): Likewise. + (u16hi): Likewise. + (u8si): Likewise. + (u4di): Likewise. + (u8sf): Likewise. + (u4df): Likewise. + + * lib/compat.exp (compat-get-options-main): Support dg-skip-if. + +2008-07-07 Andy Hutchinson <hutchinsonandy@aim.com> + + * gcc.c-torture/compile/20080625-1.c: Skip for AVR target. + * gcc.dg/torture/pr36373-10.c: Correct test where target pointer + is not same size as unsigned long. + +2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/36670 + * gfortran.dg/product_sum_bounds_1.f90: New test case. + +2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/36341 + PR fortran/34670 + * gfortran.dg/matmul_bounds_2.f90: New test. + * gfortran.dg/matmul_bounds_3.f90: New test. + * gfortran.dg/matmul_bounds_4.f90: New test. + * gfortran.dg/matmul_bounds_5.f90: New test. + +2008-07-07 Richard Guenther <rguenther@suse.de> + + * gcc.dg/torture/pta-ptrarith-1.c: New testcase. + * gcc.dg/torture/pta-ptrarith-2.c: Likewise. + * gcc.dg/torture/ipa-pta-1.c: Likewise. + +2008-07-07 Jakub Jelinek <jakub@redhat.com> + + PR middle-end/36726 + * gfortran.dg/gomp/pr36726.f90: New test. + 2008-07-06 Richard Sandiford <rdsandiford@googlemail.com> * gcc.target/mips/gcc-have-sync-compare-and-swap-1.c: Expect the diff --git a/gcc/testsuite/gcc.c-torture/compile/20080625-1.c b/gcc/testsuite/gcc.c-torture/compile/20080625-1.c index f0900fd9693..226bea1ffae 100644 --- a/gcc/testsuite/gcc.c-torture/compile/20080625-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/20080625-1.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "too much data" { "avr-*-*" } { "*" } { "" } } */ struct peakbufStruct { unsigned int lnum [5000]; int lscan [5000][4000]; diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c index c53c3e8c2bd..f6a217e6f56 100644 --- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c +++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c @@ -186,30 +186,42 @@ struct types vector_types[] = { /* vector-defs.h typedefs */ { "v8qi", TYPE_OTHER, 0, 0 }, { "v16qi", TYPE_OTHER, 0, 0 }, +{ "v32qi", TYPE_OTHER, 0, 0 }, { "v2hi", TYPE_OTHER, 0, 0 }, { "v4hi", TYPE_OTHER, 0, 0 }, { "v8hi", TYPE_OTHER, 0, 0 }, +{ "v16hi", TYPE_OTHER, 0, 0 }, { "v2si", TYPE_OTHER, 0, 0 }, { "v4si", TYPE_OTHER, 0, 0 }, +{ "v8si", TYPE_OTHER, 0, 0 }, { "v1di", TYPE_OTHER, 0, 0 }, { "v2di", TYPE_OTHER, 0, 0 }, +{ "v4di", TYPE_OTHER, 0, 0 }, { "v2sf", TYPE_OTHER, 0, 0 }, { "v4sf", TYPE_OTHER, 0, 0 }, +{ "v8sf", TYPE_OTHER, 0, 0 }, { "v16sf", TYPE_OTHER, 0, 0 }, { "v2df", TYPE_OTHER, 0, 0 }, +{ "v4df", TYPE_OTHER, 0, 0 }, { "u8qi", TYPE_OTHER, 0, 0 }, { "u16qi", TYPE_OTHER, 0, 0 }, +{ "u32qi", TYPE_OTHER, 0, 0 }, { "u2hi", TYPE_OTHER, 0, 0 }, { "u4hi", TYPE_OTHER, 0, 0 }, { "u8hi", TYPE_OTHER, 0, 0 }, +{ "u16hi", TYPE_OTHER, 0, 0 }, { "u2si", TYPE_OTHER, 0, 0 }, { "u4si", TYPE_OTHER, 0, 0 }, +{ "u8si", TYPE_OTHER, 0, 0 }, { "u1di", TYPE_OTHER, 0, 0 }, { "u2di", TYPE_OTHER, 0, 0 }, +{ "u4di", TYPE_OTHER, 0, 0 }, { "u2sf", TYPE_OTHER, 0, 0 }, { "u4sf", TYPE_OTHER, 0, 0 }, +{ "u8sf", TYPE_OTHER, 0, 0 }, { "u16sf", TYPE_OTHER, 0, 0 }, { "u2df", TYPE_OTHER, 0, 0 }, +{ "u4df", TYPE_OTHER, 0, 0 }, { "__m64", TYPE_OTHER, 0, 0 }, { "__m128", TYPE_OTHER, 0, 0 } #define NVTYPES2 (sizeof (vector_types) / sizeof (vector_types[0])) diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c index 69dd34dce57..11f872154eb 100644 --- a/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c +++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_main.c @@ -1,6 +1,8 @@ +/* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */ /* { dg-options "-O" } */ -#ifdef __x86_64__ +#include "cpuid.h" + /* Test function argument passing. PR target/15301. */ extern void union_m128_1_x (void); @@ -9,13 +11,14 @@ extern void exit (int); int main () { - union_m128_1_x (); + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + /* Run SSE vector test only if host has SSE2 support. */ + if (edx & bit_SSE2) + union_m128_1_x (); + exit (0); } -#else -int -main () -{ - return 0; -} -#endif diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c index 06a4ef5ffdb..1f92303d95b 100644 --- a/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c +++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_x.c @@ -1,6 +1,5 @@ -/* { dg-options "-O" } */ +/* { dg-options "-O -msse2" } */ -#ifdef __x86_64__ #include "union-m128-1.h" SS_union_mi128 un; @@ -23,7 +22,3 @@ union_m128_1_x () foo(un); foo(st); } -#else -int dummy_x; -#endif - diff --git a/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c b/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c index 2b6eb0a6ee8..be9d6e8f3d5 100644 --- a/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c +++ b/gcc/testsuite/gcc.dg/compat/union-m128-1_y.c @@ -1,6 +1,5 @@ -/* { dg-options "-O" } */ +/* { dg-options "-O -msse2" } */ -#ifdef __x86_64__ #include <stdlib.h> #include "union-m128-1.h" @@ -26,7 +25,3 @@ foo (SS_struct_mi128 st) || x.u [1] != 0xfedcba9876543210LL) abort (); } -#else -int dummy_y; -#endif - diff --git a/gcc/testsuite/gcc.dg/compat/vector-1_x.c b/gcc/testsuite/gcc.dg/compat/vector-1_x.c index 11995b496e5..ab4f88bf48b 100644 --- a/gcc/testsuite/gcc.dg/compat/vector-1_x.c +++ b/gcc/testsuite/gcc.dg/compat/vector-1_x.c @@ -8,13 +8,17 @@ SETUP (8, qi); SETUP (16, qi); +SETUP (32, qi); SETUP (2, hi); SETUP (4, hi); SETUP (8, hi); +SETUP (16, hi); SETUP (2, si); SETUP (4, si); +SETUP (8, si); SETUP (1, di); SETUP (2, di); +SETUP (4, di); #endif @@ -26,13 +30,17 @@ vector_1_x (void) CHECK (8, qi); CHECK (16, qi); + CHECK (32, qi); CHECK (2, hi); CHECK (4, hi); CHECK (8, hi); + CHECK (16, hi); CHECK (2, si); CHECK (4, si); + CHECK (8, si); CHECK (1, di); CHECK (2, di); + CHECK (4, di); DEBUG_FINI diff --git a/gcc/testsuite/gcc.dg/compat/vector-1_y.c b/gcc/testsuite/gcc.dg/compat/vector-1_y.c index 1cec61734b4..5a09c0eadb6 100644 --- a/gcc/testsuite/gcc.dg/compat/vector-1_y.c +++ b/gcc/testsuite/gcc.dg/compat/vector-1_y.c @@ -8,12 +8,16 @@ TEST (8, qi, 101) TEST (16, qi, 101) +TEST (32, qi, 90) TEST (2, hi, 201) TEST (4, hi, 202) TEST (8, hi, 203) +TEST (16, hi, 203) TEST (2, si, 301) TEST (4, si, 302) +TEST (8, si, 303) TEST (1, di, 401) TEST (2, di, 402) +TEST (4, di, 403) #endif diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_main.c b/gcc/testsuite/gcc.dg/compat/vector-1a_main.c new file mode 100644 index 00000000000..76fb2915e1d --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/vector-1a_main.c @@ -0,0 +1,26 @@ +/* { dg-skip-if "test SSE2 vector" { ! { i?86-*-* x86_64-*-* } } } */ + +/* Test compatibility of vector types: layout between separately-compiled + modules, parameter passing, and function return. This test uses + vectors of integer values. */ + +#include "cpuid.h" + +extern void vector_1_x (void); +extern void exit (int); +int fails; + +int +main () +{ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + /* Run SSE vector test only if host has SSE2 support. */ + if (edx & bit_SSE2) + vector_1_x (); + + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_x.c b/gcc/testsuite/gcc.dg/compat/vector-1a_x.c new file mode 100644 index 00000000000..aa0fa7f208c --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/vector-1a_x.c @@ -0,0 +1,3 @@ +/* { dg-options "-w -mno-mmx -msse2" } */ + +#include "vector-1_x.c" diff --git a/gcc/testsuite/gcc.dg/compat/vector-1a_y.c b/gcc/testsuite/gcc.dg/compat/vector-1a_y.c new file mode 100644 index 00000000000..2c88e198845 --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/vector-1a_y.c @@ -0,0 +1,3 @@ +/* { dg-options "-w -mno-mmx -msse2" } */ + +#include "vector-1_y.c" diff --git a/gcc/testsuite/gcc.dg/compat/vector-2_x.c b/gcc/testsuite/gcc.dg/compat/vector-2_x.c index de5f29c2688..d08c77fe3a0 100644 --- a/gcc/testsuite/gcc.dg/compat/vector-2_x.c +++ b/gcc/testsuite/gcc.dg/compat/vector-2_x.c @@ -10,7 +10,9 @@ SETUP (2, sf); SETUP (4, sf); SETUP (16, sf); +SETUP (8, sf); SETUP (2, df); +SETUP (4, df); #endif @@ -22,7 +24,9 @@ vector_2_x (void) CHECK (2, sf); CHECK (4, sf); + CHECK (8, sf); CHECK (16, sf); + CHECK (4, df); CHECK (2, df); DEBUG_FINI diff --git a/gcc/testsuite/gcc.dg/compat/vector-2_y.c b/gcc/testsuite/gcc.dg/compat/vector-2_y.c index 10d7a064532..fd5830c35b3 100644 --- a/gcc/testsuite/gcc.dg/compat/vector-2_y.c +++ b/gcc/testsuite/gcc.dg/compat/vector-2_y.c @@ -9,7 +9,9 @@ TEST (2, sf, 301.0) TEST (4, sf, 302.0) +TEST (8, sf, 303.0) TEST (16, sf, 304.0) TEST (2, df, 402.0) +TEST (4, df, 402.0) #endif diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_main.c b/gcc/testsuite/gcc.dg/compat/vector-2a_main.c new file mode 100644 index 00000000000..96c1111fddc --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/vector-2a_main.c @@ -0,0 +1,26 @@ +/* { dg-skip-if "test SSE2 support" { ! { i?86-*-* x86_64-*-* } } } */ + +/* Test compatibility of vector types: layout between separately-compiled + modules, parameter passing, and function return. This test uses + vectors of floating points values. */ + +#include "cpuid.h" + +extern void vector_2_x (void); +extern void exit (int); +int fails; + +int +main () +{ + unsigned int eax, ebx, ecx, edx; + + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) + return 0; + + /* Run SSE vector test only if host has SSE2 support. */ + if (edx & bit_SSE2) + vector_2_x (); + + exit (0); +} diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_x.c b/gcc/testsuite/gcc.dg/compat/vector-2a_x.c new file mode 100644 index 00000000000..fcfacec04e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/vector-2a_x.c @@ -0,0 +1,3 @@ +/* { dg-options "-w -mno-mmx -msse2" } */ + +#include "vector-2_x.c" diff --git a/gcc/testsuite/gcc.dg/compat/vector-2a_y.c b/gcc/testsuite/gcc.dg/compat/vector-2a_y.c new file mode 100644 index 00000000000..3797acb6a57 --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/vector-2a_y.c @@ -0,0 +1,3 @@ +/* { dg-options "-w -mno-mmx -msse2" } */ + +#include "vector-2_y.c" diff --git a/gcc/testsuite/gcc.dg/compat/vector-defs.h b/gcc/testsuite/gcc.dg/compat/vector-defs.h index 7574e28c53d..f2f050527ec 100644 --- a/gcc/testsuite/gcc.dg/compat/vector-defs.h +++ b/gcc/testsuite/gcc.dg/compat/vector-defs.h @@ -56,6 +56,20 @@ typedef float __attribute__((mode(V2DF))) v2df; #endif +typedef qi __attribute__((vector_size (32))) v32qi; +typedef hi __attribute__((vector_size (32))) v16hi; +typedef si __attribute__((vector_size (32))) v8si; +typedef di __attribute__((vector_size (32))) v4di; +typedef sf __attribute__((vector_size (32))) v8sf; +typedef df __attribute__((vector_size (32))) v4df; + +typedef union U32QI { v32qi v; qi a[32]; } u32qi; +typedef union U16HI { v16hi v; hi a[16]; } u16hi; +typedef union U8SI { v8si v; si a[8]; } u8si; +typedef union U4DI { v4di v; di a[4]; } u4di; +typedef union U8SF { v8sf v; sf a[8]; } u8sf; +typedef union U4DF { v4df v; df a[4]; } u4df; + typedef union U8QI { v8qi v; qi a[8]; } u8qi; typedef union U16QI { v16qi v; qi a[16]; } u16qi; diff --git a/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c new file mode 100644 index 00000000000..c5adb259d26 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/ipa-pta-1.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-fipa-pta -fdump-ipa-pta" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +struct X { char x; char y; }; + +void bar (char *p); + +void test1 (char a, char b, char c, char d, char e, char f, char g, char h) +{ + char *p = &a; + p++; + bar (p); +} + +void test2 (struct X a, char b, char c, char d, char e, char f, char g, char h) +{ + char *p = &a.x; + p++; + bar (p); +} + +void test3 (struct X a, char b, char c, char d, char e, char f, char g, char h) +{ + char *p = &a.y; + bar (p); +} + +void test4 (int a, char b, char c, char d, char e, char f, char g, char h) +{ + char *p = (char *)&a; + p++; + p++; + p++; + p++; + bar (p); +} + +/* { dg-final { scan-ipa-dump "bar.arg0 = { test4.arg0 test3.arg0 test2.arg0 test1.arg0 }" "pta" } } */ +/* { dg-final { cleanup-ipa-dump "pta" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr36373-10.c b/gcc/testsuite/gcc.dg/torture/pr36373-10.c index b84e2544152..ed701772828 100644 --- a/gcc/testsuite/gcc.dg/torture/pr36373-10.c +++ b/gcc/testsuite/gcc.dg/torture/pr36373-10.c @@ -1,6 +1,14 @@ /* { dg-do run } */ +#if (__SIZEOF_LONG_LONG__ == __SIZEOF_POINTER__) +typedef unsigned long long uintptr_t; +#elif (__SIZEOF_LONG__ == __SIZEOF_POINTER__) typedef unsigned long uintptr_t; +#elif (__SIZEOF_INT__ == __SIZEOF_POINTER__) +typedef unsigned int uintptr_t; +#else +#error Add target support here +#endif void __attribute__((noinline)) foo(uintptr_t l) diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c new file mode 100644 index 00000000000..2a8dc9e3037 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-options "-fdump-tree-alias" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +struct Foo { + int *p; +}; + +void __attribute__((noinline)) +foo (void *p) +{ + struct Foo *f = (struct Foo *)p - 1; + *f->p = 0; +} + +int bar (void) +{ + struct Foo f; + int i = 1; + f.p = &i; + foo (&f + 1); + return i; +} +extern void abort (void); +int main() +{ + if (bar () != 0) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL f .* i }" "alias" } } */ +/* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c new file mode 100644 index 00000000000..fb5b2e15ede --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-2.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ +/* { dg-options "-fdump-tree-alias" } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ + +struct Foo { + int **p; + int **q; +}; + +int __attribute__((noinline)) +bar (void) +{ + struct Foo f; + int j, i = 1; + char *p; + int *x = &i; + int *y = &j; + f.p = &y; + f.q = &x; + p = (char *)&f; + for (j = 0; j < sizeof (int *); ++j) + p++; + return ***(int ***)p; +} +extern void abort (void); +int main() +{ + if (bar () != 1) + abort (); + return 0; +} + +/* In theory = { i } is the correct solution. But it's not easy to scan + for that reliably, so just use what we create now. */ +/* { dg-final { scan-tree-dump "= { i j }" "alias" } } */ +/* { dg-final { cleanup-tree-dump "alias" } } */ diff --git a/gcc/testsuite/gfortran.dg/gomp/pr36726.f90 b/gcc/testsuite/gfortran.dg/gomp/pr36726.f90 new file mode 100644 index 00000000000..99e170ad798 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/gomp/pr36726.f90 @@ -0,0 +1,20 @@ +! PR middle-end/36726 +! { dg-do compile } +! { dg-options "-fopenmp" } + +subroutine foo + integer, allocatable :: vs(:) + !$omp parallel private (vs) + allocate (vs(10)) + vs = 2 + deallocate (vs) + !$omp end parallel +end subroutine foo +subroutine bar + integer, allocatable :: vs(:) + !$omp parallel private (vs) + allocate (vs(10)) + vs = 2 + deallocate (vs) + !$omp end parallel +end subroutine bar diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90 new file mode 100644 index 00000000000..429b28c3016 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/matmul_bounds_2.f90 @@ -0,0 +1,16 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } +! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 2: is 2, should be 3" } +program main + real, dimension(3,2) :: a + real, dimension(2,3) :: b + real, dimension(:,:), allocatable :: ret + allocate (ret(2,2)) + a = 1.0 + b = 2.3 + ret = matmul(b,a) ! This is OK + deallocate(ret) + allocate(ret(3,2)) + ret = matmul(a,b) ! This should throw an error. +end program main +! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 2: is 2, should be 3" } diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90 new file mode 100644 index 00000000000..c5830ded729 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/matmul_bounds_3.f90 @@ -0,0 +1,16 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } +! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 1: is 2, should be 3" } +program main + real, dimension(3,2) :: a + real, dimension(2,3) :: b + real, dimension(:,:), allocatable :: ret + allocate (ret(3,3)) + a = 1.0 + b = 2.3 + ret = matmul(a,b) ! This is OK + deallocate(ret) + allocate(ret(2,3)) + ret = matmul(a,b) ! This should throw an error. +end program main +! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic for dimension 1: is 2, should be 3" } diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90 new file mode 100644 index 00000000000..a61bacc1d2b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/matmul_bounds_4.f90 @@ -0,0 +1,16 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } +! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" } +program main + real, dimension(3) :: a + real, dimension(3,2) :: b + real, dimension(:), allocatable :: ret + allocate (ret(2)) + a = 1.0 + b = 2.3 + ret = matmul(a,b) ! This is OK + deallocate(ret) + allocate(ret(3)) + ret = matmul(a,b) ! This should throw an error. +end program main +! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" } diff --git a/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90 b/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90 new file mode 100644 index 00000000000..4b20098f50f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/matmul_bounds_5.f90 @@ -0,0 +1,16 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } +! { dg-shouldfail "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" } +program main + real, dimension(2,3) :: a + real, dimension(3) :: b + real, dimension(:), allocatable :: ret + allocate (ret(2)) + a = 1.0 + b = 2.3 + ret = matmul(a,b) ! This is OK + deallocate(ret) + allocate(ret(3)) + ret = matmul(a,b) ! This should throw an error. +end program main +! { dg-output "Fortran runtime error: Incorrect extent in return array in MATMUL intrinsic: is 3, should be 2" } diff --git a/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90 b/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90 new file mode 100644 index 00000000000..c6390896c17 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/product_sum_bounds_1.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +program main + real, dimension(4,3) :: a + real, dimension(2) :: b + a = 21. + b = product(a,dim=1) ! { dg-error "Different shape" } + b = sum(a,dim=2) ! { dg-error "Different shape" } +end program main diff --git a/gcc/testsuite/lib/compat.exp b/gcc/testsuite/lib/compat.exp index 84538a6f8b4..ee7cff56fbe 100644 --- a/gcc/testsuite/lib/compat.exp +++ b/gcc/testsuite/lib/compat.exp @@ -156,6 +156,8 @@ proc compat-run { testname objlist dest optall optfile optstr } { proc compat-get-options-main { src } { # dg-options sets a variable called dg-extra-tool-flags. set dg-extra-tool-flags "" + # dg-options sets a variable called tool_flags. + set tool_flags "" # dg-require-* sets dg-do-what. upvar dg-do-what dg-do-what @@ -164,6 +166,7 @@ proc compat-get-options-main { src } { foreach op $tmp { set cmd [lindex $op 0] if { ![string compare "dg-options" $cmd] \ + || [string match "dg-skip-if" $cmd] \ || [string match "dg-require-*" $cmd] } { set status [catch "$op" errmsg] if { $status != 0 } { diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c index b7363c377c0..7cc0285ff48 100644 --- a/gcc/tree-dump.c +++ b/gcc/tree-dump.c @@ -814,6 +814,7 @@ static const struct dump_option_value_info dump_options[] = {"address", TDF_ADDRESS}, {"slim", TDF_SLIM}, {"raw", TDF_RAW}, + {"graph", TDF_GRAPH}, {"details", TDF_DETAILS}, {"stats", TDF_STATS}, {"blocks", TDF_BLOCKS}, diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index bff697db5ae..19a3002dfda 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -881,7 +881,15 @@ factoring_name_p (const_tree name) return TREE_CODE (SSA_NAME_VAR (name)) == MEMORY_PARTITION_TAG; } -/* Return true if VAR is a clobbered by function calls. */ +/* Return true if VAR is used by function calls. */ +static inline bool +is_call_used (const_tree var) +{ + return (var_ann (var)->call_clobbered + || bitmap_bit_p (gimple_call_used_vars (cfun), DECL_UID (var))); +} + +/* Return true if VAR is clobbered by function calls. */ static inline bool is_call_clobbered (const_tree var) { diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index 13febcaf79b..cdf6c3fd9e6 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -265,7 +265,7 @@ dest_safe_for_nrv_p (tree dest) if (TREE_CODE (dest) == SSA_NAME) dest = SSA_NAME_VAR (dest); - if (is_call_clobbered (dest)) + if (is_call_used (dest)) return false; return true; diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 40c1d3f9c3b..21f362b9059 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -128,6 +128,8 @@ create_temp (tree t) set_symbol_mem_tag (tmp, symbol_mem_tag (t)); if (is_call_clobbered (t)) mark_call_clobbered (tmp, var_ann (t)->escape_mask); + if (bitmap_bit_p (gimple_call_used_vars (cfun), DECL_UID (t))) + bitmap_set_bit (gimple_call_used_vars (cfun), DECL_UID (tmp)); return tmp; } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index ee0f4a7316a..d4a1e219a0c 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2316,7 +2316,6 @@ compute_flow_sensitive_aliasing (struct alias_info *ai) tree ptr; timevar_push (TV_FLOW_SENSITIVE); - set_used_smts (); for (i = 0; VEC_iterate (tree, ai->processed_ptrs, i, ptr); i++) { diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 266538c8b60..6121437b245 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -220,6 +220,9 @@ struct variable_info /* True for variables whose size is not known or variable. */ unsigned int is_unknown_size_var:1; + /* True for (sub-)fields that represent a whole variable. */ + unsigned int is_full_var : 1; + /* True if this is a heap variable. */ unsigned int is_heap_var:1; @@ -373,6 +376,7 @@ new_var_info (tree t, unsigned int id, const char *name) ret->is_heap_var = false; ret->is_special_var = false; ret->is_unknown_size_var = false; + ret->is_full_var = false; var = t; if (TREE_CODE (var) == SSA_NAME) var = SSA_NAME_VAR (var); @@ -620,6 +624,96 @@ debug_constraints (void) dump_constraints (stderr); } +/* Print out to FILE the edge in the constraint graph that is created by + constraint c. The edge may have a label, depending on the type of + constraint that it represents. If complex1, e.g: a = *b, then the label + is "=*", if complex2, e.g: *a = b, then the label is "*=", if + complex with an offset, e.g: a = b + 8, then the label is "+". + Otherwise the edge has no label. */ + +void +dump_constraint_edge (FILE *file, constraint_t c) +{ + if (c->rhs.type != ADDRESSOF) + { + const char *src = get_varinfo_fc (c->rhs.var)->name; + const char *dst = get_varinfo_fc (c->lhs.var)->name; + fprintf (file, " \"%s\" -> \"%s\" ", src, dst); + /* Due to preprocessing of constraints, instructions like *a = *b are + illegal; thus, we do not have to handle such cases. */ + if (c->lhs.type == DEREF) + fprintf (file, " [ label=\"*=\" ] ;\n"); + else if (c->rhs.type == DEREF) + fprintf (file, " [ label=\"=*\" ] ;\n"); + else + { + /* We must check the case where the constraint is an offset. + In this case, it is treated as a complex constraint. */ + if (c->rhs.offset != c->lhs.offset) + fprintf (file, " [ label=\"+\" ] ;\n"); + else + fprintf (file, " ;\n"); + } + } +} + +/* Print the constraint graph in dot format. */ + +void +dump_constraint_graph (FILE *file) +{ + unsigned int i=0, size; + constraint_t c; + + /* Only print the graph if it has already been initialized: */ + if (!graph) + return; + + /* Print the constraints used to produce the constraint graph. The + constraints will be printed as comments in the dot file: */ + fprintf (file, "\n\n/* Constraints used in the constraint graph:\n"); + dump_constraints (file); + fprintf (file, "*/\n"); + + /* Prints the header of the dot file: */ + fprintf (file, "\n\n// The constraint graph in dot format:\n"); + fprintf (file, "strict digraph {\n"); + fprintf (file, " node [\n shape = box\n ]\n"); + fprintf (file, " edge [\n fontsize = \"12\"\n ]\n"); + fprintf (file, "\n // List of nodes in the constraint graph:\n"); + + /* The next lines print the nodes in the graph. In order to get the + number of nodes in the graph, we must choose the minimum between the + vector VEC (varinfo_t, varmap) and graph->size. If the graph has not + yet been initialized, then graph->size == 0, otherwise we must only + read nodes that have an entry in VEC (varinfo_t, varmap). */ + size = VEC_length (varinfo_t, varmap); + size = size < graph->size ? size : graph->size; + for (i = 0; i < size; i++) + { + const char *name = get_varinfo_fc (graph->rep[i])->name; + fprintf (file, " \"%s\" ;\n", name); + } + + /* Go over the list of constraints printing the edges in the constraint + graph. */ + fprintf (file, "\n // The constraint edges:\n"); + for (i = 0; VEC_iterate (constraint_t, constraints, i, c); i++) + if (c) + dump_constraint_edge (file, c); + + /* Prints the tail of the dot file. By now, only the closing bracket. */ + fprintf (file, "}\n\n\n"); +} + +/* Print out the constraint graph to stderr. */ + +void +debug_constraint_graph (void) +{ + dump_constraint_graph (stderr); +} + /* SOLVER FUNCTIONS The solver is a simple worklist solver, that works on the following @@ -752,22 +846,32 @@ solution_set_add (bitmap set, unsigned HOST_WIDE_INT offset) EXECUTE_IF_SET_IN_BITMAP (set, 0, i, bi) { - /* If this is a properly sized variable, only add offset if it's - less than end. Otherwise, it is globbed to a single - variable. */ + varinfo_t vi = get_varinfo (i); - if ((get_varinfo (i)->offset + offset) < get_varinfo (i)->fullsize) + /* If this is a variable with just one field just set its bit + in the result. */ + if (vi->is_artificial_var + || vi->is_unknown_size_var + || vi->is_full_var) + bitmap_set_bit (result, i); + else { - unsigned HOST_WIDE_INT fieldoffset = get_varinfo (i)->offset + offset; - varinfo_t v = first_vi_for_offset (get_varinfo (i), fieldoffset); + unsigned HOST_WIDE_INT fieldoffset = vi->offset + offset; + varinfo_t v = first_vi_for_offset (vi, fieldoffset); + /* If the result is outside of the variable use the last field. */ if (!v) - continue; + { + v = vi; + while (v->next != NULL) + v = v->next; + } bitmap_set_bit (result, v->id); - } - else if (get_varinfo (i)->is_artificial_var - || get_varinfo (i)->is_unknown_size_var) - { - bitmap_set_bit (result, i); + /* If the result is not exactly at fieldoffset include the next + field as well. See get_constraint_for_ptr_offset for more + rationale. */ + if (v->offset != fieldoffset + && v->next != NULL) + bitmap_set_bit (result, v->next->id); } } @@ -1375,7 +1479,8 @@ type_safe (unsigned int n, unsigned HOST_WIDE_INT *offset) 0. */ if (ninfo->is_special_var || ninfo->is_artificial_var - || ninfo->is_unknown_size_var) + || ninfo->is_unknown_size_var + || ninfo->is_full_var) { *offset = 0; return true; @@ -1415,7 +1520,11 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c, sub-fields off. This avoids quadratic behavior. */ EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi) { - varinfo_t v = lookup_vi_for_tree (get_varinfo (j)->decl); + varinfo_t v = get_varinfo (j); + if (v->is_full_var) + continue; + + v = lookup_vi_for_tree (v->decl); if (v->next != NULL) { if (vars == NULL) @@ -1455,6 +1564,7 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c, unsigned int t; v = first_vi_for_offset (get_varinfo (j), fieldoffset); + /* If the access is outside of the variable we can ignore it. */ if (!v) continue; t = find (v->id); @@ -1507,9 +1617,14 @@ do_ds_constraint (constraint_t c, bitmap delta) unsigned HOST_WIDE_INT fieldoffset = jvi->offset + loff; varinfo_t v; - v = first_vi_for_offset (get_varinfo (j), fieldoffset); - if (!v) - continue; + v = get_varinfo (j); + if (!v->is_full_var) + { + v = first_vi_for_offset (v, fieldoffset); + /* If the access is outside of the variable we can ignore it. */ + if (!v) + continue; + } t = find (v->id); if (bitmap_set_bit (get_varinfo (t)->solution, anything_id) @@ -1535,6 +1650,7 @@ do_ds_constraint (constraint_t c, bitmap delta) bitmap tmp; v = first_vi_for_offset (get_varinfo (j), fieldoffset); + /* If the access is outside of the variable we can ignore it. */ if (!v) continue; t = find (v->id); @@ -2597,12 +2713,6 @@ process_constraint (constraint_t t) gcc_assert (rhs.var < VEC_length (varinfo_t, varmap)); gcc_assert (lhs.var < VEC_length (varinfo_t, varmap)); - if (!use_field_sensitive) - { - t->rhs.offset = 0; - t->lhs.offset = 0; - } - /* ANYTHING == ANYTHING is pointless. */ if (lhs.var == anything_id && rhs.var == anything_id) return; @@ -2678,6 +2788,119 @@ bitpos_of_field (const tree fdecl) } +/* Get constraint expressions for offsetting PTR by OFFSET. Stores the + resulting constraint expressions in *RESULTS. */ + +static void +get_constraint_for_ptr_offset (tree ptr, tree offset, + VEC (ce_s, heap) **results) +{ + struct constraint_expr *c; + unsigned int j, n; + unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset; + + /* If we do not do field-sensitive PTA adding offsets to pointers + does not change the points-to solution. */ + if (!use_field_sensitive) + { + get_constraint_for (ptr, results); + return; + } + + /* If the offset is not a non-negative integer constant that fits + in a HOST_WIDE_INT, we have to fall back to a conservative + solution which includes all sub-fields of all pointed-to + variables of ptr. + ??? As we do not have the ability to express this, fall back + to anything. */ + if (!host_integerp (offset, 1)) + { + struct constraint_expr temp; + temp.var = anything_id; + temp.type = SCALAR; + temp.offset = 0; + VEC_safe_push (ce_s, heap, *results, &temp); + return; + } + + /* Make sure the bit-offset also fits. */ + rhsunitoffset = TREE_INT_CST_LOW (offset); + rhsoffset = rhsunitoffset * BITS_PER_UNIT; + if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) + { + struct constraint_expr temp; + temp.var = anything_id; + temp.type = SCALAR; + temp.offset = 0; + VEC_safe_push (ce_s, heap, *results, &temp); + return; + } + + get_constraint_for (ptr, results); + if (rhsoffset == 0) + return; + + /* As we are eventually appending to the solution do not use + VEC_iterate here. */ + n = VEC_length (ce_s, *results); + for (j = 0; j < n; j++) + { + varinfo_t curr; + c = VEC_index (ce_s, *results, j); + curr = get_varinfo (c->var); + + if (c->type == ADDRESSOF + && !curr->is_full_var) + { + varinfo_t temp, curr = get_varinfo (c->var); + + /* Search the sub-field which overlaps with the + pointed-to offset. As we deal with positive offsets + only, we can start the search from the current variable. */ + temp = first_vi_for_offset (curr, curr->offset + rhsoffset); + + /* If the result is outside of the variable we have to provide + a conservative result, as the variable is still reachable + from the resulting pointer (even though it technically + cannot point to anything). The last sub-field is such + a conservative result. + ??? If we always had a sub-field for &object + 1 then + we could represent this in a more precise way. */ + if (temp == NULL) + { + temp = curr; + while (temp->next != NULL) + temp = temp->next; + continue; + } + + /* If the found variable is not exactly at the pointed to + result, we have to include the next variable in the + solution as well. Otherwise two increments by offset / 2 + do not result in the same or a conservative superset + solution. */ + if (temp->offset != curr->offset + rhsoffset + && temp->next != NULL) + { + struct constraint_expr c2; + c2.var = temp->next->id; + c2.type = ADDRESSOF; + c2.offset = 0; + VEC_safe_push (ce_s, heap, *results, &c2); + } + c->var = temp->id; + c->offset = 0; + } + else if (c->type == ADDRESSOF + /* If this varinfo represents a full variable just use it. */ + && curr->is_full_var) + c->offset = 0; + else + c->offset = rhsoffset; + } +} + + /* Given a COMPONENT_REF T, return the constraint_expr vector for it. If address_p is true the result will be taken its address of. */ @@ -2714,15 +2937,18 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results, /* Pretend to take the address of the base, we'll take care of adding the required subset of sub-fields below. */ get_constraint_for_1 (t, results, true); - result = VEC_last (ce_s, *results); - gcc_assert (VEC_length (ce_s, *results) == 1); + result = VEC_last (ce_s, *results); /* This can also happen due to weird offsetof type macros. */ if (TREE_CODE (t) != ADDR_EXPR && result->type == ADDRESSOF) result->type = SCALAR; - if (result->type == SCALAR) + if (result->type == SCALAR + && get_varinfo (result->var)->is_full_var) + /* For single-field vars do not bother about the offset. */ + result->offset = 0; + else if (result->type == SCALAR) { /* In languages like C, you can access one past the end of an array. You aren't allowed to dereference it, so we can @@ -2751,12 +2977,25 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results, break; } } - /* assert that we found *some* field there. The user couldn't be - accessing *only* padding. */ - /* Still the user could access one past the end of an array - embedded in a struct resulting in accessing *only* padding. */ - gcc_assert (VEC_length (ce_s, *results) >= 1 - || ref_contains_array_ref (orig_t)); + /* If we are going to take the address of this field then + to be able to compute reachability correctly add at least + the last field of the variable. */ + if (address_p + && VEC_length (ce_s, *results) == 0) + { + curr = get_varinfo (cexpr.var); + while (curr->next != NULL) + curr = curr->next; + cexpr.var = curr->id; + VEC_safe_push (ce_s, heap, *results, &cexpr); + } + else + /* Assert that we found *some* field there. The user couldn't be + accessing *only* padding. */ + /* Still the user could access one past the end of an array + embedded in a struct resulting in accessing *only* padding. */ + gcc_assert (VEC_length (ce_s, *results) >= 1 + || ref_contains_array_ref (orig_t)); } else if (bitmaxsize == 0) { @@ -2900,24 +3139,10 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) VEC_safe_push (ce_s, heap, *results, &temp); return; } - else - { - temp.var = anything_id; - temp.type = SCALAR; - temp.offset = 0; - VEC_safe_push (ce_s, heap, *results, &temp); - return; - } break; - default: - { - temp.type = ADDRESSOF; - temp.var = anything_id; - temp.offset = 0; - VEC_safe_push (ce_s, heap, *results, &temp); - return; - } + default:; } + break; } case tcc_reference: { @@ -2934,15 +3159,9 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) case COMPONENT_REF: get_constraint_for_component_ref (t, results, address_p); return; - default: - { - temp.type = ADDRESSOF; - temp.var = anything_id; - temp.offset = 0; - VEC_safe_push (ce_s, heap, *results, &temp); - return; - } + default:; } + break; } case tcc_unary: { @@ -2963,15 +3182,19 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) /* FALLTHRU */ } - default: - { - temp.type = ADDRESSOF; - temp.var = anything_id; - temp.offset = 0; - VEC_safe_push (ce_s, heap, *results, &temp); - return; - } + default:; + } + break; + } + case tcc_binary: + { + if (TREE_CODE (t) == POINTER_PLUS_EXPR) + { + get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), + TREE_OPERAND (t, 1), results); + return; } + break; } case tcc_exceptional: { @@ -2982,37 +3205,28 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) get_constraint_for_1 (PHI_RESULT (t), results, address_p); return; } - break; case SSA_NAME: { get_constraint_for_ssa_var (t, results, address_p); return; } - break; - default: - { - temp.type = ADDRESSOF; - temp.var = anything_id; - temp.offset = 0; - VEC_safe_push (ce_s, heap, *results, &temp); - return; - } + default:; } + break; } case tcc_declaration: { get_constraint_for_ssa_var (t, results, address_p); return; } - default: - { - temp.type = ADDRESSOF; - temp.var = anything_id; - temp.offset = 0; - VEC_safe_push (ce_s, heap, *results, &temp); - return; - } + default:; } + + /* The default fallback is a constraint from anything. */ + temp.type = ADDRESSOF; + temp.var = anything_id; + temp.offset = 0; + VEC_safe_push (ce_s, heap, *results, &temp); } /* Given a gimple tree T, return the constraint expression vector for it. */ @@ -3298,80 +3512,6 @@ do_structure_copy (tree lhsop, tree rhsop) } } - -/* Handle pointer arithmetic EXPR when creating aliasing constraints. - Expressions of the type PTR + CST can be handled in two ways: - - 1- If the constraint for PTR is ADDRESSOF for a non-structure - variable, then we can use it directly because adding or - subtracting a constant may not alter the original ADDRESSOF - constraint (i.e., pointer arithmetic may not legally go outside - an object's boundaries). - - 2- If the constraint for PTR is ADDRESSOF for a structure variable, - then if CST is a compile-time constant that can be used as an - offset, we can determine which sub-variable will be pointed-to - by the expression. - - Return true if the expression is handled. For any other kind of - expression, return false so that each operand can be added as a - separate constraint by the caller. */ - -static bool -handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr) -{ - tree op0, op1; - struct constraint_expr *c, *c2; - unsigned int i = 0; - unsigned int j = 0; - VEC (ce_s, heap) *temp = NULL; - unsigned HOST_WIDE_INT rhsunitoffset, rhsoffset; - - if (TREE_CODE (expr) != POINTER_PLUS_EXPR) - return false; - - op0 = TREE_OPERAND (expr, 0); - op1 = TREE_OPERAND (expr, 1); - gcc_assert (POINTER_TYPE_P (TREE_TYPE (op0))); - - /* If the offset is not a non-negative integer constant that fits - in a HOST_WIDE_INT, we cannot handle it here. */ - if (!host_integerp (op1, 1)) - return false; - - /* Make sure the bit-offset also fits. */ - rhsunitoffset = TREE_INT_CST_LOW (op1); - rhsoffset = rhsunitoffset * BITS_PER_UNIT; - if (rhsunitoffset != rhsoffset / BITS_PER_UNIT) - return false; - - get_constraint_for (op0, &temp); - - for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++) - for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++) - { - if (c2->type == ADDRESSOF && rhsoffset != 0) - { - varinfo_t temp = get_varinfo (c2->var); - - /* An access one after the end of an array is valid, - so simply punt on accesses we cannot resolve. */ - temp = first_vi_for_offset (temp, rhsoffset); - if (temp == NULL) - continue; - c2->var = temp->id; - c2->offset = 0; - } - else - c2->offset = rhsoffset; - process_constraint (new_constraint (*c, *c2)); - } - - VEC_free (ce_s, heap, temp); - - return true; -} - /* Create a constraint ID = OP. */ static void @@ -3771,89 +3911,29 @@ find_func_aliases (tree origt) } } } - /* Otherwise, just a regular assignment statement. */ - else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT) + /* Otherwise, just a regular assignment statement. Only care about + operations with pointer result, others are dealt with as escape + points if they have pointer operands. */ + else if (TREE_CODE (t) == GIMPLE_MODIFY_STMT + && could_have_pointers (GIMPLE_STMT_OPERAND (t, 0))) { tree lhsop = GIMPLE_STMT_OPERAND (t, 0); tree rhsop = GIMPLE_STMT_OPERAND (t, 1); - int i; - if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop)) - && AGGREGATE_TYPE_P (TREE_TYPE (rhsop))) - { - do_structure_copy (lhsop, rhsop); - } + if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop))) + do_structure_copy (lhsop, rhsop); else { - /* Only care about operations with pointers, structures - containing pointers, dereferences, and call expressions. */ - if (could_have_pointers (lhsop) - || TREE_CODE (rhsop) == CALL_EXPR) + unsigned int j; + get_constraint_for (lhsop, &lhsc); + get_constraint_for (rhsop, &rhsc); + for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++) { - get_constraint_for (lhsop, &lhsc); - switch (TREE_CODE_CLASS (TREE_CODE (rhsop))) - { - /* RHS that consist of unary operations, - exceptional types, or bare decls/constants, get - handled directly by get_constraint_for. */ - case tcc_reference: - case tcc_declaration: - case tcc_constant: - case tcc_exceptional: - case tcc_expression: - case tcc_vl_exp: - case tcc_unary: - { - unsigned int j; - - get_constraint_for (rhsop, &rhsc); - for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++) - { - struct constraint_expr *c2; - unsigned int k; - - for (k = 0; VEC_iterate (ce_s, rhsc, k, c2); k++) - process_constraint (new_constraint (*c, *c2)); - } - - } - break; + struct constraint_expr *c2; + unsigned int k; - case tcc_binary: - { - /* For pointer arithmetic of the form - PTR + CST, we can simply use PTR's - constraint because pointer arithmetic is - not allowed to go out of bounds. */ - if (handle_ptr_arith (lhsc, rhsop)) - break; - } - /* FALLTHRU */ - - /* Otherwise, walk each operand. Notice that we - can't use the operand interface because we need - to process expressions other than simple operands - (e.g. INDIRECT_REF, ADDR_EXPR, CALL_EXPR). */ - default: - for (i = 0; i < TREE_OPERAND_LENGTH (rhsop); i++) - { - tree op = TREE_OPERAND (rhsop, i); - unsigned int j; - - gcc_assert (VEC_length (ce_s, rhsc) == 0); - get_constraint_for (op, &rhsc); - for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++) - { - struct constraint_expr *c2; - while (VEC_length (ce_s, rhsc) > 0) - { - c2 = VEC_last (ce_s, rhsc); - process_constraint (new_constraint (*c, *c2)); - VEC_pop (ce_s, rhsc); - } - } - } - } + for (k = 0; VEC_iterate (ce_s, rhsc, k, c2); k++) + process_constraint (new_constraint (*c, *c2)); } } } @@ -4222,8 +4302,7 @@ create_function_info_for (tree decl, const char *name) stats.total_vars++; /* If it's varargs, we don't know how many arguments it has, so we - can't do much. - */ + can't do much. */ if (is_varargs) { vi->fullsize = ~0; @@ -4257,6 +4336,7 @@ create_function_info_for (tree decl, const char *name) VEC_safe_push (varinfo_t, heap, varmap, argvi); argvi->offset = i; argvi->size = 1; + argvi->is_full_var = true; argvi->fullsize = vi->fullsize; insert_into_field_list_sorted (vi, argvi); stats.total_vars ++; @@ -4293,6 +4373,7 @@ create_function_info_for (tree decl, const char *name) resultvi->offset = i; resultvi->size = 1; resultvi->fullsize = vi->fullsize; + resultvi->is_full_var = true; insert_into_field_list_sorted (vi, resultvi); stats.total_vars ++; if (DECL_RESULT (decl)) @@ -4411,6 +4492,7 @@ create_variable_info_for (tree decl, const char *name) vi->is_unknown_size_var = 1; vi->fullsize = ~0; vi->size = ~0; + vi->is_full_var = true; VEC_free (fieldoff_s, heap, fieldstack); return index; } @@ -4447,6 +4529,8 @@ create_variable_info_for (tree decl, const char *name) stats.total_vars++; } } + else + vi->is_full_var = true; VEC_free (fieldoff_s, heap, fieldstack); @@ -4690,61 +4774,6 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed, static bool have_alias_info = false; -/* The list of SMT's that are in use by our pointer variables. This - is the set of SMT's for all pointers that can point to anything. */ -static bitmap used_smts; - -/* Due to the ordering of points-to set calculation and SMT - calculation being a bit co-dependent, we can't just calculate SMT - used info whenever we want, we have to calculate it around the time - that find_what_p_points_to is called. */ - -/* Mark which SMT's are in use by points-to anything variables. */ - -void -set_used_smts (void) -{ - int i; - varinfo_t vi; - used_smts = BITMAP_ALLOC (&pta_obstack); - - for (i = 0; VEC_iterate (varinfo_t, varmap, i, vi); i++) - { - tree var = vi->decl; - varinfo_t withsolution = get_varinfo (find (i)); - tree smt; - var_ann_t va; - struct ptr_info_def *pi = NULL; - - /* For parm decls, the pointer info may be under the default - def. */ - if (TREE_CODE (vi->decl) == PARM_DECL - && gimple_default_def (cfun, var)) - pi = SSA_NAME_PTR_INFO (gimple_default_def (cfun, var)); - else if (TREE_CODE (var) == SSA_NAME) - pi = SSA_NAME_PTR_INFO (var); - - /* Skip the special variables and those that can't be aliased. */ - if (vi->is_special_var - || !SSA_VAR_P (var) - || (pi && !pi->memory_tag_needed) - || (TREE_CODE (var) == VAR_DECL && !may_be_aliased (var)) - || !POINTER_TYPE_P (TREE_TYPE (var))) - continue; - - if (TREE_CODE (var) == SSA_NAME) - var = SSA_NAME_VAR (var); - - va = var_ann (var); - if (!va) - continue; - - smt = va->symbol_mem_tag; - if (smt && bitmap_bit_p (withsolution->solution, anything_id)) - bitmap_set_bit (used_smts, DECL_UID (smt)); - } -} - /* Given a pointer variable P, fill in its points-to set, or return false if we can't. Rather than return false for variables that point-to anything, we @@ -5198,6 +5227,8 @@ init_base_vars (void) static void init_alias_vars (void) { + use_field_sensitive = (MAX_FIELDS_FOR_FIELD_SENSITIVE > 1); + bitmap_obstack_initialize (&pta_obstack); bitmap_obstack_initialize (&oldpta_obstack); bitmap_obstack_initialize (&predbitmap_obstack); @@ -5456,6 +5487,10 @@ compute_points_to_sets (void) free_var_substitution_info (si); build_succ_graph (); + + if (dump_file && (dump_flags & TDF_GRAPH)) + dump_constraint_graph (dump_file); + move_complex_constraints (graph); if (dump_file) diff --git a/gcc/tree-ssa-structalias.h b/gcc/tree-ssa-structalias.h index 7d468b42f91..0d0d6bdf073 100644 --- a/gcc/tree-ssa-structalias.h +++ b/gcc/tree-ssa-structalias.h @@ -32,13 +32,15 @@ void update_mem_sym_stats_from_stmt (tree, tree, long, long); extern void compute_points_to_sets (void); extern void delete_points_to_sets (void); extern void dump_constraint (FILE *, constraint_t); +extern void dump_constraint_edge (FILE *, constraint_t); extern void dump_constraints (FILE *); +extern void dump_constraint_graph (FILE *); extern void debug_constraint (constraint_t); extern void debug_constraints (void); +extern void debug_constraint_graph (void); extern void dump_solution_for_var (FILE *, unsigned int); extern void debug_solution_for_var (unsigned int); extern void dump_sa_points_to_info (FILE *); extern void debug_sa_points_to_info (void); -extern void set_used_smts (void); #endif /* TREE_SSA_STRUCTALIAS_H */ diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 09a2eafe119..92127b4b7af 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -138,14 +138,14 @@ suitable_for_tail_opt_p (void) if (cfun->stdarg) return false; - /* No local variable nor structure field should be call-clobbered. We + /* No local variable nor structure field should be call-used. We ignore any kind of memory tag, as these are not real variables. */ FOR_EACH_REFERENCED_VAR (var, rvi) { if (!is_global_var (var) && !MTAG_P (var) - && (gimple_aliases_computed_p (cfun) ? is_call_clobbered (var) + && (gimple_aliases_computed_p (cfun)? is_call_used (var) : TREE_ADDRESSABLE (var))) return false; } diff --git a/gcc/unwind-pe.h b/gcc/unwind-pe.h index 9c56af08486..6924e8c1732 100644 --- a/gcc/unwind-pe.h +++ b/gcc/unwind-pe.h @@ -71,6 +71,9 @@ include leb128. */ static unsigned int +size_of_encoded_value (unsigned char encoding) __attribute__ ((unused)); + +static unsigned int size_of_encoded_value (unsigned char encoding) { if (encoding == DW_EH_PE_omit) diff --git a/include/ChangeLog b/include/ChangeLog index 66f6249ce6d..1636e982f79 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2008-07-07 Joel Brobecker <brobecker@adacore.com> + + * safe-ctype.h: Add #include of ctype.h before redefining + the ctype.h macros. + 2008-07-04 Joel Brobecker <brobecker@adacore.com> * safe-ctype.h: Remove #error when detecting that ctype.h has been diff --git a/include/safe-ctype.h b/include/safe-ctype.h index b3e911e07bd..0266bf1aa26 100644 --- a/include/safe-ctype.h +++ b/include/safe-ctype.h @@ -116,7 +116,10 @@ extern const unsigned char _sch_tolower[256]; from ctype.h. Initially, the approach was to produce an error when detecting that ctype.h has been included. But this was causing trouble as ctype.h might get indirectly included as a result of - including another system header (for instance gnulib's stdint.h). */ + including another system header (for instance gnulib's stdint.h). + So we include ctype.h here and then immediately redefine its macros. */ + +#include <ctype.h> #undef isalpha #define isalpha(c) do_not_use_isalpha_with_safe_ctype #undef isalnum diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 1b1024eba0e..348afc5d227 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,21 @@ +2008-07-08 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/64/t-softfp-compat: Update comments. + +2008-07-07 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/64/_divtc3-compat.c: Moved to ... + * config/i386/64/_divtc3.c: Here. + + * config/i386/64/_multc3-compat.c: Moved to ... + * config/i386/64/_multc3.c: Here. + + * config/i386/64/_powitf2-compat.c: Moved to ... + * config/i386/64/_powitf2.c: Here. + + * config/i386/64/t-softfp-compat (libgcc2-tf-compats): Add + .c suffix instead of -compat.c. + 2008-07-05 Uros Bizjak <ubizjak@gmail.com> * config/i386/32/sfp-machine.h (_FP_MUL_MEAT_S): Remove. diff --git a/libgcc/config/i386/64/_divtc3-compat.c b/libgcc/config/i386/64/_divtc3.c index 57ee350b7cd..57ee350b7cd 100644 --- a/libgcc/config/i386/64/_divtc3-compat.c +++ b/libgcc/config/i386/64/_divtc3.c diff --git a/libgcc/config/i386/64/_multc3-compat.c b/libgcc/config/i386/64/_multc3.c index 49141a9384f..49141a9384f 100644 --- a/libgcc/config/i386/64/_multc3-compat.c +++ b/libgcc/config/i386/64/_multc3.c diff --git a/libgcc/config/i386/64/_powitf2-compat.c b/libgcc/config/i386/64/_powitf2.c index 3bc3c904de7..3bc3c904de7 100644 --- a/libgcc/config/i386/64/_powitf2-compat.c +++ b/libgcc/config/i386/64/_powitf2.c diff --git a/libgcc/config/i386/64/t-softfp-compat b/libgcc/config/i386/64/t-softfp-compat index e8cda296cbd..afaa526ae29 100644 --- a/libgcc/config/i386/64/t-softfp-compat +++ b/libgcc/config/i386/64/t-softfp-compat @@ -1,5 +1,8 @@ -# Filter out the following TImode functions and provide backward binary -# compatibility. +# When TFmode was first added to x86-64 in gcc 4.3.0, some TFmode +# support functions got improper versions by accident. Here we +# correct the version and provide backward binary compatibility. + +# Filter out the following TFmode functions. tf-compats = getf2.c letf2.c eqtf2.c tf-functions := $(addprefix $(gcc_srcdir)/config/soft-fp/, $(tf-compats)) LIB2ADD := $(filter-out $(tf-functions), $(LIB2ADD)) @@ -8,5 +11,5 @@ LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(tf-compats)) # Replace _divtc3, _multc3 and _powitf2. libgcc2-tf-functions = _divtc3 _multc3 _powitf2 LIB2FUNCS_EXCLUDE += $(libgcc2-tf-functions) -libgcc2-tf-compats = $(addsuffix -compat.c, $(libgcc2-tf-functions)) +libgcc2-tf-compats = $(addsuffix .c, $(libgcc2-tf-functions)) LIB2ADD += $(addprefix $(srcdir)/config/i386/64/, $(libgcc2-tf-compats)) diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 6e3a729fc7a..c845606c803 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,32 @@ +2008-07-07 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/36341 + PR fortran/34670 + * m4/matmul.m4: Add bounds checking. + * m4/matmull.m4: Likewise. + * generated/matmul_c10.c: Regenerated. + * generated/matmul_c16.c: Regenerated. + * generated/matmul_c4.c: Regenerated. + * generated/matmul_c8.c: Regenerated. + * generated/matmul_i1.c: Regenerated. + * generated/matmul_i16.c: Regenerated. + * generated/matmul_i2.c: Regenerated. + * generated/matmul_i4.c: Regenerated. + * generated/matmul_i8.c: Regenerated. + * generated/matmul_l16.c: Regenerated. + * generated/matmul_l4.c: Regenerated. + * generated/matmul_l8.c: Regenerated. + * generated/matmul_r10.c: Regenerated. + * generated/matmul_r16.c: Regenerated. + * generated/matmul_r4.c: Regenerated. + * generated/matmul_r8.c: Regenerated. + +2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * acinclude.m4 (LIBGFOR_CHECK_GTHR_DEFAULT): Fix configure cache + variable name. + * configure: Regenerate. + 2008-07-01 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR fortran/36676 diff --git a/libgfortran/acinclude.m4 b/libgfortran/acinclude.m4 index d1994b49d90..9f8ae54fab6 100644 --- a/libgfortran/acinclude.m4 +++ b/libgfortran/acinclude.m4 @@ -86,10 +86,10 @@ if (foovar > 10) return __sync_add_and_fetch (&foovar, -1);], dnl Check if threads are supported. AC_DEFUN([LIBGFOR_CHECK_GTHR_DEFAULT], [ AC_CACHE_CHECK([configured target thread model], - target_thread_file, [ -target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`]) + libgfor_cv_target_thread_file, [ +libgfor_cv_target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'`]) - if test $target_thread_file != single; then + if test $libgfor_cv_target_thread_file != single; then AC_DEFINE(HAVE_GTHR_DEFAULT, 1, [Define if the compiler has a thread header that is non single.]) fi]) diff --git a/libgfortran/configure b/libgfortran/configure index 176632426b8..0bd9a22d43f 100755 --- a/libgfortran/configure +++ b/libgfortran/configure @@ -33157,16 +33157,16 @@ _ACEOF echo "$as_me:$LINENO: checking configured target thread model" >&5 echo $ECHO_N "checking configured target thread model... $ECHO_C" >&6 -if test "${target_thread_file+set}" = set; then +if test "${libgfor_cv_target_thread_file+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else -target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'` +libgfor_cv_target_thread_file=`$CC -v 2>&1 | sed -n 's/^Thread model: //p'` fi -echo "$as_me:$LINENO: result: $target_thread_file" >&5 -echo "${ECHO_T}$target_thread_file" >&6 +echo "$as_me:$LINENO: result: $libgfor_cv_target_thread_file" >&5 +echo "${ECHO_T}$libgfor_cv_target_thread_file" >&6 - if test $target_thread_file != single; then + if test $libgfor_cv_target_thread_file != single; then cat >>confdefs.h <<\_ACEOF #define HAVE_GTHR_DEFAULT 1 diff --git a/libgfortran/generated/matmul_c10.c b/libgfortran/generated/matmul_c10.c index 08c2044dd8b..0e378626f96 100644 --- a/libgfortran/generated/matmul_c10.c +++ b/libgfortran/generated/matmul_c10.c @@ -135,6 +135,47 @@ matmul_c10 (gfc_array_c10 * const restrict retarray, = internal_malloc_size (sizeof (GFC_COMPLEX_10) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_c16.c b/libgfortran/generated/matmul_c16.c index 6a2a6390967..34cc51dbd78 100644 --- a/libgfortran/generated/matmul_c16.c +++ b/libgfortran/generated/matmul_c16.c @@ -135,6 +135,47 @@ matmul_c16 (gfc_array_c16 * const restrict retarray, = internal_malloc_size (sizeof (GFC_COMPLEX_16) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_c4.c b/libgfortran/generated/matmul_c4.c index 6dcf6fea56a..fdfea1df955 100644 --- a/libgfortran/generated/matmul_c4.c +++ b/libgfortran/generated/matmul_c4.c @@ -135,6 +135,47 @@ matmul_c4 (gfc_array_c4 * const restrict retarray, = internal_malloc_size (sizeof (GFC_COMPLEX_4) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_c8.c b/libgfortran/generated/matmul_c8.c index 8bc619d879f..9d6694922f1 100644 --- a/libgfortran/generated/matmul_c8.c +++ b/libgfortran/generated/matmul_c8.c @@ -135,6 +135,47 @@ matmul_c8 (gfc_array_c8 * const restrict retarray, = internal_malloc_size (sizeof (GFC_COMPLEX_8) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_i1.c b/libgfortran/generated/matmul_i1.c index ca16ed40b2f..34fd7c51b78 100644 --- a/libgfortran/generated/matmul_i1.c +++ b/libgfortran/generated/matmul_i1.c @@ -135,6 +135,47 @@ matmul_i1 (gfc_array_i1 * const restrict retarray, = internal_malloc_size (sizeof (GFC_INTEGER_1) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_i16.c b/libgfortran/generated/matmul_i16.c index 33c62ae4152..0c7c5d8f396 100644 --- a/libgfortran/generated/matmul_i16.c +++ b/libgfortran/generated/matmul_i16.c @@ -135,6 +135,47 @@ matmul_i16 (gfc_array_i16 * const restrict retarray, = internal_malloc_size (sizeof (GFC_INTEGER_16) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_i2.c b/libgfortran/generated/matmul_i2.c index e3119acbd41..5d55847edce 100644 --- a/libgfortran/generated/matmul_i2.c +++ b/libgfortran/generated/matmul_i2.c @@ -135,6 +135,47 @@ matmul_i2 (gfc_array_i2 * const restrict retarray, = internal_malloc_size (sizeof (GFC_INTEGER_2) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_i4.c b/libgfortran/generated/matmul_i4.c index a1b8c50f051..a80f14940c8 100644 --- a/libgfortran/generated/matmul_i4.c +++ b/libgfortran/generated/matmul_i4.c @@ -135,6 +135,47 @@ matmul_i4 (gfc_array_i4 * const restrict retarray, = internal_malloc_size (sizeof (GFC_INTEGER_4) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_i8.c b/libgfortran/generated/matmul_i8.c index eee73ac88f0..91499c793e6 100644 --- a/libgfortran/generated/matmul_i8.c +++ b/libgfortran/generated/matmul_i8.c @@ -135,6 +135,47 @@ matmul_i8 (gfc_array_i8 * const restrict retarray, = internal_malloc_size (sizeof (GFC_INTEGER_8) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_l16.c b/libgfortran/generated/matmul_l16.c index b2b86ecfed1..b604edfb2ca 100644 --- a/libgfortran/generated/matmul_l16.c +++ b/libgfortran/generated/matmul_l16.c @@ -99,6 +99,47 @@ matmul_l16 (gfc_array_l16 * const restrict retarray, = internal_malloc_size (sizeof (GFC_LOGICAL_16) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } abase = a->data; a_kind = GFC_DESCRIPTOR_SIZE (a); diff --git a/libgfortran/generated/matmul_l4.c b/libgfortran/generated/matmul_l4.c index 9a6cb1d357d..5aed0fe2ba0 100644 --- a/libgfortran/generated/matmul_l4.c +++ b/libgfortran/generated/matmul_l4.c @@ -99,6 +99,47 @@ matmul_l4 (gfc_array_l4 * const restrict retarray, = internal_malloc_size (sizeof (GFC_LOGICAL_4) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } abase = a->data; a_kind = GFC_DESCRIPTOR_SIZE (a); diff --git a/libgfortran/generated/matmul_l8.c b/libgfortran/generated/matmul_l8.c index 7d4e35e82e3..26baad32136 100644 --- a/libgfortran/generated/matmul_l8.c +++ b/libgfortran/generated/matmul_l8.c @@ -99,6 +99,47 @@ matmul_l8 (gfc_array_l8 * const restrict retarray, = internal_malloc_size (sizeof (GFC_LOGICAL_8) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } abase = a->data; a_kind = GFC_DESCRIPTOR_SIZE (a); diff --git a/libgfortran/generated/matmul_r10.c b/libgfortran/generated/matmul_r10.c index 58dfe75814f..931e2bdc0f0 100644 --- a/libgfortran/generated/matmul_r10.c +++ b/libgfortran/generated/matmul_r10.c @@ -135,6 +135,47 @@ matmul_r10 (gfc_array_r10 * const restrict retarray, = internal_malloc_size (sizeof (GFC_REAL_10) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_r16.c b/libgfortran/generated/matmul_r16.c index a6a93be91fb..16ec175be0c 100644 --- a/libgfortran/generated/matmul_r16.c +++ b/libgfortran/generated/matmul_r16.c @@ -135,6 +135,47 @@ matmul_r16 (gfc_array_r16 * const restrict retarray, = internal_malloc_size (sizeof (GFC_REAL_16) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_r4.c b/libgfortran/generated/matmul_r4.c index 1154d41a33f..47d976415d0 100644 --- a/libgfortran/generated/matmul_r4.c +++ b/libgfortran/generated/matmul_r4.c @@ -135,6 +135,47 @@ matmul_r4 (gfc_array_r4 * const restrict retarray, = internal_malloc_size (sizeof (GFC_REAL_4) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/generated/matmul_r8.c b/libgfortran/generated/matmul_r8.c index 7bce2533b41..a359ffd8fd3 100644 --- a/libgfortran/generated/matmul_r8.c +++ b/libgfortran/generated/matmul_r8.c @@ -135,6 +135,47 @@ matmul_r8 (gfc_array_r8 * const restrict retarray, = internal_malloc_size (sizeof (GFC_REAL_8) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } if (GFC_DESCRIPTOR_RANK (retarray) == 1) diff --git a/libgfortran/m4/matmul.m4 b/libgfortran/m4/matmul.m4 index 181efa3b654..a43b430c2e3 100644 --- a/libgfortran/m4/matmul.m4 +++ b/libgfortran/m4/matmul.m4 @@ -136,6 +136,47 @@ matmul_'rtype_code` ('rtype` * const restrict retarray, = internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } ' sinclude(`matmul_asm_'rtype_code`.m4')dnl ` diff --git a/libgfortran/m4/matmull.m4 b/libgfortran/m4/matmull.m4 index 54afa8a238e..800444564f7 100644 --- a/libgfortran/m4/matmull.m4 +++ b/libgfortran/m4/matmull.m4 @@ -100,6 +100,47 @@ matmul_'rtype_code` ('rtype` * const restrict retarray, = internal_malloc_size (sizeof ('rtype_name`) * size0 ((array_t *) retarray)); retarray->offset = 0; } + else if (compile_options.bounds_check) + { + index_type ret_extent, arg_extent; + + if (GFC_DESCRIPTOR_RANK (a) == 1) + { + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else if (GFC_DESCRIPTOR_RANK (b) == 1) + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic: is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + else + { + arg_extent = a->dim[0].ubound + 1 - a->dim[0].lbound; + ret_extent = retarray->dim[0].ubound + 1 - retarray->dim[0].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 1:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + + arg_extent = b->dim[1].ubound + 1 - b->dim[1].lbound; + ret_extent = retarray->dim[1].ubound + 1 - retarray->dim[1].lbound; + if (arg_extent != ret_extent) + runtime_error ("Incorrect extent in return array in" + " MATMUL intrinsic for dimension 2:" + " is %ld, should be %ld", + (long int) ret_extent, (long int) arg_extent); + } + } abase = a->data; a_kind = GFC_DESCRIPTOR_SIZE (a); diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 4fb9d68fb3f..1caf0ef248b 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,7 @@ +2008-07-08 Matthias Klose <doko@ubuntu.com> + + * libtool-version: Bump soversion. + 2008-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * gnu/gcj/convert/make-trie.h: New. diff --git a/libjava/libtool-version b/libjava/libtool-version index 964dc4f4f01..db361f7b168 100644 --- a/libjava/libtool-version +++ b/libjava/libtool-version @@ -3,4 +3,4 @@ # a separate file so that version updates don't involve re-running # automake. # CURRENT:REVISION:AGE -9:0:0 +10:0:0 diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index db08bef03c2..da30a6a741e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,26 @@ +2008-07-08 Chris Fairles <chris.fairles@gmail.com> + + * include/std/type_traits: Add common_type. + * testsuite/20_util/common_type/requirements/ + explicit_instantiation.cc: New. + * testsuite/20_util/common_type/requirements/ + typedefs-1.cc: Likewise. + +2008-07-07 Paolo Carlini <paolo.carlini@oracle.com> + + * testsuite/lib/libstdc++.exp (check_v3_target_stdint): New. + * testsuite/lib/dg-options.exp (dg-require-cstdint): New. + * testsuite/20_util/ratio/cons/cons1.cc: Use it. + * testsuite/20_util/ratio/cons/cons_overflow.cc: Likewise. + * testsuite/20_util/ratio/operations/ops1.cc: Likewise. + * testsuite/20_util/ratio/operations/ops2.cc: Likewise. + * testsuite/20_util/ratio/operations/ops3.cc: Likewise. + * testsuite/20_util/ratio/operations/ops_overflow.cc: Likewise. + * testsuite/20_util/ratio/comparisons/comp1.cc: Likewise. + * testsuite/20_util/ratio/comparisons/comp2.cc: Likewise. + + * include/std/type_traits: Fix comment typo. + 2008-07-06 Roger Sayle <roger@eyesopen.com> * include/std/system_error (is_error_code_enum): Use identifier diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index 5fdc95ecad9..1a759187955 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -203,13 +203,13 @@ namespace std : public integral_constant<bool, __has_trivial_destructor(_Tp)> { }; - /// has_nothrow_default_destructor + /// has_nothrow_default_constructor template<typename _Tp> struct has_nothrow_default_constructor : public integral_constant<bool, __has_nothrow_constructor(_Tp)> { }; - /// has_nothrow_copy_destructor + /// has_nothrow_copy_constructor template<typename _Tp> struct has_nothrow_copy_constructor : public integral_constant<bool, __has_nothrow_copy(_Tp)> @@ -551,6 +551,41 @@ namespace std // Integral, but don't define. template<> struct make_signed<bool>; + + template<typename... _Tp> + struct common_type; + + template<typename _Tp> + struct common_type<_Tp> + { + static_assert(sizeof(_Tp) > 0, "must be complete type"); + typedef _Tp type; + }; + + template<typename _Tp, typename _Up> + class common_type<_Tp, _Up> + { + static_assert(sizeof(_Tp) > 0, "must be complete type"); + static_assert(sizeof(_Up) > 0, "must be complete type"); + + static _Tp&& __t(); + static _Up&& __u(); + + // HACK: Prevents optimization of ?: in the decltype + // expression when the condition is the literal, "true". + // See, PR36628. + static bool __true_or_false(); + + public: + typedef decltype(__true_or_false() ? __t() : __u()) type; + }; + + template<typename _Tp, typename _Up, typename... _Vp> + struct common_type<_Tp, _Up, _Vp...> + { + typedef typename + common_type<typename common_type<_Tp, _Up>::type, _Vp...>::type type; + }; } #endif // __GXX_EXPERIMENTAL_CXX0X__ diff --git a/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc new file mode 100644 index 00000000000..fcc5b2adf30 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/explicit_instantiation.cc @@ -0,0 +1,46 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2008 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 2, or (at your option) +// any later version. + +// This library 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 this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +// NB: This file is for testing type_traits with NO OTHER INCLUDES. + +#include <type_traits> + +namespace std +{ + typedef int test_type1; + typedef int& test_type2; + typedef double test_type3; + typedef float test_type4; + + template struct common_type<test_type1>; + template struct common_type<test_type1, test_type2>; + template struct common_type<test_type1, test_type2, test_type3>; + template struct common_type<test_type1, test_type2, test_type3, test_type4>; +} diff --git a/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc b/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc new file mode 100644 index 00000000000..e4152e51d31 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/common_type/requirements/typedefs-1.cc @@ -0,0 +1,118 @@ +// { dg-options "-std=gnu++0x" } +// +// Copyright (C) 2008 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library 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 2, or (at your option) +// any later version. +// +// This library 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 this library; see the file COPYING. If not, write to the Free +// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +// USA. + +#include <type_traits> +#include <testsuite_hooks.h> + +#define JOIN( X, Y ) DO_JOIN( X, Y ) +#define DO_JOIN( X, Y ) DO_JOIN2(X,Y) +#define DO_JOIN2( X, Y ) X##Y + +#define COMMON_TYPE_TEST_1(type1, uid) \ + typedef common_type<type1>::type JOIN(test_t,uid); \ + VERIFY( (is_same<JOIN(test_t,uid), JOIN(test_t,uid)>::value) ); \ + typedef common_type<const type1>::type JOIN(test_t,JOIN(uid,c)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,c)), \ + JOIN(test_t,JOIN(uid,c))>::value) ); \ + typedef common_type<volatile type1>::type JOIN(test_t,JOIN(uid,v)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,v)), \ + JOIN(test_t,JOIN(uid,v))>::value) ); \ + typedef common_type<const volatile type1>::type JOIN(test_t,JOIN(uid,cv)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,cv)), \ + JOIN(test_t,JOIN(uid,cv))>::value) ); \ + typedef common_type<type1 &>::type JOIN(test_t,JOIN(uid,l)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,l)), \ + JOIN(test_t,JOIN(uid,l))>::value) ); \ + typedef common_type<const type1 &>::type JOIN(test_t,JOIN(uid,lc)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,lc)), \ + JOIN(test_t,JOIN(uid,lc))>::value) ); \ + typedef common_type<volatile type1 &>::type JOIN(test_t,JOIN(uid,lv)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,lv)), \ + JOIN(test_t,JOIN(uid,lv))>::value) ); \ + typedef common_type<const volatile type1 &>::type JOIN(test_t,JOIN(uid,lcv)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,lcv)), \ + JOIN(test_t,JOIN(uid,lcv))>::value) ); \ + typedef common_type<type1 &&>::type JOIN(test_t,JOIN(uid,r)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,r)), \ + JOIN(test_t,JOIN(uid,r))>::value) ); \ + typedef common_type<const type1 &&>::type JOIN(test_t,JOIN(uid,rc)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,rc)), \ + JOIN(test_t,JOIN(uid,rc))>::value) ); \ + typedef common_type<volatile type1 &&>::type JOIN(test_t,JOIN(uid,rv)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,rv)), \ + JOIN(test_t,JOIN(uid,rv))>::value) ); \ + typedef common_type<const volatile type1 &&>::type JOIN(test_t,JOIN(uid,rcv)); \ + VERIFY( (is_same<JOIN(test_t,JOIN(uid,rcv)), \ + JOIN(test_t,JOIN(uid,rcv))>::value) ) + +struct A { }; +struct B : A { }; + +void test01() +{ + bool test __attribute__((unused)) = true; + using std::common_type; + using std::is_same; + + // Positive tests. + COMMON_TYPE_TEST_1(int, 1); + COMMON_TYPE_TEST_1(double, 2); + COMMON_TYPE_TEST_1(A, 3); + COMMON_TYPE_TEST_1(B, 4); +} + +#define COMMON_TYPE_TEST_2_IMPL(type1, type2, type3, uid) \ + typedef common_type<type1, type2>::type JOIN(JOIN(test, uid),_t1); \ + typedef common_type<type2, type1>::type JOIN(JOIN(test, uid),_t2); \ + VERIFY( (is_same<JOIN(JOIN(test, uid),_t1), type3>::value) ); \ + VERIFY( (is_same<JOIN(JOIN(test, uid),_t2), type3>::value) ) + +#define NO_CV + +#define COMMON_TYPE_TEST_2(cv_qual, type1, type2, type3, uid) \ + COMMON_TYPE_TEST_2_IMPL(cv_qual type1, type2, type3, uid); \ + COMMON_TYPE_TEST_2_IMPL(cv_qual type1 &, type2, type3, JOIN(uid,l)); \ + COMMON_TYPE_TEST_2_IMPL(cv_qual type1 &&, type2, type3, JOIN(uid,r)) + +#define COMMON_TYPE_TEST_ALL_2(type1, type2, type3, uid) \ + COMMON_TYPE_TEST_2(NO_CV, type1, type2, type3, uid); \ + COMMON_TYPE_TEST_2(const, type1, type2, type3, uid); \ + COMMON_TYPE_TEST_2(volatile, type1, type2, type3, uid); \ + COMMON_TYPE_TEST_2(const volatile, type1, type2, type3, uid) + +void test02() +{ + bool test __attribute__((unused)) = true; + using std::common_type; + using std::is_same; + + COMMON_TYPE_TEST_ALL_2(int, int, int, 1); + COMMON_TYPE_TEST_ALL_2(int, double, double, 2); + COMMON_TYPE_TEST_2(NO_CV, A, A, A, 3); + COMMON_TYPE_TEST_2(const, A, A, const A, 4); + COMMON_TYPE_TEST_2(NO_CV, B, A, A, 5); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc index 73064c70919..c916b309998 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // Copyright (C) 2008 Free Software Foundation // @@ -21,8 +22,6 @@ #include <ratio> #include <testsuite_hooks.h> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - void test01() { @@ -31,10 +30,10 @@ test01() VERIFY(( std::ratio_equal<std::ratio<2,6>, std::ratio<1,3>>::value == 1 )); VERIFY(( std::ratio_equal<std::ratio<2,6>, std::ratio<1,4>>::value == 0 )); - VERIFY(( std::ratio_not_equal<std::ratio<2,6>, - std::ratio<1,3>>::value == 0 )); - VERIFY(( std::ratio_not_equal<std::ratio<2,6>, - std::ratio<1,4>>::value == 1 )); + VERIFY( (std::ratio_not_equal<std::ratio<2,6>, + std::ratio<1,3>>::value == 0) ); + VERIFY( (std::ratio_not_equal<std::ratio<2,6>, + std::ratio<1,4>>::value == 1) ); } void @@ -42,46 +41,42 @@ test02() { bool test __attribute__((unused)) = true; - VERIFY(( std::ratio_less<std::ratio<1,4>, std::ratio<1,3>>::value == 1 )); - VERIFY(( std::ratio_less<std::ratio<-1,3>, std::ratio<1,3>>::value == 1 )); + VERIFY( (std::ratio_less<std::ratio<1,4>, std::ratio<1,3>>::value == 1) ); + VERIFY( (std::ratio_less<std::ratio<-1,3>, std::ratio<1,3>>::value == 1) ); - VERIFY(( std::ratio_less<std::ratio<1,3>, std::ratio<1,4>>::value == 0 )); - VERIFY(( std::ratio_less<std::ratio<1,3>, std::ratio<-1,3>>::value == 0 )); + VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<1,4>>::value == 0) ); + VERIFY( (std::ratio_less<std::ratio<1,3>, std::ratio<-1,3>>::value == 0) ); - VERIFY(( std::ratio_less_equal<std::ratio<-1,3>, - std::ratio<-1,3>>::value == 1 )); - VERIFY(( std::ratio_less_equal<std::ratio<1,4>, - std::ratio<1,3>>::value == 1 )); + VERIFY( (std::ratio_less_equal<std::ratio<-1,3>, + std::ratio<-1,3>>::value == 1) ); + VERIFY( ( std::ratio_less_equal<std::ratio<1,4>, + std::ratio<1,3>>::value == 1) ); - VERIFY(( std::ratio_less_equal<std::ratio<1,4>, - std::ratio<-1,3>>::value == 0 )); - VERIFY(( std::ratio_less_equal<std::ratio<1,3>, - std::ratio<-1,3>>::value == 0 )); + VERIFY( (std::ratio_less_equal<std::ratio<1,4>, + std::ratio<-1,3>>::value == 0) ); + VERIFY( (std::ratio_less_equal<std::ratio<1,3>, + std::ratio<-1,3>>::value == 0) ); - VERIFY(( std::ratio_greater<std::ratio<1,3>, std::ratio<1,4>>::value == 1 )); - VERIFY(( std::ratio_greater<std::ratio<1,3>, std::ratio<-1,3>>::value == 1 )); + VERIFY( (std::ratio_greater<std::ratio<1,3>, std::ratio<1,4>>::value == 1) ); + VERIFY( (std::ratio_greater<std::ratio<1,3>, std::ratio<-1,3>>::value == 1) ); - VERIFY(( std::ratio_greater<std::ratio<1,4>, std::ratio<1,3>>::value == 0 )); - VERIFY(( std::ratio_greater<std::ratio<-1,3>, std::ratio<1,3>>::value == 0 )); + VERIFY( (std::ratio_greater<std::ratio<1,4>, std::ratio<1,3>>::value == 0) ); + VERIFY( (std::ratio_greater<std::ratio<-1,3>, std::ratio<1,3>>::value == 0) ); - VERIFY(( std::ratio_greater_equal<std::ratio<1,3>, - std::ratio<1,3>>::value == 1 )); - VERIFY(( std::ratio_greater_equal<std::ratio<1,3>, - std::ratio<-1,3>>::value == 1 )); - - VERIFY(( std::ratio_greater_equal<std::ratio<-1,3>, - std::ratio<1,3>>::value == 0 )); - VERIFY(( std::ratio_greater_equal<std::ratio<1,4>, - std::ratio<1,3>>::value == 0 )); -} + VERIFY( (std::ratio_greater_equal<std::ratio<1,3>, + std::ratio<1,3>>::value == 1) ); + VERIFY( (std::ratio_greater_equal<std::ratio<1,3>, + std::ratio<-1,3>>::value == 1) ); -#endif //_GLIBCXX_USE_C99_STDINT_TR1 + VERIFY( (std::ratio_greater_equal<std::ratio<-1,3>, + std::ratio<1,3>>::value == 0) ); + VERIFY( (std::ratio_greater_equal<std::ratio<1,4>, + std::ratio<1,3>>::value == 0) ); +} int main() { -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 test01(); test02(); -#endif return 0; } diff --git a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc index 1d378d52880..56052e45328 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/comparisons/comp2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // Copyright (C) 2008 Free Software Foundation // @@ -21,8 +22,6 @@ #include <ratio> #include <testsuite_hooks.h> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - static const std::intmax_t M = INTMAX_MAX; void @@ -30,27 +29,23 @@ test01() { bool test __attribute__((unused)) = true; - //no overflow with same denominator - VERIFY(( std::ratio_less<std::ratio<M - 2, M>, - std::ratio<M - 1, M>>::value == 1 ) ); + // No overflow with same denominator + VERIFY( (std::ratio_less<std::ratio<M - 2, M>, + std::ratio<M - 1, M>>::value == 1) ); - VERIFY(( std::ratio_less<std::ratio<M - 1, M>, - std::ratio<M - 2, M>>::value == 0 ) ); - - //no overflow if signs differ - VERIFY(( std::ratio_less<std::ratio<-M, M - 1>, - std::ratio<M - 1, M - 2>>::value == 1 ) ); + VERIFY( (std::ratio_less<std::ratio<M - 1, M>, + std::ratio<M - 2, M>>::value == 0) ); + + // No overflow if signs differ + VERIFY( (std::ratio_less<std::ratio<-M, M - 1>, + std::ratio<M - 1, M - 2>>::value == 1) ); - VERIFY(( std::ratio_less<std::ratio<M - 1, M - 2>, - std::ratio<-M, M - 1>>::value == 0 ) ); + VERIFY( (std::ratio_less<std::ratio<M - 1, M - 2>, + std::ratio<-M, M - 1>>::value == 0) ); } -#endif //_GLIBCXX_USE_C99_STDINT_TR1 - int main() { -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 test01(); -#endif return 0; } diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc index dc2f0dabd70..84860699ac8 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // 2008-07-03 Chris Fairles <chris.fairles@gmail.com> @@ -23,8 +24,6 @@ #include <ratio> #include <testsuite_hooks.h> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - void test01() { @@ -46,12 +45,8 @@ test01() VERIFY( r3.den == r0.den ); } -#endif //_GLIBCXX_USE_C99_STDINT_TR1 - int main() { -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 test01(); -#endif //_GLIBCXX_USE_C99_STDINT_TR1 return 0; } diff --git a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc index 05daee5ea32..570ea6cbc7d 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/cons/cons_overflow.cc @@ -1,5 +1,6 @@ -// { dg-options "-std=gnu++0x" } // { dg-do compile } +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // Copyright (C) 2008 Free Software Foundation // @@ -21,8 +22,6 @@ #include <ratio> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - void test01() { @@ -48,11 +47,9 @@ test04() std::ratio<1,0> r1; } -// { dg-error "instantiated from here" "" { target *-*-* } 36 } -// { dg-error "instantiated from here" "" { target *-*-* } 42 } -// { dg-error "instantiated from here" "" { target *-*-* } 48 } +// { dg-error "instantiated from here" "" { target *-*-* } 35 } +// { dg-error "instantiated from here" "" { target *-*-* } 41 } +// { dg-error "instantiated from here" "" { target *-*-* } 47 } // { dg-error "denominator cannot be zero" "" { target *-*-* } 150 } // { dg-error "out of range" "" { target *-*-* } 151 } // { dg-excess-errors "In instantiation of" } - -#endif //_GLIBCXX_USE_C99_STDINT_TR1 diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc index 3f6a91d2180..b05092dd8e9 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops1.cc @@ -1,4 +1,5 @@ // { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // 2008-07-03 Chris Fairles <chris.fairles@gmail.com> @@ -23,8 +24,6 @@ #include <ratio> #include <testsuite_hooks.h> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - void test01() { @@ -32,8 +31,8 @@ test01() std::ratio_add<std::ratio<3,8>, std::ratio<5,12>>::type r; - VERIFY( r.num == 19); - VERIFY( r.den == 24); + VERIFY( r.num == 19 ); + VERIFY( r.den == 24 ); } void @@ -42,8 +41,8 @@ test02() bool test __attribute__((unused)) = true; std::ratio_subtract<std::ratio<3,8>, std::ratio<5,12>>::type r; - VERIFY( r.num == -1); - VERIFY( r.den == 24); + VERIFY( r.num == -1 ); + VERIFY( r.den == 24 ); } void @@ -52,8 +51,8 @@ test03() bool test __attribute__((unused)) = true; std::ratio_multiply<std::ratio<3,8>, std::ratio<5,12>>::type r; - VERIFY( r.num == 5); - VERIFY( r.den == 32); + VERIFY( r.num == 5 ); + VERIFY( r.den == 32 ); } void @@ -62,19 +61,15 @@ test04() bool test __attribute__((unused)) = true; std::ratio_divide<std::ratio<3,8>, std::ratio<5,12>>::type r; - VERIFY( r.num == 9); - VERIFY( r.den == 10); + VERIFY( r.num == 9 ); + VERIFY( r.den == 10 ); } -#endif //_GLIBCXX_USE_C99_STDINT_TR1 - int main() { -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 test01(); test02(); test03(); test04(); -#endif //_GLIBCXX_USE_C99_STDINT_TR1 return 0; } diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc index 2dc2be6b6d8..3d3241f3128 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops2.cc @@ -1,4 +1,5 @@ // { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // 2008-07-03 Chris Fairles <chris.fairles@gmail.com> @@ -23,8 +24,6 @@ #include <ratio> #include <testsuite_hooks.h> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - typedef std::ratio<1, INTMAX_MAX> one_over_max; typedef std::ratio<2, INTMAX_MAX> two_over_max; typedef std::ratio<INTMAX_MAX, 1> max_over_one; @@ -44,8 +43,8 @@ test01() std::ratio<INTMAX_MAX / 2, INTMAX_MAX / 2>, std::ratio<INTMAX_MAX / 2 , INTMAX_MAX / 2 + 1>>::type r2; - VERIFY( r2.num == INTMAX_MAX); - VERIFY( r2.den == (INTMAX_MAX / 2) + 1); + VERIFY( r2.num == INTMAX_MAX ); + VERIFY( r2.den == (INTMAX_MAX / 2) + 1 ); } void @@ -62,17 +61,13 @@ test02() std::ratio<INTMAX_MAX / 2, INTMAX_MAX / 2>, std::ratio<INTMAX_MAX / 2 , INTMAX_MAX / 2 + 1>>::type r2; - VERIFY( r2.num == 1); - VERIFY( r2.den == (INTMAX_MAX / 2) + 1); + VERIFY( r2.num == 1 ); + VERIFY( r2.den == (INTMAX_MAX / 2) + 1 ); } -#endif //_GLIBCXX_USE_C99_STDINT_TR1 - int main() { -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 test01(); test02(); -#endif //_GLIBCXX_USE_C99_STDINT_TR1 return 0; } diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc index d66c37cf383..2008275a216 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops3.cc @@ -1,4 +1,5 @@ // { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // 2008-07-03 Chris Fairles <chris.fairles@gmail.com> @@ -23,8 +24,6 @@ #include <ratio> #include <testsuite_hooks.h> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - void test01() { @@ -34,15 +33,15 @@ test01() std::ratio<2, INTMAX_MAX>, std::ratio<INTMAX_MAX, 2>>::type r1; - VERIFY( r1.num == 1); - VERIFY( r1.den == 1); + VERIFY( r1.num == 1 ); + VERIFY( r1.den == 1 ); std::ratio_multiply< std::ratio<INTMAX_MAX, 2>, std::ratio<2 , INTMAX_MAX - 1>>::type r2; - VERIFY( r2.num == INTMAX_MAX); - VERIFY( r2.den == INTMAX_MAX - 1); + VERIFY( r2.num == INTMAX_MAX ); + VERIFY( r2.den == INTMAX_MAX - 1 ); } void @@ -54,24 +53,20 @@ test02() std::ratio<INTMAX_MAX, 2>, std::ratio<INTMAX_MAX, 2>>::type r1; - VERIFY( r1.num == 1); - VERIFY( r1.den == 1); + VERIFY( r1.num == 1 ); + VERIFY( r1.den == 1 ); std::ratio_divide< std::ratio<INTMAX_MAX-1, 2>, std::ratio<INTMAX_MAX, 2>>::type r2; - VERIFY( r2.num == INTMAX_MAX - 1); - VERIFY( r2.den == INTMAX_MAX); + VERIFY( r2.num == INTMAX_MAX - 1 ); + VERIFY( r2.den == INTMAX_MAX ); } -#endif //_GLIBCXX_USE_C99_STDINT_TR1 - int main() { -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 test01(); test02(); -#endif //_GLIBCXX_USE_C99_STDINT_TR1 return 0; } diff --git a/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc index 7dffda39da2..860f9f253b2 100644 --- a/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc +++ b/libstdc++-v3/testsuite/20_util/ratio/operations/ops_overflow.cc @@ -1,5 +1,6 @@ -// { dg-options "-std=gnu++0x" } // { dg-do compile } +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } // 2008-07-03 Chris Fairles <chris.fairles@gmail.com> @@ -23,8 +24,6 @@ #include <ratio> -#ifdef _GLIBCXX_USE_C99_STDINT_TR1 - void test01() { @@ -38,14 +37,12 @@ test02() std::ratio_multiply<std::ratio<INTMAX_MAX>, std::ratio<INTMAX_MAX>>::type r2; } -// { dg-error "instantiated from here" "" { target *-*-* } 31 } +// { dg-error "instantiated from here" "" { target *-*-* } 30 } +// { dg-error "instantiated from here" "" { target *-*-* } 36 } // { dg-error "instantiated from here" "" { target *-*-* } 37 } -// { dg-error "instantiated from here" "" { target *-*-* } 38 } // { dg-error "overflow in addition" "" { target *-*-* } 127 } // { dg-error "overflow in multiplication" "" { target *-*-* } 95 } // { dg-error "overflow in multiplication" "" { target *-*-* } 97 } // { dg-error "overflow in multiplication" "" { target *-*-* } 99 } // { dg-excess-errors "In instantiation of" } // { dg-excess-errors "out of range" } - -#endif //_GLIBCXX_USE_C99_STDINT_TR1 diff --git a/libstdc++-v3/testsuite/lib/dg-options.exp b/libstdc++-v3/testsuite/lib/dg-options.exp index 327b691fc0f..e2d22ae598b 100644 --- a/libstdc++-v3/testsuite/lib/dg-options.exp +++ b/libstdc++-v3/testsuite/lib/dg-options.exp @@ -88,3 +88,12 @@ proc dg-require-rvalref { args } { } return } + +proc dg-require-cstdint { args } { + if { ![ check_v3_target_cstdint ] } { + upvar dg-do-what dg-do-what + set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] + return + } + return +} diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp index d6b372b80ef..d8c168defac 100644 --- a/libstdc++-v3/testsuite/lib/libstdc++.exp +++ b/libstdc++-v3/testsuite/lib/libstdc++.exp @@ -1,6 +1,6 @@ # libstdc++ "tool init file" for DejaGNU -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify @@ -939,7 +939,7 @@ proc check_v3_target_debug_mode { } { } else { set et_debug_mode 0 - # Set up, compile, and execute a C++ test program that depends + # Set up and compile a C++ test program that depends # on debug mode working. set src debug_mode[pid].cc set exe debug_mode[pid].exe @@ -993,7 +993,7 @@ proc check_v3_target_parallel_mode { } { } else { set et_parallel_mode 0 - # Set up, compile, and execute a C++ test program that depends + # Set up and compile a C++ test program that depends # on parallel mode working. set src parallel_mode[pid].cc set exe parallel_mode[pid].exe @@ -1021,3 +1021,61 @@ proc check_v3_target_parallel_mode { } { verbose "check_v3_target_parallel_mode: $et_parallel_mode" 2 return $et_parallel_mode } + +proc check_v3_target_cstdint { } { + global cxxflags + global DEFAULT_CXXFLAGS + global et_cstdint + + global tool + + if { ![info exists et_cstdint_target_name] } { + set et_cstdint_target_name "" + } + + # If the target has changed since we set the cached value, clear it. + set current_target [current_target_name] + if { $current_target != $et_cstdint_target_name } { + verbose "check_v3_target_cstdint: `$et_cstdint_target_name'" 2 + set et_cstdint_target_name $current_target + if [info exists et_cstdint] { + verbose "check_v3_target_cstdint: removing cached result" 2 + unset et_cstdint + } + } + + if [info exists et_cstdint] { + verbose "check_v3_target_cstdint: using cached result" 2 + } else { + set et_cstdint 0 + + # Set up and compile a C++0x test program that depends + # on the C99 stdint facilities to be available. + set src cstdint[pid].cc + set exe cstdint[pid].exe + + set f [open $src "w"] + puts $f "#include <cstdint>" + puts $f "int main()" + puts $f "#ifdef _GLIBCXX_USE_C99_STDINT_TR1" + puts $f "{ return 0; }" + puts $f "#endif" + close $f + + set cxxflags_saved $cxxflags + set cxxflags "$cxxflags $DEFAULT_CXXFLAGS -std=gnu++0x -Werror" + + set lines [v3_target_compile $src $exe executable ""] + set cxxflags $cxxflags_saved + file delete $src + + if [string match "" $lines] { + # No error message, compilation succeeded. + set et_cstdint 1 + } else { + verbose "check_v3_target_cstdint: compilation failed" 2 + } + } + verbose "check_v3_target_cstdint: $et_cstdint" 2 + return $et_cstdint +} |