re PR c++/26266 (Trouble with static const data members in template classes)
authorMark Mitchell <mark@codesourcery.com>
Sat, 18 Feb 2006 08:36:11 +0000 (08:36 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Sat, 18 Feb 2006 08:36:11 +0000 (08:36 +0000)
PR c++/26266
* cp-tree.h (cp_finish_decl): Adjust declaration.
(grokbitfield): Likewise.
(finish_static_data_member_decl): Likewise.
* init.c (constant_value_1): Ensure processing_template_decl when
folding non-dependent initializers for static data members of
dependent types.  Return error_mark_node for erroneous
initailizers.
* class.c (get_vtable_decl): Use finish_decl, not cp_finish_decl.
* decl.c (cp_make_fname_decl): Adjust call to cp_finish_decl.
(cp_finish_decl): Add init_const_expr_p parameter.  Set
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
(finish_decl): Adjust call to cp_finish_decl.
(compute_array_index_type): Robustify.
(start_method): Use finish_decl, not cp_finish_decl.
* rtti.c (emit_tinfo_decl): Likewise.
* except.c (initialize_handler_parm): Adjust call to
cp_finish_decl.
(expand_start_catch_block): Likewise.
* cvt.c (build_up_reference): Adjust call to cp_finish_decl.
* pt.c (instantiate_class_template): Adjust call to
finish_static_data_member_decl.
(tsubst_expr): Use finish_decl, not cp_finish_decl.
(instantiate_decl): Adjust call to cp_finish_decl.
* name-lookup.c (pushdecl_top_level_1): Use finish_decl, not
cp_finish_decl.
* decl2.c (finish_static_data_member_decl): Add init_const_expr_p
parameter.
(grokfield): Likewise.
* parser.c (cp_parser_condition): Check for constant initializers.
(cp_parser_init_declarator): Adjust calls to grokfield and
cp_finish_decl.  Don't set
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
(cp_parser_member_declaration): Likewise.
(cp_parser_objc_class_ivars): Likewise.
PR c++/26266
* g++.dg/template/static22.C: New test.
* g++.dg/template/static23.C: New test.
* g++.dg/template/static24.C: New test.
* g++.dg/template/non-dependent13.C: New test.

From-SVN: r111229

17 files changed:
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/decl2.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/name-lookup.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/non-dependent13.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/static22.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/static23.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/static24.C [new file with mode: 0644]

index 5f153639eb08e9308f51681009c267f06a628a10..b7cda7715f1201692987b6b64e4d19b3a1e5ecdc 100644 (file)
@@ -1,3 +1,41 @@
+2006-02-18  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/26266
+       * cp-tree.h (cp_finish_decl): Adjust declaration.
+       (grokbitfield): Likewise.
+       (finish_static_data_member_decl): Likewise.
+       * init.c (constant_value_1): Ensure processing_template_decl when
+       folding non-dependent initializers for static data members of
+       dependent types.  Return error_mark_node for erroneous
+       initailizers.
+       * class.c (get_vtable_decl): Use finish_decl, not cp_finish_decl.
+       * decl.c (cp_make_fname_decl): Adjust call to cp_finish_decl.
+       (cp_finish_decl): Add init_const_expr_p parameter.  Set
+       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
+       (finish_decl): Adjust call to cp_finish_decl.
+       (compute_array_index_type): Robustify.
+       (start_method): Use finish_decl, not cp_finish_decl.
+       * rtti.c (emit_tinfo_decl): Likewise.
+       * except.c (initialize_handler_parm): Adjust call to
+       cp_finish_decl.
+       (expand_start_catch_block): Likewise.
+       * cvt.c (build_up_reference): Adjust call to cp_finish_decl.
+       * pt.c (instantiate_class_template): Adjust call to
+       finish_static_data_member_decl.
+       (tsubst_expr): Use finish_decl, not cp_finish_decl.
+       (instantiate_decl): Adjust call to cp_finish_decl.
+       * name-lookup.c (pushdecl_top_level_1): Use finish_decl, not
+       cp_finish_decl.
+       * decl2.c (finish_static_data_member_decl): Add init_const_expr_p
+       parameter.
+       (grokfield): Likewise.
+       * parser.c (cp_parser_condition): Check for constant initializers.
+       (cp_parser_init_declarator): Adjust calls to grokfield and
+       cp_finish_decl.  Don't set
+       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P here.
+       (cp_parser_member_declaration): Likewise.
+       (cp_parser_objc_class_ivars): Likewise.
+
 2006-02-14  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        * call.c (standard_conversion): Return NULL instead of 0.
index 19d18ccf14ef8e4b27590ba01657044188264cb4..3f48faeb4eca5f5df9f07ea6c7845e277fd7ce2a 100644 (file)
@@ -741,7 +741,7 @@ get_vtable_decl (tree type, int complete)
   if (complete)
     {
       DECL_EXTERNAL (decl) = 1;
-      cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
+      finish_decl (decl, NULL_TREE, NULL_TREE);
     }
 
   return decl;
index dd10d6d317daffc081347059136a14dd27ddcdd9..2f67f374ff31b50af2f9047feeeb158ac2a4faa4 100644 (file)
@@ -3802,7 +3802,7 @@ extern tree shadow_tag                            (cp_decl_specifier_seq *);
 extern tree groktypename                       (cp_decl_specifier_seq *, const cp_declarator *);
 extern tree start_decl                         (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, tree *);
 extern void start_decl_1                       (tree);
-extern void cp_finish_decl                     (tree, tree, tree, int);
+extern void cp_finish_decl                     (tree, tree, bool, tree, int);
 extern void finish_decl                                (tree, tree, tree);
 extern int cp_complete_array_type              (tree *, tree, bool);
 extern tree build_ptrmemfunc_type              (tree);
@@ -3876,7 +3876,7 @@ extern tree delete_sanity                 (tree, tree, bool, int);
 extern tree check_classfn                      (tree, tree, tree);
 extern void check_member_template              (tree);
 extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
-                      tree, tree, tree);
+                      tree, bool, tree, tree);
 extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
                          tree);
 extern void cplus_decl_attributes              (tree *, tree, int);
