aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-parser.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2009-04-20 19:35:00 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2009-04-20 19:35:00 +0000
commitbbbbb16a888987aea0b85ce1133cf1dac4557ecc (patch)
treed88108cb1bacca1da6cfae95a807a42f3c5f612b /gcc/c-parser.c
parentc2efda0dee082ae3f57bdb2c7b1ae2dbf07ddfcd (diff)
downloadgcc-bbbbb16a888987aea0b85ce1133cf1dac4557ecc.zip
gcc-bbbbb16a888987aea0b85ce1133cf1dac4557ecc.tar.gz
gcc-bbbbb16a888987aea0b85ce1133cf1dac4557ecc.tar.bz2
Fix enum conversions which are invalid in C++:
gcc/: Fix enum conversions which are invalid in C++: * auto-inc-dec.c (attempt_change): Change 0 to SET in function call. * calls.c (store_one_arg): Change 0 to EXPAND_NORMAL in function call. * cse.c (hash_rtx_cb): Change 0 to VOIDmode in function call. * dbgcnt.c (dbg_cnt_set_limit_by_name): Add cast to enum type. * dbxout.c (dbxout_symbol): Change 0 to VOIDmode in function call. (dbxout_parms): Likewise. * df-core.c (df_set_flags): Change changeable_flags parameter to int. (df_clear_flags): Likewise. * df-problems.c (df_rd_bb_local_compute_process_def): Change top_flag parameter to int. (df_chain_create_bb_process_use): Likewise. (df_chain_add_problem): Change chain_flags parameter to unsigned int. Remove cast. * df-scan.c (df_ref_create): Change ref_flags parameter to int. (df_ref_create_structure, df_def_record_1): Likewise. (df_defs_record, df_uses_record, df_get_call_refs): Likewise. (df_notes_rescan): Change 0 to VOIDmode in function call. (df_get_call_refs, df_insn_refs_collect): Likewise. (df_bb_regs_collect): Likewise. (df_entry_block_defs_collect): Likewise. (df_exit_block_uses_collect): Likewise. * df.h: Update declarations. * double-int.c (double_int_divmod): Add cast to enum type. * dse.c (replace_inc_dec): Reverse parameters to gen_int_mode. * dwarf2out.c (new_reg_loc_descr): Add casts to enum type. (based_loc_descr): Likewise. (loc_descriptor_from_tree_1): Change first_op and second_op to enum dwarf_location_atom. Add cast to enum type. * expmed.c (init_expmed): Change 0 to SET in function call. * expr.c (init_expr_target): Change 0 to VOIDmode in function call. (expand_expr_real_1): Change 0 to EXPAND_NORMAL in function call. (do_store_flag): Likewise. * fixed-value.h (struct fixed_value): Change mode to enum machine_mode. * function.c (assign_parms): Change 0 to VOIDmode in function call. * genautomata.c (insert_automaton_decl): Change 1 to INSERT in function call. (insert_insn_decl, insert_decl, insert_state): Likewise. (automata_list_finish): Likewise. * genrecog.c (process_define_predicate): Add cast to enum type. * gensupport.c (init_predicate_table): Add cast to enum type. * gimple.c (gimple_build_return): Change 0 to ERROR_MARK in function call. (gimple_build_call_1, gimple_build_label): Likewise. (gimple_build_goto, gimple_build_asm_1): Likewise. (gimple_build_switch_1, gimple_build_cdt): Likewise. * gimple.h (GIMPLE_CHECK): Change 0 to ERROR_MARK in function call. (enum fallback): Rename from enum fallback_t. (fallback_t): Typedef as int. * gimple-low.c (lower_builtin_setjmp): Change TSI_SAME_STMT to GSI_SAME_STMT in function call. * ira.c (setup_class_subset_and_memory_move_costs): Add casts to enum type. (setup_reg_class_relations): Likewise. (setup_reg_class_nregs): Change cl to int. Add casts to enum type. (setup_prohibited_class_mode_regs): Add cast to enum type. (setup_prohibited_mode_move_regs): Likewise. * ira-costs.c (record_reg_classes): Change rclass to enum reg_class. (record_address_regs): Change i to enum reg_class. * lists.c (alloc_EXPR_LIST): Add cast to enum type. * machmode.h (GET_MODE_CLASS): Cast value to enum mode_class. (GET_MODE_WIDER_MODE): Cast value to enum machine_mode. (GET_MODE_2XWIDER_MODE): Likewise. (GET_CLASS_NARROWEST_MODE): Likewise. * omp-low.c (expand_omp_for): Add cast to enum type. * optabs.c (debug_optab_libfuncs): Add casts to enum type. * opts.c (enable_warning_as_error): Change kind to diagostic_t. * postreload.c (reload_cse_simplify_operands): Change rclass local to enum reg_class. * predict.c (combine_predictions_for_insn): Change best_predictor and predictor to enum br_predictor. (combine_predictions_for_bb): Likewise. (build_predict_expr): Change assignment to PREDICT_EXPR_OUTCOME to use SET_PREDICT_EXPR_OUTCOME. * real.c (real_arithmetic): Change icode to code in function call. * reginfo.c (init_move_cost): Add casts to enum type. (init_reg_sets_1, init_fake_stack_mems): Likewise. * regmove.c (regclass_compatible_p): Change class0 and class1 to enum reg_class. * reload.c (find_valid_class): Add casts to enum type. (push_reload): Change 0 to NO_REGS in function call. (find_reloads): Change this_alternative to array of enum reg_class. Remove some now-unnecessary casts. (make_memloc): Change 0 to VOIDmode in function call. * reload1.c (reload): Change 0 to VOIDmode in function call. (eliminate_regs_1, elimination_effects): Likewise. (eliminate_regs_in_insn): Likewise. (emit_input_reload_insns): Add cast to enum type. (delete_output_reload): Change 0 to VOIDmode in function call. * reorg.c (insn_sets_resource_p): Convert include_delayed_effects to enum type in function call. * tree.h (PREDICT_EXPR_OUTCOME): Add cast to enum type. (SET_PREDICT_EXPR_OUTCOME): Define. * tree-dump.c (get_dump_file_info): Change phase parameter to int. (get_dump_file_name, dump_begin, dump_enabled_p): Likewise. (dump_initialized_p, dump_flag_name, dump_end): Likewise. (dump_function): Likewise. * tree-dump.h: Update declarations. * tree-pass.h: Update declarations. * varasm.c (assemble_integer): Change mclass to enum mode_class. * config/arm/arm.c (thumb_legitimize_reload_address): Add cast to enum type. (arm_rtx_costs_1): Correct parenthesization. (arm_rtx_costs): Add casts to enum type. (adjacent_mem_locations): Reverse arguments to const_ok_for_op. (vfp_emit_fstmd): Use add_rg_note. (emit_multi_reg_push, emit_sfm): Likewise. (thumb_set_frame_pointer): Likewise. (arm_expand_prologue): Likewise. (arm_regno_class): Change return type to enum reg_class. (thumb1_expand_prologue): Use add_reg_note. * config/arm/arm-protos.h (arm_regno_class): Update declaration. * config/arm/arm.h (INITIALIZE_TRAMPOLINE): Change 0 to LCT_NORMAL in function call. * config/arm/gentune.sh: Add cast to enum type. * config/arm/arm-tune.md: Rebuild. * config/i386/i386.c (ix86_expand_prologue): Use add_reg_note. (ix86_split_fp_branch, predict_jump): Likewise. (ix86_expand_multi_arg_builtin): Change sub_code from enum insn_code to enum rtx_code. (ix86_builtin_vectorized_function): Add cast to enum type. * config/i386/i386.md (truncdfsf2): Change slot to enum ix86_stack_slot. (truncxf<mode>2, isinf<mode>2): Likewise. * config/i386/i386-c.c (ix86_pragma_target_parse): Add cast to enum type. * config/ia64/ia64.c (ia64_split_tmode_move): Use add_reg_note. (spill_restore_mem, do_spill, ia64_expand_prologue): Likewise. (insert_bundle_state): Change 1 to INSERT in function call. (ia64_add_bundle_selector_before): Likewise. * config/ia64/ia64.md (cpu attr): Add cast to enum type. (save_stack_nonlocal): Change 0 to LCT_NORMAL in function call. (restore_stack_nonlocal): Likewise. * config/mips/mips.h (MIPS_ICACHE_SYNC): Change 0 to LCT_NORMAL in function call. * config/mips/mips.c (mips_binary_cost): Change 0 to SET in function call. (mips_rtx_costs): Likewise. (mips_override_options): Add casts to enum type. * config/mips/sdemtk.h (MIPS_ICACHE_SYNC): Change 0 to LCT_NORMAL in function call. * config/pa/pa.c (legitimize_pic_address): Use add_reg_note. (store_reg, set_reg_plus_d): Likewise. (hppa_expand_prologue, hppa_profile_hook): Likewise. * config/rs6000/rs6000.c (rs6000_init_hard_regno_mode_ok): Add cast to enum type. (altivec_expand_vec_set_builtin): Change 0 to EXPAND_NORMAL in function call. (emit_unlikely_jump): Use add_reg_note. (rs6000_emit_allocate_stack): Likewise. (rs6000_frame_related, rs6000_emit_prologue): Likewise. (output_toc): Change 1 to INSERT in function call. (output_profile_hook): Change 0 to LCT_NORMAL in function call. (rs6000_initialize_trampoline): Likewise. (rs6000_init_dwarf_reg_sizes_extra): Change 0 to EXPAND_NORMAL in function call. * config/s390/s390.c (s390_rtx_costs): Add cast to enum type. (s390_expand_movmem): Change 0 to OPTAB_DIRECT in function call. (s390_expand_setmem, s390_expand_cmpmem): Likewise. (save_gprs): Use add_reg_note. (s390_emit_prologue): Likewise. (s390_expand_builtin): Change 0 to EXPAND_NORMAL in function call. * config/sparc/sparc.c (sparc_expand_prologue): Use add_reg_note. (sparc_fold_builtin): Add cast to enum type. * config/spu/spu.c (spu_emit_branch_or_set): Change ior_code to enum insn_code. (spu_expand_prologue): Use add_reg_note. (expand_builtin_args): Change 0 to EXPAND_NORMAL in function call. * c-parser.c (c_parser_attributes): Change VEC back to tree list. (c_parser_postfix_expression_after_primary): Get VEC for list of arguments. Get original types of arguments. Call build_function_call_vec. (cached_expr_list_1, cached_expr_list_2): New static variables. (c_parser_expr_list): Change return type to VEC *. Add p_orig_types parameter. Change all callers. (c_parser_release_expr): New static function. (c_parser_vec_to_tree_list): New static function. * c-typeck.c (build_function_call): Rewrite to build a VEC and call build_function_call_vec. (build_function_call_vec): New function, based on old build_function_call. (convert_arguments): Remove nargs and argarray parameters. Change values to a VEC. Add origtypes parameter. (build_modify_expr): Add rhs_origtype parameter. Change all callers. (convert_for_assignment): Add origtype parameter. Change all callers. If warn_cxx_compat, check for conversion to an enum type when calling a function. (store_init_value): Add origtype parameter. Change all callers. (digest_init): Likewise. (struct init_node): Add origtype field. (add_pending_init): Add origtype parameter. Change all callers. (output_init_element): Likewise. (output_pending_init_elements): Pass origtype from init_node to output_init_element. (process_init_elemnt): Pass origtype from c_expr to output_init_element. (c_finish_return): Add origtype parameter. Change all callers. * c-common.c (sync_resolve_size): Change params to VEC *. Change caller. (sync_resolve_params): Likewise. (sync_resolve_return): Change params to first_param. Change caller. (resolve_overloaded_builtins): Change params to VEC *. Change callers. Save first parameter around call to build_function_call_vec. * c-decl.c (finish_decl): Add origtype parameter. Change all callers. Call build_function_call_vec rather than build_function_call for cleanup. * c-tree.h: Update declarations. * c-common.h: Update declarations. * stub-objc.c (objc_rewrite_function_call): Change parameter from params to first_param. * target.h (struct gcc_target): Change resolve_overloaded_builtin params parameter from tree to void *. * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Change arglist parameter to have type void *, and to be a pointer to a VEC. * config/rs6000/rs6000-protos.h (altivec_resolve_overloaded_builtin): Update declaration. * config/spu/spu-c.c (spu_resolved_overloaded_builtin): Change fnargs parameter to have type void *, and to be a pointer to a VEC. Call build_function_call_vec instead of build_function_call. * config/spu/spu-protos.h (spu_expand_builtin): Update declaration. gcc/cp/: * typeck.c (build_function_call_vec): New function. (cp_build_function_call): Only pass first parameter to objc_rewrite_function_call. (build_modify_expr): Add rhs_origtype parameter. Change all callers. * decl.c (finish_decl): Add origtype parameter. Change all callers. * semantics.c (finish_call_expr): Pass VEC to resolve_overloaded_builtin. gcc/objc: * objc-act.c (objc_rewrite_function_call): Change parameter from params to first_param. Change all callers. gcc/testsuite: * gcc.dg/Wcxx-compat-3.c: New testcase. From-SVN: r146451
Diffstat (limited to 'gcc/c-parser.c')
-rw-r--r--gcc/c-parser.c144
1 files changed, 120 insertions, 24 deletions
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 9b3ace5..e5129dc 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -916,7 +916,10 @@ static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
struct c_expr);
static struct c_expr c_parser_expression (c_parser *);
static struct c_expr c_parser_expression_conv (c_parser *);
-static tree c_parser_expr_list (c_parser *, bool, bool);
+static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
+ VEC(tree,gc) **);
+static void c_parser_release_expr_list (VEC(tree,gc) *);
+static tree c_parser_vec_to_tree_list (VEC(tree,gc) *);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
@@ -1230,7 +1233,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
if (d != error_mark_node)
{
maybe_warn_string_init (TREE_TYPE (d), init);
- finish_decl (d, init.value, asm_name);
+ finish_decl (d, init.value, init.original_type, asm_name);
}
}
else
@@ -1239,7 +1242,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
chainon (postfix_attrs,
all_prefix_attrs));
if (d)
- finish_decl (d, NULL_TREE, asm_name);
+ finish_decl (d, NULL_TREE, NULL_TREE, asm_name);
}
if (c_parser_next_token_is (parser, CPP_COMMA))
{
@@ -2786,6 +2789,7 @@ c_parser_attributes (c_parser *parser)
|| c_parser_next_token_is (parser, CPP_KEYWORD))
{
tree attr, attr_name, attr_args;
+ VEC(tree,gc) *expr_list;
if (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
@@ -2864,10 +2868,12 @@ c_parser_attributes (c_parser *parser)
attr_args = build_tree_list (NULL_TREE, arg1);
else
{
+ tree tree_list;
c_parser_consume_token (parser);
- attr_args = tree_cons (NULL_TREE, arg1,
- c_parser_expr_list (parser, false,
- true));
+ expr_list = c_parser_expr_list (parser, false, true, NULL);
+ tree_list = c_parser_vec_to_tree_list (expr_list);
+ attr_args = tree_cons (NULL_TREE, arg1, tree_list);
+ c_parser_release_expr_list (expr_list);
}
}
else
@@ -2875,7 +2881,11 @@ c_parser_attributes (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
attr_args = NULL_TREE;
else
- attr_args = c_parser_expr_list (parser, false, true);
+ {
+ expr_list = c_parser_expr_list (parser, false, true, NULL);
+ attr_args = c_parser_vec_to_tree_list (expr_list);
+ c_parser_release_expr_list (expr_list);
+ }
}
attr = build_tree_list (attr_name, attr_args);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
@@ -3739,12 +3749,13 @@ c_parser_statement_after_labels (c_parser *parser)
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- stmt = c_finish_return (NULL_TREE);
+ stmt = c_finish_return (NULL_TREE, NULL_TREE);
c_parser_consume_token (parser);
}
else
{
- stmt = c_finish_return (c_parser_expression_conv (parser).value);
+ struct c_expr expr = c_parser_expression_conv (parser);
+ stmt = c_finish_return (expr.value, expr.original_type);
goto expect_semicolon;
}
break;
@@ -4434,7 +4445,8 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
c_parser_consume_token (parser);
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_conversion (rhs);
- ret.value = build_modify_expr (op_location, lhs.value, code, rhs.value);
+ ret.value = build_modify_expr (op_location, lhs.value, code, rhs.value,
+ rhs.original_type);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
@@ -5622,7 +5634,9 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
struct c_expr expr)
{
struct c_expr orig_expr;
- tree ident, idx, exprlist;
+ tree ident, idx;
+ VEC(tree,gc) *exprlist;
+ VEC(tree,gc) *origtypes;
location_t loc = c_parser_peek_token (parser)->location;
while (true)
{
@@ -5643,13 +5657,14 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
/* Function call. */
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- exprlist = NULL_TREE;
+ exprlist = NULL;
else
- exprlist = c_parser_expr_list (parser, true, false);
+ exprlist = c_parser_expr_list (parser, true, false, &origtypes);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
orig_expr = expr;
- expr.value = build_function_call (expr.value, exprlist);
+ expr.value = build_function_call_vec (expr.value, exprlist,
+ origtypes);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) == INTEGER_CST
&& TREE_CODE (orig_expr.value) == FUNCTION_DECL
@@ -5657,6 +5672,11 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
&& DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
expr.original_code = C_MAYBE_CONST_EXPR;
expr.original_type = NULL;
+ if (exprlist != NULL)
+ {
+ c_parser_release_expr_list (exprlist);
+ c_parser_release_expr_list (origtypes);
+ }
break;
case CPP_DOT:
/* Structure element reference. */
@@ -5788,17 +5808,55 @@ c_parser_expression_conv (c_parser *parser)
nonempty-expr-list , assignment-expression
*/
-static tree
-c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p)
+/* We cache two vectors, to save most allocation and deallocation. */
+static GTY((deletable)) VEC(tree,gc) *cached_expr_list_1;
+static GTY((deletable)) VEC(tree,gc) *cached_expr_list_2;
+
+static VEC(tree,gc) *
+c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
+ VEC(tree,gc) **p_orig_types)
{
+ VEC(tree,gc) *ret;
+ VEC(tree,gc) *orig_types;
struct c_expr expr;
- tree ret, cur;
+
+ if (cached_expr_list_1 != NULL)
+ {
+ ret = cached_expr_list_1;
+ cached_expr_list_1 = NULL;
+ VEC_truncate (tree, ret, 0);
+ }
+ else if (cached_expr_list_2 != NULL)
+ {
+ ret = cached_expr_list_2;
+ cached_expr_list_2 = NULL;
+ VEC_truncate (tree, ret, 0);
+ }
+ else
+ ret = VEC_alloc (tree, gc, 16);
+
+ if (p_orig_types == NULL)
+ orig_types = NULL;
+ else
+ {
+ if (cached_expr_list_2 != NULL)
+ {
+ orig_types = cached_expr_list_2;
+ cached_expr_list_2 = NULL;
+ VEC_truncate (tree, orig_types, 0);
+ }
+ else
+ orig_types = VEC_alloc (tree, gc, 16);
+ }
+
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
expr = default_function_array_conversion (expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
- ret = cur = build_tree_list (NULL_TREE, expr.value);
+ VEC_quick_push (tree, ret, expr.value);
+ if (orig_types != NULL)
+ VEC_quick_push (tree, orig_types, expr.original_type);
while (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
@@ -5807,11 +5865,45 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p)
expr = default_function_array_conversion (expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
- cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
+ VEC_safe_push (tree, gc, ret, expr.value);
+ if (orig_types != NULL)
+ VEC_safe_push (tree, gc, orig_types, expr.original_type);
}
+ if (orig_types != NULL)
+ *p_orig_types = orig_types;
return ret;
}
+/* Release a vector returned by c_parser_expr_list. */
+
+static void
+c_parser_release_expr_list (VEC(tree,gc) *vec)
+{
+ if (cached_expr_list_1 == NULL)
+ cached_expr_list_1 = vec;
+ else if (cached_expr_list_2 == NULL)
+ cached_expr_list_2 = vec;
+ else
+ VEC_free (tree, gc, vec);
+}
+
+/* Convert a vector, as returned by c_parser_expr_list, to a
+ tree_list. */
+
+static tree
+c_parser_vec_to_tree_list (VEC(tree,gc) *vec)
+{
+ tree ret = NULL_TREE;
+ tree *pp = &ret;
+ unsigned int i;
+ tree t;
+ for (i = 0; VEC_iterate (tree, vec, i, t); ++i)
+ {
+ *pp = build_tree_list (NULL, t);
+ pp = &TREE_CHAIN (*pp);
+ }
+ return ret;
+}
/* Parse Objective-C-specific constructs. */
@@ -6682,18 +6774,21 @@ c_parser_objc_message_args (c_parser *parser)
static tree
c_parser_objc_keywordexpr (c_parser *parser)
{
- tree list = c_parser_expr_list (parser, true, true);
- if (TREE_CHAIN (list) == NULL_TREE)
+ tree ret;
+ VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, NULL);
+ if (VEC_length (tree, expr_list) == 1)
{
/* Just return the expression, remove a level of
indirection. */
- return TREE_VALUE (list);
+ ret = VEC_index (tree, expr_list, 0);
}
else
{
/* We have a comma expression, we will collapse later. */
- return list;
+ ret = c_parser_vec_to_tree_list (expr_list);
}
+ c_parser_release_expr_list (expr_list);
+ return ret;
}
@@ -7738,7 +7833,8 @@ c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
init_exp = c_parser_expr_no_commas (parser, NULL);
init_exp = default_function_array_conversion (init_exp);
init = build_modify_expr (init_loc,
- decl, NOP_EXPR, init_exp.value);
+ decl, NOP_EXPR, init_exp.value,
+ init_exp.original_type);
init = c_process_expr_stmt (init);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");