This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[C++ PATCH]: Fix 19497


This patch fixes 19497, a bug where we can do some checking at parse time, rather than instantiation. In

	template<int> struct A
	{
	    A::A;
	};

The 'A::A' is parsed as an access declaration for a member 'A' of base 'A'. We spot that when instantiating the template, but not during parsing, even though nothing could ever possibly match.

In fixing this, I found we also permitted
	struct B { void f ();
		using B::f;
	};
which we shouldn't.

This patch fixes things up to do as much checking as possible as soon as the using decl is parsed. I'm not going to fix this on 4.0, as even though it is a regression, it is a minor one -- we still diagnose it at instantiation time.

booted & tested on i686-pc-linux-gnu.

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2005-06-08  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/19497
	* cp-tree.def (USING_DECL): Update documentation.
	* cp-tree.h (DECL_DEPENDENT_P): New.
	(USING_DECL_DECLS, USING_DECL_SCOPE): New.
	* class.c (handle_using_decl): Move most of the processing to ...
	* name-lookup.c (do_class_using_decl): ... here.  Make stricter.
	(push_using_decl): Use USING_DECL_SCOPE.
	(cp_emit_debug_info_for_using): Make extern.
	* cxx-pretty-print.c (pp_cxx_statement) <USING_DECL case>: Adjust.
	* name-lookup.h (cp_emit_debug_info_for_using): Declare.
	* pt.c (tsubst_decl) <USING_DECL case>: Use do_class_using_decl
	when tsubsting.
	(tsubst_expr): Use USING_DECL_SCOPE.
	* search.c (lookup_field_1): Use DECL_DEPENDENT_P.
	* semantics.c (finish_member_declaration): Likewise.

2005-06-08  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/19497
	* g++.dg/inherit/using5.C: New.
	* g++.dg/inherit/using6.C: New.

Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.719
diff -c -3 -p -r1.719 class.c
*** cp/class.c	6 Jun 2005 14:18:04 -0000	1.719
--- cp/class.c	8 Jun 2005 11:33:28 -0000
*************** alter_access (tree t, tree fdecl, tree a
*** 1119,1171 ****
  static void
  handle_using_decl (tree using_decl, tree t)
  {
!   tree ctype = DECL_INITIAL (using_decl);
    tree name = DECL_NAME (using_decl);
    tree access
      = TREE_PRIVATE (using_decl) ? access_private_node
      : TREE_PROTECTED (using_decl) ? access_protected_node
      : access_public_node;
-   tree fdecl, binfo;
    tree flist = NULL_TREE;
    tree old_value;
  
!   if (ctype == error_mark_node)
!     return;
! 
!   binfo = lookup_base (t, ctype, ba_any, NULL);
!   if (! binfo)
!     {
!       location_t saved_loc = input_location;
! 
!       input_location = DECL_SOURCE_LOCATION (using_decl);
!       error_not_base_type (ctype, t);
!       input_location = saved_loc;
!       return;
!     }
!   
!   if (constructor_name_p (name, ctype))
!     {
!       cp_error_at ("%qD names constructor", using_decl);
!       return;
!     }
!   if (constructor_name_p (name, t))
!     {
!       cp_error_at ("%qD invalid in %qT", using_decl, t);
!       return;
!     }
! 
!   fdecl = lookup_member (binfo, name, 0, false);
    
-   if (!fdecl)
-     {
-       cp_error_at ("no members matching %qD in %q#T", using_decl, ctype);
-       return;
-     }
- 
-   if (BASELINK_P (fdecl))
-     /* Ignore base type this came from.  */
-     fdecl = BASELINK_FUNCTIONS (fdecl);
- 
    old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false);
    if (old_value)
      {
--- 1119,1135 ----
  static void
  handle_using_decl (tree using_decl, tree t)
  {
!   tree decl = USING_DECL_DECLS (using_decl);
    tree name = DECL_NAME (using_decl);
    tree access
      = TREE_PRIVATE (using_decl) ? access_private_node
      : TREE_PROTECTED (using_decl) ? access_protected_node
      : access_public_node;
    tree flist = NULL_TREE;
    tree old_value;
  
!   gcc_assert (!processing_template_decl && decl);
    
    old_value = lookup_member (t, name, /*protect=*/0, /*want_type=*/false);
    if (old_value)
      {
*************** handle_using_decl (tree using_decl, tree
*** 1177,1185 ****
        else
  	old_value = NULL_TREE;
      }
! 
!   if (is_overloaded_fn (fdecl))
!     flist = fdecl;
  
    if (! old_value)
      ;
--- 1141,1151 ----
        else
  	old_value = NULL_TREE;
      }
!   
!   cp_emit_debug_info_for_using (decl, current_class_type);
!   
!   if (is_overloaded_fn (decl))
!     flist = decl;
  
    if (! old_value)
      ;
*************** handle_using_decl (tree using_decl, tree
*** 1211,1217 ****
  	alter_access (t, OVL_CURRENT (flist), access);
        }
    else
!     alter_access (t, fdecl, access);
  }
  
  /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
--- 1177,1183 ----
  	alter_access (t, OVL_CURRENT (flist), access);
        }
    else
!     alter_access (t, decl, access);
  }
  
  /* Run through the base classes of T, updating CANT_HAVE_CONST_CTOR_P,
Index: cp/cp-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.def,v
retrieving revision 1.104
diff -c -3 -p -r1.104 cp-tree.def
*** cp/cp-tree.def	7 Jun 2005 11:56:08 -0000	1.104
--- cp/cp-tree.def	8 Jun 2005 11:33:29 -0000
*************** DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PAR
*** 197,206 ****
     TYPE_NAME is an IDENTIFIER_NODE for `C', the member class template.  */
  DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0)
  
