Commit 0da99d4e by Giovanni Bajo

re PR c++/14409 (Accepts invalid function signature for explicit instantiation)

	PR c++/14409
	* pt.c (determine_specialization): For member templates, match also
	constness.

	PR c++/14448
	* parser.c (cp_parser_initializer_clause): Fold initializer if it is
	non-dependent.
	* pt.c (tsubst_copy_and_build): Handle NOP_EXPRs.

	PR c++/14409
	* g++.dg/template/spec12.C: New test.

	PR c++/14448
	* g++.dg/parse/crash14.C: New test.

From-SVN: r79172
parent c0e63064
2004-03-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/14409
* pt.c (determine_specialization): For member templates, match also
constness.
PR c++/14448
* parser.c (cp_parser_initializer_clause): Fold initializer if it is
non-dependent.
* pt.c (tsubst_copy_and_build): Handle NOP_EXPRs.
2004-03-09 Mark Mitchell <mark@codesourcery.com> 2004-03-09 Mark Mitchell <mark@codesourcery.com>
PR c++/14230 PR c++/14230
......
...@@ -4537,9 +4537,9 @@ cp_parser_new_expression (cp_parser* parser) ...@@ -4537,9 +4537,9 @@ cp_parser_new_expression (cp_parser* parser)
but GCC used to allowed this, so we check and emit a sensible error but GCC used to allowed this, so we check and emit a sensible error
message for this case. */ message for this case. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)) if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
{ {
error ("array bound forbidden after parenthesized type-id"); error ("array bound forbidden after parenthesized type-id");
inform ("try removing the parentheses around the type-id"); inform ("try removing the parentheses around the type-id");
cp_parser_direct_new_declarator (parser); cp_parser_direct_new_declarator (parser);
} }
} }
...@@ -11528,10 +11528,14 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p) ...@@ -11528,10 +11528,14 @@ cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
/* If it is not a `{', then we are looking at an /* If it is not a `{', then we are looking at an
assignment-expression. */ assignment-expression. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)) if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
initializer {
= cp_parser_constant_expression (parser, initializer
/*allow_non_constant_p=*/true, = cp_parser_constant_expression (parser,
non_constant_p); /*allow_non_constant_p=*/true,
non_constant_p);
if (!*non_constant_p)
initializer = fold_non_dependent_expr (initializer);
}
else else
{ {
/* Consume the `{' token. */ /* Consume the `{' token. */
......
...@@ -1249,6 +1249,7 @@ determine_specialization (tree template_id, ...@@ -1249,6 +1249,7 @@ determine_specialization (tree template_id,
if (TREE_CODE (fn) == TEMPLATE_DECL) if (TREE_CODE (fn) == TEMPLATE_DECL)
{ {
tree decl_arg_types; tree decl_arg_types;
tree fn_arg_types;
/* DECL might be a specialization of FN. */ /* DECL might be a specialization of FN. */
...@@ -1265,8 +1266,16 @@ determine_specialization (tree template_id, ...@@ -1265,8 +1266,16 @@ determine_specialization (tree template_id,
The specialization f<int> is invalid but is not caught The specialization f<int> is invalid but is not caught
by get_bindings below. */ by get_bindings below. */
if (list_length (TYPE_ARG_TYPES (TREE_TYPE (fn))) fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
!= list_length (decl_arg_types)) if (list_length (fn_arg_types) != list_length (decl_arg_types))
continue;
/* For a non-static member function, we need to make sure that
the const qualification is the same. This can be done by
checking the 'this' in the argument list. */
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
&& !same_type_p (TREE_VALUE (fn_arg_types),
TREE_VALUE (decl_arg_types)))
continue; continue;
/* See whether this function might be a specialization of this /* See whether this function might be a specialization of this
...@@ -8169,6 +8178,11 @@ tsubst_copy_and_build (tree t, ...@@ -8169,6 +8178,11 @@ tsubst_copy_and_build (tree t,
case INDIRECT_REF: case INDIRECT_REF:
return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *"); return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *");
case NOP_EXPR:
return build_nop
(tsubst (TREE_TYPE (t), args, complain, in_decl),
RECUR (TREE_OPERAND (t, 0)));
case CAST_EXPR: case CAST_EXPR:
return build_functional_cast return build_functional_cast
(tsubst (TREE_TYPE (t), args, complain, in_decl), (tsubst (TREE_TYPE (t), args, complain, in_decl),
......
2004-03-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/14409
* g++.dg/template/spec12.C: New test.
PR c++/14448
* g++.dg/parse/crash14.C: New test.
2004-03-09 Mark Mitchell <mark@codesourcery.com> 2004-03-09 Mark Mitchell <mark@codesourcery.com>
PR c++/14230 PR c++/14230
......
// { dg-do compile }
// Contributed by: Giovanni Bajo <giovannibajo at libero dot it>
// PR c++/14448: Fold constant initializers in templates
template <int> struct A
{
A();
};
template<typename T> void foo(T)
{
static const int n=1+1;
A<n+1> a;
}
void bar()
{
foo(0);
}
// { dg-do compile }
// Contributed by: Wolfgang Bangerth <bangerth at dealii dot org>
// PR c++/14409: Accepts invalid function signature for explicit instantiation
struct X
{
template <typename U>
void foo (U) {}
template <typename U>
void foo_const (U) const {}
};
template void X::foo (int);
template void X::foo_const (int) const;
template void X::foo (int) const; // { dg-error "" }
template void X::foo_const (int); // { dg-error "" }
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