]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/11041 (ICE: const myclass &x = *x; (when operator*() defined))
authorMark Mitchell <mark@codesourcery.com>
Fri, 20 Jun 2003 00:48:44 +0000 (00:48 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 20 Jun 2003 00:48:44 +0000 (00:48 +0000)
PR c++/11041
* call.c (initialize_reference): Do not use cp_finish_decl to emit
temporary variables.
* cp-tree.h (static_aggregates): Declare.
(pushdecl_top_level_and_finish): Likewise.
* decl.c (pushdecl_top_level_1): New function.
(pushdecl_top_level): Use it.
(pushdecl_top_level_and_finish): New function.
(initialize_local_var): Remove redundant code.
(cp_finish_decl): Remove support for RESULT_DECLs.  Don't check
building_stmt_tree.
* decl.h (static_aggregates): Remove.
* decl2.c (get_guard): Use pushdecl_top_level_and_finish.
* rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
(tinfo_base_init): Likewise.

PR c++/11041
* g++.dg/init/ref7.C: New test.

From-SVN: r68236

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/decl.h
gcc/cp/decl2.c
gcc/cp/rtti.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/ref7.C [new file with mode: 0644]

index ba1fb35884683d1779f557d853675ef57b4c0a75..30e01f2d8fd0615d9a4a6d620ee6aa694628e992 100644 (file)
@@ -1,3 +1,21 @@
+2003-06-19  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11041
+       * call.c (initialize_reference): Do not use cp_finish_decl to emit
+       temporary variables.
+       * cp-tree.h (static_aggregates): Declare.
+       (pushdecl_top_level_and_finish): Likewise.
+       * decl.c (pushdecl_top_level_1): New function.
+       (pushdecl_top_level): Use it.
+       (pushdecl_top_level_and_finish): New function.
+       (initialize_local_var): Remove redundant code.
+       (cp_finish_decl): Remove support for RESULT_DECLs.  Don't check
+       building_stmt_tree.
+       * decl.h (static_aggregates): Remove.
+       * decl2.c (get_guard): Use pushdecl_top_level_and_finish.
+       * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
+       (tinfo_base_init): Likewise.
+       
 2003-06-19  Matt Austern  <austern@apple.com>
 
        PR c++/11228
index 589a78900e51097191e0117792b6ac973d1074be..9bc55bef9e25a5415dafe68520babc7c5efec0d8 100644 (file)
@@ -6144,7 +6144,7 @@ initialize_reference (tree type, tree expr, tree decl)
        T t;
        const S& s = t;
 
-    we can extend the lifetime of the returnn value of the conversion
+    we can extend the lifetime of the return value of the conversion
     operator.  */
   my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302);
   if (decl)
@@ -6167,13 +6167,33 @@ initialize_reference (tree type, tree expr, tree decl)
       expr = convert_like (conv, expr);
       if (!real_non_cast_lvalue_p (expr))
        {
+         tree init;
+         tree type;
+
          /* Create the temporary variable.  */
-         var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr));
-         DECL_INITIAL (var) = expr;
-         cp_finish_decl (var, expr, NULL_TREE, 
-                     LOOKUP_ONLYCONVERTING|DIRECT_BIND);
+         type = TREE_TYPE (expr);
+         var = make_temporary_var_for_ref_to_temp (decl, type);
+         layout_decl (var, 0);
+         if (at_function_scope_p ())
+           {
+             tree cleanup;
+
+             add_decl_stmt (var);
+             cleanup = cxx_maybe_build_cleanup (var);
+             if (cleanup)
+               finish_decl_cleanup (var, cleanup);
+           }
+         else
+           {
+             rest_of_decl_compilation (var, NULL, /*toplev=*/1, at_eof);
+             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+               static_aggregates = tree_cons (NULL_TREE, var,
+                                              static_aggregates);
+           }
+         init = build (INIT_EXPR, type, var, expr);
          /* Use its address to initialize the reference variable.  */
          expr = build_address (var);
+         expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
        }
       else
        /* Take the address of EXPR.  */
index d3d20e7d211dffd2f507bb1641ad6b4869dc4089..bfb7e0f3e68660a3cffa597a6a8d12be993476cc 100644 (file)
@@ -3263,6 +3263,12 @@ extern GTY(()) varray_type local_classes;
 
 extern int at_eof;
 
