re PR c++/9127 (Confusing diagnostic on specialization not introduced by "template<>")
PR c++/9127 * cp-tree.h (at_namespace_scope_p): New function. * parser.c (cp_parser_class_head): Handle invalid explicit specializations. * search.c (at_namespace_scope_p): New function. PR c++/9127 * g++.dg/template/error6.C: New test. From-SVN: r74274
This commit is contained in:
parent
aedec8ddd2
commit
afb0918a9b
|
@ -5,6 +5,12 @@
|
||||||
|
|
||||||
2003-12-03 Mark Mitchell <mark@codesourcery.com>
|
2003-12-03 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/9127
|
||||||
|
* cp-tree.h (at_namespace_scope_p): New function.
|
||||||
|
* parser.c (cp_parser_class_head): Handle invalid explicit
|
||||||
|
specializations.
|
||||||
|
* search.c (at_namespace_scope_p): New function.
|
||||||
|
|
||||||
PR c++/13179
|
PR c++/13179
|
||||||
* semantics.c (finish_handler_parms): Do not call eh_type_info for
|
* semantics.c (finish_handler_parms): Do not call eh_type_info for
|
||||||
types used in templates.
|
types used in templates.
|
||||||
|
|
|
@ -3966,6 +3966,7 @@ extern void reinit_search_statistics (void);
|
||||||
extern tree current_scope (void);
|
extern tree current_scope (void);
|
||||||
extern int at_function_scope_p (void);
|
extern int at_function_scope_p (void);
|
||||||
extern bool at_class_scope_p (void);
|
extern bool at_class_scope_p (void);
|
||||||
|
extern bool at_namespace_scope_p (void);
|
||||||
extern tree context_for_name_lookup (tree);
|
extern tree context_for_name_lookup (tree);
|
||||||
extern tree lookup_conversions (tree);
|
extern tree lookup_conversions (tree);
|
||||||
extern tree binfo_for_vtable (tree);
|
extern tree binfo_for_vtable (tree);
|
||||||
|
|
|
@ -11584,6 +11584,7 @@ cp_parser_class_head (cp_parser* parser,
|
||||||
bool template_id_p = false;
|
bool template_id_p = false;
|
||||||
bool qualified_p = false;
|
bool qualified_p = false;
|
||||||
bool invalid_nested_name_p = false;
|
bool invalid_nested_name_p = false;
|
||||||
|
bool invalid_explicit_specialization_p = false;
|
||||||
unsigned num_templates;
|
unsigned num_templates;
|
||||||
|
|
||||||
/* Assume no nested-name-specifier will be present. */
|
/* Assume no nested-name-specifier will be present. */
|
||||||
|
@ -11732,12 +11733,31 @@ cp_parser_class_head (cp_parser* parser,
|
||||||
else if (invalid_nested_name_p)
|
else if (invalid_nested_name_p)
|
||||||
cp_parser_error (parser,
|
cp_parser_error (parser,
|
||||||
"qualified name does not name a class");
|
"qualified name does not name a class");
|
||||||
|
/* An explicit-specialization must be preceded by "template <>". If
|
||||||
|
it is not, try to recover gracefully. */
|
||||||
|
if (at_namespace_scope_p ()
|
||||||
|
&& parser->num_template_parameter_lists == 0
|
||||||
|
&& num_templates == 1)
|
||||||
|
{
|
||||||
|
error ("an explicit specialization must be preceded by 'template <>'");
|
||||||
|
invalid_explicit_specialization_p = true;
|
||||||
|
/* Take the same action that would have been taken by
|
||||||
|
cp_parser_explicit_specialization. */
|
||||||
|
++parser->num_template_parameter_lists;
|
||||||
|
begin_specialization ();
|
||||||
|
}
|
||||||
|
/* There must be no "return" statements between this point and the
|
||||||
|
end of this function; set "type "to the correct return value and
|
||||||
|
use "goto done;" to return. */
|
||||||
/* Make sure that the right number of template parameters were
|
/* Make sure that the right number of template parameters were
|
||||||
present. */
|
present. */
|
||||||
if (!cp_parser_check_template_parameters (parser, num_templates))
|
if (!cp_parser_check_template_parameters (parser, num_templates))
|
||||||
|
{
|
||||||
/* If something went wrong, there is no point in even trying to
|
/* If something went wrong, there is no point in even trying to
|
||||||
process the class-definition. */
|
process the class-definition. */
|
||||||
return NULL_TREE;
|
type = NULL_TREE;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* Look up the type. */
|
/* Look up the type. */
|
||||||
if (template_id_p)
|
if (template_id_p)
|
||||||
|
@ -11789,7 +11809,8 @@ cp_parser_class_head (cp_parser* parser,
|
||||||
{
|
{
|
||||||
error ("declaration of `%D' in `%D' which does not "
|
error ("declaration of `%D' in `%D' which does not "
|
||||||
"enclose `%D'", type, scope, nested_name_specifier);
|
"enclose `%D'", type, scope, nested_name_specifier);
|
||||||
return NULL_TREE;
|
type = NULL_TREE;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
/* [dcl.meaning]
|
/* [dcl.meaning]
|
||||||
|
|
||||||
|
@ -11848,6 +11869,12 @@ cp_parser_class_head (cp_parser* parser,
|
||||||
if (nested_name_specifier)
|
if (nested_name_specifier)
|
||||||
pop_scope (nested_name_specifier);
|
pop_scope (nested_name_specifier);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (invalid_explicit_specialization_p)
|
||||||
|
{
|
||||||
|
end_specialization ();
|
||||||
|
--parser->num_template_parameter_lists;
|
||||||
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -580,6 +580,16 @@ at_class_scope_p (void)
|
||||||
return cs && TYPE_P (cs);
|
return cs && TYPE_P (cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if the innermost active scope is a namespace scope. */
|
||||||
|
|
||||||
|
bool
|
||||||
|
at_namespace_scope_p (void)
|
||||||
|
{
|
||||||
|
/* We are in a namespace scope if we are not it a class scope or a
|
||||||
|
function scope. */
|
||||||
|
return !current_scope();
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the scope of DECL, as appropriate when doing name-lookup. */
|
/* Return the scope of DECL, as appropriate when doing name-lookup. */
|
||||||
|
|
||||||
tree
|
tree
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2003-12-03 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/9127
|
||||||
|
* g++.dg/template/error6.C: New test.
|
||||||
|
|
||||||
2003-12-03 Jakub Jelinek <jakub@redhat.com>
|
2003-12-03 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* gcc.dg/20031202-1.c: New test.
|
* gcc.dg/20031202-1.c: New test.
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
template<int n>
|
||||||
|
struct tento {
|
||||||
|
enum {value = 10*tento<n-1>::value};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct tento<0> { // { dg-error "" }
|
||||||
|
enum {value=1};
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
if (tento<4>::value != 10000) return -1;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue