public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Several small C++ constexpr PATCHes, including c++/63924 (constexpr and empty classes)
@ 2014-11-19  7:19 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2014-11-19  7:19 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 661 bytes --]

The first patch fixes 63924; I'm not sure whether or not it is really 
valid, but it's easy enough to allow "copying" a non-constant empty 
class object.

The second patch fixes GNU statement-expressions in 
constant-expressions.  This is mostly interesting statement-expressions 
are used internally by e.g. build_vec_init, and another patch I'm 
working on broke because they weren't supported properly.

The last two patches are basically reformatting.  The third moves the 
allow_non_const flag into constexpr_ctx, and the fourth replaces all the 
explicit NULL jump_target arguments with a default argument.

Tested x86_64-pc-linux-gnu, applying to trunk.

[-- Attachment #2: 63924.patch --]
[-- Type: text/x-patch, Size: 1269 bytes --]

commit b9482d7269f16f62657e480632e662d77477355d
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 18 21:16:10 2014 -0500

    	PR c++/63924
    	* constexpr.c (cxx_eval_constant_expression) [PARM_DECL]: A load
    	from a variable of empty class type is constant.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 1b330a0..1303fdc 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2845,6 +2845,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	r = *p;
       else if (addr)
 	/* Defer in case this is only used for its type.  */;
+      else if (is_empty_class (TREE_TYPE (t)))
+	{
+	  /* If the class is empty, we aren't actually loading anything.  */
+	  r = build_constructor (TREE_TYPE (t), NULL);
+	  TREE_CONSTANT (r) = true;
+	}
       else
 	{
 	  if (!ctx->quiet)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty8.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty8.C
new file mode 100644
index 0000000..8c1414a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty8.C
@@ -0,0 +1,7 @@
+// PR c++/63924
+// { dg-do compile { target c++11 } }
+
+struct A { };
+constexpr bool f(A a) { return true; }
+template <bool B> constexpr bool g() { return true; }
+constexpr bool g(A a) { return g<f(a)>(); }

[-- Attachment #3: cx-stmt-expr.patch --]
[-- Type: text/x-patch, Size: 2577 bytes --]

commit deec200eb93467dde2873fddc4ab30ffeb31003a
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 18 12:14:36 2014 -0500

    	* constexpr.c (cxx_eval_statement_list): Handle statement-expressions.
    	(potential_constant_expression_1): Handle STMT_EXPR.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 4669586..1b330a0 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2685,6 +2685,14 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
 {
   tree_stmt_iterator i;
   tree_stmt_iterator default_label = tree_stmt_iterator();
+  tree local_target;
+  /* In a statement-expression we want to return the last value.  */
+  tree r = NULL_TREE;
+  if (!jump_target)
+    {
+      local_target = NULL_TREE;
+      jump_target = &local_target;
+    }
   for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
     {
     reenter:
@@ -2699,10 +2707,9 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
 	  else
 	    continue;
 	}
-      cxx_eval_constant_expression (ctx, stmt,
-				    false,
-				    non_constant_p, overflow_p,
-				    jump_target);
+      r = cxx_eval_constant_expression (ctx, stmt, false,
+					non_constant_p, overflow_p,
+					jump_target);
       if (*non_constant_p)
 	break;
       if (returns (jump_target) || breaks (jump_target))
@@ -2714,7 +2721,7 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
       *jump_target = NULL_TREE;
       goto reenter;
     }
-  return NULL_TREE;
+  return r;
 }
 
 /* Evaluate a LOOP_EXPR for side-effects.  Handles break and return
@@ -3885,6 +3892,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
 	return false;
       return true;
 
+    case STMT_EXPR:
+      return potential_constant_expression_1 (STMT_EXPR_STMT (t), rval, flags);
+
     case LAMBDA_EXPR:
     case DYNAMIC_CAST_EXPR:
     case PSEUDO_DTOR_EXPR:
@@ -3900,7 +3910,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
       /* GCC internal stuff.  */
     case VA_ARG_EXPR:
     case OBJ_TYPE_REF:
-    case STMT_EXPR:
     case TRANSACTION_EXPR:
     case ASM_EXPR:
     fail:
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C
new file mode 100644
index 0000000..34ca9fa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-stmtexpr2.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+#define SA(X) static_assert((X),#X)
+
+template <class T>
+constexpr T f (T t)
+{
+  return ({ t+1; });
+}
+
+SA(f(42) == 43);

[-- Attachment #4: quiet.patch --]
[-- Type: text/x-patch, Size: 38286 bytes --]

commit 38fb0e8ae0387b39c4ec825ebc086ae5e482cf2c
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 18 09:31:54 2014 -0500

    	* constexpr.c (struct constexpr_ctx): Add quiet field.
    	(cxx_eval_outermost_constant_expr, is_sub_constant_expr): Set it.
    	(lots): Replace allow_non_constant parameter with ctx->quiet.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 517bf23..7cdf649 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -36,7 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 static bool verify_constant (tree, bool, bool *, bool *);
 #define VERIFY_CONSTANT(X)						\
 do {									\
-  if (verify_constant ((X), allow_non_constant, non_constant_p, overflow_p)) \
+  if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \
     return t;								\
  } while (0)
 
@@ -863,6 +863,7 @@ struct constexpr_ctx {
   hash_map<tree,tree> *values;
   tree ctor;
   tree object;
+  bool quiet;
 };
 
 /* A table of all constexpr calls that have been evaluated by the
@@ -871,7 +872,7 @@ struct constexpr_ctx {
 static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
 
 static tree cxx_eval_constant_expression (const constexpr_ctx *, tree,
-					  bool, bool, bool *, bool *, tree *);
+					  bool, bool *, bool *, tree *);
 
 /* Compute a hash value for a constexpr call representation.  */
 
@@ -982,7 +983,7 @@ lookup_parameter_binding (const constexpr_call *call, tree t)
 
 static tree
 cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
-				bool allow_non_constant, bool addr,
+				bool addr,
 				bool *non_constant_p, bool *overflow_p)
 {
   const int nargs = call_expr_nargs (t);
@@ -992,10 +993,10 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
   for (i = 0; i < nargs; ++i)
     {
       args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, i),
-					      allow_non_constant, addr,
+					      addr,
 					      non_constant_p, overflow_p,
 					      NULL);
-      if (allow_non_constant && *non_constant_p)
+      if (ctx->quiet && *non_constant_p)
 	return t;
     }
   if (*non_constant_p)
@@ -1034,7 +1035,6 @@ adjust_temp_type (tree type, tree temp)
 static void
 cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
                              constexpr_call *new_call,
-			     bool allow_non_constant,
 			     bool *non_constant_p, bool *overflow_p)
 {
   const int nargs = call_expr_nargs (t);
@@ -1067,11 +1067,11 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
 	  type = TREE_TYPE (type);
 	  x = convert_from_reference (x);
 	}
