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>
|
1998-12-02 Mark Mitchell <mark@markmitchell.com>
|
||||||
|
|
||||||
* decl2.c (validate_nonmember_using_decl): Complain about using
|
* 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
|
/* 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.
|
non-NULL, is the methods of T. The FIELDS are the fields of T. */
|
||||||
Returns 1 if the USING_DECL was valid, 0 otherwise. */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
handle_using_decl (using_decl, t, method_vec, fields)
|
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)
|
if (name == constructor_name (ctype)
|
||||||
|| name == constructor_name_full (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);
|
fdecl = lookup_member (binfo, name, 0, 0);
|
||||||
|
|
||||||
if (!fdecl)
|
if (!fdecl)
|
||||||
|
@ -4994,7 +4996,7 @@ validate_lhs (lhstype, complain)
|
||||||
|
|
||||||
/* This function will instantiate the type of the expression given in
|
/* This function will instantiate the type of the expression given in
|
||||||
RHS to match the type of LHSTYPE. If errors exist, then return
|
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
|
not complaining, never modify rhs, as overload resolution wants to
|
||||||
try many possible instantiations, in hopes that at least one will
|
try many possible instantiations, in hopes that at least one will
|
||||||
work.
|
work.
|
||||||
|
|
|
@ -1687,8 +1687,12 @@ extern int flag_new_for_scope;
|
||||||
NULL_TREE. */
|
NULL_TREE. */
|
||||||
#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE))
|
#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE))
|
||||||
|
|
||||||
/* The DECL_ACCESS is used to record under which context
|
/* The DECL_ACCESS, if non-NULL, is a TREE_LIST. The TREE_PURPOSE of
|
||||||
special access rules apply. */
|
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)
|
#define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.access)
|
||||||
|
|
||||||
/* C++: all of these are overloaded!
|
/* C++: all of these are overloaded!
|
||||||
|
|
|
@ -7869,14 +7869,39 @@ expand_static_init (decl, init)
|
||||||
/* Remember this information until end of file. */
|
/* Remember this information until end of file. */
|
||||||
push_obstacks (&permanent_obstack, &permanent_obstack);
|
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);
|
temp = get_temp_name (integer_type_node, 1);
|
||||||
rest_of_decl_compilation (temp, NULL_PTR, 0, 0);
|
rest_of_decl_compilation (temp, NULL_PTR, 0, 0);
|
||||||
|
|
||||||
|
/* Begin the conditional initialization. */
|
||||||
expand_start_cond (build_binary_op (EQ_EXPR, temp,
|
expand_start_cond (build_binary_op (EQ_EXPR, temp,
|
||||||
integer_zero_node, 1), 0);
|
integer_zero_node, 1), 0);
|
||||||
expand_start_target_temps ();
|
expand_start_target_temps ();
|
||||||
|
|
||||||
expand_assignment (temp, integer_one_node, 0, 0);
|
/* Do the initialization itself. */
|
||||||
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
|
if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
|
||||||
|| (init && TREE_CODE (init) == TREE_LIST))
|
|| (init && TREE_CODE (init) == TREE_LIST))
|
||||||
{
|
{
|
||||||
|
@ -7886,9 +7911,17 @@ expand_static_init (decl, init)
|
||||||
else if (init)
|
else if (init)
|
||||||
expand_assignment (decl, init, 0, 0);
|
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 ();
|
expand_end_target_temps ();
|
||||||
|
|
||||||
|
/* Use atexit to register a function for destroying this static
|
||||||
|
variable. */
|
||||||
if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
|
if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl)))
|
||||||
{
|
{
|
||||||
tree cleanup, fcall;
|
tree cleanup, fcall;
|
||||||
|
|
|
@ -523,7 +523,14 @@ lookup_field_1 (type, name)
|
||||||
if (temp)
|
if (temp)
|
||||||
return 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)
|
if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL)
|
||||||
&& DECL_ASSEMBLER_NAME (field) != NULL)
|
&& DECL_ASSEMBLER_NAME (field) != NULL)
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
// The initialization of a static local variable must be retried if a
|
// The initialization of a static local variable must be retried if a
|
||||||
// previous try finished by throwing an exception [stmt.dcl]/4
|
// previous try finished by throwing an exception [stmt.dcl]/4
|
||||||
|
|
||||||
// execution test - XFAIL *-*-*
|
|
||||||
|
|
||||||
struct foo {
|
struct foo {
|
||||||
foo() { throw true; }
|
foo() { throw true; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// execution test - re-initialization of statics XFAIL *-*-*
|
|
||||||
// This tests two things:
|
// This tests two things:
|
||||||
// 1. there is an annoying warning.
|
// 1. there is an annoying warning.
|
||||||
// singleton.C:26: warning: `class singleton' only defines private constructors and has no friends
|
// 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
|
// Based on bug report by Klaus-Georg Adams
|
||||||
// <Klaus-Georg.Adams@chemie.uni-karlsruhe.de>
|
// <Klaus-Georg.Adams@chemie.uni-karlsruhe.de>
|
||||||
|
|
||||||
// crash test - XFAIL *-*-*
|
|
||||||
|
|
||||||
struct bar {
|
struct bar {
|
||||||
typedef bar t;
|
typedef bar t;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct foo : bar {
|
struct foo : bar {
|
||||||
using bar::t;
|
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