diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 192 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/error.c | 27 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 79 |
4 files changed, 222 insertions, 77 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b3253e96f85..df32c8a2702 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,129 @@ +2010-11-01 Jason Merrill <jason@redhat.com> + + * semantics.c (call_stack, call_stack_tick, cx_error_context): New. + (last_cx_error_tick, push_cx_call_context, pop_cx_call_context): New. + (cxx_eval_call_expression): Call push/pop_cx_call_context instead + of giving follow-on errors. + * error.c (maybe_print_constexpr_context): New. + (cp_diagnostic_starter): Call it. + * cp-tree.h: Declare cx_error_context. + + * semantics.c (cxx_eval_constant_expression): Explain + unacceptable use of variable better. + +2010-11-01 Gabriel Dos Reis <gdr@cse.tamu.edu> + Jason Merrill <jason@redhat.com> + + * call.c (null_ptr_cst_p): Use maybe_constant_value. + (set_up_extended_ref_temp): Support constant initialization. + (initialize_reference): Adjust. + * class.c (check_bitfield_decl): Use cxx_constant_value. + * cvt.c (ocp_convert): Don't use integral_constant_value when + converting to class type. + * decl.c (finish_case_label): Use maybe_constant_value. + (build_init_list_var_init): Support constant initialization. + (check_initializer): Likewise. Reorganize. + (cp_finish_decl): Likewise. + (expand_static_init): Likewise. + (compute_array_index_type): Use maybe_constant_value. + Add complain parm. + (create_array_type_for_decl, grokdeclarator): Pass it. + (build_enumerator): Use cxx_constant_value. + * decl2.c (grokfield): Use maybe_constant_init. + * except.c (check_noexcept_r): Handle constexpr. + (build_noexcept_spec): Use maybe_constant_value. + * init.c (expand_default_init): Support constant initialization. + (build_vec_init): Likewise. + (constant_value_1): Adjust. + (build_new_1): Adjust. + * parser.c (cp_parser_constant_expression): Allow non-integral + in C++0x mode. + (cp_parser_direct_declarator): Don't fold yet in C++0x mode. + (cp_parser_initializer_clause): Toss folded result if non-constant. + * pt.c (fold_decl_constant_value): Remove. + (convert_nontype_argument): Use maybe_constant_value. Give clearer + error about overflow. + (tsubst): Move array bounds handling into compute_array_index_type. + (value_dependent_expression_p): Handle constant CALL_EXPR. + (tsubst_decl): Don't set + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P yet. + (tsubst_expr) [DECL_EXPR]: Pass it into cp_finish_decl. + (instantiate_decl): Here too. + * semantics.c (finish_static_assert): Use maybe_constant_value. + (ensure_literal_type_for_constexpr_object): Make sure type is complete. + (potential_constant_expression): Use maybe_constant_value. + * tree.c (cast_valid_in_integral_constant_expression_p): Any cast + is potentially valid in C++0x. + * typeck2.c (store_init_value): Handle constant init. + (check_narrowing): Use maybe_constant_value. + (build_functional_cast): Set TREE_CONSTANT on literal T(). + * cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): Remove. + (LOOKUP_ALREADY_DIGESTED): New. + (compute_array_index_type): Adjust prototype. + + * semantics.c (constexpr_call): New datatype. + (constexpr_call_table): New global table. + (constexpr_call_hash): New. + (constexpr_call_equal): Likewise. + (maybe_initialize_constexpr_call_table): Likewise. + (lookup_parameter_binding): Likewise. + (cxx_eval_builtin_function_call): Likewise. + (cxx_bind_parameters_in_call): Likewise. + (cxx_eval_call_expression): Likewise. + (cxx_eval_unary_expression): Likewise. + (cxx_eval_binary_expression): Likewise. + (cxx_eval_conditional_expression): Likewise. + (cxx_eval_array_reference): Likewise. + (cxx_eval_component_reference): Likewise. + (cxx_eval_logical_expression): Likewise. + (cxx_eval_object_construction): Likewise. + (cxx_eval_constant_expression): Likewise. + (cxx_eval_indirect_ref): Likewise. + (cxx_constant_value): Likewise. + (cxx_eval_bare_aggregate): Likewise. + (adjust_temp_type): New. + (reduced_constant_expression_p): New. + (verify_constant): New. + (cxx_eval_vec_init, cxx_eval_vec_init_1): New. + (cxx_eval_outermost_constant_expr): New. + (maybe_constant_value, maybe_constant_init): New. + (cxx_eval_constant_expression): Use them. + * pt.c (iterative_hash_template_arg): No longer static. + * cp-tree.h: Declare fns. + + * cp-tree.h (register_constexpr_fundef): Declare. + * decl.c (maybe_save_function_definition): New. + (finish_function): Use it. + * semantics.c (constexpr_fundef): New datatype. + (constexpr_fundef_table): New global table. + (constexpr_fundef_equal): New. + (constexpr_fundef_hash): Likewise. + (retrieve_constexpr_fundef): Likewise. + (validate_constexpr_fundecl): Store in the table. + (build_data_member_initialization): New fn. + (build_constexpr_constructor_member_initializers): New. + (register_constexpr_fundef): Define. + (is_this_parameter): New. + (get_function_named_in_call): Likewise. + (get_nth_callarg): Likewise. + (check_automatic_or_tls): New. + (morally_constexpr_builtin_function_p): New. + (potential_constant_expression): New. + +2010-11-01 Jason Merrill <jason@redhat.com> + + * decl2.c (decl_constant_var_p): New fn. + (decl_maybe_constant_var_p): New fn. + (mark_used): Rework instantiation of things needed for constant + expressions. + * cp-tree.h: Declare new fns. + * pt.c (instantiate_decl): Handle cp_unevaluated_operand. + (always_instantiate_p): Use decl_maybe_constant_var_p. + (instantiate_decl): Don't defer constexpr functions. + * repo.c (repo_emit_p): Use decl_maybe_constant_var_p. + * semantics.c (finish_id_expression): Use decl_constant_var_p. + Check for valid name in constant expr after mark_used. + 2010-10-31 Jason Merrill <jason@redhat.com> * class.c (is_really_empty_class): Work when type is not complete. @@ -2355,72 +2481,6 @@ * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Change the prototype. -2010-03-10 Gabriel Dos Reis <gdr@cse.tamu.edu> - - * parser.c (cp_parser_ctor_initializer_opt_and_function_body): - Check body of constexpr constructors. - * cp-tree.h (TYPE_ARRAY_P): New. - (hash_constexpr_args): Declare. - (register_constexpr_fundef): Likewise. - (cxx_constant_value): Likewise. - (generalized_constant_expression_allowed): New. - * decl.c (validate_constexpr_redeclaration): New. - (duplicate_decls): Use it. - (cp_finish_decl): Validate constexpr bit. - (grokdeclarator): Check uses of constexpr specifier. - (maybe_save_function_definition): New. - (finish_function): Use it. - * class.c (check_bases): Accumulate literal type property from - base classes. - (check_field_decls): Same for non-static data members. - (finalize_literal_type_property): New. - (check_bases_and_members): Use it. - (finish_struct_1): Assume the class being processed is literal. - * typeck2.c (store_init_value): Fold initializers of - constexpr variables. - * pt.c (hash_constexpr_args): Define. - * semantics.c (ensure_literal_type_for_constexpr_object): Tidy. - (constexpr_fundef): New datatype. - (constexpr_fundef_table): New global table. - (constexpr_fundef_equal): New. - (constexpr_fundef_hash): Likewise. - (retrieve_constexpr_fundef): Likewise. - (validate_constexpr_fundecl): Tidy. Allow constexpr function - declarations that are not definitions. - (build_constexpr_constructor_member_initializers): New. - (register_constexpr_fundef): Define. - (constexpr_call): New datatype. - (constexpr_call_table): New global table. - (constexpr_call_hash): New. - (constexpr_call_equal): Likewise. - (maybe_initialize_constexpr_call_table): Likewise. - (is_this_parameter): Likewise. - (get_function_named_in_call): Likewise. - (get_nth_callarg): Likewise. - (lookup_parameter_binding): Likewise. - (cxx_eval_builtin_function_call): Likewise. - (cxx_bind_parameters_in_call): Likewise. - (cxx_eval_call_expression): Likewise. - (cxx_eval_unary_expression): Likewise. - (cxx_eval_binary_expression): Likewise. - (cxx_eval_conditional_expression): Likewise. - (cxx_eval_array_reference): Likewise. - (cxx_eval_component_reference): Likewise. - (cxx_eval_logical_expression): Likewise. - (cxx_eval_object_construction): Likewise. - (cxx_eval_constant_expression): Likewise. - (cxx_constant_value): Define. - (has_automatic_or_tls): New. - (morally_constexpr_builtin_function_p): Likewise. - (potential_constant_expression): Likewise. - (valid_type_in_constexpr_fundecl_p): New. - (validate_constexpr_fundecl): Use it. - (valid_for_static_initialization_p): New. - (cxx_eval_bare_aggregate): Likewise. - (implicit_dereference_p): Likewise. - (implicit_address_p): Likewise. - (cxx_eval_constant_expression): Use them. - 2010-05-06 Magnus Fromreide <magfr@lysator.liu.se> Jason Merrill <jason@redhat.com> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index e408ef7ea6e..f57efb91acf 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5246,6 +5246,7 @@ extern tree maybe_constant_value (tree); extern tree maybe_constant_init (tree); extern bool is_sub_constant_expr (tree); extern bool reduced_constant_expression_p (tree); +extern VEC(tree,heap)* cx_error_context (void); enum { BCS_NO_SCOPE = 1, diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 9ad2b93844c..6f60c06887c 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -86,6 +86,7 @@ static void dump_scope (tree, int); static void dump_template_parms (tree, int, int); static int get_non_default_template_args_count (tree, int); static const char *function_category (tree); +static void maybe_print_constexpr_context (diagnostic_context *); static void maybe_print_instantiation_context (diagnostic_context *); static void print_instantiation_full_context (diagnostic_context *); static void print_instantiation_partial_context (diagnostic_context *, @@ -2635,6 +2636,7 @@ cp_diagnostic_starter (diagnostic_context *context, diagnostic_report_current_module (context); cp_print_error_function (context, diagnostic); maybe_print_instantiation_context (context); + maybe_print_constexpr_context (context); pp_base_set_prefix (context->printer, diagnostic_build_prefix (context, diagnostic)); } @@ -2955,6 +2957,31 @@ print_instantiation_context (void) diagnostic_flush_buffer (global_dc); } +/* Report what constexpr call(s) we're trying to expand, if any. */ + +void +maybe_print_constexpr_context (diagnostic_context *context) +{ + VEC(tree,heap) *call_stack = cx_error_context (); + unsigned ix; + tree t; + + FOR_EACH_VEC_ELT (tree, call_stack, ix, t) + { + expanded_location xloc = expand_location (EXPR_LOCATION (t)); + const char *s = expr_as_string (t, 0); + if (context->show_column) + pp_verbatim (context->printer, + _("%s:%d:%d: in constexpr expansion of %qs"), + xloc.file, xloc.line, xloc.column, s); + else + pp_verbatim (context->printer, + _("%s:%d: in constexpr expansion of %qs"), + xloc.file, xloc.line, s); + pp_base_newline (context->printer); + } +} + /* Called from output_format -- during diagnostic message processing -- to handle C++ specific format specifier with the following meanings: %A function argument-list. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 397d383f650..32154108107 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -5805,6 +5805,40 @@ cxx_bind_parameters_in_call (const constexpr_call *old_call, tree t, } } +/* Variables and functions to manage constexpr call expansion context. + These do not need to be marked for PCH or GC. */ + +static VEC(tree,heap) *call_stack = NULL; +static int call_stack_tick; +static int last_cx_error_tick; + +static void +push_cx_call_context (tree call) +{ + ++call_stack_tick; + if (!EXPR_HAS_LOCATION (call)) + SET_EXPR_LOCATION (call, input_location); + VEC_safe_push (tree, heap, call_stack, call); +} + +static void +pop_cx_call_context (void) +{ + ++call_stack_tick; + VEC_pop (tree, call_stack); +} + +VEC(tree,heap) * +cx_error_context (void) +{ + VEC(tree,heap) *r = NULL; + if (call_stack_tick != last_cx_error_tick + && !VEC_empty (tree, call_stack)) + r = call_stack; + last_cx_error_tick = call_stack_tick; + return r; +} + /* Subroutine of cxx_eval_constant_expression. Evaluate the call expression tree T in the context of OLD_CALL expression evaluation. */ @@ -5814,13 +5848,11 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t, bool allow_non_constant, bool addr, bool *non_constant_p) { - location_t loc = EXPR_LOCATION (t); + location_t loc = EXPR_LOC_OR_HERE (t); tree fun = get_function_named_in_call (t); tree result; constexpr_call new_call = { NULL, NULL, NULL, 0 }; constexpr_call **slot; - if (loc == UNKNOWN_LOCATION) - loc = input_location; if (TREE_CODE (fun) != FUNCTION_DECL) { /* Might be a constexpr function pointer. */ @@ -5875,6 +5907,8 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t, if (*non_constant_p) return t; + push_cx_call_context (t); + new_call.hash = iterative_hash_template_arg (new_call.bindings, constexpr_fundef_hash (new_call.fundef)); @@ -5933,13 +5967,7 @@ cxx_eval_call_expression (const constexpr_call *old_call, tree t, } } - if (result == error_mark_node) - { - if (!allow_non_constant) - error_at (loc, "in expansion of %qE", t); - *non_constant_p = true; - result = t; - } + pop_cx_call_context (); return result; } @@ -6513,7 +6541,36 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t, if (DECL_P (r)) { if (!allow_non_constant) - error ("%qD cannot appear in a constant expression", r); + { + tree type = TREE_TYPE (r); + error ("the value of %qD is not usable in a constant " + "expression", r); + if (INTEGRAL_OR_ENUMERATION_TYPE_P (type)) + { + if (!CP_TYPE_CONST_P (type)) + inform (DECL_SOURCE_LOCATION (r), + "%q#D is not const", r); + else if (CP_TYPE_VOLATILE_P (type)) + inform (DECL_SOURCE_LOCATION (r), + "%q#D is volatile", r); + else if (!DECL_INITIAL (r)) + inform (DECL_SOURCE_LOCATION (r), + "%qD was not initialized with a constant " + "expression", r); + else + gcc_unreachable (); + } + else + { + if (cxx_dialect >= cxx0x && !DECL_DECLARED_CONSTEXPR_P (r)) + inform (DECL_SOURCE_LOCATION (r), + "%qD was not declared %<constexpr%>", r); + else + inform (DECL_SOURCE_LOCATION (r), + "%qD does not have integral or enumeration type", + r); + } + } *non_constant_p = true; } break; |