In trying to test adding more constexpr support to std::optional: #include <bits/stl_construct.h> union S { int i; }; constexpr int f() { S s; std::construct_at(&s.i, 0); return 0; } constexpr int z = f(); gcc rejects with: <source>:13:20: in 'constexpr' expansion of 'f()' <source>:9:22: in 'constexpr' expansion of 'std::construct_at<int, int>((& s.S::i), 0)' <source>:13:21: error: '(void*)(& s.S::i)' is not a constant expression 13 | constexpr int z = f(); | ^ But this should be fine.
This is actually a broader bug in construct_at, unrelated to unions: ``` #include <memory> constexpr bool test() { int a = 5; std::construct_at( &a, -1 ); return true; } constexpr bool b = test(); ``` is also rejected. See it live: https://godbolt.org/z/KWK8n1 The real problem here appears to be that std::construct_at is not a constant expression for values with non-constant addresses. The following code, for example, is accepted: ``` #include <memory> struct S { constexpr S() { std::construct_at( &m, -1 ); } int m; }; constexpr S s; ``` See it live: https://godbolt.org/z/Wdx9Kx
Created attachment 49290 [details] gcc11-pr97195.patch Untested fix.
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:2805fcb32660bc0cdcd5ba54310f1f02651e039f commit r11-3581-g2805fcb32660bc0cdcd5ba54310f1f02651e039f Author: Jakub Jelinek <jakub@redhat.com> Date: Thu Oct 1 11:16:44 2020 +0200 c++: Handle std::construct_at on automatic vars during constant evaluation [PR97195] As mentioned in the PR, we only support due to a bug in constant expressions std::construct_at on non-automatic variables, because we VERIFY_CONSTANT the second argument of placement new, which fails verification if it is an address of an automatic variable. The following patch fixes it by not performing that verification, the placement new evaluation later on will verify it after it is dereferenced. 2020-10-01 Jakub Jelinek <jakub@redhat.com> PR c++/97195 * constexpr.c (cxx_eval_call_expression): Don't VERIFY_CONSTANT the second argument. * g++.dg/cpp2a/constexpr-new14.C: New test.
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:355b42c5d9d58d266829d2e44528f7a5ca0eae37 commit r10-8852-g355b42c5d9d58d266829d2e44528f7a5ca0eae37 Author: Jakub Jelinek <jakub@redhat.com> Date: Thu Oct 1 11:16:44 2020 +0200 c++: Handle std::construct_at on automatic vars during constant evaluation [PR97195] As mentioned in the PR, we only support due to a bug in constant expressions std::construct_at on non-automatic variables, because we VERIFY_CONSTANT the second argument of placement new, which fails verification if it is an address of an automatic variable. The following patch fixes it by not performing that verification, the placement new evaluation later on will verify it after it is dereferenced. 2020-10-01 Jakub Jelinek <jakub@redhat.com> PR c++/97195 * constexpr.c (cxx_eval_call_expression): Don't VERIFY_CONSTANT the second argument. * g++.dg/cpp2a/constexpr-new14.C: New test. (cherry picked from commit 2805fcb32660bc0cdcd5ba54310f1f02651e039f)
Fixed.