mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-10 11:59:58 +08:00
* semantics.c (begin_class_definition): Robustify.
From-SVN: r42937
This commit is contained in:
parent
1b577f5a58
commit
47ee89044d
@ -1,5 +1,7 @@
|
|||||||
2001-06-05 Mark Mitchell <mark@codesourcery.com>
|
2001-06-05 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
|
* semantics.c (begin_class_definition): Robustify.
|
||||||
|
|
||||||
* pt.c (instantiate_decl): Tell the repository code about the
|
* pt.c (instantiate_decl): Tell the repository code about the
|
||||||
clones, not the cloned functions.
|
clones, not the cloned functions.
|
||||||
* repo.c (repo_template_used): Explicitly instantiate the cloned
|
* repo.c (repo_template_used): Explicitly instantiate the cloned
|
||||||
|
@ -1724,18 +1724,29 @@ begin_class_definition (t)
|
|||||||
cp_error ("definition of `%#T' inside template parameter list", t);
|
cp_error ("definition of `%#T' inside template parameter list", t);
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
if (t == error_mark_node
|
|
||||||
|| ! IS_AGGR_TYPE (t))
|
/* In a definition of a member class template, we will get here with
|
||||||
|
an implicit typename. */
|
||||||
|
if (IMPLICIT_TYPENAME_P (t))
|
||||||
|
t = TREE_TYPE (t);
|
||||||
|
/* A non-implicit typename comes from code like:
|
||||||
|
|
||||||
|
template <typename T> struct A {
|
||||||
|
template <typename U> struct A<T>::B ...
|
||||||
|
|
||||||
|
This is erroneous. */
|
||||||
|
else if (TREE_CODE (t) == TYPENAME_TYPE)
|
||||||
|
{
|
||||||
|
cp_error ("invalid definition of qualified type `%T'", t);
|
||||||
|
t = error_mark_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t == error_mark_node || ! IS_AGGR_TYPE (t))
|
||||||
{
|
{
|
||||||
t = make_aggr_type (RECORD_TYPE);
|
t = make_aggr_type (RECORD_TYPE);
|
||||||
pushtag (make_anon_name (), t, 0);
|
pushtag (make_anon_name (), t, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In a definition of a member class template, we will get here with an
|
|
||||||
implicit typename, a TYPENAME_TYPE with a type. */
|
|
||||||
if (TREE_CODE (t) == TYPENAME_TYPE)
|
|
||||||
t = TREE_TYPE (t);
|
|
||||||
|
|
||||||
/* If we generated a partial instantiation of this type, but now
|
/* If we generated a partial instantiation of this type, but now
|
||||||
we're seeing a real definition, we're actually looking at a
|
we're seeing a real definition, we're actually looking at a
|
||||||
partial specialization. Consider:
|
partial specialization. Consider:
|
||||||
|
10
gcc/testsuite/g++.old-deja/g++.pt/memtemp99.C
Normal file
10
gcc/testsuite/g++.old-deja/g++.pt/memtemp99.C
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// Build don't link:
|
||||||
|
// Origin: bitti@cs.tut.fi
|
||||||
|
|
||||||
|
template<typename T, unsigned int N>
|
||||||
|
class Vector
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<unsigned int I>
|
||||||
|
class Vector<T,N>::CommaInit { }; // ERROR - invalid definition
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user