aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-04-28 06:06:59 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-04-28 06:06:59 +0000
commit772f8889ca98d1a237c43258336d4735a21e1daa (patch)
treecc7c874e3bc2ad62227d6cd6c1acb24aaa40324b
parentaa438e8f2be0b073dc5f59376befa9b4215f6604 (diff)
downloadgcc-772f8889ca98d1a237c43258336d4735a21e1daa.zip
gcc-772f8889ca98d1a237c43258336d4735a21e1daa.tar.gz
gcc-772f8889ca98d1a237c43258336d4735a21e1daa.tar.bz2
re PR c++/10506 (ICE in build_new at cp/init.c with -fkeep-inline-functions and multiple inheritance)
PR c++/10506 * method.c (use_thunk): Decrement immediate_size_expand. PR c++/10503 * cp-tree.h (DECL_VAR_MARKED_P): New macro. (DECL_MAYBE_TEMPLATE): Remove. * class.c (fixed_type_or_null): Avoid infinite recursion. PR c++/10506 * g++.dg/init/new6.C: New test. PR c++/10503 * g++.dg/init/ref6.C: New test. From-SVN: r66150
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/class.c20
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/method.c3
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/init/new6.C8
-rw-r--r--gcc/testsuite/g++.dg/init/ref6.C12
7 files changed, 61 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1b6444d..d75773f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
2003-04-27 Mark Mitchell <mark@codesourcery.com>
+ PR c++/10506
+ * method.c (use_thunk): Decrement immediate_size_expand.
+
+ PR c++/10503
+ * cp-tree.h (DECL_VAR_MARKED_P): New macro.
+ (DECL_MAYBE_TEMPLATE): Remove.
+ * class.c (fixed_type_or_null): Avoid infinite recursion.
+
* decl.c (maybe_commonize_var): Make the code match the comments.
* pt.c (instantiate_decl): Move call to import_export_decl.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 405e571..33ece0d 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5388,11 +5388,21 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
/* Reference variables should be references to objects. */
if (nonnull)
*nonnull = 1;
-
- if (TREE_CODE (instance) == VAR_DECL
- && DECL_INITIAL (instance))
- return fixed_type_or_null (DECL_INITIAL (instance),
- nonnull, cdtorp);
+
+ /* DECL_VAR_MARKED_P is used to prevent recursion; a
+ variable's initializer may refer to the variable
+ itself. */
+ if (TREE_CODE (instance) == VAR_DECL
+ && DECL_INITIAL (instance)
+ && !DECL_VAR_MARKED_P (instance))
+ {
+ tree type;
+ DECL_VAR_MARKED_P (instance) = 1;
+ type = fixed_type_or_null (DECL_INITIAL (instance),
+ nonnull, cdtorp);
+ DECL_VAR_MARKED_P (instance) = 0;
+ return type;
+ }
}
return NULL_TREE;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 2491362..9db905c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -95,7 +95,7 @@ struct diagnostic_context;
DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
3: DECL_IN_AGGR_P.
4: DECL_C_BIT_FIELD (in a FIELD_DECL)
- DECL_MAYBE_TEMPLATE (in a FUNCTION_DECL)
+ DECL_VAR_MARKED_P (in a VAR_DECL)
5: DECL_INTERFACE_KNOWN.
6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL).
7: DECL_DEAD_FOR_LOCAL (in VAR_DECL).
@@ -2131,6 +2131,12 @@ struct lang_decl GTY(())
(DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \
->decl_flags.u.template_info)
+/* For a VAR_DECL, indicates that the variable has been processed.
+ This flag is set and unset throughout the code; it is always
+ used for a temporary purpose. */
+#define DECL_VAR_MARKED_P(NODE) \
+ (DECL_LANG_FLAG_4 (VAR_DECL_CHECK (NODE)))
+
/* Template information for a RECORD_TYPE or UNION_TYPE. */
#define CLASSTYPE_TEMPLATE_INFO(NODE) \
(LANG_TYPE_CLASS_CHECK (RECORD_OR_UNION_TYPE_CHECK (NODE))->template_info)
@@ -2807,9 +2813,6 @@ struct lang_decl GTY(())
#define PROCESSING_REAL_TEMPLATE_DECL_P() \
(processing_template_decl > template_class_depth (current_class_type))
-/* This function may be a guiding decl for a template. */
-#define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE)
-
/* Nonzero if this VAR_DECL or FUNCTION_DECL has already been
instantiated, i.e. its definition has been generated from the
pattern given in the the template. */
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index b5a88f2..49bb116 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -439,6 +439,9 @@ use_thunk (tree thunk_fndecl, bool emit_p)
assemble_end_function (thunk_fndecl, fnname);
current_function_decl = 0;
cfun = 0;
+ /* Because init_function_start increments this, we must
+ decrement it. */
+ immediate_size_expand--;
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
}
else
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d2187a6..210cff6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2003-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10506
+ * g++.dg/init/new6.C: New test.
+
+ PR c++/10503
+ * g++.dg/init/ref6.C: New test.
+
2003-04-26 David Edelsohn <edelsohn@gnu.org>
* g++.dg/warn/weak1.C: XFAIL on AIX4.
diff --git a/gcc/testsuite/g++.dg/init/new6.C b/gcc/testsuite/g++.dg/init/new6.C
new file mode 100644
index 0000000..ecbafd1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new6.C
@@ -0,0 +1,8 @@
+// { dg-options "-fkeep-inline-functions" }
+
+struct B1 { virtual ~B1(); };
+struct B2 { virtual ~B2(); };
+struct D : B1, B2 {};
+struct X : D { X (); };
+
+X::X () { new int; }
diff --git a/gcc/testsuite/g++.dg/init/ref6.C b/gcc/testsuite/g++.dg/init/ref6.C
new file mode 100644
index 0000000..50a9636
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/ref6.C
@@ -0,0 +1,12 @@
+struct B {
+ void g() { }
+};
+
+struct A {
+ void f() {
+ B &b = b;
+ b.g();
+ }
+};
+
+int main(void) { }