diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/decl.c | 17 | ||||
-rw-r--r-- | gcc/cp/pt.c | 2 | ||||
-rw-r--r-- | gcc/cp/repo.c | 6 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 14 | ||||
-rw-r--r-- | gcc/cp/tree.c | 33 |
6 files changed, 77 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c613d80..798b0a6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +1998-11-15 Jason Merrill <jason@yorick.cygnus.com> + + * decl.c (struct cp_function): Add named_label_uses. + (push_cp_function_context): Save it. + (pop_cp_function_context): Restore it. + (define_label): Also complain about jumping into the scope of + non-POD objects that don't have constructors. + * tree.c (pod_type_p): New fn. + + * pt.c (instantiate_class_template): Clear TYPE_BEING_DEFINED sooner. + * rtti.c (synthesize_tinfo_fn): Call import_export_decl here. + (get_tinfo_fn): Not here. + * repo.c (repo_get_id): Abort if we get called for an incomplete + type. + 1998-11-13 Mark Mitchell <mark@markmitchell.com> * except.c (expand_throw): Make sure first argument to diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8b9bb04..70fc9fc 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4346,9 +4346,8 @@ define_label (filename, line, name) and they should be cleaned up by the time we get to the label. */ && ! DECL_ARTIFICIAL (new_decls) - && ((DECL_INITIAL (new_decls) != NULL_TREE - && DECL_INITIAL (new_decls) != error_mark_node) - || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) + && !(DECL_INITIAL (new_decls) == NULL_TREE + && pod_type_p (TREE_TYPE (new_decls)))) { if (! identified) { @@ -4358,8 +4357,13 @@ define_label (filename, line, name) " from here"); identified = 1; } - cp_error_at (" crosses initialization of `%#D'", - new_decls); + if (DECL_INITIAL (new_decls) + || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))) + cp_error_at (" crosses initialization of `%#D'", + new_decls); + else + cp_error_at (" enters scope of non-POD `%#D'", + new_decls); } new_decls = TREE_CHAIN (new_decls); } @@ -13999,6 +14003,7 @@ struct cp_function int parms_stored; int temp_name_counter; tree named_labels; + struct named_label_list *named_label_uses; tree shadowed_labels; tree ctor_label; tree dtor_label; @@ -14035,6 +14040,7 @@ push_cp_function_context (context) cp_function_chain = p; p->named_labels = named_labels; + p->named_label_uses = named_label_uses; p->shadowed_labels = shadowed_labels; p->returns_value = current_function_returns_value; p->returns_null = current_function_returns_null; @@ -14077,6 +14083,7 @@ pop_cp_function_context (context) cp_function_chain = p->next; named_labels = p->named_labels; + named_label_uses = p->named_label_uses; shadowed_labels = p->shadowed_labels; current_function_returns_value = p->returns_value; current_function_returns_null = p->returns_null; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5f3fbab..fb5bb54 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4786,6 +4786,8 @@ instantiate_class_template (type) type = finish_struct_1 (type, 0); CLASSTYPE_GOT_SEMICOLON (type) = 1; + /* Clear this now so repo_template_used is happy. */ + TYPE_BEING_DEFINED (type) = 0; repo_template_used (type); end: diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index 742250d..b784020 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -99,6 +99,12 @@ repo_get_id (t) { if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') { + /* If we're not done setting up the class, we may not have set up + the vtable, so going ahead would give the wrong answer. + See g++.pt/instantiate4.C. */ + if (TYPE_SIZE (t) == NULL_TREE || TYPE_BEING_DEFINED (t)) + my_friendly_abort (981113); + t = TYPE_BINFO_VTABLE (t); if (t == NULL_TREE) return t; diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 5b451bf..14b16c8 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -374,9 +374,6 @@ get_tinfo_fn (type) make_function_rtl (d); assemble_external (d); mark_inline_for_output (d); - if (at_eof) - import_export_decl (d); - pop_obstacks (); return d; @@ -1064,9 +1061,16 @@ synthesize_tinfo_fn (fndecl) tree fndecl; { tree type = TREE_TYPE (DECL_NAME (fndecl)); - tree tmp, addr; + tree tmp, addr, tdecl; + + if (at_eof) + { + import_export_decl (fndecl); + if (DECL_REALLY_EXTERN (fndecl)) + return; + } - tree tdecl = get_tinfo_var (type); + tdecl = get_tinfo_var (type); DECL_EXTERNAL (tdecl) = 0; TREE_STATIC (tdecl) = 1; DECL_COMMON (tdecl) = 1; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2a9b522..1b27762 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2680,3 +2680,36 @@ is_dummy_object (ob) return (TREE_CODE (ob) == NOP_EXPR && TREE_OPERAND (ob, 0) == error_mark_node); } + +/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ + +int +pod_type_p (t) + tree t; +{ + tree f; + + while (TREE_CODE (t) == ARRAY_TYPE) + t = TREE_TYPE (t); + + if (! IS_AGGR_TYPE (t)) + return 1; + + if (CLASSTYPE_NON_AGGREGATE (t) + || TYPE_HAS_COMPLEX_ASSIGN_REF (t) + || TYPE_HAS_DESTRUCTOR (t)) + return 0; + + for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f)) + { + if (TREE_CODE (f) != FIELD_DECL) + continue; + + if (TREE_CODE (TREE_TYPE (f)) == REFERENCE_TYPE + || TYPE_PTRMEMFUNC_P (TREE_TYPE (f)) + || TYPE_PTRMEM_P (TREE_TYPE (f))) + return 0; + } + + return 1; +} |