Commit ad909c97 by Jason Merrill Committed by Jason Merrill

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
parent caf271d8
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> 2009-07-03 Jason Merrill <jason@redhat.com>
* cp-tree.h (struct lang_decl): Overhaul. * cp-tree.h (struct lang_decl): Overhaul.
......
...@@ -1675,6 +1675,13 @@ struct GTY(()) lang_decl_ns { ...@@ -1675,6 +1675,13 @@ struct GTY(()) lang_decl_ns {
struct cp_binding_level *level; 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 /* 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 union rather than a struct containing a union as its only field, but
tree.h declares it as a struct. */ tree.h declares it as a struct. */
...@@ -1685,6 +1692,7 @@ struct GTY(()) lang_decl { ...@@ -1685,6 +1692,7 @@ struct GTY(()) lang_decl {
struct lang_decl_min GTY((tag ("0"))) min; struct lang_decl_min GTY((tag ("0"))) min;
struct lang_decl_fn GTY ((tag ("1"))) fn; struct lang_decl_fn GTY ((tag ("1"))) fn;
struct lang_decl_ns GTY((tag ("2"))) ns; struct lang_decl_ns GTY((tag ("2"))) ns;
struct lang_decl_parm GTY((tag ("3"))) parm;
} u; } u;
}; };
...@@ -1715,6 +1723,12 @@ struct GTY(()) lang_decl { ...@@ -1715,6 +1723,12 @@ struct GTY(()) lang_decl {
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
&lt->u.ns; }) &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__ \ #define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ ({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (lt->u.base.u2sel != TF) \ if (lt->u.base.u2sel != TF) \
...@@ -1732,6 +1746,9 @@ struct GTY(()) lang_decl { ...@@ -1732,6 +1746,9 @@ struct GTY(()) lang_decl {
#define LANG_DECL_NS_CHECK(NODE) \ #define LANG_DECL_NS_CHECK(NODE) \
(&DECL_LANG_SPECIFIC (NODE)->u.ns) (&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) \ #define LANG_DECL_U2_CHECK(NODE, TF) \
(&DECL_LANG_SPECIFIC (NODE)->u.min.u2) (&DECL_LANG_SPECIFIC (NODE)->u.min.u2)
...@@ -1847,6 +1864,11 @@ struct GTY(()) lang_decl { ...@@ -1847,6 +1864,11 @@ struct GTY(()) lang_decl {
/* Discriminator for name mangling. */ /* Discriminator for name mangling. */
#define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator) #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. */ /* Nonzero if the VTT parm has been added to NODE. */
#define DECL_HAS_VTT_PARM_P(NODE) \ #define DECL_HAS_VTT_PARM_P(NODE) \
(LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p) (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p)
......
...@@ -3910,27 +3910,4 @@ mark_used (tree decl) ...@@ -3910,27 +3910,4 @@ mark_used (tree decl)
processing_template_decl = saved_processing_template_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" #include "gt-cp-decl2.h"
...@@ -538,6 +538,8 @@ retrofit_lang_decl (tree t) ...@@ -538,6 +538,8 @@ retrofit_lang_decl (tree t)
sel = 1, size = sizeof (struct lang_decl_fn); sel = 1, size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (t) == NAMESPACE_DECL) else if (TREE_CODE (t) == NAMESPACE_DECL)
sel = 2, size = sizeof (struct lang_decl_ns); 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)) else if (LANG_DECL_HAS_MIN (t))
sel = 0, size = sizeof (struct lang_decl_min); sel = 0, size = sizeof (struct lang_decl_min);
else else
...@@ -577,6 +579,8 @@ cxx_dup_lang_specific_decl (tree node) ...@@ -577,6 +579,8 @@ cxx_dup_lang_specific_decl (tree node)
size = sizeof (struct lang_decl_fn); size = sizeof (struct lang_decl_fn);
else if (TREE_CODE (node) == NAMESPACE_DECL) else if (TREE_CODE (node) == NAMESPACE_DECL)
size = sizeof (struct lang_decl_ns); 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)) else if (LANG_DECL_HAS_MIN (node))
size = sizeof (struct lang_decl_min); size = sizeof (struct lang_decl_min);
else else
......
...@@ -2199,7 +2199,8 @@ write_expression (tree expr) ...@@ -2199,7 +2199,8 @@ write_expression (tree expr)
else if (code == PARM_DECL) else if (code == PARM_DECL)
{ {
/* A function parameter used in a late-specified return type. */ /* 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"); write_string ("fp");
if (index > 1) if (index > 1)
write_unsigned_number (index - 2); write_unsigned_number (index - 2);
......
...@@ -14111,6 +14111,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) ...@@ -14111,6 +14111,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
tree parameters = NULL_TREE; tree parameters = NULL_TREE;
tree *tail = &parameters; tree *tail = &parameters;
bool saved_in_unbraced_linkage_specification_p; bool saved_in_unbraced_linkage_specification_p;
int index = 0;
/* Assume all will go well. */ /* Assume all will go well. */
*is_error = false; *is_error = false;
...@@ -14162,6 +14163,12 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) ...@@ -14162,6 +14163,12 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error)
if (DECL_NAME (decl)) if (DECL_NAME (decl))
decl = pushdecl (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. */ /* Add the new parameter to the list. */
*tail = build_tree_list (parameter->default_argument, decl); *tail = build_tree_list (parameter->default_argument, decl);
tail = &TREE_CHAIN (*tail); tail = &TREE_CHAIN (*tail);
......
...@@ -1488,9 +1488,7 @@ iterative_hash_template_arg (tree arg, hashval_t val) ...@@ -1488,9 +1488,7 @@ iterative_hash_template_arg (tree arg, hashval_t val)
} }
case PARM_DECL: case PARM_DECL:
/* I tried hashing parm_index as well, but in some cases we get val = iterative_hash_object (DECL_PARM_INDEX (arg), val);
called too soon for that to work, so just hash the type and let
lookup check that the index matches. */
return iterative_hash_template_arg (TREE_TYPE (arg), val); return iterative_hash_template_arg (TREE_TYPE (arg), val);
case TARGET_EXPR: case TARGET_EXPR:
......
...@@ -1997,7 +1997,7 @@ cp_tree_equal (tree t1, tree t2) ...@@ -1997,7 +1997,7 @@ cp_tree_equal (tree t1, tree t2)
/* For comparing uses of parameters in late-specified return types /* For comparing uses of parameters in late-specified return types
with an out-of-class definition of the function. */ with an out-of-class definition of the function. */
if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) 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; return true;
else else
return false; return false;
...@@ -2723,7 +2723,8 @@ decl_linkage (tree decl) ...@@ -2723,7 +2723,8 @@ decl_linkage (tree decl)
template instantiations have internal linkage (in the object template instantiations have internal linkage (in the object
file), but the symbols should still be treated as having external file), but the symbols should still be treated as having external
linkage from the point of view of the language. */ 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)) && DECL_COMDAT (decl))
return lk_external; return lk_external;
......
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> 2009-07-03 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/40638 PR fortran/40638
......
// 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)> {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment