Commit 2d7d7f0f by Jason Merrill Committed by Jason Merrill

re PR c++/62129 (internal compiler error: in output_constant, at varasm.c:4755)

	PR c++/62129
	* class.c (outermost_open_class): New.
	* cp-tree.h: Declare it.
	* decl.c (maybe_register_incomplete_var): Use it.
	(complete_vars): Handle any constant variable.
	* expr.c (cplus_expand_constant): Handle CONSTRUCTOR.

From-SVN: r214333
parent 9b517712
2014-08-22 Jason Merrill <jason@redhat.com>
PR c++/62129
* class.c (outermost_open_class): New.
* cp-tree.h: Declare it.
* decl.c (maybe_register_incomplete_var): Use it.
(complete_vars): Handle any constant variable.
* expr.c (cplus_expand_constant): Handle CONSTRUCTOR.
2014-08-22 Igor Zamyatin <igor.zamyatin@intel.com>
PR other/62008
......
......@@ -7132,6 +7132,27 @@ currently_open_derived_class (tree t)
return NULL_TREE;
}
/* Return the outermost enclosing class type that is still open, or
NULL_TREE. */
tree
outermost_open_class (void)
{
if (!current_class_type)
return NULL_TREE;
tree r = NULL_TREE;
for (int i = current_class_depth; i > 0; --i)
{
if (current_class_stack[i].hidden)
break;
tree t = current_class_stack[i].type;
if (!TYPE_BEING_DEFINED (t))
break;
r = t;
}
return r;
}
/* Returns the innermost class type which is not a lambda closure type. */
tree
......
......@@ -5154,6 +5154,7 @@ extern void resort_type_method_vec (void *, void *,
extern bool add_method (tree, tree, tree);
extern bool currently_open_class (tree);
extern tree currently_open_derived_class (tree);
extern tree outermost_open_class (void);
extern tree current_nonlambda_class_type (void);
extern tree finish_struct (tree, tree);
extern void finish_struct_1 (tree);
......
......@@ -14311,8 +14311,8 @@ grokmethod (cp_decl_specifier_seq *declspecs,
/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that
we can lay it out later, when and if its type becomes complete.
Also handle constexpr pointer to member variables where the initializer
is an unlowered PTRMEM_CST because the class isn't complete yet. */
Also handle constexpr variables where the initializer involves
an unlowered PTRMEM_CST because the class isn't complete yet. */
void
maybe_register_incomplete_var (tree var)
......@@ -14337,12 +14337,13 @@ maybe_register_incomplete_var (tree var)
incomplete_var iv = {var, inner_type};
vec_safe_push (incomplete_vars, iv);
}
else if (TYPE_PTRMEM_P (inner_type)
&& DECL_INITIAL (var)
&& TREE_CODE (DECL_INITIAL (var)) == PTRMEM_CST)
else if (!(DECL_LANG_SPECIFIC (var) && DECL_TEMPLATE_INFO (var))
&& decl_constant_var_p (var)
&& (TYPE_PTRMEM_P (inner_type) || CLASS_TYPE_P (inner_type)))
{
tree context = TYPE_PTRMEM_CLASS_TYPE (inner_type);
gcc_assert (TYPE_BEING_DEFINED (context));
/* When the outermost open class is complete we can resolve any
pointers-to-members. */
tree context = outermost_open_class ();
incomplete_var iv = {var, context};
vec_safe_push (incomplete_vars, iv);
}
......@@ -14366,7 +14367,7 @@ complete_vars (tree type)
tree var = iv->decl;
tree type = TREE_TYPE (var);
if (TYPE_PTRMEM_P (type))
if (decl_constant_var_p (var))
DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
else
{
......
......@@ -74,6 +74,14 @@ cplus_expand_constant (tree cst)
}
break;
case CONSTRUCTOR:
{
constructor_elt *elt;
unsigned HOST_WIDE_INT idx;
FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt)
elt->value = cplus_expand_constant (elt->value);
}
default:
/* There's nothing to do. */
break;
......
// PR c++/62129
// { dg-do compile { target c++11 } }
class Evaluator
{
int MakeChangelist ();
typedef int (Evaluator::*fac_t)();
struct CreatorEntry
{
const char *type;
fac_t factory;
};
static constexpr CreatorEntry kCreators[] = { "", &Evaluator::MakeChangelist };
};
constexpr Evaluator::CreatorEntry Evaluator::kCreators[];
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