PR c++/26938
* cp-tree.h (redeclare_class_template): Adjust declaration
to return bool instead of void.
* pt.c (redeclare_class_template): Update definition. Return
false on error.
* decl.c (xref_tag): Return error_mark_node if redeclare_class_template
returned false.
* g++.dg/template/crash58.C: New test.
* g++.dg/template/crash59.C: New test.
* g++.dg/parse/crash28.C: Adjust error markers.
* g++.dg/template/crash34.C: Likewise.
* g++.dg/template/friend31.C: Likewise.
* g++.dg/template/crash32.C: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117205
138bc75d-0d04-0410-961f-
82ee72b054a4
+2006-09-25 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/27329
+ PR c++/26938
+ * cp-tree.h (redeclare_class_template): Adjust declaration
+ to return bool instead of void.
+ * pt.c (redeclare_class_template): Update definition.
+ Return false on error.
+ * decl.c (xref_tag): Return error_mark_node if
+ redeclare_class_template returned false.
+
2006-09-21 Mark Mitchell <mark@codesourcery.com>
PR c++/29016
extern void end_template_decl (void);
extern tree push_template_decl (tree);
extern tree push_template_decl_real (tree, bool);
-extern void redeclare_class_template (tree, tree);
+extern bool redeclare_class_template (tree, tree);
extern tree lookup_template_class (tree, tree, tree, tree,
int, tsubst_flags_t);
extern tree lookup_template_function (tree, tree);
else
{
if (template_header_p && IS_AGGR_TYPE (t))
- redeclare_class_template (t, current_template_parms);
+ {
+ if (!redeclare_class_template (t, current_template_parms))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ }
else if (!processing_template_decl
&& CLASS_TYPE_P (t)
&& CLASSTYPE_IS_TEMPLATE (t))
template <class T> struct S;
template <class T> struct S {}; */
-void
+bool
redeclare_class_template (tree type, tree parms)
{
tree tmpl;
if (!TYPE_TEMPLATE_INFO (type))
{
error ("%qT is not a template type", type);
- return;
+ return false;
}
tmpl = TYPE_TI_TEMPLATE (type);
/* The type is nested in some template class. Nothing to worry
about here; there are no new template parameters for the nested
type. */
- return;
+ return true;
if (!parms)
{
error ("template specifiers not specified in declaration of %qD",
tmpl);
- return;
+ return false;
}
parms = INNERMOST_TEMPLATE_PARMS (parms);
error ("used %d template parameter(s) instead of %d",
TREE_VEC_LENGTH (tmpl_parms),
TREE_VEC_LENGTH (parms));
- return;
+ return false;
}
for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i)
{
error ("template parameter %q+#D", tmpl_parm);
error ("redeclared here as %q#D", parm);
- return;
+ return false;
}
if (tmpl_default != NULL_TREE && parm_default != NULL_TREE)
by two different declarations in the same scope. */
error ("redefinition of default argument for %q#D", parm);
error ("%J original definition appeared here", tmpl_parm);
- return;
+ return false;
}
if (parm_default != NULL_TREE)
parameters for any members. */
TREE_PURPOSE (TREE_VEC_ELT (parms, i)) = tmpl_default;
}
+
+ return true;
}
/* Simplify EXPR if it is a non-dependent expression. Returns the
+2006-09-25 Lee Millward <lee.millward@codesourcery.com>
+
+ PR c++/26938
+ * g++.dg/template/crash58.C: New test.
+ * g++.dg/parse/crash28.C: Adjust error markers.
+ * g++.dg/template/crash34.C: Likewise.
+ * g++.dg/template/friend31.C: Likewise.
+ * g++.dg/template/crash32.C: Likewise.
+
+ PR c++/27329
+ * g++.dg/template/crash59.C: New test.
+
2006-09-24 Zdenek Dvorak <dvorakz@suse.cz>
Adam Nemet <anemet@caviumnetworks.com>
template <class _Tp> class insert_iterator<slist<_Tp> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
template <class _Value> class insert_iterator<int > { // { dg-error "template" }
- hash_set<_Value>; // { dg-error "no type|expected" }
+ hash_set<_Value>;
};
template<int> struct A<X<> > {}; // { dg-error "not a template|not declared in this scope|expected unqualified-id|extra" }
struct integral_constant { };
template<typename _Tp>
-struct is_function : public integral_constant { }; // { dg-error "previous" }
+struct is_function : public integral_constant { };
template<>
struct is_function : public integral_constant { }; // { dg-error "" }
template <typename T> class Foo { }; // { dg-error "not a template type" }
-Foo<int> x; // { dg-error "not a template" }
+Foo<int> x; // { dg-error "not a template|incomplete type" }
--- /dev/null
+//PR 26938
+
+template<int, int = 0> struct A; // { dg-error "previous declaration" }
+
+template<int> struct A // { dg-error "template" }
+{
+ A();
+};
+
+A<0> a; // { dg-error "incomplete type" }
--- /dev/null
+//PR c++/27329
+
+template<int> struct A // { dg-error "forward declaration" }
+! // { dg-error "expected unqualified-id" }
+ ;
+
+template<int> struct A { int foo(); }; // { dg-error "not a template" }
+
+int i = A<0>().foo(); // { dg-error "not a template|invalid use" }
+
+
+template<int> struct B
+! // { dg-error "expected unqualified-id" }
+ ;
+
+template<int> struct B { static int bar(); }; // { dg-error "not a template" }
+
+int j = B<0>::bar(); // { dg-error "not a template|incomplete type" }
+
class W
{
template<int i> friend class F; // { dg-error "template parameter" }
- int x;
+ int x; // { dg-error "private" }
};
template <typename T, typename U> struct F
{
- void Look(W& w) { w.x = 3; }
+ void Look(W& w) { w.x = 3; } // { dg-error "within this context" }
};
int main()