From 99e764a225b18deb086ee0e73a14c92df52bed5d Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 12 Jun 2019 22:26:54 +0000 Subject: [PATCH] PR c++/90825 - endless recursion when evaluating sizeof. PR c++/90832 - endless recursion when evaluating sizeof. * constexpr.c (cxx_eval_constant_expression): Don't recurse on the result of fold_sizeof_expr if is returns a SIZEOF_EXPR. * typeck.c (cxx_sizeof_expr): Only return a SIZEOF_EXPR if the operand is instantiation-dependent. * g++.dg/cpp0x/constexpr-sizeof2.C: New test. * g++.dg/cpp0x/constexpr-sizeof3.C: New test. From-SVN: r272221 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/constexpr.c | 16 +++++++++++++--- gcc/cp/typeck.c | 2 +- gcc/testsuite/ChangeLog | 7 +++++++ gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof3.C | 22 ++++++++++++++++++++++ 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 90a7b2a..87ca00b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,12 @@ 2019-06-12 Marek Polacek + PR c++/90825 - endless recursion when evaluating sizeof. + PR c++/90832 - endless recursion when evaluating sizeof. + * constexpr.c (cxx_eval_constant_expression): Don't recurse on the + result of fold_sizeof_expr if is returns a SIZEOF_EXPR. + * typeck.c (cxx_sizeof_expr): Only return a SIZEOF_EXPR if the operand + is instantiation-dependent. + PR c++/90736 - bogus error with alignof. * constexpr.c (adjust_temp_type): Use cv_unqualified type. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 60cfafc..8bbabd8 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -4810,9 +4810,19 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; case SIZEOF_EXPR: - r = cxx_eval_constant_expression (ctx, fold_sizeof_expr (t), lval, - non_constant_p, overflow_p, - jump_target); + r = fold_sizeof_expr (t); + /* In a template, fold_sizeof_expr may merely create a new SIZEOF_EXPR, + which could lead to an infinite recursion. */ + if (TREE_CODE (r) != SIZEOF_EXPR) + r = cxx_eval_constant_expression (ctx, r, lval, + non_constant_p, overflow_p, + jump_target); + else + { + *non_constant_p = true; + gcc_assert (ctx->quiet); + } + break; case COMPOUND_EXPR: diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 154da59..a8fb162 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1690,7 +1690,7 @@ cxx_sizeof_expr (tree e, tsubst_flags_t complain) if (e == error_mark_node) return error_mark_node; - if (processing_template_decl) + if (instantiation_dependent_uneval_expression_p (e)) { e = build_min (SIZEOF_EXPR, size_type_node, e); TREE_SIDE_EFFECTS (e) = 0; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9dc9ee8b..0580273 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-06-11 Marek Polacek + + PR c++/90825 - endless recursion when evaluating sizeof. + PR c++/90832 - endless recursion when evaluating sizeof. + * g++.dg/cpp0x/constexpr-sizeof2.C: New test. + * g++.dg/cpp0x/constexpr-sizeof3.C: New test. + 2019-06-12 Martin Sebor PR middle-end/90676 diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C new file mode 100644 index 0000000..8676ae4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof2.C @@ -0,0 +1,14 @@ +// PR c++/90825 - endless recursion when evaluating sizeof. +// { dg-do compile { target c++11 } } + +class address { + char host_[63]; +public: + static constexpr unsigned buffer_size() noexcept { return sizeof(host_); } +}; + +template +void load() +{ + char host[address::buffer_size()]; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof3.C new file mode 100644 index 0000000..05f07c3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof3.C @@ -0,0 +1,22 @@ +// PR c++/90832 - endless recursion when evaluating sizeof. +// { dg-do compile { target c++11 } } + +class B +{ + template friend struct A; + B() {} +}; + +template +struct A +{ + A() noexcept(sizeof(B{})) { } +}; + +struct C +{ + C() + { + static_assert( sizeof(A{}), "" ); + } +}; -- 2.7.4