* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@79172
138bc75d-0d04-0410-961f-
82ee72b054a4
+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>
PR c++/14230
but GCC used to allowed this, so we check and emit a sensible error
message for this case. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
- {\r
- error ("array bound forbidden after parenthesized type-id");\r
- inform ("try removing the parentheses around the type-id");\r
+ {
+ error ("array bound forbidden after parenthesized type-id");
+ inform ("try removing the parentheses around the type-id");
cp_parser_direct_new_declarator (parser);
}
}
/* If it is not a `{', then we are looking at an
assignment-expression. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
- initializer
- = cp_parser_constant_expression (parser,
- /*allow_non_constant_p=*/true,
- non_constant_p);
+ {
+ initializer
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/true,
+ non_constant_p);
+ if (!*non_constant_p)
+ initializer = fold_non_dependent_expr (initializer);
+ }
else
{
/* Consume the `{' token. */
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
tree decl_arg_types;
+ tree fn_arg_types;
/* DECL might be a specialization of FN. */
The specialization f<int> is invalid but is not caught
by get_bindings below. */
- if (list_length (TYPE_ARG_TYPES (TREE_TYPE (fn)))
- != list_length (decl_arg_types))
+ fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ 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;
/* See whether this function might be a specialization of this
case INDIRECT_REF:
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:
return build_functional_cast
(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>
PR c++/14230
--- /dev/null
+// { 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);
+}
--- /dev/null
+// { 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 "" }