Commit 1fb3244a by Mark Mitchell Committed by Mark Mitchell

re PR c++/9388 ([new parser] ICE in cxx_incomplete_type_diagnostic, at cp/typeck2.c:278)

	PR c++/9388
	* class.c (currently_open_derived_class): Use dependent_type_p.
	* cp-tree.h (dependent_type_p): New function.
	(dependent_template_arg_p): Likewise.
	(dependent_template_p): Likewise.
	(type_dependent_expression_p): Likewise.
	* parser.c (cp_parser_dependent_type_p): Remove.
	(cp_parser_value_dependent_type_p): Likewise.
	(cp_parser_type_dependent_expression_p): Likewise.
	(cp_parser_dependent_template_arg_p): Likewise.
	(cp_parser_dependent_template_id_p): Likewise.
	(cp_parser_dependent_template_p): Likewise.
	(cp_parser_diagnose_invalid_type_name): Replace
	cp_parser_dependent_type_p with dependent_type_p, etc.
	(cp_parser_primary_expresion): Likewise.
	(cp_parser_nested_name_specifier_opt): Likewise.
	(cp_parser_postfix_expression): Likewise.
	(cp_parser_unary_expression): Likewise.
	(cp_parser_template_name): Likewise.
	(cp_parser_class_name): Likewise.
	(cp_parser_lookup_name): Likewise.
	* pt.c (dependent_type_p): New function.
	(value_dependent_expression_p): Likewise.
	(type_dependent_expression_p): Likewise.
	(dependent_template_arg_p): Likewise.
	(dependent_template_id_p): Likewise.
	(dependent_template_p): Likewise.

	PR c++/9285
	PR c++/9294
	* parser.c (cp_parser_simple_declaration):

	PR c++/9285
	PR c++/9294
	* g++.dg/parse/expr2.C: New test.

	PR c++/9388
	* g++.dg/parse/lookup2.C: Likewise.

