[cfe-dev] Function template declarations and name lookup

Rahul Jain 1989.rahuljain at gmail.com
Tue Dec 17 10:49:16 PST 2013


Hi all,

This is with respect to the following test code:

template <class T> decltype(g2(T())) f2();
int g2(int);
template <class T> decltype(g2(T())) f2() // { dg-error "g2. was not
declared" }
{ return g2(T()); }
int i2 = f2<int>();

clang++ seems to compile this code but it should throw an error as per the
following standard:

Two expressions involving template parameters are considered equivalent if
two function definitions containing the expressions would satisfy the one
definition rule (3.2), except that the tokens used to name the template
parameters may differ as long as a token used to name a template parameter
in one expression is replaced by another token that names the same template
parameter in the other expression. For determining
whether two dependent names (14.6.2) are equivalent, only the name itself
is considered, not the result of name lookup in the context of the
template. If multiple declarations of the same function template differ in
the result of this name lookup, the result for the first declaration is
used.

Example:

template <class T> decltype(g(T())) h();
int g(int);
template <class T> decltype(g(T())) h()  // redeclaration of h() uses the
earlier                                                            lookup
{ return g(T()); }                                  // ..although the
lookup here does
     find g(int)
int i = h<int>();                                   // template argument
substitution
   fails; g(int) was not in scope at the
                         first declaration of h()


Is this a potential bug or am I missing something? If yes, it would be
great if someone gave some initial pointers as to how to go about fixing it.

I went through the code as to how two functions with the same signature are
handled.
The function bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD,
Scope *S,bool MergeTypeWithOld); does the check for the same.

But I lost track somewhere after instantiation.

Basically the approach I want to take is, after instantiation when it is
checked whether the declaration of g(int) is present or not using the
function call

OverloadingResult
OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
                                         iterator &Best,
                                         bool UserDefinedConversion);

I wish to check it keeping in mind the source location of the function
declaration and not definition.

Any help on this would be really helpful.


Thanks,
Rahul
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131218/6f338b20/attachment.html>


More information about the cfe-dev mailing list