[PATCH] D90448: [clang] Add type check for explicit instantiation of static data members

Chuyang Chen via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 28 23:38:17 PST 2021


nomanous added inline comments.


================
Comment at: clang/lib/Sema/SemaTemplate.cpp:10117
+        TSK == TSK_ExplicitInstantiationDefinition && Prev &&
+        !Context.hasSameTypeIgnoreLifetime(Prev->getType(), R)) {
+      Diag(T->getTypeLoc().getBeginLoc(),
----------------
nomanous wrote:
> rsmith wrote:
> > Please can you point us at an example that needs this "ignore lifetime" nuance? We should check with Apple folks what they want to happen here, and we should presumably have the same rule for all explicit instantiations of templated variables -- both in the static data member case here and the variable template case a few lines above.
> > 
> > My expectation is that we want one of these two rules:
> > 1) the declared lifetime should match exactly between the declaration and the explicit instantiation, or
> > 2) there cannot be a declared lifetime on the explicit instantiation, and a lifetime on the template declaration is ignored by the check
> > (or a combination of these rules where we accept either option). I don't think that matches what you're doing here -- in particular, I think a wrong declared lifetime on the explicit instantiation should result in an error.
> I'll do some test and give you a code snippet to trigger the lifetime mismatch when lifetime specifiers are not ignored. 
With lifetime specifiers not ignored, use command

```
clang -cc1  -fobjc-arc -fblocks -fsyntax-only snippet.mm
```

to compile the obj-c++ file `snippet.mm` whose contents are as follows:

```
typedef void (^fptr)();
template<typename T> struct StaticMembers {
  static fptr f;
};

template<typename T>
fptr StaticMembers<T>::f = [] {};

template fptr StaticMembers<float>::f;
```

The compiler will give a type mismatch error, saying that `f`'s definition in the template class  has a type `'__strong fptr' (aka 'void (^__strong)()')` while its explicit instantiation has a type `'fptr' (aka 'void (^)()')`, though they should essentially have the same type.

This problem only happens in explicit instantiation of a static member of block type and doesn't affect static members of other types.

@rsmith 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D90448



More information about the cfe-commits mailing list