[cfe-dev] Resolving non-dependent function names within a template definition

Davis, Matthew via cfe-dev cfe-dev at lists.llvm.org
Tue Nov 21 11:10:33 PST 2017

I  have a few questions about how Clang handles template definition parsing and argument dependent lookup (ADL). 
I was investigating the following bug: https://bugs.llvm.org/show_bug.cgi?id=28290

I would expect the following code (from the bug report), to emit an error message, since Clang does not default to MSVC/delayed-template-parsing behavior.  However,  Clang does not emit an error.

////////// From bug #28290
class UBS;
  template <bool bCS> struct FIBH 
   FIBH() { GDN(BS); }  // GDN() is an error, it's non-dependent and not resolvable yet.
   class UBS* BS;

  extern void foo();

  void foo()
   FIBH<false> IBH;  // Instantiation
  void GDN(UBS* BS);

>From what I understand in the spec [temp.res9], "GDN" is a name belonging to a non-dependent expression, and therefore the compiler must be able to resolve it at the lexical point in the parse.  Namely, at the point of template definition. 

The Clang parser does recognize this name as not being locatable during parse, and it suppresses the unresolved name error, in this case by creating an UnresolveLookupExpr to represent the "GDN()" in the template definition.  The lookup for GDN is then delayed, until instantiation when ADL is performed.  The result is that we get the -fdelayed-template-parsing (MSVC) semantics, which I do not believe is what we want.  The delay in the lookup allows for ADL to occur.   That seems problematic, as if the instantiation never occurs, the UnresolvedLookupExpr is never processed, and the following error message will never be produced: diag::err_not_found_by_two_phase_lookup: "a call to function %0 that is neither visible in the template definition nor found by argument dependent lookup."  I think we would want this error message to be reported even if the instantiation never occurs.

The other issue of delaying  ADL, is that in the case of the example above, GDN will be known at the point of template instantiation, and therefore ADL will resolve GDN, and never produce the aforementioned error message.  The ADL will recognize the GDN function decl from the global namespace, and use that.

With that said, I have two questions:
1) Should we emit an error for GDN during parse when the template is being parsed?
2) Should we allow ADL to resolve GDN in the template, when GDN is not really visible at the point of template definition?


More information about the cfe-dev mailing list