+/* A list of namespace-scope objects which have constructors or
+   destructors which reside in the global scope.  The decl is stored
+   in the TREE_VALUE slot and the initializer is stored in the
+   TREE_PURPOSE slot.  */
+extern GTY(()) tree static_aggregates;
+
 /* Functions called along with real static constructors and destructors.  */
 
 extern GTY(()) tree static_ctors;
@@ -3631,6 +3637,7 @@ extern void clear_anon_tags                       (void);
 extern int decls_match                         (tree, tree);
 extern int duplicate_decls                     (tree, tree);
 extern tree pushdecl_top_level                 (tree);
+extern tree pushdecl_top_level_and_finish       (tree, tree);
 extern void pushdecl_class_level               (tree);
 extern tree pushdecl_namespace_level            (tree);
 extern tree push_using_decl                     (tree, tree);
index 4ec5c3176ce2415e6a013482c627647409ba8688..d025a6fba1d35269e958993c3ed6c842e98bb1fb 100644 (file)
@@ -4143,18 +4143,40 @@ pushdecl_namespace_level (tree x)
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
 }
 
-/* Like pushdecl, only it places X in the global scope if appropriate.  */
+/* Like pushdecl, only it places X in the global scope if appropriate.
+   Calls cp_finish_decl to register the variable, initializing it with
+   *INIT, if INIT is non-NULL.  */
 
-tree
-pushdecl_top_level (tree x)
+static tree
+pushdecl_top_level_1 (tree x, tree *init)
 {
   timevar_push (TV_NAME_LOOKUP);
   push_to_top_level ();
   x = pushdecl_namespace_level (x);
+  if (init)
+    cp_finish_decl (x, *init, NULL_TREE, 0);
   pop_from_top_level ();
   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
 }
 
+/* Like pushdecl, only it places X in the global scope if appropriate.  */
+
+tree
+pushdecl_top_level (tree x)
+{
+  return pushdecl_top_level_1 (x, NULL);
+}
+
+/* Like pushdecl, only it places X in the global scope if
+   appropriate.  Calls cp_finish_decl to register the variable,
+   initializing it with INIT.  */
+
+tree
+pushdecl_top_level_and_finish (tree x, tree init)
+{
+  return pushdecl_top_level_1 (x, &init);
+}
+
 /* Make the declaration of X appear in CLASS scope.  */
 
 void
@@ -7903,6 +7925,7 @@ static void
 initialize_local_var (tree decl, tree init)
 {
   tree type = TREE_TYPE (decl);
+  tree cleanup;
 
   my_friendly_assert (TREE_CODE (decl) == VAR_DECL
                      || TREE_CODE (decl) == RESULT_DECL, 
@@ -7952,17 +7975,9 @@ initialize_local_var (tree decl, tree init)
     }
 
   /* Generate a cleanup, if necessary.  */
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
-    {
-      tree cleanup;
-
-      /* Compute the cleanup.  */
-      cleanup = cxx_maybe_build_cleanup (decl);
-      
-      /* Record the cleanup required for this declaration.  */
-      if (DECL_SIZE (decl) && cleanup)
-       finish_decl_cleanup (decl, cleanup);
-    }
+  cleanup = cxx_maybe_build_cleanup (decl);
+  if (DECL_SIZE (decl) && cleanup)
+    finish_decl_cleanup (decl, cleanup);
 }
 
 /* Finish processing of a declaration;
@@ -7991,6 +8006,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
       return;
     }
 
+  my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619);
+
   /* If a name was specified, get the string.  */
   if (global_scope_p (current_binding_level))
     asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
@@ -8031,8 +8048,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   if (processing_template_decl)
     {
       /* Add this declaration to the statement-tree.  */
-      if (at_function_scope_p ()
-         && TREE_CODE (decl) != RESULT_DECL)
+      if (at_function_scope_p ())
        add_decl_stmt (decl);
 
       if (init && DECL_INITIAL (decl))
@@ -8089,8 +8105,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
       SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
       make_decl_rtl (decl, asmspec);
     }