-      arg = cxx_eval_constant_expression (ctx, x, allow_non_constant,
+      arg = cxx_eval_constant_expression (ctx, x,
 					  TREE_CODE (type) == REFERENCE_TYPE,
 					  non_constant_p, overflow_p, NULL);
       /* Don't VERIFY_CONSTANT here.  */
-      if (*non_constant_p && allow_non_constant)
+      if (*non_constant_p && ctx->quiet)
 	return;
       /* Just discard ellipsis args after checking their constantitude.  */
       if (!parms)
@@ -1134,7 +1134,7 @@ cx_error_context (void)
 
 static tree
 cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
-			  bool allow_non_constant, bool addr,
+			  bool addr,
 			  bool *non_constant_p, bool *overflow_p)
 {
   location_t loc = EXPR_LOC_OR_LOC (t, input_location);
@@ -1148,7 +1148,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
   if (TREE_CODE (fun) != FUNCTION_DECL)
     {
       /* Might be a constexpr function pointer.  */
-      fun = cxx_eval_constant_expression (ctx, fun, allow_non_constant,
+      fun = cxx_eval_constant_expression (ctx, fun,
 					  /*addr*/false, non_constant_p,
 					  overflow_p, NULL);
       STRIP_NOPS (fun);
@@ -1157,7 +1157,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
     }
   if (TREE_CODE (fun) != FUNCTION_DECL)
     {
-      if (!allow_non_constant && !*non_constant_p)
+      if (!ctx->quiet && !*non_constant_p)
 	error_at (loc, "expression %qE does not designate a constexpr "
 		  "function", fun);
       *non_constant_p = true;
@@ -1166,11 +1166,11 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
   if (DECL_CLONED_FUNCTION_P (fun))
     fun = DECL_CLONED_FUNCTION (fun);
   if (is_builtin_fn (fun))
-    return cxx_eval_builtin_function_call (ctx, t, allow_non_constant,
+    return cxx_eval_builtin_function_call (ctx, t,
 					   addr, non_constant_p, overflow_p);
   if (!DECL_DECLARED_CONSTEXPR_P (fun))
     {
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	{
 	  error_at (loc, "call to non-constexpr function %qD", fun);
 	  explain_invalid_constexpr_fn (fun);
@@ -1185,7 +1185,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
       if (call_expr_nargs (t) == 2)
 	{
 	  tree arg = convert_from_reference (get_nth_callarg (t, 1));
-	  return cxx_eval_constant_expression (ctx, arg, allow_non_constant,
+	  return cxx_eval_constant_expression (ctx, arg,
 					       addr, non_constant_p,
 					       overflow_p, NULL);
 	}
@@ -1202,7 +1202,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
       new_call.fundef = retrieve_constexpr_fundef (fun);
       if (new_call.fundef == NULL || new_call.fundef->body == NULL)
         {
-	  if (!allow_non_constant)
+	  if (!ctx->quiet)
 	    {
 	      if (DECL_INITIAL (fun))
 		{
@@ -1232,7 +1232,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
     }
 
   cxx_bind_parameters_in_call (ctx, t, &new_call,
-			       allow_non_constant, non_constant_p, overflow_p);
+			       non_constant_p, overflow_p);
   if (*non_constant_p)
     return t;
 
@@ -1257,7 +1257,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
      so that we can detect circular dependencies.  */
   else if (entry->result == NULL)
     {
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("call has circular dependency");
       *non_constant_p = true;
       entry->result = result = error_mark_node;
@@ -1265,7 +1265,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 
   if (!depth_ok)
     {
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("constexpr evaluation depth exceeds maximum of %d (use "
 	       "-fconstexpr-depth= to increase the maximum)",
 	       max_constexpr_depth);
@@ -1282,7 +1282,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 	      new_ctx.call = &new_call;
 	      result = (cxx_eval_constant_expression
 			(&new_ctx, new_call.fundef->body,
-			 allow_non_constant, addr,
+			 addr,
 			 non_constant_p, overflow_p, NULL));
 	    }
 	  else
@@ -1324,7 +1324,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 		ctx->values->put (res, NULL_TREE);
 
 	      tree jump_target = NULL_TREE;
-	      cxx_eval_constant_expression (ctx, body, allow_non_constant,
+	      cxx_eval_constant_expression (ctx, body,
 					    addr, non_constant_p, overflow_p,
 					    &jump_target);
 
@@ -1340,7 +1340,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 		  result = *ctx->values->get (slot ? slot : res);
 		  if (result == NULL_TREE)
 		    {
-		      if (!allow_non_constant)
+		      if (!ctx->quiet)
 			error ("constexpr call flows off the end "
 			       "of the function");
 		      *non_constant_p = true;
@@ -1452,12 +1452,12 @@ verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
 
 static tree
 cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
-			   bool allow_non_constant, bool addr,
+			   bool addr,
 			   bool *non_constant_p, bool *overflow_p)
 {
   tree r;
   tree orig_arg = TREE_OPERAND (t, 0);
-  tree arg = cxx_eval_constant_expression (ctx, orig_arg, allow_non_constant,
+  tree arg = cxx_eval_constant_expression (ctx, orig_arg,
 					   addr, non_constant_p, overflow_p,
 					   NULL);
   VERIFY_CONSTANT (arg);
@@ -1481,7 +1481,7 @@ cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
-			    bool allow_non_constant, bool addr,
+			    bool addr,
 			    bool *non_constant_p, bool *overflow_p)
 {
   tree r;
@@ -1489,11 +1489,11 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
   tree orig_rhs = TREE_OPERAND (t, 1);
   tree lhs, rhs;
   lhs = cxx_eval_constant_expression (ctx, orig_lhs,
-				      allow_non_constant, addr,
+				      addr,
 				      non_constant_p, overflow_p, NULL);
   VERIFY_CONSTANT (lhs);
   rhs = cxx_eval_constant_expression (ctx, orig_rhs,
-				      allow_non_constant, addr,
+				      addr,
 				      non_constant_p, overflow_p, NULL);
   VERIFY_CONSTANT (rhs);
 
@@ -1518,23 +1518,23 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
-				 bool allow_non_constant, bool addr,
+				 bool addr,
 				 bool *non_constant_p, bool *overflow_p,
 				 tree *jump_target)
 {
   tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
-					   allow_non_constant, addr,
+					   addr,
 					   non_constant_p, overflow_p,
 					   NULL);
   VERIFY_CONSTANT (val);
   /* Don't VERIFY_CONSTANT the other operands.  */
   if (integer_zerop (val))
     return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
-					 allow_non_constant, addr,
+					 addr,
 					 non_constant_p, overflow_p,
 					 jump_target);
   return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
-				       allow_non_constant, addr,
+				       addr,
 				       non_constant_p, overflow_p,
 				       jump_target);
 }
@@ -1544,12 +1544,12 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
-			  bool allow_non_constant, bool addr,
+			  bool addr,
 			  bool *non_constant_p, bool *overflow_p)
 {
   tree oldary = TREE_OPERAND (t, 0);
   tree ary = cxx_eval_constant_expression (ctx, oldary,
-					   allow_non_constant, addr,
+					   addr,
 					   non_constant_p, overflow_p, NULL);
   tree index, oldidx;
   HOST_WIDE_INT i;
@@ -1559,7 +1559,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
     return t;
   oldidx = TREE_OPERAND (t, 1);
   index = cxx_eval_constant_expression (ctx, oldidx,
-					allow_non_constant, false,
+					false,
 					non_constant_p, overflow_p, NULL);
   VERIFY_CONSTANT (index);
   if (addr && ary == oldary && index == oldidx)
@@ -1590,19 +1590,19 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
 	     initializer, it's value-initialized.  */
 	  tree val = build_value_init (elem_type, tf_warning_or_error);
 	  return cxx_eval_constant_expression (ctx, val,
-					       allow_non_constant, addr,
+					       addr,
 					       non_constant_p, overflow_p,
 					       NULL);
 	}
 
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("array subscript out of bound");
       *non_constant_p = true;
       return t;
     }
   else if (tree_int_cst_lt (index, integer_zero_node))
     {
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("negative array subscript");
       *non_constant_p = true;
       return t;
@@ -1628,7 +1628,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
-			      bool allow_non_constant, bool addr,
+			      bool addr,
 			      bool *non_constant_p, bool *overflow_p)
 {
   unsigned HOST_WIDE_INT i;
@@ -1637,7 +1637,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
   tree part = TREE_OPERAND (t, 1);
   tree orig_whole = TREE_OPERAND (t, 0);
   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
-					     allow_non_constant, addr,
+					     addr,
 					     non_constant_p, overflow_p, NULL);
   if (whole == orig_whole)
     return t;
@@ -1648,13 +1648,13 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
      CONSTRUCTOR.  */
   if (!*non_constant_p && TREE_CODE (whole) != CONSTRUCTOR)
     {
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("%qE is not a constant expression", orig_whole);
       *non_constant_p = true;
     }
   if (DECL_MUTABLE_P (part))
     {
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("mutable %qD is not usable in a constant expression", part);
       *non_constant_p = true;
     }
@@ -1675,7 +1675,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
       && CONSTRUCTOR_NELTS (whole) > 0)
     {
       /* DR 1188 says we don't have to deal with this.  */
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("accessing %qD member instead of initialized %qD member in "
 	       "constant expression", part, CONSTRUCTOR_ELT (whole, 0)->index);
       *non_constant_p = true;
@@ -1687,7 +1687,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
       /* 'whole' is part of the aggregate initializer we're currently
 	 building; if there's no initializer for this member yet, that's an
 	 error. */
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("accessing uninitialized member %qD", part);
       *non_constant_p = true;
       return t;
@@ -1696,7 +1696,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
   /* If there's no explicit init for this field, it's value-initialized.  */
   value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
   return cxx_eval_constant_expression (ctx, value,
-				       allow_non_constant, addr,
+				       addr,
 				       non_constant_p, overflow_p, NULL);
 }
 
@@ -1706,7 +1706,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
-			bool allow_non_constant, bool addr,
+			bool addr,
 			bool *non_constant_p, bool *overflow_p)
 {
   tree orig_whole = TREE_OPERAND (t, 0);
@@ -1714,7 +1714,7 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
   bool fld_seen = false;
   HOST_WIDE_INT istart, isize;
   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
-					     allow_non_constant, addr,
+					     addr,
 					     non_constant_p, overflow_p, NULL);
   tree start, field, value;
   unsigned HOST_WIDE_INT i;
@@ -1727,7 +1727,7 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
       && TREE_CODE (whole) != VECTOR_CST
       && TREE_CODE (whole) != CONSTRUCTOR)
     {
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("%qE is not a constant expression", orig_whole);
       *non_constant_p = true;
     }
@@ -1792,19 +1792,19 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
 static tree
 cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
                              tree bailout_value, tree continue_value,
-			     bool allow_non_constant, bool addr,
+			     bool addr,
 			     bool *non_constant_p, bool *overflow_p)
 {
   tree r;
   tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
-					   allow_non_constant, addr,
+					   addr,
 					   non_constant_p, overflow_p, NULL);
   VERIFY_CONSTANT (lhs);
   if (tree_int_cst_equal (lhs, bailout_value))
     return lhs;
   gcc_assert (tree_int_cst_equal (lhs, continue_value));
   r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
-				    allow_non_constant, addr, non_constant_p,
+				    addr, non_constant_p,
 				    overflow_p, NULL);
   VERIFY_CONSTANT (r);
   return r;
@@ -1926,7 +1926,7 @@ verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
 
 static tree
 cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
-			 bool allow_non_constant, bool addr,
+			 bool addr,
 			 bool *non_constant_p, bool *overflow_p)
 {
   vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
@@ -1947,11 +1947,11 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
 	   initializers can refer to it.  */
 	CONSTRUCTOR_APPEND_ELT (*p, index, new_ctx.ctor);
       tree elt = cxx_eval_constant_expression (&new_ctx, value,
-					       allow_non_constant, addr,
+					       addr,
 					       non_constant_p, overflow_p,
 					       NULL);
       /* Don't VERIFY_CONSTANT here.  */
-      if (allow_non_constant && *non_constant_p)
+      if (ctx->quiet && *non_constant_p)
 	break;
       if (elt != value)
 	changed = true;
@@ -2007,7 +2007,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
-		     bool value_init, bool allow_non_constant, bool addr,
+		     bool value_init, bool addr,
 		     bool *non_constant_p, bool *overflow_p)
 {
   tree elttype = TREE_TYPE (atype);
@@ -2058,7 +2058,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
 	    eltinit = cp_build_array_ref (input_location, init, idx,
 					  tf_warning_or_error);
 	  eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit, value_init,
-					 allow_non_constant, addr,
+					 addr,
 					 non_constant_p, overflow_p);
 	}
       else if (pre_init)
