aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2000-07-23 19:59:41 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2000-07-23 19:59:41 +0000
commit95ee998ceb1d196000e2cb4e61b760d818119dee (patch)
tree3530f888190774b58b61b605cab7584a692609b7
parent07964b9c09eb5bfe56851851d4e1696cb34e763d (diff)
downloadgcc-95ee998ceb1d196000e2cb4e61b760d818119dee.zip
gcc-95ee998ceb1d196000e2cb4e61b760d818119dee.tar.gz
gcc-95ee998ceb1d196000e2cb4e61b760d818119dee.tar.bz2
c-semantics.c (make_rtl_for_local_static): Use TREE_ASM_WRITTEN to figure out whether or not a variable has already been...
* c-semantics.c (make_rtl_for_local_static): Use TREE_ASM_WRITTEN to figure out whether or not a variable has already been emitted. * decl.c (make_rtl_for_nonlocal_decl): Rework. * pt.c (lookup_template_class): Ensure that TYPE_CONTEXT is set correctly. From-SVN: r35215
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/c-semantics.c2
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c86
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/crash20.C38
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/static12.C8
7 files changed, 106 insertions, 48 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a4b171..06ec826 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2000-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * c-semantics.c (make_rtl_for_local_static): Use TREE_ASM_WRITTEN
+ to figure out whether or not a variable has already been emitted.
+
Sun Jul 23 14:49:12 2000 Jason Eckhardt <jle@cygnus.com>
* config/i860/i860.md (untyped_call expander): Use GEN_CALL
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index fb669b3..2e0d537 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -96,7 +96,7 @@ make_rtl_for_local_static (decl)
/* If we inlined this variable, we could see it's declaration
again. */
- if (DECL_RTL (decl))
+ if (TREE_ASM_WRITTEN (decl))
return;
if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index aa2a2fa..1c52799 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2000-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Rework.
+
+ * pt.c (lookup_template_class): Ensure that TYPE_CONTEXT is set
+ correctly.
+
2000-07-20 Zack Weinberg <zack@wolery.cumb.org>
* cp-tree.h: Use __FUNCTION__ not __PRETTY_FUNCTION__.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a6b21fd..b4e1477 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7825,11 +7825,8 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec)
tree init;
const char *asmspec;
{
- int toplev;
- tree type;
-
- type = TREE_TYPE (decl);
- toplev = toplevel_bindings_p ();
+ int toplev = toplevel_bindings_p ();
+ int defer_p;
/* Handle non-variables up front. */
if (TREE_CODE (decl) != VAR_DECL)
@@ -7838,54 +7835,55 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec)
return;
}
+ /* If we see a class member here, it should be a static data
+ member. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl))
+ {
+ my_friendly_assert (TREE_STATIC (decl), 19990828);
+ /* An in-class declaration of a static data member should be
+ external; it is only a declaration, and not a definition. */
+ if (init == NULL_TREE)
+ my_friendly_assert (DECL_EXTERNAL (decl), 20000723);
+ }
+
/* Set the DECL_ASSEMBLER_NAME for the variable. */
if (asmspec)
DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec);
- if (DECL_VIRTUAL_P (decl))
- make_decl_rtl (decl, NULL_PTR, toplev);
- else if (TREE_READONLY (decl)
- && DECL_INITIAL (decl) != NULL_TREE
- && DECL_INITIAL (decl) != error_mark_node
- && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl)))
- {
- DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl));
+ /* We don't create any RTL for local variables. */
+ if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
+ return;
- if (toplev && ! TREE_PUBLIC (decl))
- {
- /* If this is a static const, change its apparent linkage
- if it belongs to a #pragma interface. */
- if (!interface_unknown)
- {
- TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl) = interface_only;
- }
- make_decl_rtl (decl, asmspec, toplev);
- }
- else if (toplev)
- rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
- }
- else if (DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl))
- {
- my_friendly_assert (TREE_STATIC (decl), 19990828);
+ /* We defer emission of local statics until the corresponding
+ DECL_STMT is expanded. */
+ defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl);
- if (init == NULL_TREE
-#ifdef DEFAULT_STATIC_DEFS
- /* If this code is dead, then users must
- explicitly declare static member variables
- outside the class def'n as well. */
- && TYPE_NEEDS_CONSTRUCTING (type)
-#endif
- )
+ /* We try to defer namespace-scope static constants so that they are
+ not emitted into the object file unncessarily. */
+ if (!DECL_VIRTUAL_P (decl)
+ && TREE_READONLY (decl)
+ && DECL_INITIAL (decl) != NULL_TREE
+ && DECL_INITIAL (decl) != error_mark_node
+ && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))
+ && toplev
+ && !TREE_PUBLIC (decl))
+ {
+ /* Fool with the linkage according to #pragma interface. */
+ if (!interface_unknown)
{
- DECL_EXTERNAL (decl) = 1;
- make_decl_rtl (decl, asmspec, 1);
+ TREE_PUBLIC (decl) = 1;
+ DECL_EXTERNAL (decl) = interface_only;
}
- else
- rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
+
+ defer_p = 1;
}
- else if (TREE_CODE (CP_DECL_CONTEXT (decl)) == NAMESPACE_DECL
- || (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)))
+
+ /* If we're deferring the variable, just make RTL. Do not actually
+ emit the variable. */
+ if (defer_p)
+ make_decl_rtl (decl, asmspec, toplev);
+ /* If we're not deferring, go ahead and assemble the variable. */
+ else
rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index cef1512..d5a75ca 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3785,9 +3785,6 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
return error_mark_node;
}
- if (context == NULL_TREE)
- context = global_namespace;
-
if (TREE_CODE (template) != TEMPLATE_DECL)
{
cp_error ("non-template type `%T' used as a template", d1);
@@ -3963,6 +3960,11 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
return found;
}
+ context = tsubst (DECL_CONTEXT (template), arglist,
+ /*complain=*/0, in_decl);
+ if (!context)
+ context = global_namespace;
+
/* Create the type. */
if (TREE_CODE (template_type) == ENUMERAL_TYPE)
{
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash20.C b/gcc/testsuite/g++.old-deja/g++.other/crash20.C
new file mode 100644
index 0000000..08e42fd
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/crash20.C
@@ -0,0 +1,38 @@
+// Build don't link:
+
+#include <typeinfo>
+
+struct GcspFlags
+{
+ enum Enum
+ {
+ OffYes,
+ OffNo,
+ Root
+ };
+
+ static char const* name(Enum flag);
+
+ template<Enum GCSP_FLAG>
+ struct btmFlag
+ {
+ static Enum const f=OffNo;
+ };
+
+};
+
+template<>
+struct
+GcspFlags::btmFlag<GcspFlags::OffYes>
+{
+ static GcspFlags::Enum const f=GcspFlags::OffYes;
+};
+
+int
+main ()
+{
+ GcspFlags::btmFlag<GcspFlags::OffYes> f;
+ const type_info& ti = typeid (f);
+ return 0;
+}
+
diff --git a/gcc/testsuite/g++.old-deja/g++.other/static12.C b/gcc/testsuite/g++.old-deja/g++.other/static12.C
new file mode 100644
index 0000000..5b302d4
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/static12.C
@@ -0,0 +1,8 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@redhat.com>
+
+int main ()
+{
+ static const int n = 10;
+ static const int *p = &n;
+}