Static Analysis Fixes in Visual Studio 2019 version 16.11


The C++ static analysis team is committed to making your C++ coding experience as safe as possible. We are adding richer code safety checks and addressing high impact customer feedback bugs posted on the C++ Developer Community page. Thank you for engaging with us and giving us great feedback on the past releases and early previews leading to this point. Below is the compilation of bug fixes that were made from Visual Studio 2019 version 16.10 to 16.11 for code analysis.  Note that 16.11 is the last non-servicing release of Visual Studio 2019, so the focus was on stabilization and minor improvements rather than new features (stay tuned for updates in 17.0). We also found time to improve the performance of certain checks. The changes are summarized below:

  • Clarified the warning message for C26445. The old message implied that there is a lifetime problem. The new message is: “Do not assign gsl::span or std::string_view to a reference. They are cheap to construct and are not owners of the underlying data. (gsl.view)”
  • Fixed false positive due to not considering lifetime extension rules in C26444. See the code example below:
struct MyStruct { int i; }; 
void example() { 
  const MyStruct& s = {}; // Previously, false positive C26444 was emitted. 
  • Fixed using ALL_CPPCORECHECK_WARNINGS in suppression would not suppress C26457.
  • Fixed a problem where certain control flows could trick Concurrency Check into emitting false positive warnings.
  • Fixed a false positive in Concurrency Check due to incorrect modelling of unwinding paths (for exceptions). This fixed the false positive below. Previously, analysis would proceed along the exception path of the constructor call (no lock is acquired in the exception path), leading to a false warning.
mutex mtx; 
mutex& mutexRef() { return mtx; } 
void test() { 
  lock_guard<mutex> lock(mutexRef()); // No C26110 (failing to hold lock) 
  • Fixed a compilation failure of code snippets relying on guaranteed copy elision during code analysis.
struct S { 
  S(const S& o) = delete; 
  S& operator=(const S& o) = delete; 
  S(const S&& o) = delete; 
  S& operator=(const S&& o) = delete; 
  static const S foo(); 

void bar() {
  S s = S::foo(); // Used to trigger compilation failure.

  • Fixed a bug that caused the /external options for specifying external headers to override CAExcludePath and generate warnings for external files.
  • Performance improvements to the checker that reports warnings on misuse of `VARIANT`s (warnings C33001, C33004, and C33005). Please refer to “New Safety Rules for in C++ Code Analysis” for more information on these warnings.
  • Performance improvements to the checker that reports warnings on misuse of enum values as an index (warnings C33010 and C33011). Please refer to “Even More Safety Rules in C++ Code Analysis” for more information on these warnings. Improved the performance of pointer safety related C++ Core Guidelines checks. See OWNER_POINTER, RAW_POINTER, UNIQUE_POINTER, and SHARED_POINTER groups here.
  • Fixed some memory leaks in some checks when multiple translation units are analyzed in a single compiler invocation.

Fixes in 16.11.1 to 16.11.3 servicing releases

  • Fixed a crash when __uuidof was used in a template argument a certain way.
  • Fixed a rare crash when SAL annotations refer to fields of unnamed structs.

Try it out and let us know what you think

The work that we do is heavily influenced by feedback we receive on Developer Community so thank you again for your participation. Please continue to file feedback and let us know if there is a checker or rule that you would like to see added to C++ Core Check.   Stay tuned for more C++ static analysis blogs. In the meanwhile, do not hesitate to reach out to us. We can be reached via the comments below or @VisualC on Twitter.


Leave a comment

    • Gabor HorvathMicrosoft employee

      Thanks for opening a ticket! Indeed, modules are still in active development and the static analysis team has some catch up to do on that front.

      Unfortunately, there are several challenges with the lifetime analysis. The main obstacle is that we need some sort of annotation support to help users better explain the code when the default analysis is deducing the wrong things. We were planning to piggy back on the standard contracts feature but it was not included in C++20. We do plan to continue working on lifetime analysis but the contracts delay forced us to reconsider some of the priorities.

      In the meantime, there are some statement local warnings that can catch certain lifetime problems (like C26816) and we plan to ship more safety focused checks in the near future.