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>
* cp-tree.h (struct lang_decl): Overhaul.
......
......@@ -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)
......
......@@ -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"
......@@ -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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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:
......
......@@ -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;
......
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
......
// 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