Fix empty class parameters with constexpr.
PR c++/67131 * class.c (is_really_empty_class): Call complete_type. * constexpr.c (cxx_eval_constant_expression): Check is_really_empty_class. (potential_constant_expression_1): Likewise. Check for error type. From-SVN: r239267
This commit is contained in:
parent
b08e71f9e8
commit
7dc2b4a235
@ -1,3 +1,11 @@
|
||||
2016-08-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/67131
|
||||
* class.c (is_really_empty_class): Call complete_type.
|
||||
* constexpr.c (cxx_eval_constant_expression): Check
|
||||
is_really_empty_class.
|
||||
(potential_constant_expression_1): Likewise. Check for error type.
|
||||
|
||||
2016-08-08 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/58706
|
||||
|
@ -8419,7 +8419,7 @@ is_really_empty_class (tree type)
|
||||
|
||||
/* CLASSTYPE_EMPTY_P isn't set properly until the class is actually laid
|
||||
out, but we'd like to be able to check this before then. */
|
||||
if (COMPLETE_TYPE_P (type) && is_empty_class (type))
|
||||
if (COMPLETE_TYPE_P (complete_type (type)) && is_empty_class (type))
|
||||
return true;
|
||||
|
||||
for (binfo = TYPE_BINFO (type), i = 0;
|
||||
|
@ -3670,7 +3670,13 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
|
||||
CONST_DECL for aggregate constants. */
|
||||
if (lval)
|
||||
return t;
|
||||
if (ctx->strict)
|
||||
if (is_really_empty_class (TREE_TYPE (t)))
|
||||
{
|
||||
/* If the class is empty, we aren't actually loading anything. */
|
||||
r = build_constructor (TREE_TYPE (t), NULL);
|
||||
TREE_CONSTANT (r) = true;
|
||||
}
|
||||
else if (ctx->strict)
|
||||
r = decl_really_constant_value (t);
|
||||
else
|
||||
r = decl_constant_value (t);
|
||||
@ -3705,7 +3711,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
|
||||
/* Defer in case this is only used for its type. */;
|
||||
else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
|
||||
/* Defer, there's no lvalue->rvalue conversion. */;
|
||||
else if (is_empty_class (TREE_TYPE (t)))
|
||||
else if (is_really_empty_class (TREE_TYPE (t)))
|
||||
{
|
||||
/* If the class is empty, we aren't actually loading anything. */
|
||||
r = build_constructor (TREE_TYPE (t), NULL);
|
||||
@ -4736,6 +4742,9 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
|
||||
}
|
||||
if (CONSTANT_CLASS_P (t))
|
||||
return true;
|
||||
if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)
|
||||
&& TREE_TYPE (t) == error_mark_node)
|
||||
return false;
|
||||
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
@ -4891,12 +4900,14 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict,
|
||||
|
||||
case VAR_DECL:
|
||||
if (want_rval
|
||||
&& !var_in_constexpr_fn (t)
|
||||
&& !type_dependent_expression_p (t)
|
||||
&& !decl_constant_var_p (t)
|
||||
&& (strict
|
||||
|| !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
|
||||
|| !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t))
|
||||
&& !var_in_constexpr_fn (t)
|
||||
&& !type_dependent_expression_p (t))
|
||||
&& COMPLETE_TYPE_P (TREE_TYPE (t))
|
||||
&& !is_really_empty_class (TREE_TYPE (t)))
|
||||
{
|
||||
if (flags & tf_error)
|
||||
non_const_var_error (t);
|
||||
|
5
gcc/testsuite/g++.dg/cpp0x/constexpr-empty12.C
Normal file
5
gcc/testsuite/g++.dg/cpp0x/constexpr-empty12.C
Normal file
@ -0,0 +1,5 @@
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct A { } a;
|
||||
constexpr int f (A a) { return 42; }
|
||||
constexpr int i = f(a);
|
7
gcc/testsuite/g++.dg/cpp0x/constexpr-empty13.C
Normal file
7
gcc/testsuite/g++.dg/cpp0x/constexpr-empty13.C
Normal file
@ -0,0 +1,7 @@
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct A {
|
||||
struct B { } b;
|
||||
} a;
|
||||
constexpr int f (A a) { return 42; }
|
||||
constexpr int i = f(a);
|
@ -14,4 +14,4 @@ template <template <typename...> class F> struct A {
|
||||
template <typename F> auto valid_call(F f) -> decltype(f());
|
||||
constexpr auto valid_call(...) { return 0; }
|
||||
template <typename> struct no_type;
|
||||
static_assert(!valid_call(metafunction<no_type>),""); // { dg-error "" }
|
||||
static_assert(!valid_call(metafunction<no_type>),"");
|
||||
|
Loading…
Reference in New Issue
Block a user