[Bug c++/91353] New: Implement P1331R2: Permitting trivial default initialization in constexprcontexts
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Aug 5 09:11:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91353
Bug ID: 91353
Summary: Implement P1331R2: Permitting trivial default
initialization in constexprcontexts
Product: gcc
Version: 9.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
Out of curiousity, I've played with this a little bit.
Given
constexpr int
foo (int x)
{
int a;
a = 5;
return x + a;
}
static_assert (foo (2) == 7);
constexpr int
bar (int x)
{
const int a; // { dg-error "" }
constexpr int b; // { dg-error "" }
return x;
}
constexpr int
baz (int x)
{
int a;
return x + a; // { dg-error "" }
}
constexpr int a = baz (5);
constexpr int
qux ()
{
struct S { int a = -5; int b; } s;
return s.a;
}
static_assert (qux () == -5);
constexpr int
quux ()
{
struct S { int a = 9; int b; } s;
return s.b; // { dg-error "" }
}
constexpr int b = quux ();
the following patch doesn't diagnose the quux bug of using uninitialized s.b.
For some reason CONSTRUCTOR_NO_CLEARING is not set and thus we value-initialize
instead of diagnosing.
--- gcc/cp/decl.c.jj 2019-08-05 09:58:07.713491022 +0200
+++ gcc/cp/decl.c 2019-08-05 10:22:28.534127984 +0200
@@ -5742,8 +5742,10 @@ check_for_uninitialized_const_var (tree
7.1.6 */
if (VAR_P (decl)
&& !TYPE_REF_P (type)
- && (constexpr_context_p
- || CP_TYPE_CONST_P (type) || var_in_constexpr_fn (decl))
+ && (CP_TYPE_CONST_P (type)
+ || (cxx_dialect < cxx2a
+ && (constexpr_context_p
+ || var_in_constexpr_fn (decl))))
&& !DECL_NONTRIVIALLY_INITIALIZED_P (decl))
{
tree field = default_init_uninitialized_part (type);
@@ -5752,7 +5754,7 @@ check_for_uninitialized_const_var (tree
bool show_notes = true;
- if (!constexpr_context_p)
+ if (!constexpr_context_p || cxx_dialect >= cxx2a)
{
if (CP_TYPE_CONST_P (type))
{
--- gcc/cp/constexpr.c.jj 2019-08-05 09:57:55.147683227 +0200
+++ gcc/cp/constexpr.c 2019-08-05 10:51:56.954215860 +0200
@@ -814,13 +814,15 @@ cx_check_missing_mem_inits (tree ctype,
continue;
if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
{
- /* Recurse to check the anonummous aggregate member. */
+ /* Recurse to check the anonymous aggregate member. */
bad |= cx_check_missing_mem_inits
(TREE_TYPE (field), NULL_TREE, complain);
if (bad && !complain)
return true;
continue;
}
+ if (cxx_dialect >= cxx2a)
+ continue;
ftype = strip_array_types (TREE_TYPE (field));
if (type_has_constexpr_default_constructor (ftype))
{
@@ -6617,8 +6619,9 @@ potential_constant_expression_1 (tree t,
"%<thread_local%> in %<constexpr%> context", tmp);
return false;
}
- else if (!check_for_uninitialized_const_var
- (tmp, /*constexpr_context_p=*/true, flags))
+ else if (cxx_dialect < cxx2a
+ && !check_for_uninitialized_const_var
+ (tmp, /*constexpr_context_p=*/true, flags))
return false;
}
return RECUR (tmp, want_rval);
--- gcc/cp/method.c.jj 2019-05-20 23:33:13.818084173 +0200
+++ gcc/cp/method.c 2019-08-05 10:46:07.057545848 +0200
@@ -1410,7 +1410,9 @@ walk_field_subobs (tree fields, special_
/* For an implicitly-defined default constructor to be constexpr,
every member must have a user-provided default constructor or
an explicit initializer. */
- if (constexpr_p && !CLASS_TYPE_P (mem_type)
+ if (constexpr_p
+ && cxx_dialect < cxx2a
+ && !CLASS_TYPE_P (mem_type)
&& TREE_CODE (DECL_CONTEXT (field)) != UNION_TYPE)
{
*constexpr_p = false;
Not really sure with the removal of diagnostics for constexpr ctors not
initializing all non-static data members for -std=c++2a, shall we diagnose
somewhere else if a const or constexpr variable is initialized with such a
constructor? And part of this change shall be bumping for cxx_dialect >= cxx2a
of __cpp_constexpr value.
More information about the Gcc-bugs
mailing list