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:
parent
63358530f8
commit
dcba9b0fab
8 changed files with 85 additions and 25 deletions
|
@ -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.
|
||||
|
|
22
gcc/cp/NEWS
22
gcc/cp/NEWS
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
4
gcc/testsuite/g++.dg/template/static1.C
Normal file
4
gcc/testsuite/g++.dg/template/static1.C
Normal file
|
@ -0,0 +1,4 @@
|
|||
template <typename T> struct A
|
||||
{
|
||||
static const int t[1][1]={{0}}; // { dg-error "in-class" }
|
||||
};
|
17
gcc/testsuite/g++.dg/template/static2.C
Normal file
17
gcc/testsuite/g++.dg/template/static2.C
Normal 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;
|
||||
};
|
|
@ -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 ();
|
||||
|
|
Loading…
Add table
Reference in a new issue