+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
extern bool maybe_clone_body (tree);
/* in pt.c */
-extern void check_template_shadow (tree);
+extern bool check_template_shadow (tree);
extern tree get_innermost_template_args (tree, int);
extern void maybe_begin_member_template_processing (tree);
extern void maybe_end_member_template_processing (void);
&& TREE_TYPE (decl) == error_mark_node)
decl = TREE_VALUE (decl);
- check_template_shadow (decl);
+ if (!check_template_shadow (decl))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
/* [class.mem]
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
- 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)
{
tree olddecl;
/* If we're not in a template, we can't possibly shadow a template
parameter. */
if (!current_template_parms)
- return;
+ return true;
/* Figure out what we're shadowing. */
if (TREE_CODE (decl) == OVERLOAD)
/* If there's no previous binding for this name, we're not shadowing
anything, let alone a template parameter. */
if (!olddecl)
- return;
+ return true;
/* If we're not shadowing a template parameter, we're done. Note
that OLDDECL might be an OVERLOAD (or perhaps even an
ERROR_MARK), so we can't just blithely assume it to be a _DECL
node. */
if (!DECL_P (olddecl) || !DECL_TEMPLATE_PARM_P (olddecl))
- return;
+ return true;
/* We check for decl != olddecl to avoid bogus errors for using a
name inside a class. We check TPFI to avoid duplicate errors for
inline member templates. */
if (decl == olddecl
|| TEMPLATE_PARMS_FOR_INLINE (current_template_parms))
- return;
+ return true;
error ("declaration of %q+#D", decl);
error (" shadows template parm %q+#D", olddecl);
+ return false;
}
/* 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>
PR libfortran/36886
--- /dev/null
+// 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'" }
+};
template <class T10, int i> struct Xfour {// { dg-error "" } .*
int T10; // { dg-error "" } .*
void f(){
- char T10;
+ char T10; // { dg-error "error: declaration of 'char T10'" }
}
};
template <class U>
friend bool fooy(U u);
- template <class T161>
+ template <class T161> // { dg-error "error: declaration of 'class T161'" }
friend bool foo(T161 u)
{
- Xseven<T161, 5, int> obj; // { dg-error "" } .*
- return (obj.inst == u.inst); // { dg-error "" } .*
+ Xseven<T161, 5, int> obj;
+ return (obj.inst == u.inst);
}
};
template <typename T14, template <typename T15> class C12>// { dg-error "" } .*
class Xeighteen {
protected:
- C12<T14> value; // { dg-error "" }
+ C12<T14> value;
int C12; // { dg-error "" } .*
};
void
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> >'" }
}