aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-11-01 21:31:40 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-11-01 21:31:40 -0400
commit2bfe0527cd744a6f526fe11dd6c11ab39ad0a653 (patch)
tree5361d6c7e3709d19625d07d0d987fa9edd7ff5db /gcc/cp
parentddbbc9a109f3d8b91f5ba43a4b0d933d048a3b0f (diff)
downloadgcc-2bfe0527cd744a6f526fe11dd6c11ab39ad0a653.zip
gcc-2bfe0527cd744a6f526fe11dd6c11ab39ad0a653.tar.gz
gcc-2bfe0527cd744a6f526fe11dd6c11ab39ad0a653.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/error.c27
-rw-r--r--gcc/cp/semantics.c48
4 files changed, 74 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 93f1b7a..df32c8a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e408ef7..f57efb9 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 9ad2b93..6f60c06 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 2b8e9e3..3215410 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;
}