That looks like delayed template instantiation behavior (the default you get on Windows, because thatās how MSVC behaves). You have to instantiate the template in order to generate its body in that case (or disable delayed template parsing with -fno-delayed-template-parsing).
Not usually. A lot of the tests specify -fno-delayed-template-parsing or instantiate the templates somehow. However, we do run into the issue where someone forgets to do that and build bots break with some degree of regularity. (The same happens in Clang when writing SemaCXX template tests.)
IMO itās high time to reconsider the default setting for this flag. This MSVC compatibility is regularly causing more issues than it solves. It most recently came up in this code review in 2021, which as I understand it did not land: https://reviews.llvm.org/D103772
As I understand it, flipping the default here would be inconsistent with MSVC. Some people look at this issue and say, āMSVC uses /Zc:twoPhase- by default, so clang-cl should follow MSVCā. However, Clangās -fdelayed-template-parsing setting isnāt really the same thing as /Zc:twoPhase-, and I think if we can address the build failure from last time, users will get more value from a more C+Ā±conforming default compiler behavior. So, I think we should go ahead and make the change anyway.
I think an RFC to reconsider that behavior would be interesting, because I agree, itās a disruptive behavior to have on by default. However, I think we need be very cautious about breaking system headers. Iām not super worried about most Win32 headers given that theyāre generally C headers. But Iām definitely worried about the massive amount of e.g., MFC (and other more C++ heavy) code that still exists.
(A secondary concern would be silent ABI breakage, but Iām not certain changing this default should impact ABI at all ā if the template was being instantiated, ABI wonāt be changed, and if the template was never instantiated, it was never ODR-used to begin with and so there should be no ABI impact either.)
Is this a Windows-only problem though? We use Linux and experience many situations where clang-tidy will not catch issues simply due to templates not being instantiated. From this thread my understanding is that ādelayed template instantiationā is a feature enabled by default only on Windows; why does it happen on Linux too? For example:
template <typename T>
T foo(int x)
{
return T(x); // Expect: google-readability-casting
}
int main()
{
float x = foo<float>(123); // Only when the function is instantiated we get the warning
}
However, I think we need be very cautious about breaking system headers. ā¦ But Iām definitely worried about the massive amount of e.g., MFC (and other more C++ heavy) code that still exists.
Iām optimistic that MFC, ATL, and other C++ template libraries already work without delayed template parsing because Microsoft added the /permissive- flag to new VS projects by default a long time ago. That means that most templates written by Microsoft should parse correctly where they are written, and not later at the point of instantiation.
Thereās always some user somewhere that relies on every compiler implementation detail, but I feel pretty confident that we can find a way to make this flag flip. Itās certainly release noteworthy.
Re: ABI, yep, this should be pretty safe.
Is this a Windows-only problem though? We use Linux and experience many situations where clang-tidy will not catch issues simply due to templates not being instantiated.
I think what you describe is the expected behavior.
There are also a significant amount of warnings that are only possible once expression is instantiated. I donāt know much about Tidy, but in the CFE itself we have a bunch that are like that.
For example:
return T(x);
might just be a constructor call, at which point it makes little sense to diagnose it as a āreadability castā, IMO.
I share that optimism, but Iād want to know how we fare against the oldest headers we expect to support rather than the newest. But if the newest work well but previous versions are a problem, this at least sets a timer for when we can enable the functionality by default (or it may inform us that we can never switch the defaults, but that would be a surprise to me).
+1; if the breakage doesnāt happen in a system or ācommonly used 3rd party headerā (whatever that means to folks), I think itās worth trying. And I agree, warning folks weāre thinking about doing this switch is something we definitely should do. Perhaps we could run an RFC by community and at least get the release note into Clang 15 so that we can flip defaults (if possible) in Clang 16?