Bug 58538 - Injected class-name treated as type-name instead of template-name when used as a template-argument for a template template-parameter
Summary: Injected class-name treated as type-name instead of template-name when used a...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: 13.0
Assignee: Jason Merrill
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2013-09-25 22:22 UTC by Daniel Frey
Modified: 2023-04-19 19:16 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-08-04 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Daniel Frey 2013-09-25 22:22:29 UTC
The following program fail to compile.

  template<typename> struct A
  {
    template<template<typename> class B=A> void f();
  };
  int main(){}

with

main.cpp:3:39: error: invalid use of type ‘A< <template-parameter-1-1> >’ as a default value for a template template-parameter

   template<template<typename> class B=A> void f();

on GCC 4.8.1. Me (and some other on SO, see <http://http://stackoverflow.com/questions/19013071/>) think it's a bug due to §14.6.1.

Work-around in case it helps to narrow down the bug: Replace B=A with B=::A
Comment 1 Jonathan Wakely 2013-09-26 09:24:24 UTC
The URL should be http://stackoverflow.com/questions/19013071/
Comment 2 Jonathan Wakely 2013-09-26 09:40:07 UTC
Possibly related is that G++ treats X as the class template here, not the injected class name, on contrast to other compilers:

template< template< typename > class T >
class factory { };

template< typename T >
class X
{
      friend class factory< X >;  // ***
};

int main()
{
}
Comment 3 Jonathan Wakely 2018-04-24 19:27:48 UTC
For comment 2, Clang now accepts the code (since 5.0.0), and so does EDG. That seems correct according to [temp.local].

GCC still gets the original case in comment 0 wrong.
Comment 4 Jonathan Wakely 2018-04-24 19:50:15 UTC
cp/pt.c convert_template_argument has this code:

  /* Deal with an injected-class-name used as a template template arg.  */
  if (requires_tmpl_type && CLASS_TYPE_P (arg))
    {
      tree t = maybe_get_template_decl_from_type_decl (TYPE_NAME (arg));
      if (TREE_CODE (t) == TEMPLATE_DECL)
	{
	  if (cxx_dialect >= cxx11)
	    /* OK under DR 1004.  */;
	  else if (complain & tf_warning_or_error)
	    pedwarn (input_location, OPT_Wpedantic, "injected-class-name %qD"
		     " used as template template argument", TYPE_NAME (arg));
	  else if (flag_pedantic_errors)
	    t = arg;

	  arg = t;
	}
    }

So cp/semantics.c check_template_template_default_arg needs something similar.
Comment 5 GCC Commits 2023-03-15 12:45:21 UTC
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:40c1352c5a4530350012d6a922435cf491663daa

commit r13-6694-g40c1352c5a4530350012d6a922435cf491663daa
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Mar 14 23:16:21 2023 -0400

    c++: injected class name as default ttp arg [PR58538]
    
    This function needs to handle this case like convert_template_argument.
    
            PR c++/58538
    
    gcc/cp/ChangeLog:
    
            * semantics.cc (check_template_template_default_arg): Check
            maybe_get_template_decl_from_type_decl.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/ttp7.C: Remove expected error.
Comment 6 Patrick Palka 2023-04-19 19:16:22 UTC
Fixed for GCC 13 then I suppose