[PATCH] D56411: [CUDA][HIP][Sema] Fix template kernel with function as template parameter

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 24 12:41:47 PST 2019


rjmccall added a comment.

In D56411#1369906 <https://reviews.llvm.org/D56411#1369906>, @yaxunl wrote:

> In D56411#1365745 <https://reviews.llvm.org/D56411#1365745>, @rjmccall wrote:
>
> > In D56411#1365727 <https://reviews.llvm.org/D56411#1365727>, @yaxunl wrote:
> >
> > > In D56411#1360010 <https://reviews.llvm.org/D56411#1360010>, @rjmccall wrote:
> > >
> > > > I think the diagnostic should come during instantiation when you find an evaluated use of a host function within a device function.
> > >
> > >
> > > It seems the body of function template is checked only during parsing of the definition of the template itself. When a function
> > >  template is instantiated, the body of the instantiated function is not checked again.
> >
> >
> > No, that's not correct.  However, it's checked somewhat differently, and it's possible that the existing diagnostic is not set up to fire along all common paths.  Try moving the diagnostic to `MarkFunctionReferenced`, and note that `OdrUse` will be `false` in all the unevaluated contexts.
>
>
> I got regression in the folowing test when checking CheckCUDACall in MarkFunctionReferenced:
>
>   typedef struct {
>     template <unsigned n> void *foo() { return 0; }
>   
>     void foo() {
>       foo<0>();
>     }
>   } A;
>   
>   
>
> Basically clang does not allow getting linkage of foo<0> before ActOnTypedefDeclarator, quoting SemaDecl.cpp line 4171
>
>   // If we've already computed linkage for the anonymous tag, then
>   // adding a typedef name for the anonymous decl can change that
>   // linkage, which might be a serious problem.  Diagnose this as
>   // unsupported and ignore the typedef name.  TODO: we should
>   // pursue this as a language defect and establish a formal rule
>   // for how to handle it.
>   if (TagFromDeclSpec->hasLinkageBeenComputed()) {
>     Diag(NewTD->getLocation(), diag::err_typedef_changes_linkage);
>   
>   
>
> However, CheckCUDACall needs to call GetGVALinkageForFunction on the callee to know if it will be emitted,
>  which causes the linkage of the anonymous struct to be cached and triggers err_typedef_changes_linkage.


Sounds like you were missing a case in the diagnostic, then.

Can you check whether you're in an `inline` function before you check the linkage?  It's a bit of a hack but it might work.  You have logic to look for evaluated references in used inline functions anyway, right?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56411/new/

https://reviews.llvm.org/D56411





More information about the cfe-commits mailing list