Files
gcc-reflection/gcc/testsuite/g++.dg/cpp1y/constexpr-union2.C
Patrick Palka b599bf9d6d c++: Reject changing active member of union during initialization [PR94066]
This patch adds a check to detect changing the active union member during
initialization of another member of the union in cxx_eval_store_expression.  It
uses the CONSTRUCTOR_NO_CLEARING flag as a proxy for whether the non-empty
CONSTRUCTOR of UNION_TYPE we're assigning to is in the process of being
initialized.

This patch additionally fixes an issue in reduced_constant_expression_p where we
were returning false for an uninitialized union with no active member.  This
lets us correctly reject the uninitialized use in the testcase
testconstexpr-union4.C that we weren't before.

gcc/cp/ChangeLog:

	PR c++/94066
	* constexpr.c (reduced_constant_expression_p) [CONSTRUCTOR]: Properly
	handle unions without an initializer.
	(cxx_eval_component_reference): Emit a different diagnostic when the
	constructor element corresponding to a union member is NULL.
	(cxx_eval_bare_aggregate): When constructing a union, always set the
	active union member before evaluating the initializer.  Relax assertion
	that verifies the index of the constructor element we're initializing
	hasn't been changed.
	(cxx_eval_store_expression): Diagnose changing the active union member
	while the union is in the process of being initialized.  After setting
	an active union member, clear CONSTRUCTOR_NO_CLEARING on the underlying
	CONSTRUCTOR.
	(cxx_eval_constant_expression) [PLACEHOLDER_EXPR]: Don't re-reduce a
	CONSTRUCTOR returned by lookup_placeholder.

gcc/testsuite/ChangeLog:

	PR c++/94066
	* g++.dg/cpp1y/constexpr-union2.C: New test.
	* g++.dg/cpp1y/constexpr-union3.C: New test.
	* g++.dg/cpp1y/constexpr-union4.C: New test.
	* g++.dg/cpp1y/constexpr-union5.C: New test.
	* g++.dg/cpp1y/pr94066.C: New test.
	* g++.dg/cpp1y/pr94066-2.C: New test.
	* g++.dg/cpp1y/pr94066-3.C: New test.
	* g++.dg/cpp2a/constexpr-union1.C: New test.
2020-03-21 09:49:05 -04:00

10 lines
99 B
C

// { dg-do compile { target c++14 } }
union U
{
char *x = &y;
char y;
};
constexpr U u = {};