aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-12-03 16:58:03 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-12-03 16:58:03 +0000
commit2036a15c6d3583a413934700c527ae626be01075 (patch)
treeb46735bab28a343106b9d77c6ed5d1bb21f63107 /gcc/cp/decl.c
parent52e01aa669275fa5ad78b13e6f2cd9330a928f7f (diff)
downloadgcc-2036a15c6d3583a413934700c527ae626be01075.zip
gcc-2036a15c6d3583a413934700c527ae626be01075.tar.gz
gcc-2036a15c6d3583a413934700c527ae626be01075.tar.bz2
class.c (handle_using_decl): Fix comment.
* 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
Diffstat (limited to 'gcc/cp/decl.c')
-rw-r--r--gcc/cp/decl.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index cbb284e..4a4f138 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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;