@@ -2066,7 +2066,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
 	  /* Initializing an element using value or default initialization
 	     we just pre-built above.  */
 	  eltinit = (cxx_eval_constant_expression
-		     (&new_ctx, init, allow_non_constant,
+		     (&new_ctx, init,
 		      addr, non_constant_p, overflow_p, NULL));
 	}
       else
@@ -2080,10 +2080,10 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
 	    eltinit = move (eltinit);
 	  eltinit = force_rvalue (eltinit, tf_warning_or_error);
 	  eltinit = (cxx_eval_constant_expression
-		     (&new_ctx, eltinit, allow_non_constant, addr,
+		     (&new_ctx, eltinit, addr,
 		      non_constant_p, overflow_p, NULL));
 	}
-      if (*non_constant_p && !allow_non_constant)
+      if (*non_constant_p && !ctx->quiet)
 	break;
       if (new_ctx.ctor != ctx->ctor)
 	{
@@ -2105,14 +2105,14 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
 
 static tree
 cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
-		   bool allow_non_constant, bool addr,
+		   bool addr,
 		   bool *non_constant_p, bool *overflow_p)
 {
   tree atype = TREE_TYPE (t);
   tree init = VEC_INIT_EXPR_INIT (t);
   tree r = cxx_eval_vec_init_1 (ctx, atype, init,
 				VEC_INIT_EXPR_VALUE_INIT (t),
-				allow_non_constant, addr, non_constant_p, overflow_p);
+				addr, non_constant_p, overflow_p);
   if (*non_constant_p)
     return t;
   else
