Commit fd338b13 by Jason Merrill Committed by Jason Merrill

Allow references in constant-expressions.

	* decl2.c (decl_maybe_constant_var_p): References qualify.
	* constexpr.c (non_const_var_error): Handle references.
	* init.c (constant_value_1): Always check decl_constant_var_p.
	* cp-gimplify.c (cp_fold_maybe_rvalue): Don't fold references.
	* error.c (dump_decl_name): Split out from dump_decl.

From-SVN: r242422
parent f05a874c
2016-11-15 Jason Merrill <jason@redhat.com>
* decl2.c (decl_maybe_constant_var_p): References qualify.
* constexpr.c (non_const_var_error): Handle references.
* init.c (constant_value_1): Always check decl_constant_var_p.
* cp-gimplify.c (cp_fold_maybe_rvalue): Don't fold references.
* error.c (dump_decl_name): Split out from dump_decl.
2016-11-14 Jason Merrill <jason@redhat.com> 2016-11-14 Jason Merrill <jason@redhat.com>
* tree.c (bitfield_p): New. * tree.c (bitfield_p): New.
......
...@@ -3153,6 +3153,10 @@ non_const_var_error (tree r) ...@@ -3153,6 +3153,10 @@ non_const_var_error (tree r)
else else
gcc_unreachable (); gcc_unreachable ();
} }
else if (TREE_CODE (type) == REFERENCE_TYPE)
inform (DECL_SOURCE_LOCATION (r),
"%qD was not initialized with a constant "
"expression", r);
else else
{ {
if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r)) if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
......
...@@ -1977,7 +1977,8 @@ cp_fold_maybe_rvalue (tree x, bool rval) ...@@ -1977,7 +1977,8 @@ cp_fold_maybe_rvalue (tree x, bool rval)
while (true) while (true)
{ {
x = cp_fold (x); x = cp_fold (x);
if (rval && DECL_P (x)) if (rval && DECL_P (x)
&& TREE_CODE (TREE_TYPE (x)) != REFERENCE_TYPE)
{ {
tree v = decl_constant_value (x); tree v = decl_constant_value (x);
if (v != x && v != error_mark_node) if (v != x && v != error_mark_node)
......
...@@ -4144,6 +4144,9 @@ decl_maybe_constant_var_p (tree decl) ...@@ -4144,6 +4144,9 @@ decl_maybe_constant_var_p (tree decl)
if (DECL_HAS_VALUE_EXPR_P (decl)) if (DECL_HAS_VALUE_EXPR_P (decl))
/* A proxy isn't constant. */ /* A proxy isn't constant. */
return false; return false;
if (TREE_CODE (type) == REFERENCE_TYPE)
/* References can be constant. */
return true;
return (CP_TYPE_CONST_NON_VOLATILE_P (type) return (CP_TYPE_CONST_NON_VOLATILE_P (type)
&& INTEGRAL_OR_ENUMERATION_TYPE_P (type)); && INTEGRAL_OR_ENUMERATION_TYPE_P (type));
} }
......
...@@ -1000,6 +1000,37 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags) ...@@ -1000,6 +1000,37 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
dump_type_suffix (pp, type, flags); dump_type_suffix (pp, type, flags);
} }
/* Print an IDENTIFIER_NODE that is the name of a declaration. */
static void
dump_decl_name (cxx_pretty_printer *pp, tree t, int flags)
{
/* These special cases are duplicated here so that other functions
can feed identifiers to error and get them demangled properly. */
if (IDENTIFIER_TYPENAME_P (t))
{
pp_cxx_ws_string (pp, "operator");
/* Not exactly IDENTIFIER_TYPE_VALUE. */
dump_type (pp, TREE_TYPE (t), flags);
return;
}
if (dguide_name_p (t))
{
dump_decl (pp, CLASSTYPE_TI_TEMPLATE (TREE_TYPE (t)),
TFF_PLAIN_IDENTIFIER);
return;
}
const char *str = IDENTIFIER_POINTER (t);
if (!strncmp (str, "_ZGR", 3))
{
pp_cxx_ws_string (pp, "<temporary>");
return;
}
pp_cxx_tree_identifier (pp, t);
}
/* Dump a human readable string for the decl T under control of FLAGS. */ /* Dump a human readable string for the decl T under control of FLAGS. */
static void static void
...@@ -1155,21 +1186,8 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags) ...@@ -1155,21 +1186,8 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
gcc_unreachable (); gcc_unreachable ();
break; break;
/* These special cases are duplicated here so that other functions
can feed identifiers to error and get them demangled properly. */
case IDENTIFIER_NODE: case IDENTIFIER_NODE:
if (IDENTIFIER_TYPENAME_P (t)) dump_decl_name (pp, t, flags);
{
pp_cxx_ws_string (pp, "operator");
/* Not exactly IDENTIFIER_TYPE_VALUE. */
dump_type (pp, TREE_TYPE (t), flags);
break;
}
else if (dguide_name_p (t))
dump_decl (pp, CLASSTYPE_TI_TEMPLATE (TREE_TYPE (t)),
TFF_PLAIN_IDENTIFIER);
else
pp_cxx_tree_identifier (pp, t);
break; break;
case OVERLOAD: case OVERLOAD:
......
...@@ -2078,10 +2078,9 @@ static tree ...@@ -2078,10 +2078,9 @@ static tree
constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p) constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p)
{ {
while (TREE_CODE (decl) == CONST_DECL while (TREE_CODE (decl) == CONST_DECL
|| (strict_p || decl_constant_var_p (decl)
? decl_constant_var_p (decl) || (!strict_p && VAR_P (decl)
: (VAR_P (decl) && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))))
&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))))
{ {
tree init; tree init;
/* If DECL is a static data member in a template /* If DECL is a static data member in a template
......
// { dg-do compile { target c++11 } }
int &&r = 42;
static_assert (r, ""); // { dg-error "temporary" }
// { dg-prune-output "assert" }
// { dg-do compile { target c++11 } }
int a[2] = { 1, 2 };
int main()
{
auto &r = a;
static_assert (&r[0] == &a[0], "");
}
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