aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-07-14 05:12:56 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-07-14 05:12:56 +0000
commita3d8777127800e056bf525c39ab4f7bd72b7818b (patch)
tree87f9283f2bab95f2d3eae355b5779dedea7a7f1b /gcc
parentb34459943bbfaf3f6fb32408bec5443b5bd007a9 (diff)
downloadgcc-a3d8777127800e056bf525c39ab4f7bd72b7818b.zip
gcc-a3d8777127800e056bf525c39ab4f7bd72b7818b.tar.gz
gcc-a3d8777127800e056bf525c39ab4f7bd72b7818b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/class.c1
-rw-r--r--gcc/cp/cp-tree.h17
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/search.c4
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/anon1.C21
7 files changed, 49 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c096405..6351dd6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,14 @@
2003-07-13 Mark Mitchell <mark@codesourcery.com>
+ 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 bac2e09..5674590 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 24fd278..32b791f 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 37ec8688..ac032d1 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 c2c158a..1161084 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 1dedd65..e51dda8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2003-07-13 Mark Mitchell <mark@codesourcery.com>
+ 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 0000000..ef73df6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/anon1.C
@@ -0,0 +1,21 @@
+struct x {
+ int foo () {}
+};
+
+template <class T>
+struct vector {
+ T& bar () {}
+};
+
+template <class T>
+struct y {
+ typedef struct {
+ x t;
+ } s;
+
+ vector<s> array;
+
+ int foo ()
+ { return array.bar().t.foo(); }
+};
+int i = y<x>().foo ();