@@ -2312,11 +2312,11 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base)
 
 static tree
 cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
-		       bool allow_non_constant, bool addr,
+		       bool addr,
 		       bool *non_constant_p, bool *overflow_p)
 {
   tree orig_op0 = TREE_OPERAND (t, 0);
-  tree op0 = cxx_eval_constant_expression (ctx, orig_op0, allow_non_constant,
+  tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
 					   /*addr*/false, non_constant_p,
 					   overflow_p, NULL);
   bool empty_base = false;
@@ -2330,7 +2330,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
 			     &empty_base);
 
   if (r)
-    r = cxx_eval_constant_expression (ctx, r, allow_non_constant,
+    r = cxx_eval_constant_expression (ctx, r,
 				      addr, non_constant_p, overflow_p, NULL);
   else
     {
@@ -2343,7 +2343,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
 	  gcc_assert (!same_type_ignoring_top_level_qualifiers_p
 		      (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
 	  /* DR 1188 says we don't have to deal with this.  */
-	  if (!allow_non_constant)
+	  if (!ctx->quiet)
 	    error ("accessing value of %qE through a %qT glvalue in a "
 		   "constant expression", build_fold_indirect_ref (sub),
 		   TREE_TYPE (t));
@@ -2422,7 +2422,7 @@ non_const_var_error (tree r)
 
 static tree
 cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
-			     bool allow_non_constant, bool addr,
+			     bool addr,
 			     bool *non_constant_p, bool *overflow_p)
 {
   int i;
@@ -2432,7 +2432,7 @@ cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
   for (i = 0; i < 3; i++)
     {
       args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
-					      allow_non_constant, addr,
+					      addr,
 					      non_constant_p, overflow_p,
 					      NULL);
       VERIFY_CONSTANT (args[i]);
@@ -2458,7 +2458,7 @@ var_in_constexpr_fn (tree t)
 
 static tree
 cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
-			   bool allow_non_constant, bool addr,
+			   bool addr,
 			   bool *non_constant_p, bool *overflow_p)
 {
   constexpr_ctx new_ctx = *ctx;
@@ -2466,7 +2466,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
   /* First we figure out where we're storing to.  */
   tree target = TREE_OPERAND (t, 0);
   target = cxx_eval_constant_expression (ctx, target,
-					 allow_non_constant, true,
+					 true,
 					 non_constant_p, overflow_p, NULL);
   if (*non_constant_p)
     return t;
@@ -2499,7 +2499,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
     {
       /* A constant-expression cannot modify objects from outside the
 	 constant-expression.  */
-      if (!allow_non_constant)
+      if (!ctx->quiet)
 	error ("modification of %qD is not a constant-expression", object);
       *non_constant_p = true;
       return t;
@@ -2542,7 +2542,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
     }
 
   tree init = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 1),
-					    allow_non_constant, false,
+					    false,
 					    non_constant_p, overflow_p, NULL);
   if (target == object)
     /* The hash table might have moved since the get earlier.  */
@@ -2562,7 +2562,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
-			      bool allow_non_constant, bool addr,
+			      bool addr,
 			      bool *non_constant_p, bool *overflow_p)
 {
   enum tree_code code = TREE_CODE (t);
@@ -2572,12 +2572,12 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
   gcc_assert (TREE_CONSTANT (offset));
 
   /* The operand as an lvalue.  */
-  op = cxx_eval_constant_expression (ctx, op, allow_non_constant, true,
+  op = cxx_eval_constant_expression (ctx, op, true,
 				     non_constant_p, overflow_p, NULL);
 
   /* The operand as an rvalue.  */
   tree val = rvalue (op);
-  val = cxx_eval_constant_expression (ctx, val, allow_non_constant, false,
+  val = cxx_eval_constant_expression (ctx, val, false,
 				      non_constant_p, overflow_p, NULL);
   VERIFY_CONSTANT (val);
 
@@ -2598,7 +2598,7 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
 
   /* Storing the modified value.  */
   tree store = build2 (MODIFY_EXPR, type, op, mod);
-  cxx_eval_constant_expression (ctx, store, allow_non_constant,
+  cxx_eval_constant_expression (ctx, store,
 				true, non_constant_p, overflow_p, NULL);
 
   /* And the value of the expression.  */
@@ -2686,7 +2686,6 @@ label_matches (tree *jump_target, tree_stmt_iterator i,
 
 static tree
 cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
-			 bool allow_non_constant,
 			 bool *non_constant_p, bool *overflow_p,
 			 tree *jump_target)
 {
@@ -2707,7 +2706,7 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
 	    continue;
 	}
       cxx_eval_constant_expression (ctx, stmt,
-				    allow_non_constant, false,
+				    false,
 				    non_constant_p, overflow_p,
 				    jump_target);
       if (*non_constant_p)
@@ -2729,14 +2728,13 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
-		    bool allow_non_constant,
 		    bool *non_constant_p, bool *overflow_p,
 		    tree *jump_target)
 {
   tree body = TREE_OPERAND (t, 0);
   while (true)
     {
-      cxx_eval_statement_list (ctx, body, allow_non_constant,
+      cxx_eval_statement_list (ctx, body,
 			       non_constant_p, overflow_p, jump_target);
       if (returns (jump_target) || breaks (jump_target))
 	break;
@@ -2751,18 +2749,17 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
-		      bool allow_non_constant,
 		      bool *non_constant_p, bool *overflow_p,
 		      tree *jump_target)
 {
   tree cond = TREE_OPERAND (t, 0);
-  cond = cxx_eval_constant_expression (ctx, cond, allow_non_constant, false,
+  cond = cxx_eval_constant_expression (ctx, cond, false,
 				       non_constant_p, overflow_p, NULL);
   VERIFY_CONSTANT (cond);
   *jump_target = cond;
 
   tree body = TREE_OPERAND (t, 1);
-  cxx_eval_statement_list (ctx, body, allow_non_constant,
+  cxx_eval_statement_list (ctx, body,
 			   non_constant_p, overflow_p, jump_target);
   if (breaks (jump_target) || switches (jump_target))
     *jump_target = NULL_TREE;
@@ -2776,7 +2773,7 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
 
 static tree
 cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
-			      bool allow_non_constant, bool addr,
+			      bool addr,
 			      bool *non_constant_p, bool *overflow_p,
 			      tree *jump_target)
 {
@@ -2792,7 +2789,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     {
       if (TREE_CODE (t) == PTRMEM_CST)
 	t = cplus_expand_constant (t);
-      else if (TREE_OVERFLOW (t) && (!flag_permissive || allow_non_constant))
+      else if (TREE_OVERFLOW (t) && (!flag_permissive || ctx->quiet))
 	*overflow_p = true;
       return t;
     }
@@ -2824,7 +2821,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	  r = *p;
       if (DECL_P (r))
 	{
-	  if (!allow_non_constant)
+	  if (!ctx->quiet)
 	    non_const_var_error (r);
 	  *non_constant_p = true;
 	}
@@ -2849,7 +2846,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	/* Defer in case this is only used for its type.  */;
       else
 	{
-	  if (!allow_non_constant)
+	  if (!ctx->quiet)
 	    error ("%qE is not a constant expression", t);
 	  *non_constant_p = true;
 	}
@@ -2857,7 +2854,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 
     case CALL_EXPR:
     case AGGR_INIT_EXPR:
-      r = cxx_eval_call_expression (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_call_expression (ctx, t, addr,
 				    non_constant_p, overflow_p);
       break;
 
@@ -2878,7 +2875,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	if (tree init = DECL_INITIAL (r))
 	  {
 	    init = cxx_eval_constant_expression (ctx, init,
-						 allow_non_constant, false,
+						 false,
 						 non_constant_p, overflow_p,
 						 NULL);
 	    ctx->values->put (r, init);
@@ -2893,7 +2890,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case TARGET_EXPR:
       if (!literal_type_p (TREE_TYPE (t)))
 	{
-	  if (!allow_non_constant)
+	  if (!ctx->quiet)
 	    {
 	      error ("temporary of non-literal type %qT in a "
 		     "constant expression", TREE_TYPE (t));
@@ -2917,7 +2914,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       /* Pass false for 'addr' because this indicates
 	 initialization of a temporary.  */
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
-					allow_non_constant, false,
+					false,
 					non_constant_p, overflow_p, NULL);
       if (!*non_constant_p)
 	/* Adjust the type of the result to the type of the temporary.  */
@@ -2930,25 +2927,25 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	  /* In C++11 constexpr evaluation we are looking for the value,
 	     not the side-effect of the initialization.  */
 	  r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
-					    allow_non_constant, false,
+					    false,
 					    non_constant_p, overflow_p, NULL);
 	  break;
 	}
       /* else fall through */
     case MODIFY_EXPR:
-      r = cxx_eval_store_expression (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_store_expression (ctx, t, addr,
 				     non_constant_p, overflow_p);
       break;
 
     case SCOPE_REF:
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
-					allow_non_constant, addr,
+					addr,
 					non_constant_p, overflow_p, NULL);
       break;
 
     case RETURN_EXPR:
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
-					allow_non_constant, addr,
+					addr,
 					non_constant_p, overflow_p, NULL);
       *jump_target = t;
       break;
@@ -2961,7 +2958,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case EXPR_STMT:
     case EH_SPEC_BLOCK:
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
-					allow_non_constant, addr,
+					addr,
 					non_constant_p, overflow_p,
 					jump_target);
       break;
@@ -2970,7 +2967,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	 check for a constant operand or result; an address can be
 	 constant without its operand being, and vice versa.  */
     case INDIRECT_REF:
-      r = cxx_eval_indirect_ref (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_indirect_ref (ctx, t, addr,
 				 non_constant_p, overflow_p);
       break;
 
@@ -2978,7 +2975,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       {
 	tree oldop = TREE_OPERAND (t, 0);
 	tree op = cxx_eval_constant_expression (ctx, oldop,
-						allow_non_constant,
 						/*addr*/true,
 						non_constant_p, overflow_p,
 						NULL);
@@ -3002,7 +2998,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case BIT_NOT_EXPR:
     case TRUTH_NOT_EXPR:
     case FIXED_CONVERT_EXPR:
-      r = cxx_eval_unary_expression (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_unary_expression (ctx, t, addr,
 				     non_constant_p, overflow_p);
       break;
 
@@ -3031,17 +3027,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	STRIP_NOPS (op1);
 	if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
 	    || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
-	  r = cxx_eval_constant_expression (ctx, op0, allow_non_constant,
+	  r = cxx_eval_constant_expression (ctx, op0,
 					    addr, non_constant_p, overflow_p,
 					    jump_target);
 	else
 	  {
 	    /* Check that the LHS is constant and then discard it.  */
-	    cxx_eval_constant_expression (ctx, op0, allow_non_constant,
+	    cxx_eval_constant_expression (ctx, op0,
 					  false, non_constant_p, overflow_p,
 					  jump_target);
 	    op1 = TREE_OPERAND (t, 1);
-	    r = cxx_eval_constant_expression (ctx, op1, allow_non_constant,
+	    r = cxx_eval_constant_expression (ctx, op1,
 					      addr, non_constant_p, overflow_p,
 					      jump_target);
 	  }
@@ -3087,7 +3083,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case LTGT_EXPR:
     case RANGE_EXPR:
     case COMPLEX_EXPR:
-      r = cxx_eval_binary_expression (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_binary_expression (ctx, t, addr,
 				      non_constant_p, overflow_p);
       break;
 
@@ -3097,7 +3093,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case TRUTH_ANDIF_EXPR:
       r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
 				       boolean_true_node,
-				       allow_non_constant, addr,
+				       addr,
 				       non_constant_p, overflow_p);
       break;
 
@@ -3105,12 +3101,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case TRUTH_ORIF_EXPR:
       r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
 				       boolean_false_node,
-				       allow_non_constant, addr,
+				       addr,
 				       non_constant_p, overflow_p);
       break;
 
     case ARRAY_REF:
-      r = cxx_eval_array_reference (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_array_reference (ctx, t, addr,
 				    non_constant_p, overflow_p);
       break;
 
@@ -3121,28 +3117,28 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	     build_non_dependent_expr,  because any expression that
 	     calls or takes the address of the function will have
 	     pulled a FUNCTION_DECL out of the COMPONENT_REF.  */
-	  gcc_checking_assert (allow_non_constant || errorcount);
+	  gcc_checking_assert (ctx->quiet || errorcount);
 	  *non_constant_p = true;
 	  return t;
 	}
-      r = cxx_eval_component_reference (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_component_reference (ctx, t, addr,
 					non_constant_p, overflow_p);
       break;
 
     case BIT_FIELD_REF:
-      r = cxx_eval_bit_field_ref (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_bit_field_ref (ctx, t, addr,
 				  non_constant_p, overflow_p);
       break;
 
     case COND_EXPR:
     case VEC_COND_EXPR:
-      r = cxx_eval_conditional_expression (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_conditional_expression (ctx, t, addr,
 					   non_constant_p, overflow_p,
 					   jump_target);
       break;
 
     case CONSTRUCTOR:
-      r = cxx_eval_bare_aggregate (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_bare_aggregate (ctx, t, addr,
 				   non_constant_p, overflow_p);
       break;
 
@@ -3152,13 +3148,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	 be NULL, meaning default-initialization, or it will be an lvalue
 	 or xvalue of the same type, meaning direct-initialization from the
 	 corresponding member.  */
-      r = cxx_eval_vec_init (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_vec_init (ctx, t, addr,
 			     non_constant_p, overflow_p);
       break;
 
     case FMA_EXPR:
     case VEC_PERM_EXPR:
-      r = cxx_eval_trinary_expression (ctx, t, allow_non_constant, addr,
+      r = cxx_eval_trinary_expression (ctx, t, addr,
 				       non_constant_p, overflow_p);
       break;
 
@@ -3168,7 +3164,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       {
 	tree oldop = TREE_OPERAND (t, 0);
 	tree op = cxx_eval_constant_expression (ctx, oldop,
-						allow_non_constant, addr,
+						addr,
 						non_constant_p, overflow_p,
 						NULL);
 	if (*non_constant_p)
@@ -3177,7 +3173,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	    && TREE_CODE (op) == INTEGER_CST
 	    && !integer_zerop (op))
 	  {
-	    if (!allow_non_constant)
+	    if (!ctx->quiet)
 	      error_at (EXPR_LOC_OR_LOC (t, input_location),
 			"reinterpret_cast from integer to pointer");
 	    *non_constant_p = true;
@@ -3204,12 +3200,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case STATEMENT_LIST:
       new_ctx = *ctx;
       new_ctx.ctor = new_ctx.object = NULL_TREE;
-      return cxx_eval_statement_list (&new_ctx, t, allow_non_constant,
+      return cxx_eval_statement_list (&new_ctx, t,
 				      non_constant_p, overflow_p, jump_target);
 
     case BIND_EXPR:
       return cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
-					   allow_non_constant, addr,
+					   addr,
 					   non_constant_p, overflow_p,
 					   jump_target);
 
@@ -3217,7 +3213,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case POSTINCREMENT_EXPR:
     case PREDECREMENT_EXPR:
     case POSTDECREMENT_EXPR:
-      return cxx_eval_increment_expression (ctx, t, allow_non_constant,
+      return cxx_eval_increment_expression (ctx, t,
 					    addr, non_constant_p, overflow_p);
 
     case LAMBDA_EXPR:
@@ -3234,7 +3230,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case NON_DEPENDENT_EXPR:
     case BASELINK:
     case OFFSET_REF:
-      if (!allow_non_constant)
+      if (!ctx->quiet)
         error_at (EXPR_LOC_OR_LOC (t, input_location),
 		  "expression %qE is not a constant-expression", t);
       *non_constant_p = true;
@@ -3246,7 +3242,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	  /* A placeholder without a referent.  We can get here when
 	     checking whether NSDMIs are noexcept, or in massage_init_elt;
 	     just say it's non-constant for now.  */
-	  gcc_assert (allow_non_constant);
+	  gcc_assert (ctx->quiet);
 	  *non_constant_p = true;
 	  break;
 	}
@@ -3259,7 +3255,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	  gcc_assert (same_type_ignoring_top_level_qualifiers_p
 		      (TREE_TYPE (t), TREE_TYPE (ctor)));
 	  return cxx_eval_constant_expression
-	    (ctx, ctor, allow_non_constant, addr,
+	    (ctx, ctor, addr,
 	     non_constant_p, overflow_p, NULL);
 	}
       break;
@@ -3270,12 +3266,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       break;
 
     case LOOP_EXPR:
-      cxx_eval_loop_expr (ctx, t, allow_non_constant,
+      cxx_eval_loop_expr (ctx, t,
 			  non_constant_p, overflow_p, jump_target);
       break;
 
     case SWITCH_EXPR:
-      cxx_eval_switch_expr (ctx, t, allow_non_constant,
+      cxx_eval_switch_expr (ctx, t,
 			    non_constant_p, overflow_p, jump_target);
       break;
 
@@ -3301,7 +3297,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
 {
   bool non_constant_p = false;
   bool overflow_p = false;
-  constexpr_ctx ctx = { NULL, NULL, NULL, NULL };
+  constexpr_ctx ctx = { NULL, NULL, NULL, NULL, allow_non_constant };
   hash_map<tree,tree> map;
   ctx.values = &map;
   tree type = initialized_type (t);
@@ -3336,7 +3332,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
 	r = TARGET_EXPR_INITIAL (r);
     }
 
-  r = cxx_eval_constant_expression (&ctx, r, allow_non_constant,
+  r = cxx_eval_constant_expression (&ctx, r,
 				    false, &non_constant_p, &overflow_p, NULL);
 
   verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
@@ -3410,10 +3406,10 @@ is_sub_constant_expr (tree t)
 {
   bool non_constant_p = false;
   bool overflow_p = false;
-  constexpr_ctx ctx = { NULL, NULL, NULL, NULL };
+  constexpr_ctx ctx = { NULL, NULL, NULL, NULL, true };
   hash_map <tree, tree> map;
   ctx.values = &map;
-  cxx_eval_constant_expression (&ctx, t, true, false, &non_constant_p,
+  cxx_eval_constant_expression (&ctx, t, false, &non_constant_p,
 				&overflow_p, NULL);
   return !non_constant_p && !overflow_p;
 }

[-- Attachment #5: jump-defarg.patch --]
[-- Type: text/x-patch, Size: 13589 bytes --]

commit ac735597ec600bbced61e4fb3d16a2b204d092df
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Nov 18 12:13:56 2014 -0500

    	* constexpr.c (cxx_eval_constant_expression): Give jump_target a
    	default argument.
    	(lots): Omit NULL jump_target arguments.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 7cdf649..4669586 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -872,7 +872,7 @@ struct constexpr_ctx {
 static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
 
 static tree cxx_eval_constant_expression (const constexpr_ctx *, tree,
-					  bool, bool *, bool *, tree *);
+					  bool, bool *, bool *, tree * = NULL);
 
 /* Compute a hash value for a constexpr call representation.  */
 
@@ -994,8 +994,7 @@ cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t,
     {
       args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, i),
 					      addr,
-					      non_constant_p, overflow_p,
-					      NULL);
+					      non_constant_p, overflow_p);
       if (ctx->quiet && *non_constant_p)
 	return t;
     }
@@ -1069,7 +1068,7 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
 	}
       arg = cxx_eval_constant_expression (ctx, x,
 					  TREE_CODE (type) == REFERENCE_TYPE,
-					  non_constant_p, overflow_p, NULL);
+					  non_constant_p, overflow_p);
       /* Don't VERIFY_CONSTANT here.  */
       if (*non_constant_p && ctx->quiet)
 	return;
@@ -1150,7 +1149,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
       /* Might be a constexpr function pointer.  */
       fun = cxx_eval_constant_expression (ctx, fun,
 					  /*addr*/false, non_constant_p,
-					  overflow_p, NULL);
+					  overflow_p);
       STRIP_NOPS (fun);
       if (TREE_CODE (fun) == ADDR_EXPR)
 	fun = TREE_OPERAND (fun, 0);
@@ -1187,7 +1186,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 	  tree arg = convert_from_reference (get_nth_callarg (t, 1));
 	  return cxx_eval_constant_expression (ctx, arg,
 					       addr, non_constant_p,
-					       overflow_p, NULL);
+					       overflow_p);
 	}
       else if (TREE_CODE (t) == AGGR_INIT_EXPR
 	       && AGGR_INIT_ZERO_FIRST (t))
@@ -1283,7 +1282,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
 	      result = (cxx_eval_constant_expression
 			(&new_ctx, new_call.fundef->body,
 			 addr,
-			 non_constant_p, overflow_p, NULL));
+			 non_constant_p, overflow_p));
 	    }
 	  else
 	    {
@@ -1458,8 +1457,7 @@ cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
   tree r;
   tree orig_arg = TREE_OPERAND (t, 0);
   tree arg = cxx_eval_constant_expression (ctx, orig_arg,
-					   addr, non_constant_p, overflow_p,
-					   NULL);
+					   addr, non_constant_p, overflow_p);
   VERIFY_CONSTANT (arg);
   location_t loc = EXPR_LOCATION (t);
   enum tree_code code = TREE_CODE (t);
@@ -1490,11 +1488,11 @@ cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
   tree lhs, rhs;
   lhs = cxx_eval_constant_expression (ctx, orig_lhs,
 				      addr,
-				      non_constant_p, overflow_p, NULL);
+				      non_constant_p, overflow_p);
   VERIFY_CONSTANT (lhs);
   rhs = cxx_eval_constant_expression (ctx, orig_rhs,
 				      addr,
-				      non_constant_p, overflow_p, NULL);
+				      non_constant_p, overflow_p);
   VERIFY_CONSTANT (rhs);
 
   location_t loc = EXPR_LOCATION (t);
@@ -1524,8 +1522,7 @@ cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
 {
   tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
 					   addr,
-					   non_constant_p, overflow_p,
-					   NULL);
+					   non_constant_p, overflow_p);
   VERIFY_CONSTANT (val);
   /* Don't VERIFY_CONSTANT the other operands.  */
   if (integer_zerop (val))
@@ -1550,7 +1547,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
   tree oldary = TREE_OPERAND (t, 0);
   tree ary = cxx_eval_constant_expression (ctx, oldary,
 					   addr,
-					   non_constant_p, overflow_p, NULL);
+					   non_constant_p, overflow_p);
   tree index, oldidx;
   HOST_WIDE_INT i;
   tree elem_type;
@@ -1560,7 +1557,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
   oldidx = TREE_OPERAND (t, 1);
   index = cxx_eval_constant_expression (ctx, oldidx,
 					false,
-					non_constant_p, overflow_p, NULL);
+					non_constant_p, overflow_p);
   VERIFY_CONSTANT (index);
   if (addr && ary == oldary && index == oldidx)
     return t;
@@ -1591,8 +1588,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
 	  tree val = build_value_init (elem_type, tf_warning_or_error);
 	  return cxx_eval_constant_expression (ctx, val,
 					       addr,
-					       non_constant_p, overflow_p,
-					       NULL);
+					       non_constant_p, overflow_p);
 	}
 
       if (!ctx->quiet)
@@ -1638,7 +1634,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
   tree orig_whole = TREE_OPERAND (t, 0);
   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
 					     addr,
-					     non_constant_p, overflow_p, NULL);
+					     non_constant_p, overflow_p);
   if (whole == orig_whole)
     return t;
   if (addr)
@@ -1697,7 +1693,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
   value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
   return cxx_eval_constant_expression (ctx, value,
 				       addr,
-				       non_constant_p, overflow_p, NULL);
+				       non_constant_p, overflow_p);
 }
 
 /* Subroutine of cxx_eval_constant_expression.
@@ -1715,7 +1711,7 @@ cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
   HOST_WIDE_INT istart, isize;
   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
 					     addr,
-					     non_constant_p, overflow_p, NULL);
+					     non_constant_p, overflow_p);
   tree start, field, value;
   unsigned HOST_WIDE_INT i;
 
@@ -1798,14 +1794,14 @@ cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
   tree r;
   tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
 					   addr,
-					   non_constant_p, overflow_p, NULL);
+					   non_constant_p, overflow_p);
   VERIFY_CONSTANT (lhs);
   if (tree_int_cst_equal (lhs, bailout_value))
     return lhs;
   gcc_assert (tree_int_cst_equal (lhs, continue_value));
   r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
 				    addr, non_constant_p,
-				    overflow_p, NULL);
+				    overflow_p);
   VERIFY_CONSTANT (r);
   return r;
 }
@@ -1948,8 +1944,7 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
 	CONSTRUCTOR_APPEND_ELT (*p, index, new_ctx.ctor);
       tree elt = cxx_eval_constant_expression (&new_ctx, value,
 					       addr,
-					       non_constant_p, overflow_p,
-					       NULL);
+					       non_constant_p, overflow_p);
       /* Don't VERIFY_CONSTANT here.  */
       if (ctx->quiet && *non_constant_p)
 	break;
@@ -2067,7 +2062,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
 	     we just pre-built above.  */
 	  eltinit = (cxx_eval_constant_expression
 		     (&new_ctx, init,
-		      addr, non_constant_p, overflow_p, NULL));
+		      addr, non_constant_p, overflow_p));
 	}
       else
 	{
@@ -2081,7 +2076,7 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
 	  eltinit = force_rvalue (eltinit, tf_warning_or_error);
 	  eltinit = (cxx_eval_constant_expression
 		     (&new_ctx, eltinit, addr,
-		      non_constant_p, overflow_p, NULL));
+		      non_constant_p, overflow_p));
 	}
       if (*non_constant_p && !ctx->quiet)
 	break;