-  else if (TREE_CODE (decl) == RESULT_DECL)
-    init = check_initializer (decl, init, flags);
   else if (TREE_CODE (decl) == VAR_DECL)
     {
       /* Only PODs can have thread-local storage.  Other types may require
@@ -8146,9 +8160,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   /* Add this declaration to the statement-tree.  This needs to happen
      after the call to check_initializer so that the DECL_STMT for a
      reference temp is added before the DECL_STMT for the reference itself.  */
-  if (building_stmt_tree ()
-      && at_function_scope_p ()
-      && TREE_CODE (decl) != RESULT_DECL)
+  if (at_function_scope_p ())
     add_decl_stmt (decl);
 
   if (TREE_CODE (decl) == VAR_DECL)
@@ -8157,8 +8169,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   /* Output the assembler code and/or RTL code for variables and functions,
      unless the type is an undefined structure or union.
      If not, it will get done when the type is completed.  */
-  if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL
-      || TREE_CODE (decl) == RESULT_DECL)
+  if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
     {
       if (TREE_CODE (decl) == VAR_DECL)
        maybe_commonize_var (decl);
index b942687407f07bedfceedbfe7356cb57e16fcbbc..2a7a7659e1bcb30c869c6981a6321a421f619595 100644 (file)
@@ -37,12 +37,6 @@ extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*);
    or a chain or parameter decls here.  */
 extern GTY(()) tree last_function_parms;
 
-/* A list of objects which have constructors or destructors
-   which reside in the global scope.  The decl is stored in
-   the TREE_VALUE slot and the initializer is stored
-   in the TREE_PURPOSE slot.  */
-extern GTY(()) tree static_aggregates;
-
 #ifdef DEBUG_CP_BINDING_LEVELS
 /* Purely for debugging purposes.  */
 extern int debug_bindings_indentation;
index 1413f3944b9b89d017fddd9c0feb2f0b5b1ca0c3..3fa4d74c53eaa7b680c0ac96c23a71c64306fdcc 100644 (file)
@@ -1886,8 +1886,7 @@ get_guard (tree decl)
       
       DECL_ARTIFICIAL (guard) = 1;
       TREE_USED (guard) = 1;
-      pushdecl_top_level (guard);
-      cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
+      pushdecl_top_level_and_finish (guard, NULL_TREE);
     }
   return guard;
 }
index ac117fa1ed929e78199f53ca14e57b56367dfe21..1a29c1c783ec51bbdf6ea117e7f72709d85d642d 100644 (file)
@@ -364,9 +364,8 @@ get_tinfo_decl (tree type)
       DECL_EXTERNAL (d) = 1;
       SET_DECL_ASSEMBLER_NAME (d, name);
       DECL_COMDAT (d) = 1;
-      cp_finish_decl (d, NULL_TREE, NULL_TREE, 0);
 
-      pushdecl_top_level (d);
+      pushdecl_top_level_and_finish (d, NULL_TREE);
 
       if (CLASS_TYPE_P (type))
        CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d;
@@ -770,8 +769,7 @@ tinfo_base_init (tree desc, tree target)
     SET_DECL_ASSEMBLER_NAME (name_decl,
                             mangle_typeinfo_string_for_type (target));
     DECL_INITIAL (name_decl) = name_string;
-    cp_finish_decl (name_decl, name_string, NULL_TREE, 0);
-    pushdecl_top_level (name_decl);
+    pushdecl_top_level_and_finish (name_decl, name_string);
   }
 
   vtable_ptr = TINFO_VTABLE_DECL (desc);
index 2a1363af422cc89296149ea0147837d92b11a4af..dd5c99251abe64ded364383f035e64ae479fa1d1 100644 (file)
@@ -1,3 +1,8 @@
+2003-06-19  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/11041
+       * g++.dg/init/ref7.C: New test.
+
 2003-06-19  Matt Austern  <austern@apple.com>
 
        PR c++/11228
diff --git a/gcc/testsuite/g++.dg/init/ref7.C b/gcc/testsuite/g++.dg/init/ref7.C
new file mode 100644 (file)
index 0000000..0832069
--- /dev/null
@@ -0,0 +1,9 @@
+class hop
+{
+public:
+    hop operator* () const;
+};
+int main(void)
+{
+    const hop &x = *x;
+}