[LLVMbugs] [Bug 6723] New: Deduced/Explicit template arguments to parameter conversions madness

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sat Mar 27 05:32:20 PDT 2010


           Summary: Deduced/Explicit template arguments to parameter
                    conversions madness
           Product: clang
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: schaub-johannes at web.de
                CC: llvmbugs at cs.uiuc.edu, dgregor at apple.com

I have done some tests how clang behaves for conversions and deduction failures
regarding explicit and deduced arguments:

struct S { };
void operator<<(S, unsigned char);
// uncomment this, and all works
// void operator<<(S, unsigned int);
void operator<<(S, long);

void g(unsigned char);
void g(long);

template<typename T>
void same_type_e(T, T);

template<unsigned char C>
void f(int(&)[C]) { // C deduced to 512 
  S() << C; // ambiguity
  S() << (unsigned char)0; // works

  g(C); // works

  same_type_e((unsigned char)0, C); // works
  typedef char x[C == 512 ? 1 : -1]; // works

template<unsigned char C>
void f1(int(*)[C]) { // C explicitly specified => converted to 0
  S() << C; // works
  S() << (unsigned char)0; // works

  g(C); // works

  same_type_e((unsigned char)0, C); // works
  typedef char x[C == 0 ? 1 : -1]; // works

int main() { 
  int x[512]; 

Clang does not yield a deduction failure for f1<512>(0) - i'm not sure what the
Standard says. It depends on whether 14.9.2[temp.deduct]p2b2 when it says "The
specified template argument values are substituted for the corresponding
template parameters as specified below" whether it refers to the
template-argument expressions as specified, or to the converted arguments after
they gone through 14.4.2[temp.arg.nontype]p5. If it uses the converted
arguments, we will SFINAE fail, but if not, we won't sfinae fail. 

In any case, if we *don't* SFINAE fail, then the parameter type shold be
"int(*)[512]" but clang gives it the "type" int(*)[0] currently, it seems. That
doesn't seem to make sense. 

One other thing that needs correction is the type of "C" in some overload
contexts. While when C is deduced it has type "unsigned char" when in normal
function calls, it seems to have type "unsigned int" when in
overload-resolution-in-expressions contexts. 

The behavior of EDG is that in f, it compiles everything, so it gives "C" the
value 512, but the type unsigned int. For f1, it converts the explicitly
specified argument before substituting it into the function type of the
template and starting argument deduction with it. So it will SFINAE fail for
f1. If i call it with "f1<513>(0)" and change the typedef test to "C == 1",
comeau accepts the whole code. 

I find the Standard is quite mysteriously silent about the handling of these
situations, unfortunately. I haven't found anything that mandates converting
deduced arguments. But in any case, the currently different behavior regarding
overload resolution and the construction of the "int(*)[0]" type in clang needs
a change i suspect.

Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

More information about the llvm-bugs mailing list