@@ -2318,7 +2313,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
   tree orig_op0 = TREE_OPERAND (t, 0);
   tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
 					   /*addr*/false, non_constant_p,
-					   overflow_p, NULL);
+					   overflow_p);
   bool empty_base = false;
   tree r;
 
@@ -2331,7 +2326,7 @@ cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
 
   if (r)
     r = cxx_eval_constant_expression (ctx, r,
-				      addr, non_constant_p, overflow_p, NULL);
+				      addr, non_constant_p, overflow_p);
   else
     {
       tree sub = op0;
@@ -2433,8 +2428,7 @@ cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
     {
       args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
 					      addr,
-					      non_constant_p, overflow_p,
-					      NULL);
+					      non_constant_p, overflow_p);
       VERIFY_CONSTANT (args[i]);
     }
 
@@ -2467,7 +2461,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
   tree target = TREE_OPERAND (t, 0);
   target = cxx_eval_constant_expression (ctx, target,
 					 true,
-					 non_constant_p, overflow_p, NULL);
+					 non_constant_p, overflow_p);
   if (*non_constant_p)
     return t;
 
@@ -2543,7 +2537,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
 
   tree init = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 1),
 					    false,
-					    non_constant_p, overflow_p, NULL);
+					    non_constant_p, overflow_p);
   if (target == object)
     /* The hash table might have moved since the get earlier.  */
     ctx->values->put (object, init);