From-SVN: r61596
parent 4888ec5d
2003-01-22 Mark Mitchell <mark@codesourcery.com>
PR c++/9388
* class.c (currently_open_derived_class): Use dependent_type_p.
* cp-tree.h (dependent_type_p): New function.
(dependent_template_arg_p): Likewise.
(dependent_template_p): Likewise.
(type_dependent_expression_p): Likewise.
* parser.c (cp_parser_dependent_type_p): Remove.
(cp_parser_value_dependent_type_p): Likewise.
(cp_parser_type_dependent_expression_p): Likewise.
(cp_parser_dependent_template_arg_p): Likewise.
(cp_parser_dependent_template_id_p): Likewise.
(cp_parser_dependent_template_p): Likewise.
(cp_parser_diagnose_invalid_type_name): Replace
cp_parser_dependent_type_p with dependent_type_p, etc.
(cp_parser_primary_expresion): Likewise.
(cp_parser_nested_name_specifier_opt): Likewise.
(cp_parser_postfix_expression): Likewise.
(cp_parser_unary_expression): Likewise.
(cp_parser_template_name): Likewise.
(cp_parser_class_name): Likewise.
(cp_parser_lookup_name): Likewise.
* pt.c (dependent_type_p): New function.
(value_dependent_expression_p): Likewise.
(type_dependent_expression_p): Likewise.
(dependent_template_arg_p): Likewise.
(dependent_template_id_p): Likewise.
(dependent_template_p): Likewise.
PR c++/9285
PR c++/9294
* parser.c (cp_parser_simple_declaration):
2003-01-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
Make-lang.in (cp/decl.o-warn): Add -Wno-error.
......
......@@ -6001,6 +6001,10 @@ currently_open_derived_class (t)
{
int i;
/* The bases of a dependent type are unknown. */
if (dependent_type_p (t))
return NULL_TREE;
if (DERIVED_FROM_P (t, current_class_type))
return current_class_type;
......
......@@ -4088,6 +4088,10 @@ extern void record_last_problematic_instantiation (void);
extern tree current_instantiation (void);
extern tree maybe_get_template_decl_from_type_decl (tree);
extern int processing_template_parmlist;
extern bool dependent_type_p (tree);
extern bool dependent_template_arg_p (tree);
extern bool dependent_template_p (tree);
extern bool type_dependent_expression_p (tree);
/* in repo.c */
extern void repo_template_used (tree);
......
......@@ -171,6 +171,8 @@ static void copy_default_args_to_explicit_spec PARAMS ((tree));
static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
static int eq_local_specializations (const void *, const void *);
static tree template_for_substitution (tree);
static bool value_dependent_expression_p (tree);
static bool dependent_template_id_p (tree, tree);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
......@@ -11187,4 +11189,283 @@ invalid_nontype_parm_type_p (type, complain)
return 1;
}
/* Returns TRUE if TYPE is dependent, in the sense of
[temp.dep.type]. */
bool
dependent_type_p (type)
tree type;
{
tree scope;
/* If there are no template parameters in scope, then there can't be
any dependent types. */
if (!processing_template_decl)
return false;
/* If the type is NULL, we have not computed a type for the entity
in question; in that case, the type is dependent. */
if (!type)
return true;
/* Erroneous types can be considered non-dependent. */
if (type == error_mark_node)
return false;
/* [temp.dep.type]
A type is dependent if it is:
-- a template parameter. */
if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
return true;
/* -- a qualified-id with a nested-name-specifier which contains a
class-name that names a dependent type or whose unqualified-id
names a dependent type. */
if (TREE_CODE (type) == TYPENAME_TYPE)
return true;
/* -- a cv-qualified type where the cv-unqualified type is
dependent. */
type = TYPE_MAIN_VARIANT (type);
/* -- a compound type constructed from any dependent type. */
if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
|| dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE
(type)));
else if (TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == REFERENCE_TYPE)
return dependent_type_p (TREE_TYPE (type));
else if (TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE)
{
tree arg_type;
if (dependent_type_p (TREE_TYPE (type)))
return true;
for (arg_type = TYPE_ARG_TYPES (type);
arg_type;
arg_type = TREE_CHAIN (arg_type))
if (dependent_type_p (TREE_VALUE (arg_type)))
return true;
return false;
}
/* -- an array type constructed from any dependent type or whose
size is specified by a constant expression that is
value-dependent. */
if (TREE_CODE (type) == ARRAY_TYPE)
{
if (TYPE_DOMAIN (type)
&& ((value_dependent_expression_p
(TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
|| (type_dependent_expression_p
(TYPE_MAX_VALUE (TYPE_DOMAIN (type))))))
return true;
return dependent_type_p (TREE_TYPE (type));
}
/* -- a template-id in which either the template name is a template
parameter or any of the template arguments is a dependent type or
an expression that is type-dependent or value-dependent.
This language seems somewhat confused; for example, it does not
discuss template template arguments. Therefore, we use the
definition for dependent template arguments in [temp.dep.temp]. */
if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
&& (dependent_template_id_p
(CLASSTYPE_TI_TEMPLATE (type),
CLASSTYPE_TI_ARGS (type))))
return true;
else if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
return true;
/* All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
expression is not type-dependent, then it should already been
have resolved. */
if (TREE_CODE (type) == TYPEOF_TYPE)
return true;
/* The standard does not specifically mention types that are local
to template functions or local classes, but they should be
considered dependent too. For example:
template <int I> void f() {
enum E { a = I };
S<sizeof (E)> s;
}
The size of `E' cannot be known until the value of `I' has been
determined. Therefore, `E' must be considered dependent. */
scope = TYPE_CONTEXT (type);
if (scope && TYPE_P (scope))
return dependent_type_p (scope);
else if (scope && TREE_CODE (scope) == FUNCTION_DECL)
return type_dependent_expression_p (scope);
/* Other types are non-dependent. */
return false;
}
/* Returns TRUE if the EXPRESSION is value-dependent. */
static bool
value_dependent_expression_p (tree expression)
{
if (!processing_template_decl)
return false;
/* A name declared with a dependent type. */
if (DECL_P (expression)
&& dependent_type_p (TREE_TYPE (expression)))
return true;
/* A non-type template parameter. */
if ((TREE_CODE (expression) == CONST_DECL
&& DECL_TEMPLATE_PARM_P (expression))
|| TREE_CODE (expression) == TEMPLATE_PARM_INDEX)
return true;
/* A constant with integral or enumeration type and is initialized
with an expression that is value-dependent. */
if (TREE_CODE (expression) == VAR_DECL
&& DECL_INITIAL (expression)
&& (CP_INTEGRAL_TYPE_P (TREE_TYPE (expression))
|| TREE_CODE (TREE_TYPE (expression)) == ENUMERAL_TYPE)
&& value_dependent_expression_p (DECL_INITIAL (expression)))
return true;
/* These expressions are value-dependent if the type to which the
cast occurs is dependent. */
if ((TREE_CODE (expression) == DYNAMIC_CAST_EXPR
|| TREE_CODE (expression) == STATIC_CAST_EXPR
|| TREE_CODE (expression) == CONST_CAST_EXPR
|| TREE_CODE (expression) == REINTERPRET_CAST_EXPR
|| TREE_CODE (expression) == CAST_EXPR)
&& dependent_type_p (TREE_TYPE (expression)))
return true;
/* A `sizeof' expression where the sizeof operand is a type is
value-dependent if the type is dependent. If the type was not
dependent, we would no longer have a SIZEOF_EXPR, so any
SIZEOF_EXPR is dependent. */
if (TREE_CODE (expression) == SIZEOF_EXPR)
return true;
/* A constant expression is value-dependent if any subexpression is
value-dependent. */
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
{
switch (TREE_CODE_CLASS (TREE_CODE (expression)))
{
case '1':
return (value_dependent_expression_p
(TREE_OPERAND (expression, 0)));
case '<':
case '2':
return ((value_dependent_expression_p
(TREE_OPERAND (expression, 0)))
|| (value_dependent_expression_p
(TREE_OPERAND (expression, 1))));
case 'e':
{
int i;
for (i = 0;
i < TREE_CODE_LENGTH (TREE_CODE (expression));
++i)
if (value_dependent_expression_p
(TREE_OPERAND (expression, i)))
return true;
return false;
}
}
}
/* The expression is not value-dependent. */
return false;
}
/* Returns TRUE if the EXPRESSION is type-dependent, in the sense of
[temp.dep.expr]. */
bool
type_dependent_expression_p (expression)
tree expression;
{
if (!processing_template_decl)
return false;
/* Some expression forms are never type-dependent. */
if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
|| TREE_CODE (expression) == SIZEOF_EXPR
|| TREE_CODE (expression) == ALIGNOF_EXPR
|| TREE_CODE (expression) == TYPEID_EXPR
|| TREE_CODE (expression) == DELETE_EXPR
|| TREE_CODE (expression) == VEC_DELETE_EXPR
|| TREE_CODE (expression) == THROW_EXPR)
return false;
/* The types of these expressions depends only on the type to which
the cast occurs. */
if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR
|| TREE_CODE (expression) == STATIC_CAST_EXPR
|| TREE_CODE (expression) == CONST_CAST_EXPR
|| TREE_CODE (expression) == REINTERPRET_CAST_EXPR
|| TREE_CODE (expression) == CAST_EXPR)
return dependent_type_p (TREE_TYPE (expression));
/* The types of these expressions depends only on the type created
by the expression. */
else if (TREE_CODE (expression) == NEW_EXPR
|| TREE_CODE (expression) == VEC_NEW_EXPR)
return dependent_type_p (TREE_OPERAND (expression, 1));
if (TREE_CODE (expression) == FUNCTION_DECL
&& DECL_LANG_SPECIFIC (expression)
&& DECL_TEMPLATE_INFO (expression)
&& (dependent_template_id_p
(DECL_TI_TEMPLATE (expression),
INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
return true;
return (dependent_type_p (TREE_TYPE (expression)));
}
/* Returns TRUE if the ARG (a template argument) is dependent. */
bool
dependent_template_arg_p (tree arg)
{
if (!processing_template_decl)
return false;
if (TREE_CODE (arg) == TEMPLATE_DECL
|| TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
return dependent_template_p (arg);
else if (TYPE_P (arg))
return dependent_type_p (arg);
else
return (type_dependent_expression_p (arg)
|| value_dependent_expression_p (arg));
}
/* Returns TRUE if the specialization TMPL<ARGS> is dependent. */
static bool
dependent_template_id_p (tree tmpl, tree args)
{
int i;
if (dependent_template_p (tmpl))
return true;
for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
return true;
return false;
}
/* Returns TRUE if the template TMPL is dependent. */
bool
dependent_template_p (tree tmpl)
{
/* Template template parameters are dependent. */
if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
|| TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM)
return true;
/* So are member templates of dependent classes. */
if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
return dependent_type_p (DECL_CONTEXT (tmpl));
return false;
}
#include "gt-cp-pt.h"
2003-01-22 Mark Mitchell <mark@codesourcery.com>
PR c++/9285
PR c++/9294
* g++.dg/parse/expr2.C: New test.
PR c++/9388
* g++.dg/parse/lookup2.C: Likewise.
Tue Jan 21 18:01:35 CET 2003 Jan Hubicka <jh@suse.cz>
* gcc.c-torture/execute/990208-1.c: Add noinline attributes as needed.
......
struct X {
X(double *data, double d0, double d1);
};
int foo(double d0) {
double * data;
X(data,d0,d0);
}
template <typename T> struct A
{
typedef int X;
};
template <typename T> struct B
{
typename A<T>::X x;
};
template <typename T> struct C
{
void foo(int);
B<A<T>*> b;
};
template <typename T> struct D
{
enum { e };
void bar() { C<T*>::foo(e); }
};
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