@@ -3891,7 +3891,7 @@ extern tree build_cleanup                 (tree);
 extern tree build_offset_ref_call_from_tree    (tree, tree);
 extern void check_default_args                 (tree);
 extern void mark_used                          (tree);
-extern void finish_static_data_member_decl     (tree, tree, tree, int);
+extern void finish_static_data_member_decl     (tree, tree, bool, tree, int);
 extern tree cp_build_parm_decl                 (tree, tree);
 extern tree get_guard                          (tree);
 extern tree get_guard_cond                     (tree);
index abdb4990a8bc18e850eec119a518c5c10cfc329c..c59c74c135cae45d3485aebbf73c053314696b83 100644 (file)
@@ -365,7 +365,7 @@ build_up_reference (tree type, tree arg, int flags, tree decl)
 
       /* Process the initializer for the declaration.  */
       DECL_INITIAL (arg) = targ;
-      cp_finish_decl (arg, targ, NULL_TREE,
+      cp_finish_decl (arg, targ, /*init_const_expr_p=*/false, NULL_TREE,
                      LOOKUP_ONLYCONVERTING|DIRECT_BIND);
     }
   else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
index 146c967461d32eed42feb02534cbcc20fd335519..35dc38c0a45537bc4eb9b8d3f1a80bcedbf01a54 100644 (file)
@@ -3197,7 +3197,8 @@ cp_make_fname_decl (tree id, int type_dep)
       while (b->level_chain->kind != sk_function_parms)
        b = b->level_chain;
       pushdecl_with_scope (decl, b, /*is_friend=*/false);
-      cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+      cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE, 
+                     LOOKUP_ONLYCONVERTING);
     }
   else
     pushdecl_top_level_and_finish (decl, init);
@@ -4855,14 +4856,15 @@ initialize_artificial_var (tree decl, tree init)
    If the length of an array type is not known before,
    it must be determined now, from the initial value, or it is an error.
 
-   INIT holds the value of an initializer that should be allowed to escape
-   the normal rules.
+   INIT is the initializer (if any) for DECL.  If INIT_CONST_EXPR_P is
+   true, then INIT is an integral constant expression.
 
    FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
    if the (init) syntax was used.  */
 
 void
-cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
+cp_finish_decl (tree decl, tree init, bool init_const_expr_p, 
+               tree asmspec_tree, int flags)
 {
   tree type;
   tree cleanup;
@@ -4914,7 +4916,16 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
        add_decl_expr (decl);
 
       if (init && DECL_INITIAL (decl))
-       DECL_INITIAL (decl) = init;
+       {
+         DECL_INITIAL (decl) = init;
+         if (init_const_expr_p)
+           {
+             DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+             if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+               TREE_CONSTANT (decl) = 1;
+           }
+       }
+
       if (TREE_CODE (decl) == VAR_DECL
          && !DECL_PRETTY_FUNCTION_P (decl)
          && !dependent_type_p (TREE_TYPE (decl)))
@@ -4975,7 +4986,15 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
          && (!DECL_EXTERNAL (decl) || init))
        {
          if (init)
-           DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+           {
+             DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
+             if (init_const_expr_p)
+               {
+                 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+                 if (DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+                   TREE_CONSTANT (decl) = 1;
+               }
+           }
          init = check_initializer (decl, init, flags, &cleanup);
          /* Thread-local storage cannot be dynamically initialized.  */
          if (DECL_THREAD_LOCAL_P (decl) && init)
@@ -5127,7 +5146,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
 void
 finish_decl (tree decl, tree init, tree asmspec_tree)
 {
-  cp_finish_decl (decl, init, asmspec_tree, 0);
+  cp_finish_decl (decl, init, /*init_const_expr_p=*/false, asmspec_tree, 0);
 }
 
 /* Returns a declaration for a VAR_DECL as if:
@@ -5152,7 +5171,7 @@ declare_global_var (tree name, tree type)
      library), then it is possible that our declaration will be merged
      with theirs by pushdecl.  */
   decl = pushdecl (decl);
-  cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0);
+  finish_decl (decl, NULL_TREE, NULL_TREE);
   pop_from_top_level ();
 
   return decl;
@@ -6274,9 +6293,13 @@ check_static_variable_definition (tree decl, tree type)
 tree
 compute_array_index_type (tree name, tree size)
 {
-  tree type = TREE_TYPE (size);
+  tree type;
   tree itype;
 
+  if (error_operand_p (size))
+    return error_mark_node;
+
+  type = TREE_TYPE (size);
   /* The array bound must be an integer type.  */
   if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
     {
@@ -11033,7 +11056,7 @@ start_method (cp_decl_specifier_seq *declspecs,
       grok_special_member_properties (fndecl);
     }
 
-  cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0);
+  finish_decl (fndecl, NULL_TREE, NULL_TREE);
 
   /* Make a place for the parms.  */
   begin_scope (sk_function_parms, fndecl);
index be9f326b156035a7df87b197a8253e29786129f0..18cdae214f9af3e323807027a716fc25df6936e5 100644 (file)
@@ -737,12 +737,12 @@ note_vague_linkage_var (tree var)
 }
 
 /* We have just processed the DECL, which is a static data member.
-   Its initializer, if present, is INIT.  The ASMSPEC_TREE, if
-   present, is the assembly-language name for the data member.
-   FLAGS is as for cp_finish_decl.  */
+   The other parameters are as for cp_finish_decl.  */
 
 void
-finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
+finish_static_data_member_decl (tree decl, 
+                               tree init, bool init_const_expr_p,
+                               tree asmspec_tree,
                                int flags)
 {
   gcc_assert (TREE_PUBLIC (decl));
@@ -783,31 +783,18 @@ finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
   DECL_INITIAL (decl) = init;
   DECL_IN_AGGR_P (decl) = 1;
 
-  cp_finish_decl (decl, init, asmspec_tree, flags);
+  cp_finish_decl (decl, init, init_const_expr_p, asmspec_tree, flags);
 }
 
-/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
-   of a structure component, returning a _DECL node.
-   QUALS is a list of type qualifiers for this decl (such as for declaring
-   const member functions).
-
-   This is done during the parsing of the struct declaration.
-   The _DECL nodes are chained together and the lot of them
-   are ultimately passed to `build_struct' to make the RECORD_TYPE node.
-
-   If class A defines that certain functions in class B are friends, then
-   the way I have set things up, it is B who is interested in permission
-   granted by A.  However, it is in A's context that these declarations
-   are parsed.  By returning a void_type_node, class A does not attempt
-   to incorporate the declarations of the friends within its structure.
-
-   DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING
-   CHANGES TO CODE IN `start_method'.  */
+/* DECLARATOR and DECLSPECS correspond to a class member.  The othe
+   parameters are as for cp_finish_decl.  Return the DECL for the
+   class member declared.  */ 
 
 tree
 grokfield (const cp_declarator *declarator,
           cp_decl_specifier_seq *declspecs,
-          tree init, tree asmspec_tree,
+          tree init, bool init_const_expr_p,
+          tree asmspec_tree,
           tree attrlist)
 {
   tree value;
@@ -946,8 +933,8 @@ grokfield (const cp_declarator *declarator,
   switch (TREE_CODE (value))
     {
     case VAR_DECL:
-      finish_static_data_member_decl (value, init, asmspec_tree,
-                                     flags);
+      finish_static_data_member_decl (value, init, init_const_expr_p,
+                                     asmspec_tree, flags);
       return value;
 
     case FIELD_DECL:
@@ -955,7 +942,8 @@ grokfield (const cp_declarator *declarator,
        error ("%<asm%> specifiers are not permitted on non-static data members");
       if (DECL_INITIAL (value) == error_mark_node)
        init = error_mark_node;
-      cp_finish_decl (value, init, NULL_TREE, flags);
+      cp_finish_decl (value, init, /*init_const_expr_p=*/false, 
+                     NULL_TREE, flags);
       DECL_INITIAL (value) = init;
       DECL_IN_AGGR_P (value) = 1;
       return value;
@@ -966,7 +954,8 @@ grokfield (const cp_declarator *declarator,
       if (!DECL_FRIEND_P (value))
        grok_special_member_properties (value);
 
-      cp_finish_decl (value, init, asmspec_tree, flags);
+      cp_finish_decl (value, init, /*init_const_expr_p=*/false, 
+                     asmspec_tree, flags);
 
       /* Pass friends back this way.  */
       if (DECL_FRIEND_P (value))
@@ -1025,7 +1014,7 @@ grokbitfield (const cp_declarator *declarator,
       error ("static member %qD cannot be a bit-field", value);
       return NULL_TREE;
     }
-  cp_finish_decl (value, NULL_TREE, NULL_TREE, 0);
+  finish_decl (value, NULL_TREE, NULL_TREE);
 
   if (width != error_mark_node)
     {
index 9041342ba32450972ad2cfac5862eedb736be383..8d684864232263d3015495be43e6fa551b781edf 100644 (file)
@@ -397,7 +397,7 @@ initialize_handler_parm (tree decl, tree exp)
   decl = pushdecl (decl);
 
   start_decl_1 (decl);
-  cp_finish_decl (decl, init, NULL_TREE,
+  cp_finish_decl (decl, init, /*init_const_expr_p=*/false, NULL_TREE,
                  LOOKUP_ONLYCONVERTING|DIRECT_BIND);
 }
 
@@ -461,7 +461,8 @@ expand_start_catch_block (tree decl)
       tree init = do_begin_catch ();
       exp = create_temporary_var (ptr_type_node);
       DECL_REGISTER (exp) = 1;
-      cp_finish_decl (exp, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+      cp_finish_decl (exp, init, /*init_const_expr=*/false, 
+                     NULL_TREE, LOOKUP_ONLYCONVERTING);
       finish_expr_stmt (build_modify_expr (exp, INIT_EXPR, init));
       initialize_handler_parm (decl, exp);
     }
index 0ef0c1ada73fe27b2f6bf4860c4f7e80b21835e8..6a7e625a00f28d8d7da8d817e4c7a94ccaf11739 100644 (file)
@@ -1484,7 +1484,7 @@ constant_value_1 (tree decl, bool integral_p)
       tree init;
       /* Static data members in template classes may have
         non-dependent initializers.  References to such non-static
-        data members are no value-dependent, so we must retrieve the
+        data members are not value-dependent, so we must retrieve the
         initializer here.  The DECL_INITIAL will have the right type,
         but will not have been folded because that would prevent us
         from performing all appropriate semantic checks at
@@ -1493,7 +1493,11 @@ constant_value_1 (tree decl, bool integral_p)
          && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
          && uses_template_parms (CLASSTYPE_TI_ARGS 
                                  (DECL_CONTEXT (decl))))
-       init = fold_non_dependent_expr (DECL_INITIAL (decl));
+       {
+         ++processing_template_decl;
+         init = fold_non_dependent_expr (DECL_INITIAL (decl));
+         --processing_template_decl;
+       }
       else
        {
          /* If DECL is a static data member in a template
@@ -1503,7 +1507,9 @@ constant_value_1 (tree decl, bool integral_p)
          mark_used (decl);
          init = DECL_INITIAL (decl);
        }
-      if (!init || init == error_mark_node
+      if (init == error_mark_node)
+       return error_mark_node;
+      if (!init
          || !TREE_TYPE (init)
          || (integral_p
              ? !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (init))
index 449b8c625ac3d28c41338d61f40030fa10cf3722..52cef59bb9573055747bcf32ca7e7aae2db213a6 100644 (file)
@@ -3324,7 +3324,7 @@ pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
   push_to_top_level ();
   x = pushdecl_namespace_level (x, is_friend);
   if (init)
-    cp_finish_decl (x, *init, NULL_TREE, 0);
+    finish_decl (x, *init, NULL_TREE);
   pop_from_top_level ();
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
 }
index 37df31160d22928afb11ca25669606ef91ed4e3b..ffec8f2fdddb776f8b72ea64c44d2d64b31df124 100644 (file)
@@ -6500,6 +6500,7 @@ cp_parser_condition (cp_parser* parser)
       if (cp_parser_parse_definitely (parser))
        {
          tree pushed_scope;
+         bool non_constant_p;
 
          /* Create the declaration.  */
          decl = start_decl (declarator, &type_specifiers,
@@ -6507,12 +6508,16 @@ cp_parser_condition (cp_parser* parser)
                             attributes, /*prefix_attributes=*/NULL_TREE,
                             &pushed_scope);
          /* Parse the assignment-expression.  */
-         initializer = cp_parser_assignment_expression (parser,
-                                                        /*cast_p=*/false);
+         initializer 
+           = cp_parser_constant_expression (parser,
+                                            /*allow_non_constant_p=*/true,
+                                            &non_constant_p);
+         if (!non_constant_p)
+           initializer = fold_non_dependent_expr (initializer);
 
          /* Process the initializer.  */
          cp_finish_decl (decl,
-                         initializer,
+                         initializer, !non_constant_p, 
                          asm_specification,
                          LOOKUP_ONLYCONVERTING);
 
@@ -11061,7 +11066,8 @@ cp_parser_init_declarator (cp_parser* parser,
          pushed_scope = false;
        }
       decl = grokfield (declarator, decl_specifiers,
-                       initializer, /*asmspec=*/NULL_TREE,
+                       initializer, !is_non_constant_init,
+                       /*asmspec=*/NULL_TREE,
                        prefix_attributes);
       if (decl && TREE_CODE (decl) == FUNCTION_DECL)
        cp_parser_save_default_args (parser, decl);
@@ -11072,7 +11078,7 @@ cp_parser_init_declarator (cp_parser* parser,
   if (!friend_p && decl && decl != error_mark_node)
     {
       cp_finish_decl (decl,
-                     initializer,
+                     initializer, !is_non_constant_init,
                      asm_specification,
                      /* If the initializer is in parentheses, then this is
                         a direct-initialization, which means that an
@@ -11084,12 +11090,6 @@ cp_parser_init_declarator (cp_parser* parser,
   if (!friend_p && pushed_scope)
     pop_scope (pushed_scope);
 
-  /* Remember whether or not variables were initialized by
-     constant-expressions.  */
-  if (decl && TREE_CODE (decl) == VAR_DECL
-      && is_initialized && !is_non_constant_init)
-    DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
-
   return decl;
 }
 
@@ -13706,16 +13706,11 @@ cp_parser_member_declaration (cp_parser* parser)
                  return;
                }
              else
-               {
-                 /* Create the declaration.  */
-                 decl = grokfield (declarator, &decl_specifiers,
-                                   initializer, asm_specification,
-                                   attributes);
-                 /* Any initialization must have been from a
-                    constant-expression.  */
-                 if (decl && TREE_CODE (decl) == VAR_DECL && initializer)
-                   DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
-               }
+               /* Create the declaration.  */
+               decl = grokfield (declarator, &decl_specifiers,
+                                 initializer, /*init_const_expr_p=*/true,
+                                 asm_specification,
+                                 attributes);
            }
 
          /* Reset PREFIX_ATTRIBUTES.  */
@@ -17278,7 +17273,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
              cplus_decl_attributes (&decl, attributes, /*flags=*/0);
            }
          else
-           decl = grokfield (declarator, &declspecs, NULL_TREE,
+           decl = grokfield (declarator, &declspecs, 
+                             NULL_TREE, /*init_const_expr_p=*/false,
                              NULL_TREE, attributes);
 
          /* Add the instance variable.  */
index c113f41b285e14bb48cced7dbbc6f7fc28cafd03..40c682f93c2b67da1a4f9b171ee2af0a28fa7a8e 100644 (file)
@@ -5743,6 +5743,7 @@ instantiate_class_template (tree type)
                      finish_static_data_member_decl 
                        (r, 
                         /*init=*/NULL_TREE, 
+                        /*init_const_expr_p=*/false,
                         /*asmspec_tree=*/NULL_TREE, 
                         /*flags=*/0);
                      if (DECL_INITIALIZED_IN_CLASS_P (r))
@@ -8218,7 +8219,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
                      }
                    else
                      init = tsubst_expr (init, args, complain, in_decl);
-                   cp_finish_decl (decl, init, NULL_TREE, 0);
+                   finish_decl (decl, init, NULL_TREE);
                  }
              }
          }
@@ -11694,7 +11695,8 @@ instantiate_decl (tree d, int defer_ok,
                              args,
                              tf_warning_or_error, NULL_TREE);
          DECL_INITIAL (d) = init;
-         cp_finish_decl (d, init, /*asmspec_tree=*/NULL_TREE,
+         cp_finish_decl (d, init, /*init_const_expr_p=*/false,
+                         /*asmspec_tree=*/NULL_TREE,
                          LOOKUP_ONLYCONVERTING);
          pop_nested_class ();
          pop_nested_namespace (ns);
@@ -11771,7 +11773,7 @@ instantiate_decl (tree d, int defer_ok,
 
       /* Enter the scope of D so that access-checking works correctly.  */
       push_nested_class (DECL_CONTEXT (d));
-      cp_finish_decl (d, DECL_INITIAL (d), NULL_TREE, 0);
+      finish_decl (d, DECL_INITIAL (d), NULL_TREE);
       pop_nested_class ();
     }
   else if (TREE_CODE (d) == FUNCTION_DECL)
index 7b1a667c214058d0b24dcc8f8f1958b0e16c0ff5..0275ed9675d9debc451e8346058537953e2b8e61 100644 (file)
@@ -1482,7 +1482,7 @@ emit_tinfo_decl (tree decl)
       init = get_pseudo_ti_init (type, get_pseudo_ti_index (type));
       DECL_INITIAL (decl) = init;
       mark_used (decl);
-      cp_finish_decl (decl, init, NULL_TREE, 0);
+      finish_decl (decl, init, NULL_TREE);
       return true;
     }
   else
index af4ac3c04b1f8d95fc1e833a30ccd85ebde843c5..137938c5f7f16241c2a365b95310060155c48edd 100644 (file)
@@ -1,3 +1,11 @@
+2006-02-18  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/26266
+       * g++.dg/template/static22.C: New test.
+       * g++.dg/template/static23.C: New test.
+       * g++.dg/template/static24.C: New test.
+       * g++.dg/template/non-dependent13.C: New test.
+
 2006-02-16  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR target/26255
diff --git a/gcc/testsuite/g++.dg/template/non-dependent13.C b/gcc/testsuite/g++.dg/template/non-dependent13.C
new file mode 100644 (file)
index 0000000..9e69948
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/26266
+
+template <int I>
+struct S;
+
+template <int I>
+void f() {
+  if (const int i = 3) {
+    S<i>::j; // { dg-error "incomplete" }
+  }
+}
diff --git a/gcc/testsuite/g++.dg/template/static22.C b/gcc/testsuite/g++.dg/template/static22.C
new file mode 100644 (file)
index 0000000..02c7a0c
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/26266
+
+template<typename> struct A
+{
+  static const int i = 1;
+  static const int j = i;
+  static const int k = int(j);
+  int x[k];
+};
+
+A<char> a;
diff --git a/gcc/testsuite/g++.dg/template/static23.C b/gcc/testsuite/g++.dg/template/static23.C
new file mode 100644 (file)
index 0000000..b28400a
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/26266
+
+template<typename> struct A
+{
+  static const int i = 1;
+};
+
+template<typename> struct B
+{
+  static const int j = A<char>::i;
+  static const int k = int(j);
+  int x[k];
+};
+
+B<char> b;
diff --git a/gcc/testsuite/g++.dg/template/static24.C b/gcc/testsuite/g++.dg/template/static24.C
new file mode 100644 (file)
index 0000000..3d8f9e3
--- /dev/null
@@ -0,0 +1,15 @@
+template<typename> struct A;
+
+template<> struct A<char>
+{
+  static const char i = 1;
+};
+
+template<typename T> struct B
+{
+  static const int j = A<T>::i;
+  static const int k = int(j);
+  int x[k];
+};
+
+B<char> b;