The following code is not accepted by GCC: #include<cstddef> constexpr volatile std::nullptr_t n{}; constexpr std::nullptr_t m=n; int main(){} Clang and MSVC accept this code. It should be valid since there is a specific exemption for volatile std::nullptr_t in [expr.const], quoting section 7.7 paragraph 10 from N5001: > An expression E is a core constant expression unless the evaluation of E, > following the rules of the abstract machine (6.9.1), would evaluate one of the > following: > > ... > > - an lvalue-to-rvalue conversion (7.3.2) unless it is applied to > - a glvalue of type cv std::nullptr_t, > - a non-volatile glvalue that refers to an object that is usable in constant > expressions, or > - a non-volatile glvalue of literal type that refers to a non-volatile > object whose lifetime began within the evaluation of E;
Regression, even.
Related https://cplusplus.github.io/CWG/issues/2140.html
Confirmed. Note I think there is 2 different changes which caused this. That is a change in 8 caused use to reject: ``` typedef decltype(nullptr) tt; constexpr volatile tt n{}; constexpr tt m=n; ``` But it was not until GCC 9 we (correctly) rejected: ``` constexpr volatile int n1{}; constexpr short m1=n1; ```
(In reply to Andrew Pinski from comment #3) > Confirmed. Note I think there is 2 different changes which caused this. > > That is a change in 8 caused use to reject: > ``` > typedef decltype(nullptr) tt; > constexpr volatile tt n{}; > constexpr tt m=n; > ``` Since my r9-4793: commit 3c393a2c012f7f5f1c3df7d6d7b17a9cf992af17 Author: Marek Polacek <polacek@redhat.com> Date: Tue Dec 11 18:53:03 2018 +0000 PR c++/86608 - reading constexpr volatile variable. > But it was not until GCC 9 we (correctly) rejected: > ``` > constexpr volatile int n1{}; > constexpr short m1=n1; > ``` Same change.
Created attachment 60392 [details] gcc15-pr118661.patch Untested fix.
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:6c8e6d6febaed3c167ca9534935c2cb18045528e commit r15-7413-g6c8e6d6febaed3c167ca9534935c2cb18045528e Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Feb 7 14:27:18 2025 +0100 c++: Allow constexpr reads from volatile std::nullptr_t objects [PR118661] As mentioned in the PR, https://eel.is/c++draft/conv.lval#note-1 says that even volatile reads from std::nullptr_t typed objects actually don't read anything and https://eel.is/c++draft/expr.const#10.9 says that even those are ok in constant expressions. So, the following patch adjusts the r9-4793 changes to have an exception for NULLPTR_TYPE. As [conv.lval]/3 also talks about accessing to inactive member, I've added testcase to cover that as well. 2025-02-07 Jakub Jelinek <jakub@redhat.com> PR c++/118661 * constexpr.cc (potential_constant_expression_1): Don't diagnose lvalue-to-rvalue conversion of volatile lvalue if it has NULLPTR_TYPE. * decl2.cc (decl_maybe_constant_var_p): Return true for constexpr decls with NULLPTR_TYPE even if they are volatile. * g++.dg/cpp0x/constexpr-volatile4.C: New test. * g++.dg/cpp0x/constexpr-union9.C: New test.
Fixed on the trunk so far.
The releases/gcc-14 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:6f5ada57162c10d5ff4b04de275aadf9c81a3da5 commit r14-11295-g6f5ada57162c10d5ff4b04de275aadf9c81a3da5 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Feb 7 14:27:18 2025 +0100 c++: Allow constexpr reads from volatile std::nullptr_t objects [PR118661] As mentioned in the PR, https://eel.is/c++draft/conv.lval#note-1 says that even volatile reads from std::nullptr_t typed objects actually don't read anything and https://eel.is/c++draft/expr.const#10.9 says that even those are ok in constant expressions. So, the following patch adjusts the r9-4793 changes to have an exception for NULLPTR_TYPE. As [conv.lval]/3 also talks about accessing to inactive member, I've added testcase to cover that as well. 2025-02-07 Jakub Jelinek <jakub@redhat.com> PR c++/118661 * constexpr.cc (potential_constant_expression_1): Don't diagnose lvalue-to-rvalue conversion of volatile lvalue if it has NULLPTR_TYPE. * decl2.cc (decl_maybe_constant_var_p): Return true for constexpr decls with NULLPTR_TYPE even if they are volatile. * g++.dg/cpp0x/constexpr-volatile4.C: New test. * g++.dg/cpp0x/constexpr-union9.C: New test. (cherry picked from commit 6c8e6d6febaed3c167ca9534935c2cb18045528e)
Fixed for 14.3 too.
The releases/gcc-13 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:eb3e7de323a67e5a92f1c2224f3251cb47b49c0b commit r13-9588-geb3e7de323a67e5a92f1c2224f3251cb47b49c0b Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Feb 7 14:27:18 2025 +0100 c++: Allow constexpr reads from volatile std::nullptr_t objects [PR118661] As mentioned in the PR, https://eel.is/c++draft/conv.lval#note-1 says that even volatile reads from std::nullptr_t typed objects actually don't read anything and https://eel.is/c++draft/expr.const#10.9 says that even those are ok in constant expressions. So, the following patch adjusts the r9-4793 changes to have an exception for NULLPTR_TYPE. As [conv.lval]/3 also talks about accessing to inactive member, I've added testcase to cover that as well. 2025-02-07 Jakub Jelinek <jakub@redhat.com> PR c++/118661 * constexpr.cc (potential_constant_expression_1): Don't diagnose lvalue-to-rvalue conversion of volatile lvalue if it has NULLPTR_TYPE. * decl2.cc (decl_maybe_constant_var_p): Return true for constexpr decls with NULLPTR_TYPE even if they are volatile. * g++.dg/cpp0x/constexpr-volatile4.C: New test. * g++.dg/cpp0x/constexpr-union9.C: New test. (cherry picked from commit 6c8e6d6febaed3c167ca9534935c2cb18045528e)
Fixed also for 13.4.
The releases/gcc-12 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:c95cd1c5effaec023360c902b38376dc461d41e4 commit r12-11166-gc95cd1c5effaec023360c902b38376dc461d41e4 Author: Jakub Jelinek <jakub@redhat.com> Date: Fri Feb 7 14:27:18 2025 +0100 c++: Allow constexpr reads from volatile std::nullptr_t objects [PR118661] As mentioned in the PR, https://eel.is/c++draft/conv.lval#note-1 says that even volatile reads from std::nullptr_t typed objects actually don't read anything and https://eel.is/c++draft/expr.const#10.9 says that even those are ok in constant expressions. So, the following patch adjusts the r9-4793 changes to have an exception for NULLPTR_TYPE. As [conv.lval]/3 also talks about accessing to inactive member, I've added testcase to cover that as well. 2025-02-07 Jakub Jelinek <jakub@redhat.com> PR c++/118661 * constexpr.cc (potential_constant_expression_1): Don't diagnose lvalue-to-rvalue conversion of volatile lvalue if it has NULLPTR_TYPE. * decl2.cc (decl_maybe_constant_var_p): Return true for constexpr decls with NULLPTR_TYPE even if they are volatile. * g++.dg/cpp0x/constexpr-volatile4.C: New test. * g++.dg/cpp0x/constexpr-union9.C: New test. (cherry picked from commit 6c8e6d6febaed3c167ca9534935c2cb18045528e)
Fixed also for 12.5.
(In reply to Halalaluyafail3 from comment #0) > > - an lvalue-to-rvalue conversion (7.3.2) unless it is applied to > > - a glvalue of type cv std::nullptr_t, https://cplusplus.github.io/CWG/issues/2907.html added the above part.