Commit c46f1a17 by Marek Polacek Committed by Marek Polacek

PR c++/87603 - constexpr functions are no longer noexcept.

	* constexpr.c (is_sub_constant_expr): Remove unused function.
	* cp-tree.h (is_sub_constant_expr): Remove declaration.
	* except.c (check_noexcept_r): Don't consider a call to a constexpr
	function noexcept.

	* g++.dg/cpp0x/constexpr-noexcept.C: Adjust the expected result.
	* g++.dg/cpp0x/constexpr-noexcept3.C: Likewise.
	* g++.dg/cpp0x/constexpr-noexcept4.C: Likewise.
	* g++.dg/cpp0x/constexpr-noexcept8.C: New test.
	* g++.dg/cpp0x/inh-ctor32.C: Remove dg-message.
	* g++.dg/cpp1y/constexpr-noexcept1.C: New test.

From-SVN: r270320
parent cc3bae3d
......@@ -3,6 +3,12 @@
* except.c (build_noexcept_spec): Use build_converted_constant_bool_expr
instead of perform_implicit_conversion_flags.
PR c++/87603 - constexpr functions are no longer noexcept.
* constexpr.c (is_sub_constant_expr): Remove unused function.
* cp-tree.h (is_sub_constant_expr): Remove declaration.
* except.c (check_noexcept_r): Don't consider a call to a constexpr
function noexcept.
2019-04-11 Jakub Jelinek <jakub@redhat.com>
PR translation/90035
......
......@@ -5423,27 +5423,6 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
return r;
}
/* Returns true if T is a valid subexpression of a constant expression,
even if it isn't itself a constant expression. */
bool
is_sub_constant_expr (tree t)
{
bool non_constant_p = false;
bool overflow_p = false;
hash_map <tree, tree> map;
HOST_WIDE_INT constexpr_ops_count = 0;
constexpr_ctx ctx
= { NULL, &map, NULL, NULL, NULL, NULL, &constexpr_ops_count,
true, true, false };
instantiate_constexpr_fns (t);
cxx_eval_constant_expression (&ctx, t, false, &non_constant_p,
&overflow_p);
return !non_constant_p && !overflow_p;
}
/* If T represents a constant expression returns its reduced value.
Otherwise return error_mark_node. If T is dependent, then
return NULL. */
......
......@@ -7720,7 +7720,6 @@ extern tree fold_non_dependent_init (tree,
tsubst_flags_t = tf_warning_or_error,
bool = false);
extern tree fold_simple (tree);
extern bool is_sub_constant_expr (tree);
extern bool reduced_constant_expression_p (tree);
extern bool is_instantiation_of_constexpr (tree);
extern bool var_in_constexpr_fn (tree);
......
......@@ -1128,11 +1128,14 @@ check_noexcept_r (tree *tp, int * /*walk_subtrees*/, void * /*data*/)
&& (DECL_ARTIFICIAL (fn)
|| nothrow_libfn_p (fn)))
return TREE_NOTHROW (fn) ? NULL_TREE : fn;
/* A call to a constexpr function is noexcept if the call
is a constant expression. */
if (DECL_DECLARED_CONSTEXPR_P (fn)
&& is_sub_constant_expr (t))
return NULL_TREE;
/* We used to treat a call to a constexpr function as noexcept if
the call was a constant expression (CWG 1129). This has changed
in P0003 whereby noexcept has no special rule for constant
expressions anymore. Since the current behavior is important for
certain library functionality, we treat this as a DR, therefore
adjusting the behavior for C++11 and C++14. Previously, we had
to evaluate the noexcept-specifier's operand here, but that could
cause instantiations that would fail. */
}
if (!TYPE_NOTHROW_P (type))
return fn;
......
2019-04-12 Marek Polacek <polacek@redhat.com>
PR c++/87603 - constexpr functions are no longer noexcept.
* g++.dg/cpp0x/constexpr-noexcept.C: Adjust the expected result.
* g++.dg/cpp0x/constexpr-noexcept3.C: Likewise.
* g++.dg/cpp0x/constexpr-noexcept4.C: Likewise.
* g++.dg/cpp0x/constexpr-noexcept8.C: New test.
* g++.dg/cpp0x/inh-ctor32.C: Remove dg-message.
* g++.dg/cpp1y/constexpr-noexcept1.C: New test.
2019-04-12 Marek Polacek <polacek@redhat.com>
* g++.dg/cpp0x/noexcept30.C: Tweak dg-error.
* g++.dg/cpp0x/pr86397-1.C: Likewise.
* g++.dg/cpp0x/pr86397-2.C: Likewise.
......
......@@ -10,4 +10,7 @@ constexpr T value(T t) noexcept(is_funny<T>::value) { return t; } // Line 7
constexpr bool ok = noexcept(value(42));
static_assert(ok, "Assertion failure");
// We used to treat a call to a constexpr function as noexcept if
// the call was a constant expression. We no longer do since
// c++/87603.
static_assert(!ok, "Assertion failure");
......@@ -2,6 +2,8 @@
constexpr int f(int i) { return i; }
#define SA(X) static_assert (X, #X)
SA(noexcept(f(42)));
/* We used to assert that the following *is* noexcept, but this has changed
in c++/87603. */
SA(!noexcept(f(42)));
int j;
SA(!noexcept(f(j)));
// { dg-do compile { target c++11 } }
// A call is noexcept if it is a valid subexpression of a constant
// expression, even if it is not itself a constant expression.
// We used to treat a call to a constexpr function as noexcept if
// the call was a constant expression. We no longer do since
// c++/87603.
#define SA(X) static_assert(X,#X)
......@@ -9,6 +10,6 @@ constexpr const int* f(const int *p) { return p; }
int main()
{
constexpr int i = 42;
SA(noexcept(*f(&i)));
SA(noexcept(f(&i)));
SA(!noexcept(*f(&i)));
SA(!noexcept(f(&i)));
}
// PR c++/87603
// { dg-do compile { target c++11 } }
struct Y { };
bool operator<(Y a, Y b) { return false; }
constexpr bool operator>(Y a, Y b) { return false; }
static_assert(!noexcept(Y{} > Y{}), "");
static_assert(!noexcept(Y{} < Y{}), "");
......@@ -168,7 +168,7 @@ namespace derived_ctor {
};
struct bar : boo {
template <typename ...T>
constexpr bar(T ... args) : boo(args...) {} // { dg-message "sorry, unimplemented: passing arguments to ellipsis" }
constexpr bar(T ... args) : boo(args...) {}
};
void f() noexcept(noexcept(bar{0,1}));
}
......@@ -200,12 +200,12 @@ namespace derived_ctor {
};
struct bor : boo {
template <typename ...T>
constexpr bor(T ... args) : boo(args...) {} // { dg-message "sorry, unimplemented: passing arguments to ellipsis" }
constexpr bor(T ... args) : boo(args...) {}
};
struct bar : bor {
using bor::bor;
};
void f() noexcept(noexcept(bar{0,1})); // { dg-message "'constexpr' expansion" }
void f() noexcept(noexcept(bar{0,1}));
}
namespace no_constexpr_noninherited_ctor {
......
// PR c++/87603
// { dg-do compile { target c++14 } }
template<typename T>
struct basic_string_view
{
constexpr basic_string_view(T p) noexcept { (void) p.i; }
};
struct X { } x;
bool b = noexcept(basic_string_view<X>{x});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment