Commit bb64bef6 by Marek Polacek Committed by Marek Polacek

PR c++/91644 - ICE with constinit in function template.

	* decl.c (start_decl): Call retrofit_lang_decl for constinit variables.
	* pt.c (tsubst_expr): Pass LOOKUP_CONSTINIT down to cp_finish_decl for
	constinit variables.

	* g++.dg/cpp2a/constinit13.C: New test.

From-SVN: r275421
parent b2c113ae
2019-09-05 Marek Polacek <polacek@redhat.com>
PR c++/91644 - ICE with constinit in function template.
* decl.c (start_decl): Call retrofit_lang_decl for constinit variables.
* pt.c (tsubst_expr): Pass LOOKUP_CONSTINIT down to cp_finish_decl for
constinit variables.
2019-09-05 Nathan Sidwell <nathan@acm.org> 2019-09-05 Nathan Sidwell <nathan@acm.org>
* cp-tree.h (DECL_VTABLE_OR_VTT_P): Forward to DECL_VIRTUAL_P. * cp-tree.h (DECL_VTABLE_OR_VTT_P): Forward to DECL_VIRTUAL_P.
......
...@@ -5308,7 +5308,14 @@ start_decl (const cp_declarator *declarator, ...@@ -5308,7 +5308,14 @@ start_decl (const cp_declarator *declarator,
decl = maybe_push_decl (decl); decl = maybe_push_decl (decl);
if (processing_template_decl) if (processing_template_decl)
decl = push_template_decl (decl); {
/* Make sure that for a `constinit' decl push_template_decl creates
a DECL_TEMPLATE_INFO info for us, so that cp_finish_decl can then set
TINFO_VAR_DECLARED_CONSTINIT. */
if (decl_spec_seq_has_spec_p (declspecs, ds_constinit))
retrofit_lang_decl (decl);
decl = push_template_decl (decl);
}
if (decl == error_mark_node) if (decl == error_mark_node)
return error_mark_node; return error_mark_node;
......
...@@ -17108,6 +17108,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, ...@@ -17108,6 +17108,13 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
else else
{ {
init = DECL_INITIAL (decl); init = DECL_INITIAL (decl);
/* The following tsubst call will clear the DECL_TEMPLATE_INFO
for local variables, so save if DECL was declared constinit. */
const bool constinit_p
= (VAR_P (decl)
&& DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_INFO (decl)
&& TINFO_VAR_DECLARED_CONSTINIT (DECL_TEMPLATE_INFO (decl)));
decl = tsubst (decl, args, complain, in_decl); decl = tsubst (decl, args, complain, in_decl);
if (decl != error_mark_node) if (decl != error_mark_node)
{ {
...@@ -17146,7 +17153,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, ...@@ -17146,7 +17153,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
} }
else else
{ {
int const_init = false; bool const_init = false;
unsigned int cnt = 0; unsigned int cnt = 0;
tree first = NULL_TREE, ndecl = error_mark_node; tree first = NULL_TREE, ndecl = error_mark_node;
maybe_push_decl (decl); maybe_push_decl (decl);
...@@ -17167,7 +17174,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, ...@@ -17167,7 +17174,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
if (ndecl != error_mark_node) if (ndecl != error_mark_node)
cp_maybe_mangle_decomp (ndecl, first, cnt); cp_maybe_mangle_decomp (ndecl, first, cnt);
cp_finish_decl (decl, init, const_init, NULL_TREE, 0); cp_finish_decl (decl, init, const_init, NULL_TREE,
constinit_p ? LOOKUP_CONSTINIT : 0);
if (ndecl != error_mark_node) if (ndecl != error_mark_node)
cp_finish_decomp (ndecl, first, cnt); cp_finish_decomp (ndecl, first, cnt);
......
2019-09-05 Marek Polacek <polacek@redhat.com>
PR c++/91644 - ICE with constinit in function template.
* g++.dg/cpp2a/constinit13.C: New test.
2019-09-05 Jakub Jelinek <jakub@redhat.com> 2019-09-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/91001 PR middle-end/91001
......
// PR c++/91644 - ICE with constinit in function template.
// { dg-do compile { target c++11 } }
template <typename T>
static void fn1 ()
{
static __constinit auto v1 = 0;
static __constinit int v2 = 0;
}
int nonconst;
template <typename T>
static void fn2 ()
{
static __constinit auto v1 = nonconst; // { dg-error "does not have a constant initializer|not usable" }
static __constinit int v2 = nonconst; // { dg-error "does not have a constant initializer|not usable" }
}
template <typename T>
static void fn3 ()
{
static __constinit T v1 = 0;
static __constinit T v2 = nonconst; // { dg-error "does not have a constant initializer|not usable" }
}
void
g ()
{
fn1<int>();
fn2<int>();
fn3<int>();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment