Bug 4205

Summary: function template can call other function with incorrect parameters
Product: gcc Reporter: Jens Maurer <jens.maurer>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: bangerth, fang, gcc-bugs, gianni, jajarvi, japple, jason, nathan, pinskia
Priority: P3 Keywords: accepts-invalid
Version: 3.0.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: 4.1.0 Last reconfirmed: 2005-12-11 21:49:13
Attachments: 4205.ii

Description Jens Maurer 2001-09-02 10:16:01 UTC
The attached code should give an error at least in the
call to foo(&wibble), because you can't call wibble() with
just one argument, but these gcc versions don't:

gcc version 3.0.1
gcc version 3.1 20010901 (experimental)
gcc version 2.95.3 20010315 (release)

Release:
gcc 3.0.1

Environment:
Linux 2.4.8 with glibc 2.2.3

How-To-Repeat:
// Douglas Gregor on boost 2001-08-22

#include <iostream>

template<typename F>
void foo(F f)
{
  f(1);
}

void bar(int i, int j = 5, int k = 7)
{
  std::cout << "bar(" << i << ", " << j << ", " << k << ")" << std::endl;
}

void wibble(int i, int j, int k = 9)
{
  std::cout << "wibble(" << i << ", " << j << ", " << k << ")" << std::endl;
}

int main()
{
  foo(&bar); 
  foo(&wibble); // should give an error, "wibble" cannot be called with one arg
}
Comment 1 Nathan Sidwell 2001-09-04 08:20:42 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: confirmed as a bug. I've attached a smaller test case
Comment 2 Wolfgang Bangerth 2002-11-15 19:55:02 UTC
From: Wolfgang Bangerth <bangerth@ticam.utexas.edu>
To: gcc-bugs@gcc.gnu.org, <gcc-gnats@gcc.gnu.org>, <nathan@codesourcery.com>,
   <gdr@codesourcery.com>
Cc:  
Subject: Re: c++/4205: function template can call other function with incorrect
 parameters
Date: Fri, 15 Nov 2002 19:55:02 -0600 (CST)

 This code compiles silently:
 -------------------------------------
 template<typename F> void quirk(F f) {
   (*f) (1);
 }
 
 void foo(int i, int j = 5){}
 void bar(int i, int j)    {}
 
 int main() {
   quirk(&foo); 
   quirk(&bar);
 }
 -------------------------------------
 
 The assertion of the submitter is that the first quirk(&foo) is ok, since 
 the call to (*f)(1) will substitute the second arg of foo by the default 
 argument of that function. The second call would be wrong. It succeeds, of 
 course, since the function quirk for exactly this template arg has already 
 been compiled, and no re-compilation means no re-check.
 
 However, I believe that already the first one is bogus. The template 
 argument F of quirk is 
   void (*) (int, int),
 so the call to (*p)(1) should be invalid. We should not know about default 
 arguments in quirk, right? I'm surprised that default arguments are 
 propagated to the template function. They don't appear in the type of 
 quirk as well, since if I enter a
     std::cout << __PRETTY_FUNCTION__ << std::endl;
 into that function, I only get 
     void quirk(F) [with F = void (*)(int, int)]
 But that may of course have other roots.
 
 Regards
   Wolfgang
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth              email:           bangerth@ticam.utexas.edu
                                www: http://www.ticam.utexas.edu/~bangerth
 
 

Comment 3 Nathanael C. Nerode 2003-01-03 07:07:54 UTC
From: Nathanael Nerode <neroden@twcny.rr.com>
To: gcc-gnats@gcc.gnu.org, gcc-prs@gcc.gnu.org, Jens.Maurer@gmx.net,
   gcc-bugs@gcc.gnu.org, nobody@gcc.gnu.org
Cc:  
Subject: Re: c++/4205
Date: Fri, 3 Jan 2003 07:07:54 -0500

 This has a further perverse piece of behavior not noted before:
 the following code will, correctly, give an error!
 --
  template<typename F> void quirk(F f) {
    (*f) (1);
  }
 
 
 // void foo(int i, int j = 5){}
  void bar(int i, int j)    {}
 
  int main() {
 //   quirk(&foo);
    quirk(&bar);
  }
 --
 And so will this:
 --
 template<typename F> void quirk(F f) {
    (*f) (1);
  }
 
 
  void foo(int i, int j = 5){}
  void bar(int i, int j)    {}
 
  int main() {
    quirk(&bar);
    quirk(&foo);
  }
 --
 
 As long as "foo" is seen *first*, it 'immunizes' all subsequent functions.  
 But not otherwise.  This is really bad behavior.  
 It may possibly be related to c++/3784, which has similar "first one seen 
 controls everyone else" behavior, though I doubt it.
Comment 4 Andrew Pinski 2003-12-28 04:12:14 UTC
*** Bug 13500 has been marked as a duplicate of this bug. ***
Comment 5 Andrew Pinski 2004-01-03 12:54:52 UTC
*** Bug 4908 has been marked as a duplicate of this bug. ***
Comment 6 Andrew Pinski 2004-01-29 04:18:35 UTC
*** Bug 13916 has been marked as a duplicate of this bug. ***
Comment 7 Jim Apple 2004-02-01 21:59:45 UTC
template<typename T, typename U = int>
struct foo {};
                                                                                
template<template <typename> class TT>
struct bar {};
                                                                                
bar<foo> x;

compiles for me with 3.3.2.  Is this bug related?
Comment 8 Gabriel Dos Reis 2004-02-01 22:21:50 UTC
Subject: Re:  function template can call other function with incorrect parameters

"japple at freeshell dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| template<typename T, typename U = int>
| struct foo {};

| template<template <typename> class TT>
| struct bar {};

| bar<foo> x;
| 
| compiles for me with 3.3.2.  Is this bug related?

Not really.  But yes,  you have a point:  GCC currently does not have
a uniform infrastructure for sharing codes for functions and
templates.

-- Gaby
Comment 9 Jim Apple 2004-02-01 22:42:27 UTC
(In reply to comment #8)

> Not really.  But yes,  you have a point:  GCC currently does not have
> a uniform infrastructure for sharing codes for functions and
> templates.

See new bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13966

Jim
Comment 10 Gabriel Dos Reis 2004-02-01 22:57:15 UTC
Subject: Re:  function template can call other function with incorrect parameters

"japple at freeshell dot org" <gcc-bugzilla@gcc.gnu.org> writes:

| ------- Additional Comments From japple at freeshell dot org  2004-02-01 22:42 -------
| (In reply to comment #8)
| 
| > Not really.  But yes,  you have a point:  GCC currently does not have
| > a uniform infrastructure for sharing codes for functions and
| > templates.
| 
| See new bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13966

Thanks.  I should have been clearer.  Technically, this is a GNU
extension that really goes against the C++ committee clarification.
(I don't have the DR number off hand).  There is a special code in
cp/pt.c to implement that extension.  I remember having submitted a
patch to remove it; but at the time, some people think we should keep
it around.  I don't necessarily agree.

-- Gaby
Comment 11 Richard Biener 2005-09-09 13:14:54 UTC
EDG accepts this too.
Comment 12 Andrew Pinski 2007-08-06 05:12:30 UTC
*** Bug 32993 has been marked as a duplicate of this bug. ***
Comment 13 gianni 2007-08-06 06:26:14 UTC
This seems like a serious bug and it has been around for 6 years and there has been a patch to fix this as noted by Gaby.

Is someone of the opinion that this should not be fixed ?
Comment 14 Jason Merrill 2009-11-19 06:18:04 UTC
This seems to have been fixed sometime in the 4.3 release cycle; it works properly with the current 4.3, 4.4 and 4.5 branches.