From: Jason Merrill Date: Thu, 18 Feb 2016 05:08:09 +0000 (-0500) Subject: re PR c++/65985 (compiler segfault with assert() in constexpr constructor body) X-Git-Tag: basepoints/gcc-7~885 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa837fb670c502e7fbcb3f48aa1932b55704521c;p=thirdparty%2Fgcc.git re PR c++/65985 (compiler segfault with assert() in constexpr constructor body) PR c++/65985 * constexpr.c (build_constexpr_constructor_member_initializers): Handle an additional STATEMENT_LIST. From-SVN: r233514 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 963ba5a5644e..18f80729b78c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-02-17 Jason Merrill + PR c++/65985 + * constexpr.c (build_constexpr_constructor_member_initializers): + Handle an additional STATEMENT_LIST. + PR c++/68585 * constexpr.c (cxx_eval_bare_aggregate): Fix 'changed' detection. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 0eedfca6663a..d3b04b11e803 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -528,21 +528,32 @@ build_constexpr_constructor_member_initializers (tree type, tree body) { vec *vec = NULL; bool ok = true; - if (TREE_CODE (body) == MUST_NOT_THROW_EXPR - || TREE_CODE (body) == EH_SPEC_BLOCK) - body = TREE_OPERAND (body, 0); - if (TREE_CODE (body) == STATEMENT_LIST) - { - for (tree_stmt_iterator i = tsi_start (body); - !tsi_end_p (i); tsi_next (&i)) - { - body = tsi_stmt (i); - if (TREE_CODE (body) == BIND_EXPR) - break; - } + while (true) + switch (TREE_CODE (body)) + { + case MUST_NOT_THROW_EXPR: + case EH_SPEC_BLOCK: + body = TREE_OPERAND (body, 0); + break; + + case STATEMENT_LIST: + for (tree_stmt_iterator i = tsi_start (body); + !tsi_end_p (i); tsi_next (&i)) + { + body = tsi_stmt (i); + if (TREE_CODE (body) == BIND_EXPR) + break; + } + break; + + case BIND_EXPR: + body = BIND_EXPR_BODY (body); + goto found; + + default: + gcc_unreachable (); } - if (TREE_CODE (body) == BIND_EXPR) - body = BIND_EXPR_BODY (body); + found: if (TREE_CODE (body) == CLEANUP_POINT_EXPR) { body = TREE_OPERAND (body, 0); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C new file mode 100644 index 000000000000..a3291017324e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-assert2.C @@ -0,0 +1,31 @@ +// PR c++/65985 +// { dg-do compile { target c++14 } } + +#include + +class Angle +{ + int degrees = 0; + + constexpr auto invariant() const noexcept + { + return 0 <= degrees && degrees < 360; + } + +public: + explicit constexpr Angle(int n) noexcept + : degrees{n % 360} + { + assert(invariant()); + } + + /* implicit */ constexpr operator auto() const noexcept + { + return degrees; + } +}; + +int main() +{ + static_assert(Angle{360} == 0, ""); +}