From: Marek Polacek Date: Wed, 12 Jun 2019 22:26:54 +0000 (+0000) Subject: PR c++/90825 - endless recursion when evaluating sizeof. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=99e764a225b18deb086ee0e73a14c92df52bed5d;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 90a7b2a87fd..87ca00bcf79 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 60cfafce1f2..8bbabd8ab44 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 154da59627b..a8fb1624b48 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 9dc9ee8bd6a..05802734f6e 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 00000000000..8676ae40b61 --- /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 00000000000..05f07c38796 --- /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{}), "" ); + } +};