From a3d8777127800e056bf525c39ab4f7bd72b7818b Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 14 Jul 2003 05:12:56 +0000 Subject: [PATCH] re PR c++/11503 (segfault when instantiating template with ADDR_EXPR) PR c++/11503 * g++.dg/template/anon1.C: New test. PR c++/11503 * cp-tree.h (DECL_SELF_REFERENCE_P): New macro. (SET_DECL_SELF_REFERENCE_P): Likewise. * class.c (build_self_reference): Use SET_DECL_SELF_REFERENCE_P. * pt.c (tsubst_decl): Copy it. * search.c (lookup_base): Use DECL_SELF_REFERENCE_P. From-SVN: r69317 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/class.c | 1 + gcc/cp/cp-tree.h | 17 +++++++++++------ gcc/cp/pt.c | 4 +++- gcc/cp/search.c | 4 +--- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/template/anon1.C | 21 +++++++++++++++++++++ 7 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/anon1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c096405890f2..6351dd6365cc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2003-07-13 Mark Mitchell + PR c++/11503 + * cp-tree.h (DECL_SELF_REFERENCE_P): New macro. + (SET_DECL_SELF_REFERENCE_P): Likewise. + * class.c (build_self_reference): Use SET_DECL_SELF_REFERENCE_P. + * pt.c (tsubst_decl): Copy it. + * search.c (lookup_base): Use DECL_SELF_REFERENCE_P. + + * pt.c (reregister_specialization): Fix thinko in previous change. + * cp-tree.h (cp_id_kind): New type. (unqualified_name_lookup_error): Change prototype. (unqualified_fn_lookup_error): New function. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index bac2e0974a21..56745901e9a0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -6307,6 +6307,7 @@ build_self_reference (void) DECL_NONLOCAL (value) = 1; DECL_CONTEXT (value) = current_class_type; DECL_ARTIFICIAL (value) = 1; + SET_DECL_SELF_REFERENCE_P (value); if (processing_template_decl) value = push_template_decl (value); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 24fd278c5371..32b791fb8054 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -97,6 +97,7 @@ struct diagnostic_context; 3: DECL_IN_AGGR_P. 4: DECL_C_BIT_FIELD (in a FIELD_DECL) DECL_VAR_MARKED_P (in a VAR_DECL) + DECL_SELF_REFERENCE_P (in a TYPE_DECL) 5: DECL_INTERFACE_KNOWN. 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). @@ -2751,16 +2752,20 @@ struct lang_decl GTY(()) (TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE)) /* Nonzero if NODE is the typedef implicitly generated for a type when - the type is declared. (In C++, `struct S {};' is roughly equivalent - to `struct S {}; typedef struct S S;' in C. This macro will hold - for the typedef indicated in this example. Note that in C++, there - is a second implicit typedef for each class, in the scope of `S' - itself, so that you can say `S::S'. This macro does *not* hold for - those typedefs. */ + the type is declared. In C++, `struct S {};' is roughly + equivalent to `struct S {}; typedef struct S S;' in C. + DECL_IMPLICIT_TYPEDEF_P will hold for the typedef indicated in this + example. In C++, there is a second implicit typedef for each + class, in the scope of `S' itself, so that you can say `S::S'. + DECL_SELF_REFERENCE_P will hold for that second typedef. */ #define DECL_IMPLICIT_TYPEDEF_P(NODE) \ (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_2 (NODE)) #define SET_DECL_IMPLICIT_TYPEDEF_P(NODE) \ (DECL_LANG_FLAG_2 (NODE) = 1) +#define DECL_SELF_REFERENCE_P(NODE) \ + (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_4 (NODE)) +#define SET_DECL_SELF_REFERENCE_P(NODE) \ + (DECL_LANG_FLAG_4 (NODE) = 1) /* A `primary' template is one that has its own template header. A member function of a class template is a template, but not primary. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 37ec8688637a..ac032d13d953 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1002,7 +1002,7 @@ reregister_specialization (tree spec, tree tmpl, tree new_spec) if (!new_spec) *s = TREE_CHAIN (*s); else - TREE_VALUE (*s) == new_spec; + TREE_VALUE (*s) = new_spec; return 1; } @@ -6200,6 +6200,8 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain) r = copy_decl (t); if (TREE_CODE (r) == VAR_DECL) type = complete_type (type); + else if (DECL_SELF_REFERENCE_P (t)) + SET_DECL_SELF_REFERENCE_P (r); TREE_TYPE (r) = type; c_apply_type_quals_to_decl (cp_type_quals (type), r); DECL_CONTEXT (r) = ctx; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index c2c158a691c3..1161084980df 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -305,9 +305,7 @@ lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr) /* Rather than inventing a public member, we use the implicit public typedef created in the scope of every class. */ decl = TYPE_FIELDS (base); - while (TREE_CODE (decl) != TYPE_DECL - || !DECL_ARTIFICIAL (decl) - || DECL_NAME (decl) != constructor_name (base)) + while (!DECL_SELF_REFERENCE_P (decl)) decl = TREE_CHAIN (decl); while (ANON_AGGR_TYPE_P (t)) t = TYPE_CONTEXT (t); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1dedd6563d45..e51dda898336 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2003-07-13 Mark Mitchell + PR c++/11503 + * g++.dg/template/anon1.C: New test. + PR c++/11493 PR c++/11495 * g++.dg/parse/template9.C: Likewise. diff --git a/gcc/testsuite/g++.dg/template/anon1.C b/gcc/testsuite/g++.dg/template/anon1.C new file mode 100644 index 000000000000..ef73df6b39e6 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/anon1.C @@ -0,0 +1,21 @@ +struct x { + int foo () {} +}; + +template +struct vector { + T& bar () {} +}; + +template +struct y { + typedef struct { + x t; + } s; + + vector array; + + int foo () + { return array.bar().t.foo(); } +}; +int i = y().foo ();