Commit b3445994 by Mark Mitchell Committed by Mark Mitchell

re PR c++/11493 (tree check ICE in error.c)

	* cp-tree.h (cp_id_kind): New type.
	(unqualified_name_lookup_error): Change prototype.
	(unqualified_fn_lookup_error): New function.
	(do_identifier): Remove.
	(do_scoped_id): Likewise.
	(tsubst_copy_and_build): Change prototype.
	(reregister_specialization): New function.
	(perform_koenig_lookup): Likewise.
	(finish_id_expression): Likewise.
	* call.c (build_method_call): Adjust call to
	unqualified_name_lookup_error.
	* decl.c (duplicate_decls): Use reregister_specialization.
	* lex.c (is_global): Remove.
	(unqualified_name_lookup_error): Return a value.
	(do_identifier): Remove.
	(do_scoped_id): Likewise.
	(identifier_typedecl_value): Remove.
	(unqualified_fn_lookup_error): New function.
	* parser.c (cp_parser_id_kind): Remove.
	(cp_parser_non_constant_id_expression): Remove.
	(cp_parser_primary_expression): Use finish_id_expression.
	(cp_parser_class_or_namespace_name): Use cp_id_kind, not
	cp_parser_id_kind.
	(cp_parser_postfix_expression): Use perform_koenig_lookup.
	(cp_parser_template_argument): Use cp_id_kind.
	(cp_parser_fold_non_dependent_expr): Adjust call to
	tsubst_copy_and_build.
	* pt.c (unregister_specialization): Rename to ...
	(reregister_specialization): This.
	(tsubst_friend_function): Use it.
	(maybe_fold_nontype_arg): Adjust call to tsubst_copy_and_build.
	(tsubst_qualified_id): Likewise.
	(tsubst_expr): Likewise.
	(tsubst_copy_and_build): Add function_p parameter.  Use
	finish_id_expression.  Introduce RECUR macro.
	(tsubst_non_call_postfix_expression): New function.
	(regenerate_decl_from_template): Use reregister_specialization.
	* semantics.c (perform_koenig_lookup): New function.
	(finish_id_expression): Likewise.

	PR c++/11493
	PR c++/11495
	* g++.dg/parse/template9.C: Likewise.
	* g++.dg/template/crash4.C: New test.
	* g++.dg/template/koenig1.C: Likewise.
	* g++.old-deja/g++.benjamin/tem03.C: Adjust error markers.
	* g++.old-deja/g++.benjamin/tem06.C: Declare "x".
	* g++.old-deja/g++.jason/overload33.C: Use this-> when calling
	functions.
	* g++.old-deja/g++.jason/template36.C: Likewise.
	* g++.old-deja/g++.mike/p1989.C: Likewise.
	* g++.old-deja/g++.pt/lookup2.C: Use -fpermissive when compiling.
	* g++.old-deja/g++.pt/ttp20.C: Use this->.
	* g++.old-deja/g++.pt/ttp21.C: Use this->.
	* g++.old-deja/g++.pt/typename13.C: Use -fpermissive when
	compiling.
	* g++.old-deja/g++.pt/union2.C: Use this->.