@@ -2573,12 +2567,12 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
 
   /* The operand as an lvalue.  */
   op = cxx_eval_constant_expression (ctx, op, true,
-				     non_constant_p, overflow_p, NULL);
+				     non_constant_p, overflow_p);
 
   /* The operand as an rvalue.  */
   tree val = rvalue (op);
   val = cxx_eval_constant_expression (ctx, val, false,
-				      non_constant_p, overflow_p, NULL);
+				      non_constant_p, overflow_p);
   VERIFY_CONSTANT (val);
 
   /* The modified value.  */
@@ -2599,7 +2593,7 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
   /* Storing the modified value.  */
   tree store = build2 (MODIFY_EXPR, type, op, mod);
   cxx_eval_constant_expression (ctx, store,
-				true, non_constant_p, overflow_p, NULL);
+				true, non_constant_p, overflow_p);
 
   /* And the value of the expression.  */
   if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
@@ -2754,7 +2748,7 @@ cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
 {
   tree cond = TREE_OPERAND (t, 0);
   cond = cxx_eval_constant_expression (ctx, cond, false,
-				       non_constant_p, overflow_p, NULL);
+				       non_constant_p, overflow_p);
   VERIFY_CONSTANT (cond);
   *jump_target = cond;
 
@@ -2876,8 +2870,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	  {
 	    init = cxx_eval_constant_expression (ctx, init,
 						 false,
-						 non_constant_p, overflow_p,
-						 NULL);
+						 non_constant_p, overflow_p);
 	    ctx->values->put (r, init);
 	  }
 	else if (ctx == &new_ctx)
