LOL, this compiles: // P1330R0 - Changing the active member of a union inside constexpr union Foo { int i; float f; }; constexpr int use() { Foo foo{}; foo.i = 3; foo.f = 1.2f; return 1; }
It looks like try blocks in constexpr is in. p1002r1. This may be enough to do some constexpr library bits.
P1330R0 should be now implemented correctly, please report if you see any issues (for -std=c++2a, with error for -std=c++{11,14,17}). The dynamic_cast/rtti constexpr relaxation is not implemented, that one is related to PR63164.
P1002R1 and P1330R0 were implemented in GCC 9. Taking this PR since I'm looking into P1327R1 (for GCC 10).
Looks like we need to teach constexpr how to evaluate a call to __dynamic_cast.
First steps: this now compiles in c++2a: struct B { virtual void baz () {} }; struct D : B { }; constexpr bool fn () { bool ok = true; B b; B *b1 = &b; if (D *pd = dynamic_cast<D*>(b1)) ok = false; D d; B *b2 = &d; if (D *pd = dynamic_cast<D*>(b2)) /*OK*/; else ok = false; return ok; } static_assert(fn ());
Sidecast now works too: struct A { virtual void afn () {} }; struct B { virtual void bfn () {} }; struct D : A, B { }; constexpr bool fn () { bool ok = true; D d; A *a = &d; if (B *bp = dynamic_cast<B*>(a)) /*OK*/; else ok = false; A &ar = d; B &br = dynamic_cast<B&>(ar); return ok; } static_assert(fn ());
Patch posted: https://gcc.gnu.org/ml/gcc-patches/2019-11/msg00650.html For the typeid case, it seems that all that needs to be done is to resolve 356 /* FIXME when integrating with c_fully_fold, mark 357 resolves_to_fixed_type_p case as a non-constant expression. */ 358 if (TYPE_POLYMORPHIC_P (TREE_TYPE (exp)) 359 && ! resolves_to_fixed_type_p (exp, &nonnull) 360 && ! nonnull)
Not entirely true, this template case should be accepted: #include <typeinfo> struct B { virtual void f(); }; struct B2 : B { }; template<typename T> constexpr bool fn () { constexpr B2 b2; static_assert(&typeid(b2) == &typeid(B2)); return true; } static_assert (fn<int>());
Author: mpolacek Date: Fri Nov 22 23:48:25 2019 New Revision: 278635 URL: https://gcc.gnu.org/viewcvs?rev=278635&root=gcc&view=rev Log: PR c++/88337 - P1327R1: Allow polymorphic typeid in constexpr. Part of P1327R1 is to allow typeid with an operand of polymorphic type in constexpr. I found that we pretty much support it already, the only tweak was to allow TYPEID_EXPR (only created in a template) in constexpr in C++20. * constexpr.c (potential_constant_expression_1): Allow a typeid expression whose operand is of polymorphic type in constexpr in C++20. * rtti.c (build_typeid): Remove obsolete FIXME comment. * g++.dg/cpp2a/constexpr-typeid1.C: New test. * g++.dg/cpp2a/constexpr-typeid2.C: New test. * g++.dg/cpp2a/constexpr-typeid3.C: New test. * g++.dg/cpp2a/constexpr-typeid4.C: New test. Added: trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-typeid1.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-typeid2.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-typeid3.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-typeid4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c trunk/gcc/cp/rtti.c trunk/gcc/testsuite/ChangeLog
Author: mpolacek Date: Sun Dec 29 16:44:41 2019 New Revision: 279755 URL: https://gcc.gnu.org/viewcvs?rev=279755&root=gcc&view=rev Log: PR c++/88337 - Implement P1327R1: Allow dynamic_cast in constexpr. This patch implements <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1327r1.html>. When build_dynamic_cast realizes that a dynamic_cast needs a run-time check, it generates a call to __dynamic_cast -- see dyncast.cc in libsupc++ for its definition. The gist of my approach is to evaluate such a call at compile time. * constexpr.c (cxx_dynamic_cast_fn_p): New function. (extract_obj_from_addr_offset): New function. (get_component_with_type): New function. (cxx_eval_dynamic_cast_fn): New function. (cxx_eval_call_expression): Call cxx_eval_dynamic_cast_fn for a call to __dynamic_cast. (potential_constant_expression_1): Don't give up on cxx_dynamic_cast_fn_p. * rtti.c (build_dynamic_cast_1): When creating a call to __dynamic_cast, use the location of the original expression. * g++.dg/cpp2a/constexpr-dynamic1.C: New test. * g++.dg/cpp2a/constexpr-dynamic10.C: New test. * g++.dg/cpp2a/constexpr-dynamic11.C: New test. * g++.dg/cpp2a/constexpr-dynamic12.C: New test. * g++.dg/cpp2a/constexpr-dynamic13.C: New test. * g++.dg/cpp2a/constexpr-dynamic14.C: New test. * g++.dg/cpp2a/constexpr-dynamic15.C: New test. * g++.dg/cpp2a/constexpr-dynamic16.C: New test. * g++.dg/cpp2a/constexpr-dynamic17.C: New test. * g++.dg/cpp2a/constexpr-dynamic2.C: New test. * g++.dg/cpp2a/constexpr-dynamic3.C: New test. * g++.dg/cpp2a/constexpr-dynamic4.C: New test. * g++.dg/cpp2a/constexpr-dynamic5.C: New test. * g++.dg/cpp2a/constexpr-dynamic6.C: New test. * g++.dg/cpp2a/constexpr-dynamic7.C: New test. * g++.dg/cpp2a/constexpr-dynamic8.C: New test. * g++.dg/cpp2a/constexpr-dynamic9.C: New test. Added: trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic1.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic10.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic11.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic12.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic13.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic14.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic15.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic16.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic17.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic2.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic3.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic4.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic5.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic6.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic7.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic8.C trunk/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic9.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c trunk/gcc/cp/rtti.c trunk/gcc/testsuite/ChangeLog
Implemented in GCC 10.