semantics.c (call_stack, [...]): New.
* 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. From-SVN: r166169
This commit is contained in:
parent
ddbbc9a109
commit
2bfe0527cd
|
@ -1,5 +1,13 @@
|
|||
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.
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ constexpr pixel::pixel(int a)
|
|||
|
||||
// error: square not defined, so small(2) not constant (5.19), so constexpr
|
||||
// not satisfied
|
||||
constexpr pixel small(2); // { dg-error "" }
|
||||
constexpr pixel small(2); // { dg-message "in constexpr expansion" }
|
||||
|
||||
// error: not for parameters
|
||||
int next(constexpr int x) { // { dg-error "parameter" }
|
||||
|
|
|
@ -4,5 +4,5 @@ constexpr int may_throw(bool decide) {
|
|||
return decide ? 42 : throw -1; // { dg-error "throw" }
|
||||
}
|
||||
|
||||
constexpr int x = may_throw(false); // { dg-error "may_throw" }
|
||||
constexpr int x = may_throw(false); // { dg-message "may_throw" }
|
||||
constexpr int y = may_throw(true);
|
||||
|
|
Loading…
Reference in New Issue