Hello.
The following C++ code triggers a bug in clang:
Hello.
The following C++ code triggers a bug in clang:
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 methodbool 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.
Sema::RebuildTypeInCurrentInstantiation is supposed to perform this normalization, because we can't actually get the types right until we know that we're in the scope of Outer<T> (which happens after we've parsed the return type). Since this is probably a bug in that normalization, it's best if I address it, because it requires fairly deep knowledge of the type and template systems to get right.
Anyway, I hope that the observations above are useful for clang experts.
Very useful, thank you! I've filed this bug here:
http://llvm.org/bugs/show_bug.cgi?id=6268
and will address it when I can.
- Doug