class.c (handle_using_decl): Fix comment.
authorMark Mitchell <mark@markmitchell.com>
Thu, 3 Dec 1998 16:58:03 +0000 (16:58 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 3 Dec 1998 16:58:03 +0000 (16:58 +0000)
* class.c (handle_using_decl): Fix comment.  Don't lookup
constructors in base classes.
(validate_lhs): Fix typo in comment.
* search.c (lookup_field_1): Don't return a USING_DECL.
* cp-tree.h (DECL_ACCESS): Improve documentation.
* decl.c (expand_static_init): Don't set the initialization-done
flag until the initialization is done.

From-SVN: r24076

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/search.c
gcc/testsuite/g++.old-deja/g++.other/init7.C
gcc/testsuite/g++.old-deja/g++.other/singleton.C
gcc/testsuite/g++.old-deja/g++.other/using6.C
gcc/testsuite/g++.old-deja/g++.other/using7.C [deleted file]

index 336e694d8760b3578ae6917de3ae987b949b4d37..41e9f2ff959bc43b5914b0550919000f70b0714c 100644 (file)
@@ -1,3 +1,15 @@
+1998-12-03  Mark Mitchell  <mark@markmitchell.com>
+
+       * class.c (handle_using_decl): Fix comment.  Don't lookup
+       constructors in base classes.
+       (validate_lhs): Fix typo in comment.
+       * search.c (lookup_field_1): Don't return a USING_DECL.
+       
+       * cp-tree.h (DECL_ACCESS): Improve documentation.
+
+       * decl.c (expand_static_init): Don't set the initialization-done
+       flag until the initialization is done.
+       
 1998-12-02  Mark Mitchell  <mark@markmitchell.com>
 
        * decl2.c (validate_nonmember_using_decl): Complain about using
index a2e824478e812c39707c90c862ef77009cecff38..8cd1c82ba8dd2f2a3196a73257d83610e936d3e8 100644 (file)
@@ -1457,8 +1457,7 @@ alter_access (t, binfo, fdecl, access)
 }
 
 /* Process the USING_DECL, which is a member of T.  The METHOD_VEC, if
-   non-NULL, is the methods of T.  The FIELDS are the fields of T.
-   Returns 1 if the USING_DECL was valid, 0 otherwise.  */
+   non-NULL, is the methods of T.  The FIELDS are the fields of T.  */
 
 void
 handle_using_decl (using_decl, t, method_vec, fields)
@@ -1485,8 +1484,11 @@ handle_using_decl (using_decl, t, method_vec, fields)
   
   if (name == constructor_name (ctype)
       || name == constructor_name_full (ctype))
-    cp_error_at ("using-declaration for constructor", using_decl);
-  
+    {
+      cp_error_at ("using-declaration for constructor", using_decl);
+      return;
+    }
+
   fdecl = lookup_member (binfo, name, 0, 0);
   
   if (!fdecl)
@@ -4994,7 +4996,7 @@ validate_lhs (lhstype, complain)
 
 /* This function will instantiate the type of the expression given in
    RHS to match the type of LHSTYPE.  If errors exist, then return
-   error_mark_node.  If only complain is COMPLAIN is set.  If we are
+   error_mark_node.  We only complain is COMPLAIN is set.  If we are
    not complaining, never modify rhs, as overload resolution wants to
    try many possible instantiations, in hopes that at least one will
    work.
index 09928446733ef5178a75658096905bd19c750671..8f2dc856c98dcf6ce23b2ad36513debf1ba26fad 100644 (file)
@@ -1687,8 +1687,12 @@ extern int flag_new_for_scope;
    NULL_TREE.  */
 #define DECL_FRIENDLIST(NODE)          (DECL_INITIAL (NODE))
 
-/* The DECL_ACCESS is used to record under which context
-   special access rules apply.  */
+/* The DECL_ACCESS, if non-NULL, is a TREE_LIST.  The TREE_PURPOSE of
+   each node is a type; the TREE_VALUE is the access granted for this
+   DECL in that type.  The DECL_ACCESS is set by access declarations.
+   For example, if a member that would normally be public in a
+   derived class is made protected, then the derived class and the
+   protected_access_node will appear in the DECL_ACCESS for the node.  */
 #define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.access)
 
 /* C++: all of these are overloaded!
index cbb284e9f2bd234e5c9622bd5d810191c3405ee5..4a4f13822acc467673ef367faacc014795c18ad7 100644 (file)
@@ -7869,14 +7869,39 @@ expand_static_init (decl, init)
       /* Remember this information until end of file.  */
       push_obstacks (&permanent_obstack, &permanent_obstack);
 
