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
This commit is contained in:
parent
52e01aa669
commit
2036a15c6d
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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 *-*-*
|
||||
};
|
Loading…
Reference in New Issue