summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog192
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/error.c27
-rw-r--r--gcc/cp/semantics.c79
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;