{"id":27707,"date":"2021-03-17T10:58:32","date_gmt":"2021-03-17T10:58:32","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cppblog\/?p=27707"},"modified":"2021-03-19T17:25:39","modified_gmt":"2021-03-19T17:25:39","slug":"static-analysis-fixes-improvements-and-updates-in-visual-studio-2019-16-9","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/static-analysis-fixes-improvements-and-updates-in-visual-studio-2019-16-9\/","title":{"rendered":"Static Analysis Fixes, Improvements, and Updates in Visual Studio 2019 16.9"},"content":{"rendered":"<p>The C++ static analysis team&#8217;s goal is to make 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 <a href=\"https:\/\/developercommunity.visualstudio.com\/spaces\/8\/index.html\">C++ Developer Community<\/a> page. Thank you for engaging with us and giving us great feedback on the past releases and early previews leading to this point. Going forward, the C++ team will provide a list of code analysis bug and crash fixes with every GA release of Visual Studio. Below is the compilation of improvements and bug fixes that were made from VS 2019 16.8 to 16.9 for <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/build\/reference\/analyze-code-analysis\">code analysis<\/a> and <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/using-the-cpp-core-guidelines-checkers\">Cpp Core Check<\/a>.<\/p>\n<h3>Analysis crash fixes:<\/h3>\n<ul>\n<li>Using an index operator on the address of a non-address and non-array object.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">void function() {\r\n    int buf{};\r\n    ((unsigned char*)&amp;buf)[3] = 1;\r\n}<\/pre>\n<ul>\n<li>Functions with more than 255 arguments would cause a crash during analysis.<\/li>\n<li>Array member field addresses were incorrectly converted in dynamic initializer function.<\/li>\n<li>Fixed internal compiler error for aggregate initialization in \/analyze.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">char c[]{'1', {}};<\/pre>\n<ul>\n<li>Fixed a crash caused during analysis of bitfields and enums.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">struct TestStruct {\r\npublic:\r\n    enum TestEnum : char { Dummy };\r\n    TestEnum    m1 : 1;\r\n    TestEnum    m2 : 1;\r\n    short       m3;\r\n}\r\n\r\nTestStruct Test() {\r\n    return{ TestStruct::Dummy, TestStruct::Dummy, {} };\r\n}<\/pre>\n<ul>\n<li>Specifying an array of three elements but only providing two elements in the initializer list.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">#include &lt;array&gt;\r\n#include &lt;string&gt;\r\nusing namespace std;\r\nvoid function() {\r\n    array&lt;string, 3&gt; arr {\"one\", \"two\"};\r\n}<\/pre>\n<ul>\n<li>Fixed crash on empty KMDF projects.<\/li>\n<\/ul>\n<h3>Bug fixes:<\/h3>\n<ul>\n<li>Addressed noisy warnings in an object&#8217;s destructor when a function that would have initialized or updated the object fails.<\/li>\n<li>Support for the GSL functions <code>gsl::as_bytes<\/code> and <code>gsl::as_writable_bytes<\/code> was added to prevent <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26710\">C26710<\/a> warnings from being issued against otherwise valid buffer accesses.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">#include &lt;gsl\/span&gt;\r\nvoid fn1(gsl::span&lt;int, 5&gt; view, byte val) {\r\n    auto bview = as_writable_bytes(view);\r\n    bview[19] = val;  \/\/ OK\r\n    bview[20] = val;  \/\/ C26710 &amp; C26000\r\n}<\/pre>\n<ul>\n<li>Fixed ruleset loading failures that occurred when a relative path of a ruleset was used in combination with the exact path of a ruleset directory.\nE.g: <code>\/analyze:rulesetdirectory f:\\customRuleset \/analyze:ruleset myrules.ruleset<\/code><\/li>\n<li>Fixed false positives of <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c6237\">C6237<\/a> and <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c6285\">C6285<\/a> on <code>if constexpr<\/code> expressions.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">constexpr bool get_condition_a() { return false; }\r\nconstexpr bool some_other_check() { return true; }\r\nconstexpr void f1() {\r\n    constexpr bool some_condition = get_condition_a();\r\n    if constexpr (some_condition &amp;&amp; some_other_check()) {  \/\/Previously issued C6237\r\n        \/\/...\r\n    }\r\n}\r\n\r\nconstexpr void f2() {\r\n    constexpr int print_debug = false;\r\n    constexpr int headers_debug = false;\r\n    if constexpr (print_debug == true || headers_debug == true) { \/\/Previously issued C6285\r\n        \/\/...\r\n    }\r\n}<\/pre>\n<ul>\n<li>Fixed false positive of <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26444\">C26444<\/a> when returning upon construction.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">struct Test {\r\n    int i{};\r\n};\r\n\r\nTest foo() {\r\n    return Test(); \/\/Previously issued C26444\r\n}<\/pre>\n<ul>\n<li>Fixed issue where casts with the same source and destination types were being misidentified as reinterpret cast, which would produce <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26490\">C26490<\/a> instead of <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26473\">C26473<\/a>.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">struct S{};\r\nvoid foo(S* s) {\r\n    S* s2 = static_cast&lt;S*&gt;(s); \/\/Previously C26490, now C26473\r\n}<\/pre>\n<ul>\n<li>Fixed an incorrect <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26465\">C26465<\/a> warning when attempting to cast away const. <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26492\">C26492<\/a> will now be issued instead.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">struct S{};\r\nvoid foo(const S&amp; s) {\r\n    const S* pS = &amp;s;\r\n    S* s2 = const_cast&lt;S*&gt;(pS); \/\/Previously C26465, now C26492\r\n}<\/pre>\n<ul>\n<li>Fixed false positive for <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26814\">C26814<\/a> that would be issued on <code>const<\/code> member variables.<\/li>\n<li>Fixed corner case where PREFast entered an infinite loop while examining buffer extents.<\/li>\n<li>Fixed false positive of <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26815\">C26815<\/a> that fired when assigning a value to a <code>std::optional<\/code> that is passed by reference into a function.<\/li>\n<li>Fixed false positive <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26816\">C26816<\/a> when returning a pointer from a vector of pointers.<\/li>\n<li>Fixed false positive of <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26485\">C26485<\/a> which appeared when calls to printf used string literals chosen by a ternary operator.<\/li>\n<\/ul>\n<h3>Additional changes:<\/h3>\n<ul>\n<li>Updated support for SARIF format to conform to the version 2.1 specification.<\/li>\n<li>Added SARIF support for additional rule action levels for ruleset files.\nThe rule actions can now be specified as \u201cNone\u201d, \u201cDefault\u201d, \u201cInfo\u201d, \u201cWarning\u201d, and \u201cError\u201d.<\/li>\n<li>Removed <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26443\">C26443<\/a> \u2013 The enforcement for <a href=\"https:\/\/github.com\/isocpp\/CppCoreGuidelines\/blob\/master\/CppCoreGuidelines.md#c128-virtual-functions-should-specify-exactly-one-of-virtual-override-or-final\">C.128<\/a> has changed making C26443 obsolete.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n&lt;RuleSet Name=\"Example For Warning Levels\" Description=\"\" ToolsVersion=\"16.0\"&gt;\r\n  &lt;IncludeAll Action=\"Info\" \/&gt;\r\n  &lt;Rules AnalyzerId=\"Microsoft.Analyzers.NativeCodeAnalysis\"\r\n         RuleNamespace=\"Microsoft.Rules.Native\"&gt;\r\n    &lt;Rule Id=\"C6001\" Action=\"Error\" \/&gt;\r\n    &lt;Rule Id=\"C6011\" Action=\"Warning\" \/&gt;\r\n    &lt;Rule Id=\"C6101\" Action=\"Info\" \/&gt;\r\n    &lt;Rule Id=\"C6201\" Action=\"Default\" \/&gt;\r\n    &lt;Rule Id=\"C6386\" Action=\"None\" \/&gt;\r\n  &lt;\/Rules&gt;\r\n&lt;\/RuleSet&gt;<\/pre>\n<ul>\n<li>Using a C-style void cast to ignore return values decorated with <code>[[nodiscard]]<\/code> previously issued <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26493\">C26493<\/a> urging developers to not use C-style casts. The new rule <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26457\">C26457<\/a> will be issued in its place, guiding the developer to assign the return value to <code>std::ignore<\/code> if they intend to discard the return value.<\/li>\n<\/ul>\n<pre class=\"prettyprint\">#include &lt;tuple&gt;\r\n\r\nstruct S{};\r\n[[nodiscard]] S fn1();\r\n\r\nvoid function() {\r\n    (void)fn1(); \/\/Previously C26493, now C26457\r\n    std::ignore = fn1();\r\n}<\/pre>\n<ul>\n<li>The text for <a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/code-quality\/c26496\">C26496<\/a> was updated from <code>\u201cThe variable '%variable%' is assigned only once, mark it as const (con.4)\u201d<\/code> to <code>\u201cThe variable '%variable%' does not change after construction, mark it as const (con.4)\u201d.<\/code><\/li>\n<\/ul>\n<p>As mentioned earlier, the work that we do is heavily influenced by feedback we receive on the <a href=\"https:\/\/developercommunity.visualstudio.com\/spaces\/8\/index.html\">Developer Community<\/a> 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.<\/p>\n<p>Stay tuned for more C++ static analysis blogs as we work towards 16.10. Coming soon are posts on improvements to C++ Core Check rules, improved diagnostics, and an update on the Microsoft\/GSL GitHub project. In the meanwhile, do not hesitate to reach out to us. We can be reached via the comments below or <a href=\"https:\/\/twitter.com\/visualc\">@VisualC<\/a> on Twitter.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>MSVC static analysis update for Visual Studio 16.9.<\/p>\n","protected":false},"author":6068,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1,512,277],"tags":[140,245,163],"class_list":["post-27707","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","category-general-cpp-series","category-writing-code","tag-c","tag-cppcorecheck","tag-static-analysis"],"acf":[],"blog_post_summary":"<p>MSVC static analysis update for Visual Studio 16.9.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/27707","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/6068"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=27707"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/27707\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=27707"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=27707"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=27707"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}