[cfe-dev] Bug shown by out-of-line definition of template method.

Enea Zaffanella zaffanella at cs.unipr.it
Tue Feb 9 08:16:20 PST 2010


Hello.

The following C++ code triggers a bug in clang:

===================================================
template <typename T>
struct Outer {
   template <typename U>
   struct Inner {};

   template <typename U>
   typename Outer<T>::template Inner<U>
   foo(typename Outer<T>::template Inner<U>);
};

template <typename T>
template <typename U>
typename Outer<T>::template Inner<U>
Outer<T>::foo(typename Outer<T>::template Inner<U>) {
   return Inner<U>();
}
==================================================

# llvm/Debug/bin/clang++ -fsyntax-only bug.cc
bug.cc:14:11: error: out-of-line definition of 'foo' does not match any
       declaration in 'struct Outer'
Outer<T>::foo(typename Outer<T>::template Inner<U>) {
~~~~~~~~~~^
1 diagnostic generated.


I tried to trace it to its origin: the wrong error message is generated 
in a call to method

   bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old);

namely, in the very last of the following tests:

   if (NewTemplate &&
(!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
                                  OldTemplate->getTemplateParameters(),
                                  false, TPL_TemplateMatch) ||
       OldType->getResultType() != NewType->getResultType()))
     return true;

The result types of the out-of-line method definition type (NewType) and 
the method declaration type (OldType) do not match:

declaration result type: TemplateSpecializationType
Inner<type-parameter-1-0>

definition  result type: TypenameType
typename Outer<type-parameter-0-0>::Inner<type-parameter-1-0>

In contrast, parameter types do match, as they are both normalized to 
Inner<type-parameter-1-0>.

This instance of the bug will disappear if the result type of the method 
definition is normalized before comparision ... but honestly I am not 
sure at all regarding how to perform such a normalization (is it enough 
to query TemplateType::getTemplateId() ?) and whether or not this is the 
right place to do it.

Anyway, I hope that the observations above are useful for clang experts.

Cheers,
Enea Zaffanella.




More information about the cfe-dev mailing list