! /* A using declaration.  DECL_INITIAL contains the specified scope.  
!    This is not an alias, but is later expanded into multiple aliases.
!    The decl will have a NULL_TYPE iff the scope is a dependent scope,
!    otherwise it will have a void type.  */
  DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0)
  
  /* A using directive. The operand is USING_STMT_NAMESPACE.  */     
--- 197,206 ----
     TYPE_NAME is an IDENTIFIER_NODE for `C', the member class template.  */
  DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0)
  
! /* A using declaration.  USING_DECL_SCOPE contains the specified
!    scope.  In a member using decl, unless DECL_DEPENDENT_P is true,
!    USING_DECL_DECLS contains the _DECL or OVERLOAD so named.  This is
!    not an alias, but is later expanded into multiple aliases.  */
  DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0)
  
  /* A using directive. The operand is USING_STMT_NAMESPACE.  */     
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1143
diff -c -3 -p -r1.1143 cp-tree.h
*** cp/cp-tree.h	7 Jun 2005 11:56:08 -0000	1.1143
--- cp/cp-tree.h	8 Jun 2005 11:33:42 -0000
*************** struct diagnostic_context;
*** 93,98 ****
--- 93,99 ----
        DECL_TEMPLATE_PARM_P (in PARM_DECL, CONST_DECL, TYPE_DECL, or TEMPLATE_DECL)
        DECL_LOCAL_FUNCTION_P (in FUNCTION_DECL)
        DECL_MUTABLE_P (in FIELD_DECL)
+       DECL_DEPENDENT_P (in USING_DECL)
     1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL).
        DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
        DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
*************** struct lang_decl GTY(())
*** 2039,2044 ****
--- 2040,2054 ----
     directives  */
  #define TREE_INDIRECT_USING(NODE) (TREE_LIST_CHECK (NODE)->common.lang_flag_0)
  
+ /* Non zero if this is a using decl for a dependent scope. */
+ #define DECL_DEPENDENT_P(NODE) DECL_LANG_FLAG_0 (USING_DECL_CHECK (NODE))
+ 
+ /* The scope named in a using decl.  */
+ #define USING_DECL_SCOPE(NODE) TREE_TYPE (USING_DECL_CHECK (NODE))
+ 
+ /* The decls named by a using decl.  */
+ #define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))
+ 
  /* In a VAR_DECL for a variable declared in a for statement,
     this is the shadowed (local) variable.  */
  #define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT_FLD(VAR_DECL_CHECK (NODE))
Index: cp/cxx-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cxx-pretty-print.c,v
retrieving revision 1.34
diff -c -3 -p -r1.34 cxx-pretty-print.c
*** cp/cxx-pretty-print.c	27 May 2005 23:17:08 -0000	1.34
--- cp/cxx-pretty-print.c	8 Jun 2005 11:33:47 -0000
*************** pp_cxx_statement (cxx_pretty_printer *pp
*** 1519,1525 ****
  
      case USING_DECL:
        pp_cxx_identifier (pp, "using");
!       pp_cxx_nested_name_specifier (pp, DECL_INITIAL (t));
        pp_cxx_unqualified_id (pp, DECL_NAME (t));
        break;
  
--- 1519,1525 ----
  
      case USING_DECL:
        pp_cxx_identifier (pp, "using");
!       pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
        pp_cxx_unqualified_id (pp, DECL_NAME (t));
        break;
  
Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.122
diff -c -3 -p -r1.122 name-lookup.c
*** cp/name-lookup.c	2 Jun 2005 08:53:43 -0000	1.122
--- cp/name-lookup.c	8 Jun 2005 11:33:56 -0000
*************** static bool qualified_lookup_using_names
*** 51,57 ****
  					      struct scope_binding *, int);
  static tree lookup_type_current_level (tree);
  static tree push_using_directive (tree);
- static void cp_emit_debug_info_for_using (tree, tree);
  
  /* The :: namespace.  */
  
--- 51,56 ----
*************** push_using_decl (tree scope, tree name)
*** 1779,1791 ****
    gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
    for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
!     if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
        break;
    if (decl)
      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
                              namespace_bindings_p () ? decl : NULL_TREE);
!   decl = build_lang_decl (USING_DECL, name, void_type_node);
!   DECL_INITIAL (decl) = scope;
    TREE_CHAIN (decl) = current_binding_level->usings;
    current_binding_level->usings = decl;
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
--- 1778,1790 ----
    gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL);
    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
    for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
!     if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name)
        break;
    if (decl)
      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
                              namespace_bindings_p () ? decl : NULL_TREE);
!   decl = build_lang_decl (USING_DECL, name, NULL_TREE);
!   USING_DECL_SCOPE (decl) = scope;
    TREE_CHAIN (decl) = current_binding_level->usings;
    current_binding_level->usings = decl;
    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
*************** push_class_level_binding (tree name, tre
*** 2691,2725 ****
  tree
  do_class_using_decl (tree scope, tree name)
  {
!   tree value, type;
    
    if (!scope || !TYPE_P (scope))
      {
        error ("using-declaration for non-member at class scope");
        return NULL_TREE;
      }
    if (TREE_CODE (name) == BIT_NOT_EXPR)
      {
!       error ("using-declaration cannot name destructor");
        return NULL_TREE;
      }
  
!   gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  
-   /* Dependent using decls have a NULL type, non-dependent ones have a
-      void type.  */
-   type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
-   value = build_lang_decl (USING_DECL, name, type);
-   DECL_INITIAL (value) = scope;
- 
-   if (scope && !processing_template_decl)
-     {
-       tree r;
- 
-       r = lookup_qualified_name (scope, name, false, false);
-       if (r && (DECL_P (r) || TREE_CODE (r) == OVERLOAD))
- 	cp_emit_debug_info_for_using (r, scope);
-     }
    return value;
  }
  
--- 2690,2769 ----
  tree
  do_class_using_decl (tree scope, tree name)
  {
!   tree value, decl, binfo;
!   base_kind b_kind;
!   bool dependent_p;
    
    if (!scope || !TYPE_P (scope))
      {
        error ("using-declaration for non-member at class scope");
        return NULL_TREE;
      }
+ 
+   /* Make sure the scope is a base.  */
+   dependent_p = dependent_type_p (scope);
+   if (!dependent_p)
+     binfo = lookup_base (current_class_type, scope, ba_any, &b_kind);
+   else
+     {
+       binfo = NULL;
+       if (same_type_p (current_class_type, scope))
+ 	b_kind = bk_same_type;
+       else
+ 	b_kind = bk_proper_base;
+     }
+   
+   if (b_kind < bk_proper_base)
+     {
+       error_not_base_type (scope, current_class_type);
+       return NULL_TREE;
+     }
+   
+   /* Make sure the name is not invalid */
    if (TREE_CODE (name) == BIT_NOT_EXPR)
      {
!       error ("%<%T::%D%> names destructor", scope, name);
!       return NULL_TREE;
!     }
!   if (constructor_name_p (name, scope))
!     {
!       error ("%<%T::%D%> names constructor", scope, name);
!       return NULL_TREE;
!     }
!   if (constructor_name_p (name, current_class_type))
!     {
!       error ("%<%T::%D%> names constructor in %qT",
! 	     scope, name, current_class_type);
        return NULL_TREE;
      }
  
!   if (!dependent_p
!       && IDENTIFIER_OPNAME_P (name) && dependent_type_p (TREE_TYPE (name)))
!     dependent_p = 1;
! 
!   /* See if there are any members of the base. */
!   if (!dependent_p)
!     {
!       decl = lookup_member (binfo, name, 0, false);
!   
!       if (!decl)
! 	{
! 	  error ("no members matching %<%T::%D%> in %q#T", scope, name, scope);
! 	  return NULL_TREE;
! 	}
! 
!       if (BASELINK_P (decl))
! 	/* Ignore base type this came from.  */
! 	decl = BASELINK_FUNCTIONS (decl);
!    }
!   else
!     decl = NULL_TREE;
! 
!   value = build_lang_decl (USING_DECL, name, NULL_TREE);
!   USING_DECL_DECLS (value) = decl;
!   USING_DECL_SCOPE (value) = scope;
!   DECL_DEPENDENT_P (value) = dependent_p;
  
    return value;
  }
  
*************** pop_everything (void)
*** 4923,4929 ****
     If input tree is overloaded fn then emit debug info for all 
     candidates.  */
  
! static void
  cp_emit_debug_info_for_using (tree t, tree context)
  {
    /* Ignore this FUNCTION_DECL if it refers to a builtin declaration 
--- 4967,4973 ----
     If input tree is overloaded fn then emit debug info for all 
     candidates.  */
  
! void
  cp_emit_debug_info_for_using (tree t, tree context)
  {
    /* Ignore this FUNCTION_DECL if it refers to a builtin declaration 
*************** cp_emit_debug_info_for_using (tree t, tr
*** 4945,4950 ****
    for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
      if (TREE_CODE (t) != TEMPLATE_DECL)
        (*debug_hooks->imported_module_or_decl) (t, context);
!   }
  
  #include "gt-cp-name-lookup.h"
--- 4989,4994 ----
    for (t = OVL_CURRENT (t); t; t = OVL_NEXT (t))
      if (TREE_CODE (t) != TEMPLATE_DECL)
        (*debug_hooks->imported_module_or_decl) (t, context);
! }
  
  #include "gt-cp-name-lookup.h"
Index: cp/name-lookup.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.h,v
retrieving revision 1.40
diff -c -3 -p -r1.40 name-lookup.h
*** cp/name-lookup.h	7 May 2005 02:29:34 -0000	1.40
--- cp/name-lookup.h	8 Jun 2005 11:33:57 -0000
*************** extern bool is_associated_namespace (tre
*** 341,346 ****
--- 341,347 ----
  extern void parse_using_directive (tree, tree);
  extern tree innermost_non_namespace_value (tree);
  extern cxx_binding *outer_binding (tree, cxx_binding *, bool);
+ extern void cp_emit_debug_info_for_using (tree, tree);
  
  /* Set *DECL to the (non-hidden) declaration for ID at global scope,
     if present and return true; otherwise return false.  */
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.1004
diff -c -3 -p -r1.1004 pt.c
*** cp/pt.c	8 Jun 2005 11:09:01 -0000	1.1004
--- cp/pt.c	8 Jun 2005 11:34:26 -0000
*************** tsubst_decl (tree t, tree args, tsubst_f
*** 6557,6572 ****
        break;
  
      case USING_DECL:
!       {
! 	r = copy_node (t);
! 	/* It is not a dependent using decl any more.  */
! 	TREE_TYPE (r) = void_type_node;
! 	DECL_INITIAL (r)
! 	  = tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
! 	DECL_NAME (r)
! 	  = tsubst_copy (DECL_NAME (t), args, complain, in_decl);
! 	TREE_CHAIN (r) = NULL_TREE;
!       }
        break;
  
      case TYPE_DECL:
--- 6557,6576 ----
        break;
  
      case USING_DECL:
!       /* We reach here only for member using decls.  */
!       if (DECL_DEPENDENT_P (t))
! 	{
! 	  r = do_class_using_decl
! 	    (tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl),
! 	     tsubst_copy (DECL_NAME (t), args, complain, in_decl));
! 	  if (!r)
! 	    r = error_mark_node;
! 	}
!       else
! 	{
! 	  r = copy_node (t);
! 	  TREE_CHAIN (r) = NULL_TREE;
! 	}
        break;
  
      case TYPE_DECL:
*************** tsubst_expr (tree t, tree args, tsubst_f
*** 8085,8091 ****
  	  finish_label_decl (DECL_NAME (decl));
  	else if (TREE_CODE (decl) == USING_DECL)
  	  {
! 	    tree scope = DECL_INITIAL (decl);
  	    tree name = DECL_NAME (decl);
  	    tree decl;
  	    
--- 8089,8095 ----
  	  finish_label_decl (DECL_NAME (decl));
  	else if (TREE_CODE (decl) == USING_DECL)
  	  {
! 	    tree scope = USING_DECL_SCOPE (decl);
  	    tree name = DECL_NAME (decl);
  	    tree decl;
  	    
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.346
diff -c -3 -p -r1.346 search.c
*** cp/search.c	21 Apr 2005 09:18:22 -0000	1.346
--- cp/search.c	8 Jun 2005 11:34:31 -0000
*************** lookup_field_1 (tree type, tree name, bo
*** 471,479 ****
  	     defined, USING_DECLs are purged from TYPE_FIELDS; see
  	     handle_using_decl.  However, we make special efforts to
  	     make using-declarations in class templates and class
! 	     template partial specializations work correctly noticing
! 	     that dependent USING_DECL's do not have TREE_TYPE set.  */
! 	  if (TREE_TYPE (field))
  	    continue;
  	}
  
--- 471,478 ----
  	     defined, USING_DECLs are purged from TYPE_FIELDS; see
  	     handle_using_decl.  However, we make special efforts to
  	     make using-declarations in class templates and class
! 	     template partial specializations work correctly.  */
! 	  if (!DECL_DEPENDENT_P (field))
  	    continue;
  	}
  
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.474
diff -c -3 -p -r1.474 semantics.c
*** cp/semantics.c	6 Jun 2005 14:18:11 -0000	1.474
--- cp/semantics.c	8 Jun 2005 11:34:37 -0000
*************** finish_member_declaration (tree decl)
*** 2259,2265 ****
  					  /*friend_p=*/0);
      }
    /* Enter the DECL into the scope of the class.  */
!   else if ((TREE_CODE (decl) == USING_DECL && TREE_TYPE (decl))
  	   || pushdecl_class_level (decl))
      {
        /* All TYPE_DECLs go at the end of TYPE_FIELDS.  Ordinary fields
--- 2259,2265 ----
  					  /*friend_p=*/0);
      }
    /* Enter the DECL into the scope of the class.  */
!   else if ((TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl))
  	   || pushdecl_class_level (decl))
      {
        /* All TYPE_DECLs go at the end of TYPE_FIELDS.  Ordinary fields
Index: testsuite/g++.dg/inherit/using5.C
===================================================================
RCS file: testsuite/g++.dg/inherit/using5.C
diff -N testsuite/g++.dg/inherit/using5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/using5.C	8 Jun 2005 11:45:04 -0000
***************
*** 0 ****
--- 1,17 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 8 Jun 2005 <nathan@codesourcery.com>
+ 
+ // PR 19496: Missing error during parsing.
+ // Origin:  Volker Reichelt <reichelt@gcc.gnu.org>
+ 
+ template<int> struct A
+ {
+   A::A; // { dg-error "not a base" }
+ };
+ 
+ struct B
+ {
+   void f ();
+   using B::f; // { dg-error "not a base" }
+ };
+ 
Index: testsuite/g++.dg/inherit/using6.C
===================================================================
RCS file: testsuite/g++.dg/inherit/using6.C
diff -N testsuite/g++.dg/inherit/using6.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/inherit/using6.C	8 Jun 2005 11:45:04 -0000
***************
*** 0 ****
--- 1,15 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 8 Jun 2005 <nathan@codesourcery.com>
+ 
+ struct A
+ {
+   operator int ();
+ };
+ 
+ template <typename T> struct TPL : A
+ {
+   using A::operator T; // { dg-error "operator float" }
+ };
+ 
+ TPL<int> i;
+ TPL<float> j; // { dg-error "instantiated" }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]