@@ -2915,7 +2908,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	 initialization of a temporary.  */
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
 					false,
-					non_constant_p, overflow_p, NULL);
+					non_constant_p, overflow_p);
       if (!*non_constant_p)
 	/* Adjust the type of the result to the type of the temporary.  */
 	r = adjust_temp_type (TREE_TYPE (t), r);
@@ -2928,7 +2921,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	     not the side-effect of the initialization.  */
 	  r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
 					    false,
-					    non_constant_p, overflow_p, NULL);
+					    non_constant_p, overflow_p);
 	  break;
 	}
       /* else fall through */
@@ -2940,13 +2933,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
     case SCOPE_REF:
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
 					addr,
-					non_constant_p, overflow_p, NULL);
+					non_constant_p, overflow_p);
       break;
 
     case RETURN_EXPR:
       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
 					addr,
-					non_constant_p, overflow_p, NULL);
+					non_constant_p, overflow_p);
       *jump_target = t;
       break;
 
@@ -2976,8 +2969,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	tree oldop = TREE_OPERAND (t, 0);
 	tree op = cxx_eval_constant_expression (ctx, oldop,
 						/*addr*/true,
-						non_constant_p, overflow_p,
-						NULL);
+						non_constant_p, overflow_p);
 	/* Don't VERIFY_CONSTANT here.  */
 	if (*non_constant_p)
 	  return t;
