From 04a96e5e5c303d93fdb9ffba6b96e723c4b4fe53 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 10 Dec 2002 07:16:06 +0000 Subject: [PATCH] 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: r59982 --- gcc/cp/NEWS | 24 ++++++++++ gcc/cp/decl.c | 4 +- gcc/cp/decl2.c | 46 ++++++++++--------- gcc/testsuite/g++.old-deja/g++.ext/memconst.C | 2 +- 4 files changed, 51 insertions(+), 25 deletions(-) diff --git a/gcc/cp/NEWS b/gcc/cp/NEWS index caee3fb48b09..97d4cd83f510 100644 --- a/gcc/cp/NEWS +++ b/gcc/cp/NEWS @@ -1,3 +1,27 @@ +*** Changes in GCC 3.2.2: + +* 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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b1981c0e1ffd..9ec1170bc7e0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9402,10 +9402,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 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index be72010125c0..1e8101a6bd15 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1583,30 +1583,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; + } } } } diff --git a/gcc/testsuite/g++.old-deja/g++.ext/memconst.C b/gcc/testsuite/g++.old-deja/g++.ext/memconst.C index a49d3a058982..a47a45ca8f6a 100644 --- a/gcc/testsuite/g++.old-deja/g++.ext/memconst.C +++ b/gcc/testsuite/g++.old-deja/g++.ext/memconst.C @@ -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 (); -- 2.47.2