diff options
author | Mark Mitchell <mark@codesourcery.com> | 2000-07-23 19:59:41 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2000-07-23 19:59:41 +0000 |
commit | 95ee998ceb1d196000e2cb4e61b760d818119dee (patch) | |
tree | 3530f888190774b58b61b605cab7584a692609b7 | |
parent | 07964b9c09eb5bfe56851851d4e1696cb34e763d (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/c-semantics.c | 2 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 86 | ||||
-rw-r--r-- | gcc/cp/pt.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/crash20.C | 38 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/static12.C | 8 |
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; +} |