Add type check for explicit instantiation of template classes' static data members. This is a bug fix for #38205.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Unit Tests
Time | Test | |
---|---|---|
430 ms | linux > HWAddressSanitizer-x86_64.TestCases::sizes.cpp |
Event Timeline
How's this compare to the similar checks for variable templates? Is there some code/checking we could share here?
The code of checks for variable templates is just before the additional code. But the conditions of if statement and the format of diagnostics are different, so it may be better to do the check for static member instantiation separately. And I have reused the type comparing function (with an argument different).
clang/include/clang/AST/ASTContext.h | ||
---|---|---|
2342–2345 | I'm guessing this function is pretty widely used - so this change might be a bit invasive/may not be what all callers want? @rsmith - this is getting a bit out of my wheelhouse and I'd rather like you to take a look when you've got a chance | |
clang/lib/Sema/SemaTemplate.cpp | ||
10149–10151 | The ObjC comment seems a bit out of place here - since the code here doesn't seem to mention them. Maybe skip that part here, and leave it to be described up in the hasSameType function? | |
clang/test/SemaCXX/template-explicit-instant-type-mismatch.cpp | ||
15–17 ↗ | (On Diff #301872) | I assume this was already tested somewhere else, perhaps? (since your change was about static member variables of class templates, and didn't touch the existing code for variable templates) So probably doesn't need re-testing here. |
In this update I delete some extra test code, move several comments and split the new type comparing code into a new function to make sure that the commonly used old type comparing function not affected by it.
Which? Do you mean the unit test? It seems to be irrelevant with this revision. This revision doesn't change the code covered by that test. The failure should be caused by other commit on the trunk.
clang/lib/Sema/SemaTemplate.cpp | ||
---|---|---|
10146–10159 | Can we combine this with the previous if? This is really checking the same thing that the hasSameType check above checked. | |
10151 | The check of TSK seems unnecessary (and incorrect) here -- we should check the type is correct regardless of whether this is an explicit instantiation declaration or an explicit instantiation definition. | |
10152 | 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:
(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. |
clang/lib/Sema/SemaTemplate.cpp | ||
---|---|---|
10146–10159 | It seems difficult to combine this with the previous one.
So, if we want to combine the two blocks, we must write two sub-if-blocks in the combined block, which, I think, has no advantage over the current code (if not more confusing). | |
10152 | I'll do some test and give you a code snippet to trigger the lifetime mismatch when lifetime specifiers are not ignored. |
clang/lib/Sema/SemaTemplate.cpp | ||
---|---|---|
10152 | 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. |
I'm guessing this function is pretty widely used - so this change might be a bit invasive/may not be what all callers want?
@rsmith - this is getting a bit out of my wheelhouse and I'd rather like you to take a look when you've got a chance