aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog15
-rw-r--r--gcc/cp/decl.c17
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/repo.c6
-rw-r--r--gcc/cp/rtti.c14
-rw-r--r--gcc/cp/tree.c33
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;
+}