re PR c++/8153 (ICE with static const member in class)

PR c++/8153
	PR c++/8036
	* NEWS: Document removal of in-class initialization extension for
	static data members of non-arithmetic, non-enumeration type.
	* decl.c (check_static_variable_definition): Do not allow that
	extension.
	* decl2.c (grokfield): Do not call digest_init when processing
	templates.

	PR c++/8153
	PR c++/8036
	* g++.dg/template/static1.C: New test.
	* g++.dg/template/static2.C: New test.
	* g++.old-deja/g++.ext/memconst.C: New test.

From-SVN: r59980
This commit is contained in:
Mark Mitchell 2002-12-10 07:11:46 +00:00 committed by Mark Mitchell
parent 63358530f8
commit dcba9b0fab
8 changed files with 85 additions and 25 deletions

View File

@ -1,3 +1,12 @@
2002-12-09 Mark Mitchell <mark@codesourcery.com>
* NEWS: Document removal of in-class initialization extension for
static data members of non-arithmetic, non-enumeration type.
* decl.c (check_static_variable_definition): Do not allow that
extension.
* decl2.c (grokfield): Do not call digest_init when processing
templates.
2002-12-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* error.c (dump_expr): Fix format specifier warning.

View File

@ -2,6 +2,28 @@
* The "new X = 3" extension has been removed; you must now use "new X(3)".
* G++ no longer allows in-class initializations of static data members
that do not have arithmetic or enumeration type. For example:
struct S {
static const char* const p = "abc";
};
is no longer accepted.
Use the standards-conformant form:
struct S {
static const char* const p;
};
const char* const S::p = "abc";
instead.
(ISO C++ is even stricter; it does not allow in-class
initializations of floating-point types.)
*** Changes in GCC 3.1:
* -fhonor-std and -fno-honor-std have been removed. -fno-honor-std was

View File

@ -9616,10 +9616,10 @@ check_static_variable_definition (decl, type)
the definition, but not both. If it appears in the class, the
member is a member constant. The file-scope definition is always
required. */
if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
{
error ("invalid in-class initialization of static data member of non-integral type `%T'",
type);
type);
/* If we just return the declaration, crashes will sometimes
occur. We therefore return void_type_node, as if this was a
friend declaration, to cause callers to completely ignore

View File

@ -979,30 +979,32 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
else
init = digest_init (TREE_TYPE (value), init, (tree *)0);
}
if (TREE_CODE (init) == CONST_DECL)
init = DECL_INITIAL (init);
else if (TREE_READONLY_DECL_P (init))
init = decl_constant_value (init);
else if (TREE_CODE (init) == CONSTRUCTOR)
init = digest_init (TREE_TYPE (value), init, (tree *)0);
if (init == error_mark_node)
/* We must make this look different than `error_mark_node'
because `decl_const_value' would mis-interpret it
as only meaning that this VAR_DECL is defined. */
init = build1 (NOP_EXPR, TREE_TYPE (value), init);
else if (processing_template_decl)
;
else if (! TREE_CONSTANT (init))
if (!processing_template_decl)
{
/* We can allow references to things that are effectively
static, since references are initialized with the address. */
if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE
|| (TREE_STATIC (init) == 0
&& (!DECL_P (init) || DECL_EXTERNAL (init) == 0)))
if (TREE_CODE (init) == CONST_DECL)
init = DECL_INITIAL (init);
else if (TREE_READONLY_DECL_P (init))
init = decl_constant_value (init);
else if (TREE_CODE (init) == CONSTRUCTOR)
init = digest_init (TREE_TYPE (value), init, (tree *)0);
if (init == error_mark_node)
/* We must make this look different than `error_mark_node'
because `decl_const_value' would mis-interpret it
as only meaning that this VAR_DECL is defined. */
init = build1 (NOP_EXPR, TREE_TYPE (value), init);
else if (! TREE_CONSTANT (init))
{
error ("field initializer is not constant");
init = error_mark_node;
/* We can allow references to things that are effectively
static, since references are initialized with the
address. */
if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE
|| (TREE_STATIC (init) == 0
&& (!DECL_P (init) || DECL_EXTERNAL (init) == 0)))
{
error ("field initializer is not constant");
init = error_mark_node;
}
}
}
}

View File

@ -1,3 +1,9 @@
2002-12-09 Mark Mitchell <mark@codesourcery.com>
* g++.dg/template/static1.C: New test.
* g++.dg/template/static2.C: New test.
* g++.old-deja/g++.ext/memconst.C: New test.
2002-12-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* g++.dg/special/conpr-2.C: Expect failure on solaris2.

View File

@ -0,0 +1,4 @@
template <typename T> struct A
{
static const int t[1][1]={{0}}; // { dg-error "in-class" }
};

View File

@ -0,0 +1,17 @@
class A;
template<int A::* P>
class B
{
public:
static int A::* const p = P; // { dg-error "in-class" }
};
class A
{
public:
int dummy;
B<&A::dummy> d;
};

View File

@ -12,7 +12,7 @@ public:
class foo {
private:
static const unsigned char * const dummy_key = (unsigned char*)"ThisIs a dummy!";
static const unsigned char * const dummy_key = (unsigned char*)"ThisIs a dummy!"; // { dg-error "in-class" }
public:
void bar ();