OSDN Git Service

* semantics.c (call_stack, call_stack_tick, cx_error_context): New.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Nov 2010 01:31:40 +0000 (01:31 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Nov 2010 01:31:40 +0000 (01:31 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166169 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/error.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C
gcc/testsuite/g++.dg/cpp0x/constexpr-throw.C

index 93f1b7a..df32c8a 100644 (file)
@@ -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.
 
index e408ef7..f57efb9 100644 (file)
@@ -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,
index 9ad2b93..6f60c06 100644 (file)
@@ -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);
 }
 \f
+/* 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);
+    }
+}
+\f
 /* Called from output_format -- during diagnostic message processing --
    to handle C++ specific format specifier with the following meanings:
    %A   function argument-list.
index 2b8e9e3..3215410 100644 (file)
@@ -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;
 }
 
index ce01f8b..8294afa 100644 (file)
@@ -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" }
index 345b240..f1ef9dc 100644 (file)
@@ -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);