Commit 157b0647 by Paolo Carlini Committed by Paolo Carlini

re PR c++/34485 (ICE with undefined type in template parameter)

/cp
2008-08-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/34485
	* pt.c (check_template_shadow): Change to return a bool.
	* name-lookup.c (push_class_level_binding): Early return if
	check_template_shadow returns false.
	* cp-tree.h (check_template_shadow): Adjust declaration.

/testsuite
2008-08-14  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/34485
	* g++.dg/template/crash81.C: New.
	* g++.old-deja/g++.benjamin/tem03.C: Adjust.
	* g++.old-deja/g++.benjamin/tem04.C: Likewise.
	* g++.old-deja/g++.brendan/crash7.C: Likewise.

From-SVN: r139114
parent c2b00cdc
2008-08-14 Paolo Carlini <paolo.carlini@oracle.com> 2008-08-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/34485
* pt.c (check_template_shadow): Change to return a bool.
* name-lookup.c (push_class_level_binding): Early return if
check_template_shadow returns false.
* cp-tree.h (check_template_shadow): Adjust declaration.
2008-08-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/34600 PR c++/34600
* decl.c (grokdeclarator): In case of extern and initializer, return * decl.c (grokdeclarator): In case of extern and initializer, return
error_mark_node after the error. error_mark_node after the error.
......
...@@ -4450,7 +4450,7 @@ extern tree locate_dtor (tree, void *); ...@@ -4450,7 +4450,7 @@ extern tree locate_dtor (tree, void *);
extern bool maybe_clone_body (tree); extern bool maybe_clone_body (tree);
/* in pt.c */ /* in pt.c */
extern void check_template_shadow (tree); extern bool check_template_shadow (tree);
extern tree get_innermost_template_args (tree, int); extern tree get_innermost_template_args (tree, int);
extern void maybe_begin_member_template_processing (tree); extern void maybe_begin_member_template_processing (tree);
extern void maybe_end_member_template_processing (void); extern void maybe_end_member_template_processing (void);
......
...@@ -2753,7 +2753,8 @@ push_class_level_binding (tree name, tree x) ...@@ -2753,7 +2753,8 @@ push_class_level_binding (tree name, tree x)
&& TREE_TYPE (decl) == error_mark_node) && TREE_TYPE (decl) == error_mark_node)
decl = TREE_VALUE (decl); decl = TREE_VALUE (decl);
check_template_shadow (decl); if (!check_template_shadow (decl))
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
/* [class.mem] /* [class.mem]
......
...@@ -2809,12 +2809,15 @@ expand_template_argument_pack (tree args) ...@@ -2809,12 +2809,15 @@ expand_template_argument_pack (tree args)
return result_args; return result_args;
} }
/* Complain if DECL shadows a template parameter. /* Checks if DECL shadows a template parameter.
[temp.local]: A template-parameter shall not be redeclared within its [temp.local]: A template-parameter shall not be redeclared within its
scope (including nested scopes). */ scope (including nested scopes).
void Emits an error and returns TRUE if the DECL shadows a parameter,
returns FALSE otherwise. */
bool
check_template_shadow (tree decl) check_template_shadow (tree decl)
{ {
tree olddecl; tree olddecl;
...@@ -2822,7 +2825,7 @@ check_template_shadow (tree decl) ...@@ -2822,7 +2825,7 @@ check_template_shadow (tree decl)
/* If we're not in a template, we can't possibly shadow a template /* If we're not in a template, we can't possibly shadow a template
parameter. */ parameter. */
if (!current_template_parms) if (!current_template_parms)
return; return true;
/* Figure out what we're shadowing. */ /* Figure out what we're shadowing. */
if (TREE_CODE (decl) == OVERLOAD) if (TREE_CODE (decl) == OVERLOAD)
...@@ -2832,24 +2835,25 @@ check_template_shadow (tree decl) ...@@ -2832,24 +2835,25 @@ check_template_shadow (tree decl)
/* If there's no previous binding for this name, we're not shadowing /* If there's no previous binding for this name, we're not shadowing
anything, let alone a template parameter. */ anything, let alone a template parameter. */
if (!olddecl) if (!olddecl)
return; return true;
/* If we're not shadowing a template parameter, we're done. Note /* If we're not shadowing a template parameter, we're done. Note
that OLDDECL might be an OVERLOAD (or perhaps even an that OLDDECL might be an OVERLOAD (or perhaps even an
ERROR_MARK), so we can't just blithely assume it to be a _DECL ERROR_MARK), so we can't just blithely assume it to be a _DECL
node. */ node. */
if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl)) if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl))
return; return true;
/* We check for decl != olddecl to avoid bogus errors for using a /* We check for decl != olddecl to avoid bogus errors for using a
name inside a class. We check TPFI to avoid duplicate errors for name inside a class. We check TPFI to avoid duplicate errors for
inline member templates. */ inline member templates. */
if (decl == olddecl if (decl == olddecl
|| TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) || TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
return; return true;
error ("declaration of %q+#D", decl); error ("declaration of %q+#D", decl);
error (" shadows template parm %q+#D", olddecl); error (" shadows template parm %q+#D", olddecl);
return false;
} }
/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL, /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL,
......
2008-08-14 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/34485
* g++.dg/template/crash81.C: New.
* g++.old-deja/g++.benjamin/tem03.C: Adjust.
* g++.old-deja/g++.benjamin/tem04.C: Likewise.
* g++.old-deja/g++.brendan/crash7.C: Likewise.
2008-08-14 Thomas Koenig <tkoenig@gcc.gnu.org> 2008-08-14 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libfortran/36886 PR libfortran/36886
......
// PR c++/34485
struct A
{
template<T::X> struct X; // { dg-error "error: 'T' has not been declared|error: declaration of 'template<int X> struct A::X'|error: shadows template parm 'int X'" }
};
...@@ -83,7 +83,7 @@ public: ...@@ -83,7 +83,7 @@ public:
template <class T10, int i> struct Xfour {// { dg-error "" } .* template <class T10, int i> struct Xfour {// { dg-error "" } .*
int T10; // { dg-error "" } .* int T10; // { dg-error "" } .*
void f(){ void f(){
char T10; char T10; // { dg-error "error: declaration of 'char T10'" }
} }
}; };
...@@ -123,11 +123,11 @@ public: ...@@ -123,11 +123,11 @@ public:
template <class U> template <class U>
friend bool fooy(U u); friend bool fooy(U u);
template <class T161> template <class T161> // { dg-error "error: declaration of 'class T161'" }
friend bool foo(T161 u) friend bool foo(T161 u)
{ {
Xseven<T161, 5, int> obj; // { dg-error "" } .* Xseven<T161, 5, int> obj;
return (obj.inst == u.inst); // { dg-error "" } .* return (obj.inst == u.inst);
} }
}; };
......
...@@ -91,7 +91,7 @@ public: ...@@ -91,7 +91,7 @@ public:
template <typename T14, template <typename T15> class C12>// { dg-error "" } .* template <typename T14, template <typename T15> class C12>// { dg-error "" } .*
class Xeighteen { class Xeighteen {
protected: protected:
C12<T14> value; // { dg-error "" } C12<T14> value;
int C12; // { dg-error "" } .* int C12; // { dg-error "" } .*
}; };
......
...@@ -44,5 +44,5 @@ void Sort<Comp>::sort (Vector<Comp::T> &v)// { dg-error "" } use of bad T ...@@ -44,5 +44,5 @@ void Sort<Comp>::sort (Vector<Comp::T> &v)// { dg-error "" } use of bad T
void void
f (Vector<int> &vi) f (Vector<int> &vi)
{ {
Sort<Comparator<int> >::sort (vi); Sort<Comparator<int> >::sort (vi); // { dg-error "error: 'sort' is not a member of 'Sort<Comparator<int> >'" }
} }
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