-      /* Emit code to perform this initialization but once.  */
+      /* Emit code to perform this initialization but once.  This code
+        looks like:
+
+           static int temp = 0;
+           if (!temp) {
+             // Do initialization.
+            temp = 1;
+            // Register variable for destruction at end of program.
+          }
+
+        Note that the `temp' variable is only set to 1 *after* the
+        initialization is complete.  This ensures that an exception,
+        thrown during the construction, will cause the variable to
+        reinitialized when we pass through this code again, as per:
+        
+          [stmt.dcl]
+
+          If the initialization exits by throwing an exception, the
+          initialization is not complete, so it will be tried again
+          the next time control enters the declaration.
+
+         In theory, this process should be thread-safe, too; multiple
+        threads should not be able to initialize the variable more
+        than once.  We don't yet attempt to ensure thread-safety.  */
       temp = get_temp_name (integer_type_node, 1);
       rest_of_decl_compilation (temp, NULL_PTR, 0, 0);
+
+      /* Begin the conditional initialization.  */
       expand_start_cond (build_binary_op (EQ_EXPR, temp,
                                          integer_zero_node, 1), 0);
       expand_start_target_temps ();
 
-      expand_assignment (temp, integer_one_node, 0, 0);
+      /* Do the initialization itself.  */
       if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
          || (init && TREE_CODE (init) == TREE_LIST))
        {
@@ -7886,9 +7911,17 @@ expand_static_init (decl, init)
       else if (init)
        expand_assignment (decl, init, 0, 0);
 
-      /* Cleanup any temporaries needed for the initial value.  */
+      /* Set TEMP to 1.  */
+      expand_assignment (temp, integer_one_node, 0, 0);
+
+      /* Cleanup any temporaries needed for the initial value.  If
+        destroying one of the temporaries causes an exception to be
+        thrown, then the object itself has still been fully
+        constructed.  */
       expand_end_target_temps ();
 
+      /* Use atexit to register a function for destroying this static
+        variable.  */
       if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
        {
          tree cleanup, fcall;
index 94fdbc28cee311ec63b38f85e12ec4fae0671aa5..8b1576458f94c9a0fd2bb540572d83fd9b5e12ab 100644 (file)
@@ -523,7 +523,14 @@ lookup_field_1 (type, name)
          if (temp)
            return temp;
        }
-      if (DECL_NAME (field) == name)
+      if (TREE_CODE (field) == USING_DECL)
+       /* For now, we're just treating member using declarations as
+          old ARM-style access declarations.  Thus, there's no reason
+          to return a USING_DECL, and the rest of the compiler can't
+          handle it.  Once the class is defined, these are purged
+          from TYPE_FIELDS anyhow; see handle_using_decl.  */
+       ;
+      else if (DECL_NAME (field) == name)
        {
          if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL)
              && DECL_ASSEMBLER_NAME (field) != NULL)
index 9a3d5d03dfa1b7e98d9217a0ee1c113ccb700c95..3b17da029e83999daa35f69be9fb1c36002c37d7 100644 (file)
@@ -4,8 +4,6 @@
 // The initialization of a static local variable must be retried if a
 // previous try finished by throwing an exception [stmt.dcl]/4
 
-// execution test - XFAIL *-*-*
-
 struct foo {
   foo() { throw true; }
 };
index c2c481075fffbf038952ffac28b64fedf723d6f4..075d83ac79a5c49857bc3af1971aa986ed4a51b5 100644 (file)
@@ -1,4 +1,3 @@
-// execution test - re-initialization of statics XFAIL *-*-*
 // This tests two things:
 // 1. there is an annoying warning.
 // singleton.C:26: warning: `class singleton' only defines private constructors and has no friends
index 8e518ac95dde50d18aa6fbbf875b47792bdeb657..31aa7cd560d5cf2970d20db9f7a85c3c9616318a 100644 (file)
@@ -3,13 +3,11 @@
 // Based on bug report by Klaus-Georg Adams
 // <Klaus-Georg.Adams@chemie.uni-karlsruhe.de>
 
-// crash test - XFAIL *-*-*
-
 struct bar {
   typedef bar t;
 };
 
 struct foo : bar {
   using bar::t;
-  t baz(); // gets bogus error - XFAIL *-*-*
+  t baz(); 
 };
diff --git a/gcc/testsuite/g++.old-deja/g++.other/using7.C b/gcc/testsuite/g++.old-deja/g++.other/using7.C
deleted file mode 100644 (file)
index 76af0de..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// Build don't link:
-
-// Based on bug report by Klaus-Georg Adams
-// <Klaus-Georg.Adams@chemie.uni-karlsruhe.de>
-
-// crash test - XFAIL *-*-*
-
-struct bar {
-  typedef bar t;
-};
-
-struct foo : bar {
-  using bar::t;
-  t baz; // gets bogus error - XFAIL *-*-*
-};