@@ -3165,8 +3157,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	tree oldop = TREE_OPERAND (t, 0);
 	tree op = cxx_eval_constant_expression (ctx, oldop,
 						addr,
-						non_constant_p, overflow_p,
-						NULL);
+						non_constant_p, overflow_p);
 	if (*non_constant_p)
 	  return t;
 	if (POINTER_TYPE_P (TREE_TYPE (t))
@@ -3256,7 +3247,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 		      (TREE_TYPE (t), TREE_TYPE (ctor)));
 	  return cxx_eval_constant_expression
 	    (ctx, ctor, addr,
-	     non_constant_p, overflow_p, NULL);
+	     non_constant_p, overflow_p);
 	}
       break;
 
@@ -3333,7 +3324,7 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
     }
 
   r = cxx_eval_constant_expression (&ctx, r,
-				    false, &non_constant_p, &overflow_p, NULL);
+				    false, &non_constant_p, &overflow_p);
 
   verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
 
@@ -3410,7 +3401,7 @@ is_sub_constant_expr (tree t)
   hash_map <tree, tree> map;
   ctx.values = &map;
   cxx_eval_constant_expression (&ctx, t, false, &non_constant_p,
-				&overflow_p, NULL);
+				&overflow_p);
   return !non_constant_p && !overflow_p;
 }
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-11-19  3:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-19  7:19 Several small C++ constexpr PATCHes, including c++/63924 (constexpr and empty classes) Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).