return t;
}
+/* Try folding the expression T to a simple constant.
+ Returns that constant, otherwise returns T. */
+
+tree
+fold_to_constant (tree t)
+{
+ tree r = fold (t);
+ if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
+ return r;
+ else
+ return t;
+}
+
/* If T is a constant expression, returns its reduced value.
Otherwise, if T does not have TREE_CONSTANT set, returns T.
Otherwise, returns a version of T without TREE_CONSTANT.
/* No caching or evaluation needed. */
return t;
+ /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
+ but at least try folding it to a simple constant. */
+ if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
+ return fold_to_constant (t);
+
if (manifestly_const_eval != mce_unknown)
return cxx_eval_outermost_constant_expr (t, true, true,
manifestly_const_eval, false, decl);
return r;
}
- /* Don't evaluate an unevaluated operand. */
- if (cp_unevaluated_operand)
- return t;
-
uid_sensitive_constexpr_evaluation_checker c;
r = cxx_eval_outermost_constant_expr (t, true, true,
manifestly_const_eval, false, decl);
}
return t;
}
+ else if (CONSTANT_CLASS_P (t))
+ /* No evaluation needed. */
+ return t;
+ /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
+ but at least try folding it to a simple constant. */
if (cp_unevaluated_operand && !manifestly_const_eval)
- return t;
+ return fold_to_constant (t);
tree r = cxx_eval_outermost_constant_expr (t, true, true,
mce_value (manifestly_const_eval),
tsubst_flags_t = tf_warning_or_error,
bool = false, tree = NULL_TREE);
extern tree fold_simple (tree);
+extern tree fold_to_constant (tree);
extern bool reduced_constant_expression_p (tree);
extern bool is_instantiation_of_constexpr (tree);
extern bool var_in_constexpr_fn (tree);
--- /dev/null
+// PR c++/108218
+// { dg-do compile { target c++11 } }
+
+template<class T>
+void f() {
+ decltype(new int[-1]) p; // { dg-error "negative" }
+ decltype(new int[0-1]) q; // { dg-error "negative" }
+ decltype(new int[1*-1]) r; // { dg-error "negative" }
+}
+
+decltype(new int[-1]) p; // { dg-error "negative" }
+decltype(new int[0-1]) q; // { dg-error "negative" }
+decltype(new int[1*-1]) r; // { dg-error "negative" }