aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-07-04 00:34:03 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-07-04 00:34:03 -0400
commitad909c97e2d84c7a497287eaabd498131d1ef5eb (patch)
tree8ef0778c524d062435bf88b94bc898d7b8a51acb /gcc
parentcaf271d8026c2f9a3ade32a8e670fa3be6e3892b (diff)
downloadgcc-ad909c97e2d84c7a497287eaabd498131d1ef5eb.zip
gcc-ad909c97e2d84c7a497287eaabd498131d1ef5eb.tar.gz
gcc-ad909c97e2d84c7a497287eaabd498131d1ef5eb.tar.bz2
re PR c++/40619 ([c++0x] ICE on repeated decltype expression in auto functions)
PR c++/40619 * cp-tree.h (struct lang_decl_parm): New. (struct lang_decl): Add it. (LANG_DECL_PARM_CHECK): New. (DECL_PARM_INDEX): New. * decl2.c (parm_index): Remove. * lex.c (retrofit_lang_decl): Handle parms. (cxx_dup_lang_specific_decl): Likewise. * mangle.c (write_expression): Adjust. * tree.c (cp_tree_equal): Adjust. (decl_linkage): Only check DECL_COMDAT for functions and variables. * parser.c (cp_parser_parameter_declaration_list): Set DECL_PARM_INDEX. * pt.c (iterative_hash_template_arg): Hash it. From-SVN: r149223
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog17
-rw-r--r--gcc/cp/cp-tree.h22
-rw-r--r--gcc/cp/decl2.c23
-rw-r--r--gcc/cp/lex.c4
-rw-r--r--gcc/cp/mangle.c3
-rw-r--r--gcc/cp/parser.c7
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/tree.c5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto16.C7
10 files changed, 68 insertions, 29 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 257dca4..9cc2aab 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+2009-07-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/40619
+ * cp-tree.h (struct lang_decl_parm): New.
+ (struct lang_decl): Add it.
+ (LANG_DECL_PARM_CHECK): New.
+ (DECL_PARM_INDEX): New.
+ * decl2.c (parm_index): Remove.
+ * lex.c (retrofit_lang_decl): Handle parms.
+ (cxx_dup_lang_specific_decl): Likewise.
+ * mangle.c (write_expression): Adjust.
+ * tree.c (cp_tree_equal): Adjust.
+ (decl_linkage): Only check DECL_COMDAT for functions and variables.
+ * parser.c (cp_parser_parameter_declaration_list): Set
+ DECL_PARM_INDEX.
+ * pt.c (iterative_hash_template_arg): Hash it.
+
2009-07-03 Jason Merrill <jason@redhat.com>
* cp-tree.h (struct lang_decl): Overhaul.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 50ed2ea..4cf5b14 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1675,6 +1675,13 @@ struct GTY(()) lang_decl_ns {
struct cp_binding_level *level;
};
+/* DECL_LANG_SPECIFIC for parameters. */
+
+struct GTY(()) lang_decl_parm {
+ struct lang_decl_base base;
+ int index;
+};
+
/* DECL_LANG_SPECIFIC for all types. It would be nice to just make this a
union rather than a struct containing a union as its only field, but
tree.h declares it as a struct. */
@@ -1685,6 +1692,7 @@ struct GTY(()) lang_decl {
struct lang_decl_min GTY((tag ("0"))) min;
struct lang_decl_fn GTY ((tag ("1"))) fn;
struct lang_decl_ns GTY((tag ("2"))) ns;
+ struct lang_decl_parm GTY((tag ("3"))) parm;
} u;
};
@@ -1715,6 +1723,12 @@ struct GTY(()) lang_decl {
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
&lt->u.ns; })
+#define LANG_DECL_PARM_CHECK(NODE) __extension__ \
+({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
+ if (TREE_CODE (NODE) != PARM_DECL) \
+ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
+ &lt->u.parm; })
+
#define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (lt->u.base.u2sel != TF) \
@@ -1732,6 +1746,9 @@ struct GTY(()) lang_decl {
#define LANG_DECL_NS_CHECK(NODE) \
(&DECL_LANG_SPECIFIC (NODE)->u.ns)
+#define LANG_DECL_PARM_CHECK(NODE) \
+ (&DECL_LANG_SPECIFIC (NODE)->u.parm)
+
#define LANG_DECL_U2_CHECK(NODE, TF) \
(&DECL_LANG_SPECIFIC (NODE)->u.min.u2)
@@ -1847,6 +1864,11 @@ struct GTY(()) lang_decl {
/* Discriminator for name mangling. */
#define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator)
+/* The index of a user-declared parameter in its function, starting at 1.
+ All artificial parameters will have index 0. */
+#define DECL_PARM_INDEX(NODE) \
+ (LANG_DECL_PARM_CHECK (NODE)->index)
+
/* Nonzero if the VTT parm has been added to NODE. */
#define DECL_HAS_VTT_PARM_P(NODE) \
(LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 6be57a6..b3b567e 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3910,27 +3910,4 @@ mark_used (tree decl)
processing_template_decl = saved_processing_template_decl;
}
-/* Given function PARM_DECL PARM, return its index in the function's list
- of parameters, beginning with 1. */
-
-int
-parm_index (tree parm)
-{
- int index;
- tree arg;
-
- for (index = 1, arg = DECL_ARGUMENTS (DECL_CONTEXT (parm));
- arg;
- ++index, arg = TREE_CHAIN (arg))
- {
- if (DECL_NAME (parm) == DECL_NAME (arg))
- break;
- if (DECL_ARTIFICIAL (arg))
- --index;
- }
-
- gcc_assert (arg);
- return index;
-}
-
#include "gt-cp-decl2.h"
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 5effd7a..5eb182d 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -538,6 +538,8 @@ retrofit_lang_decl (tree t)
sel = 1, size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (t) == NAMESPACE_DECL)
sel = 2, size = sizeof (struct lang_decl_ns);
+ else if (TREE_CODE (t) == PARM_DECL)
+ sel = 3, size = sizeof (struct lang_decl_parm);
else if (LANG_DECL_HAS_MIN (t))
sel = 0, size = sizeof (struct lang_decl_min);
else
@@ -577,6 +579,8 @@ cxx_dup_lang_specific_decl (tree node)
size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (node) == NAMESPACE_DECL)
size = sizeof (struct lang_decl_ns);
+ else if (TREE_CODE (node) == PARM_DECL)
+ size = sizeof (struct lang_decl_parm);
else if (LANG_DECL_HAS_MIN (node))
size = sizeof (struct lang_decl_min);
else
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index fe2f6fd..c49439d 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2199,7 +2199,8 @@ write_expression (tree expr)
else if (code == PARM_DECL)
{
/* A function parameter used in a late-specified return type. */
- int index = parm_index (expr);
+ int index = DECL_PARM_INDEX (expr);
+ gcc_assert (index >= 1);
write_string ("fp");
if (index > 1)
write_unsigned_number (index - 2);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f71ea46..f3122bc 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -14111,6 +14111,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
tree parameters = NULL_TREE;
tree *tail = &parameters;
bool saved_in_unbraced_linkage_specification_p;
+ int index = 0;
/* Assume all will go well. */
*is_error = false;
@@ -14162,6 +14163,12 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
if (DECL_NAME (decl))
decl = pushdecl (decl);
+ if (decl != error_mark_node)
+ {
+ retrofit_lang_decl (decl);
+ DECL_PARM_INDEX (decl) = ++index;
+ }
+
/* Add the new parameter to the list. */
*tail = build_tree_list (parameter->default_argument, decl);
tail = &TREE_CHAIN (*tail);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b93c811..527fe04 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1488,9 +1488,7 @@ iterative_hash_template_arg (tree arg, hashval_t val)
}
case PARM_DECL:
- /* I tried hashing parm_index as well, but in some cases we get
- called too soon for that to work, so just hash the type and let
- lookup check that the index matches. */
+ val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
return iterative_hash_template_arg (TREE_TYPE (arg), val);
case TARGET_EXPR:
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 7c48a32..644e53c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1997,7 +1997,7 @@ cp_tree_equal (tree t1, tree t2)
/* For comparing uses of parameters in late-specified return types
with an out-of-class definition of the function. */
if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
- && parm_index (t1) == parm_index (t2))
+ && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2))
return true;
else
return false;
@@ -2723,7 +2723,8 @@ decl_linkage (tree decl)
template instantiations have internal linkage (in the object
file), but the symbols should still be treated as having external
linkage from the point of view of the language. */
- if (TREE_CODE (decl) != TYPE_DECL && DECL_LANG_SPECIFIC (decl)
+ if ((TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == VAR_DECL)
&& DECL_COMDAT (decl))
return lk_external;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4dd0719..bc92638 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-07-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/40619
+ * g++.dg/cpp0x/auto16.C: New.
+
2009-07-03 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/40638
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto16.C b/gcc/testsuite/g++.dg/cpp0x/auto16.C
new file mode 100644
index 0000000..1b4ae8f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto16.C
@@ -0,0 +1,7 @@
+// PR c++/40619
+// { dg-options "-std=c++0x" }
+
+template<typename U> struct X {};
+
+template<typename T> auto f(T t) -> X<decltype(t+1)> {}
+template<typename T> auto g(T t) -> X<decltype(t+1)> {}