From-SVN: r69316
parent f2ffecb1
2003-07-13 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (cp_id_kind): New type.
(unqualified_name_lookup_error): Change prototype.
(unqualified_fn_lookup_error): New function.
(do_identifier): Remove.
(do_scoped_id): Likewise.
(tsubst_copy_and_build): Change prototype.
(reregister_specialization): New function.
(perform_koenig_lookup): Likewise.
(finish_id_expression): Likewise.
* call.c (build_method_call): Adjust call to
unqualified_name_lookup_error.
* decl.c (duplicate_decls): Use reregister_specialization.
* lex.c (is_global): Remove.
(unqualified_name_lookup_error): Return a value.
(do_identifier): Remove.
(do_scoped_id): Likewise.
(identifier_typedecl_value): Remove.
(unqualified_fn_lookup_error): New function.
* parser.c (cp_parser_id_kind): Remove.
(cp_parser_non_constant_id_expression): Remove.
(cp_parser_primary_expression): Use finish_id_expression.
(cp_parser_class_or_namespace_name): Use cp_id_kind, not
cp_parser_id_kind.
(cp_parser_postfix_expression): Use perform_koenig_lookup.
(cp_parser_template_argument): Use cp_id_kind.
(cp_parser_fold_non_dependent_expr): Adjust call to
tsubst_copy_and_build.
* pt.c (unregister_specialization): Rename to ...
(reregister_specialization): This.
(tsubst_friend_function): Use it.
(maybe_fold_nontype_arg): Adjust call to tsubst_copy_and_build.
(tsubst_qualified_id): Likewise.
(tsubst_expr): Likewise.
(tsubst_copy_and_build): Add function_p parameter. Use
finish_id_expression. Introduce RECUR macro.
(tsubst_non_call_postfix_expression): New function.
(regenerate_decl_from_template): Use reregister_specialization.
* semantics.c (perform_koenig_lookup): New function.
(finish_id_expression): Likewise.
2003-07-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net> 2003-07-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
* pt.c (push_access_scope_real): Remove. * pt.c (push_access_scope_real): Remove.
......
...@@ -423,10 +423,7 @@ build_method_call (tree instance, tree name, tree parms, ...@@ -423,10 +423,7 @@ build_method_call (tree instance, tree name, tree parms,
/* If the name could not be found, issue an error. */ /* If the name could not be found, issue an error. */
if (!fn) if (!fn)
{ return unqualified_name_lookup_error (name);
unqualified_name_lookup_error (name);
return error_mark_node;
}
if (BASELINK_P (fn) && has_template_args) if (BASELINK_P (fn) && has_template_args)
BASELINK_FUNCTIONS (fn) BASELINK_FUNCTIONS (fn)
......
...@@ -350,6 +350,20 @@ struct tree_wrapper GTY(()) ...@@ -350,6 +350,20 @@ struct tree_wrapper GTY(())
struct z_candidate *z_c; struct z_candidate *z_c;
}; };
/* The different kinds of ids that we ecounter. */
typedef enum cp_id_kind
{
/* Not an id at all. */
CP_ID_KIND_NONE,
/* An unqualified-id that is not a template-id. */
CP_ID_KIND_UNQUALIFIED,
/* An unqualified template-id. */
CP_ID_KIND_TEMPLATE_ID,
/* A qualified-id. */
CP_ID_KIND_QUALIFIED
} cp_id_kind;
/* Macros for access to language-specific slots in an identifier. */ /* Macros for access to language-specific slots in an identifier. */
#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \
...@@ -3883,10 +3897,8 @@ extern void snarf_method (tree); ...@@ -3883,10 +3897,8 @@ extern void snarf_method (tree);
extern void note_got_semicolon (tree); extern void note_got_semicolon (tree);
extern void note_list_got_semicolon (tree); extern void note_list_got_semicolon (tree);
extern void see_typename (void); extern void see_typename (void);
extern void unqualified_name_lookup_error (tree); extern tree unqualified_name_lookup_error (tree);
extern tree do_identifier (tree, tree); extern tree unqualified_fn_lookup_error (tree);
extern tree do_scoped_id (tree, tree);
extern tree identifier_typedecl_value (tree);
extern tree build_lang_decl (enum tree_code, tree, tree); extern tree build_lang_decl (enum tree_code, tree, tree);
extern void retrofit_lang_decl (tree); extern void retrofit_lang_decl (tree);
extern tree copy_decl (tree); extern tree copy_decl (tree);
...@@ -3963,7 +3975,7 @@ extern tree most_specialized_instantiation (tree); ...@@ -3963,7 +3975,7 @@ extern tree most_specialized_instantiation (tree);
extern void print_candidates (tree); extern void print_candidates (tree);
extern int instantiate_pending_templates (void); extern int instantiate_pending_templates (void);
extern tree tsubst_default_argument (tree, tree, tree); extern tree tsubst_default_argument (tree, tree, tree);
extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree); extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool);
extern tree most_general_template (tree); extern tree most_general_template (tree);
extern tree get_mostly_instantiated_function_type (tree); extern tree get_mostly_instantiated_function_type (tree);
extern int problematic_instantiation_changed (void); extern int problematic_instantiation_changed (void);
...@@ -3982,6 +3994,7 @@ extern tree resolve_typename_type (tree, bool); ...@@ -3982,6 +3994,7 @@ extern tree resolve_typename_type (tree, bool);
extern tree template_for_substitution (tree); extern tree template_for_substitution (tree);
extern tree build_non_dependent_expr (tree); extern tree build_non_dependent_expr (tree);
extern tree build_non_dependent_args (tree); extern tree build_non_dependent_args (tree);
extern bool reregister_specialization (tree, tree, tree);
/* in repo.c */ /* in repo.c */
extern void repo_template_used (tree); extern void repo_template_used (tree);
...@@ -4111,6 +4124,7 @@ extern tree finish_parenthesized_expr (tree); ...@@ -4111,6 +4124,7 @@ extern tree finish_parenthesized_expr (tree);
extern tree finish_non_static_data_member (tree, tree); extern tree finish_non_static_data_member (tree, tree);
extern tree begin_stmt_expr (void); extern tree begin_stmt_expr (void);
extern tree finish_stmt_expr (tree); extern tree finish_stmt_expr (tree);
extern tree perform_koenig_lookup (tree, tree);
extern tree finish_call_expr (tree, tree, bool); extern tree finish_call_expr (tree, tree, bool);
extern tree finish_increment_expr (tree, enum tree_code); extern tree finish_increment_expr (tree, enum tree_code);
extern tree finish_this_expr (void); extern tree finish_this_expr (void);
...@@ -4133,6 +4147,10 @@ extern tree finish_template_type (tree, tree, int); ...@@ -4133,6 +4147,10 @@ extern tree finish_template_type (tree, tree, int);
extern tree finish_base_specifier (tree, tree, bool); extern tree finish_base_specifier (tree, tree, bool);
extern void finish_member_declaration (tree); extern void finish_member_declaration (tree);
extern void check_multiple_declarators (void); extern void check_multiple_declarators (void);
extern tree finish_id_expression (tree, tree, tree,
cp_id_kind *, tree *,
bool, bool, bool *,
const char **);
extern tree finish_typeof (tree); extern tree finish_typeof (tree);
extern tree finish_sizeof (tree); extern tree finish_sizeof (tree);
extern tree finish_alignof (tree); extern tree finish_alignof (tree);
......
...@@ -3558,36 +3558,30 @@ duplicate_decls (tree newdecl, tree olddecl) ...@@ -3558,36 +3558,30 @@ duplicate_decls (tree newdecl, tree olddecl)
function_size - sizeof (struct tree_common)); function_size - sizeof (struct tree_common));
if (DECL_TEMPLATE_INSTANTIATION (newdecl)) if (DECL_TEMPLATE_INSTANTIATION (newdecl))
{ /* If newdecl is a template instantiation, it is possible that
/* If newdecl is a template instantiation, it is possible that the following sequence of events has occurred:
the following sequence of events has occurred:
o A friend function was declared in a class template. The
o A friend function was declared in a class template. The class template was instantiated.
class template was instantiated.
o The instantiation of the friend declaration was
o The instantiation of the friend declaration was recorded on the instantiation list, and is newdecl.
recorded on the instantiation list, and is newdecl.
o Later, however, instantiate_class_template called pushdecl
o Later, however, instantiate_class_template called pushdecl on the newdecl to perform name injection. But, pushdecl in
on the newdecl to perform name injection. But, pushdecl in turn called duplicate_decls when it discovered that another
turn called duplicate_decls when it discovered that another declaration of a global function with the same name already
declaration of a global function with the same name already existed.
existed.
o Here, in duplicate_decls, we decided to clobber newdecl.
o Here, in duplicate_decls, we decided to clobber newdecl.
If we're going to do that, we'd better make sure that
If we're going to do that, we'd better make sure that olddecl, and not newdecl, is on the list of
olddecl, and not newdecl, is on the list of instantiations so that if we try to do the instantiation
instantiations so that if we try to do the instantiation again we won't get the clobbered declaration. */
again we won't get the clobbered declaration. */ reregister_specialization (newdecl,
DECL_TI_TEMPLATE (newdecl),
tree tmpl = DECL_TI_TEMPLATE (newdecl); olddecl);
tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
for (; decls; decls = TREE_CHAIN (decls))
if (TREE_VALUE (decls) == newdecl)
TREE_VALUE (decls) = olddecl;
}
} }
else else
{ {
......
...@@ -49,7 +49,6 @@ static void handle_pragma_interface (cpp_reader *); ...@@ -49,7 +49,6 @@ static void handle_pragma_interface (cpp_reader *);
static void handle_pragma_implementation (cpp_reader *); static void handle_pragma_implementation (cpp_reader *);
static void handle_pragma_java_exceptions (cpp_reader *); static void handle_pragma_java_exceptions (cpp_reader *);
static int is_global (tree);
static void init_operators (void); static void init_operators (void);
static void copy_lang_type (tree); static void copy_lang_type (tree);
...@@ -662,30 +661,10 @@ handle_pragma_java_exceptions (cpp_reader* dfile ATTRIBUTE_UNUSED ) ...@@ -662,30 +661,10 @@ handle_pragma_java_exceptions (cpp_reader* dfile ATTRIBUTE_UNUSED )
choose_personality_routine (lang_java); choose_personality_routine (lang_java);
} }
/* Return true if d is in a global scope. */
static int
is_global (tree d)
{
while (1)
switch (TREE_CODE (d))
{
case ERROR_MARK:
return 1;
case OVERLOAD: d = OVL_FUNCTION (d); continue;
case TREE_LIST: d = TREE_VALUE (d); continue;
default:
my_friendly_assert (DECL_P (d), 980629);
return DECL_NAMESPACE_SCOPE_P (d);
}
}
/* Issue an error message indicating that the lookup of NAME (an /* Issue an error message indicating that the lookup of NAME (an
IDENTIFIER_NODE) failed. */ IDENTIFIER_NODE) failed. Returns the ERROR_MARK_NODE. */
void tree
unqualified_name_lookup_error (tree name) unqualified_name_lookup_error (tree name)
{ {
if (IDENTIFIER_OPNAME_P (name)) if (IDENTIFIER_OPNAME_P (name))
...@@ -714,164 +693,43 @@ unqualified_name_lookup_error (tree name) ...@@ -714,164 +693,43 @@ unqualified_name_lookup_error (tree name)
SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node); SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node);
SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl); SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl);
} }
}
tree
do_identifier (register tree token, tree args)
{
register tree id;
timevar_push (TV_NAME_LOOKUP);
id = lookup_name (token, 0);
/* Do Koenig lookup if appropriate (inside templates we build lookup
expressions instead).
[basic.lookup.koenig]: If the ordinary unqualified lookup of the name
finds the declaration of a class member function, the associated
namespaces and classes are not considered. */
if (args && !current_template_parms && (!id || is_global (id)))
id = lookup_arg_dependent (token, id, args);
if (id == error_mark_node)
{
/* lookup_name quietly returns error_mark_node if we're parsing,
as we don't want to complain about an identifier that ends up
being used as a declarator. So we call it again to get the error
message. */
id = lookup_name (token, 0);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
if (!id || (TREE_CODE (id) == FUNCTION_DECL return error_mark_node;
&& DECL_ANTICIPATED (id)))
{
if (current_template_parms)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
build_min_nt (LOOKUP_EXPR, token));
else if (IDENTIFIER_TYPENAME_P (token))
/* A templated conversion operator might exist. */
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, token);
else
{
unqualified_name_lookup_error (token);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
}
id = check_for_out_of_scope_variable (id);
/* TREE_USED is set in `hack_identifier'. */
if (TREE_CODE (id) == CONST_DECL)
{
/* Check access. */
if (IDENTIFIER_CLASS_VALUE (token) == id)
perform_or_defer_access_check (TYPE_BINFO (DECL_CONTEXT (id)), id);
if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
id = DECL_INITIAL (id);
}
else
id = hack_identifier (id, token);
/* We must look up dependent names when the template is
instantiated, not while parsing it. For now, we don't
distinguish between dependent and independent names. So, for
example, we look up all overloaded functions at
instantiation-time, even though in some cases we should just use
the DECL we have here. We also use LOOKUP_EXPRs to find things
like local variables, rather than creating TEMPLATE_DECLs for the
local variables and then finding matching instantiations. */
if (current_template_parms
&& (is_overloaded_fn (id)
|| (TREE_CODE (id) == VAR_DECL
&& CP_DECL_CONTEXT (id)
&& TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
|| TREE_CODE (id) == PARM_DECL
|| TREE_CODE (id) == RESULT_DECL
|| TREE_CODE (id) == USING_DECL))
id = build_min_nt (LOOKUP_EXPR, token);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id);
} }
/* Like unqualified_name_lookup_error, but NAME is an unqualified-id
used as a function. Returns an appropriate expression for
NAME. */
tree tree
do_scoped_id (tree token, tree id) unqualified_fn_lookup_error (tree name)
{ {
timevar_push (TV_NAME_LOOKUP);
if (!id || (TREE_CODE (id) == FUNCTION_DECL
&& DECL_ANTICIPATED (id)))
{
if (processing_template_decl)
{
id = build_min_nt (LOOKUP_EXPR, token);
LOOKUP_EXPR_GLOBAL (id) = 1;
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id);
}
if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
error ("`::%D' undeclared (first use here)", token);
id = error_mark_node;
/* Prevent repeated error messages. */
SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
}
else
{
if (TREE_CODE (id) == ADDR_EXPR)
mark_used (TREE_OPERAND (id, 0));
else if (TREE_CODE (id) != OVERLOAD)
mark_used (id);
}
if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
{
/* XXX CHS - should we set TREE_USED of the constant? */
id = DECL_INITIAL (id);
/* This is to prevent an enum whose value is 0
from being considered a null pointer constant. */
id = build1 (NOP_EXPR, TREE_TYPE (id), id);
TREE_CONSTANT (id) = 1;
}
if (processing_template_decl) if (processing_template_decl)
{ {
if (is_overloaded_fn (id)) /* In a template, it is invalid to write "f()" or "f(3)" if no
declaration of "f" is available. Historically, G++ and most
other compilers accepted that usage; explain to the user what
is going wrong. */
(flag_permissive ? warning : error)
("there are no arguments to `%D' that depend on a template "
"parameter, so a declaration of `%D' must be available", name,
name);
if (!flag_permissive)
{ {
id = build_min_nt (LOOKUP_EXPR, token); static bool hint;
LOOKUP_EXPR_GLOBAL (id) = 1; if (!hint)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id); {
error ("(if you use `-fpermissive', G++ will accept your code, "
"but allowing the use of an undeclared name is "
"deprecated)");
hint = true;
}
} }
/* else just use the decl */ return build_min_nt (LOOKUP_EXPR, name);
} }
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, convert_from_reference (id));
}
tree
identifier_typedecl_value (tree node)
{
tree t, type;
type = IDENTIFIER_TYPE_VALUE (node);
if (type == NULL_TREE)
return NULL_TREE;
if (IDENTIFIER_BINDING (node))
{
t = IDENTIFIER_VALUE (node);
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
return t;
}
if (IDENTIFIER_NAMESPACE_VALUE (node))
{
t = IDENTIFIER_NAMESPACE_VALUE (node);
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
return t;
}
/* Will this one ever happen? */
if (TYPE_MAIN_DECL (type))
return TYPE_MAIN_DECL (type);
/* We used to do an internal error of 62 here, but instead we will return unqualified_name_lookup_error (name);
handle the return of a null appropriately in the callers. */
return NULL_TREE;
} }
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
......
2003-07-13 Mark Mitchell <mark@codesourcery.com>
PR c++/11493
PR c++/11495
* g++.dg/parse/template9.C: Likewise.
* g++.dg/template/crash4.C: New test.
* g++.dg/template/koenig1.C: Likewise.
* g++.old-deja/g++.benjamin/tem03.C: Adjust error markers.
* g++.old-deja/g++.benjamin/tem06.C: Declare "x".
* g++.old-deja/g++.jason/overload33.C: Use this-> when calling
functions.
* g++.old-deja/g++.jason/template36.C: Likewise.
* g++.old-deja/g++.mike/p1989.C: Likewise.
* g++.old-deja/g++.pt/lookup2.C: Use -fpermissive when compiling.
* g++.old-deja/g++.pt/ttp20.C: Use this->.
* g++.old-deja/g++.pt/ttp21.C: Use this->.
* g++.old-deja/g++.pt/typename13.C: Use -fpermissive when
compiling.
* g++.old-deja/g++.pt/union2.C: Use this->.
2003-07-11 Jakub Jelinek <jakub@redhat.com> 2003-07-11 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/20030711-1.c: New test. * gcc.dg/20030711-1.c: New test.
......
template <typename T>
void f() {
g(); // { dg-error "" }
h(3); // { dg-error "" }
}
namespace NS {
struct C {};
void foo();
}
template <class T> struct X {};
template <class T> struct A {
A() { foo (X<T>()); }
void foo(X<T>);
};
template struct A<NS::C>;
namespace NS {
struct C {};
void foo(C);
}
template <class T> void bar() { T t; foo (t); }
template void bar<NS::C> ();
...@@ -195,7 +195,7 @@ struct Xthirteen { ...@@ -195,7 +195,7 @@ struct Xthirteen {
if (local_value > value) // { dg-error "" } .* if (local_value > value) // { dg-error "" } .*
return local_value; return local_value;
else else
return value; // { dg-error "" } .* return value;
} }
}; };
......
...@@ -14,6 +14,8 @@ public: ...@@ -14,6 +14,8 @@ public:
friend void x (const T &) { } friend void x (const T &) { }
}; };
void x(const int &);
template<class T> template<class T>
void blah (const T &) { void blah (const T &) {
T y; T y;
......
...@@ -58,10 +58,10 @@ class SmartPtr : public ConstSmartPtr<T> ...@@ -58,10 +58,10 @@ class SmartPtr : public ConstSmartPtr<T>
: ConstSmartPtr<T>(theItem) {} : ConstSmartPtr<T>(theItem) {}
T* item() const T* item() const
{ return _item(); } { return this->_item(); }
operator T*() const operator T*() const
{ return _item(); } { return this->_item(); }
}; };
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
......
...@@ -33,7 +33,7 @@ public: ...@@ -33,7 +33,7 @@ public:
int base::* g (); int base::* g ();
int zowee() const int zowee() const
{ return bar(); } { return this->bar(); }
}; };
template <class T> template <class T>
......
...@@ -195,8 +195,8 @@ template<class T> ...@@ -195,8 +195,8 @@ template<class T>
Pix Pix
List_DLS<T>::search(const T& item) const List_DLS<T>::search(const T& item) const
{ {
for (Pix x=first(); 0 != x; next(x)) { for (Pix x=this->first(); 0 != x; this->next(x)) {
if (item == operator()(x)) // { dg-error "" } const subversion if (item == this->operator()(x)) // { dg-error "" } const subversion
return x; return x;
} }
return 0; return 0;
...@@ -223,8 +223,8 @@ template<class T> ...@@ -223,8 +223,8 @@ template<class T>
bool bool
List_DLSp<T>::contains(const T& item) const List_DLSp<T>::contains(const T& item) const
{ {
for (Pix x=first(); 0 != x; next(x)) { for (Pix x=this->first(); 0 != x; this->next(x)) {
if (*item == *operator()(x)) if (*item == *(this->operator()(x)))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
......
// { dg-do assemble } // { dg-do assemble }
// { dg-options "" } // { dg-options "-fpermissive" }
class A class A
{ {
...@@ -15,6 +15,6 @@ protected: ...@@ -15,6 +15,6 @@ protected:
template <class T> class D : private B<T> template <class T> class D : private B<T>
{ {
public: public:
void f2() { f1(); }; void f2() { f1(); }; // { dg-warning "" }
}; };
...@@ -18,7 +18,7 @@ template<template<class> class D,class E> class C : D<E> ...@@ -18,7 +18,7 @@ template<template<class> class D,class E> class C : D<E>
template<template<class> class D,class E> int C<D,E>::g() template<template<class> class D,class E> int C<D,E>::g()
{ {
return f(); return this->f();
} }
int main() int main()
......
...@@ -18,13 +18,13 @@ template<template<class> class D,class E> class C : D<E> ...@@ -18,13 +18,13 @@ template<template<class> class D,class E> class C : D<E>
template<template<class> class D,class E> int C<D,E>::g() template<template<class> class D,class E> int C<D,E>::g()
{ {
return f(); return this->f();
} }
class E : C<D,int> class E : C<D,int>
{ {
public: public:
int h() { return g(); } int h() { return this->g(); }
}; };
int main() int main()
......
// { dg-do assemble } // { dg-do assemble }
// { dg-options "" } // { dg-options "-fpermissive" }
template <class T> template <class T>
struct B struct B
...@@ -18,7 +18,7 @@ struct D : public B<T> ...@@ -18,7 +18,7 @@ struct D : public B<T>
template <class T> template <class T>
void D<T>::f() void D<T>::f()
{ {
I(); I(); // { dg-warning "" }
} }
......
...@@ -12,7 +12,7 @@ protected: ...@@ -12,7 +12,7 @@ protected:
}; };
template<class T> struct vector : public vector_base<T> { template<class T> struct vector : public vector_base<T> {
vector () { def_basep (); } vector () { this->def_basep (); }
}; };
vector<int> iv; vector<int> iv;
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