In addition to other test coverage, this adds the examples from
  https://cwe.mitre.org/data/definitions/457.html
(aka "CWE-457: Use of Uninitialized Variable")

For reference, the output from -fanalyzer looks like this
(after stripping away the DejaGnu directives):

uninit-CWE-457-examples.c: In function 'example_2_bad_code':
uninit-CWE-457-examples.c:56:3: warning: use of uninitialized value 'bN' 
[CWE-457] [-Wanalyzer-use-of-uninitialized-value]
   56 |   repaint(aN, bN); /* { dg-warning "use of uninitialized value 'bN'" } 
*/
      |   ^~~~~~~~~~~~~~~
  'example_2_bad_code': events 1-4
    |
    |   34 |   int aN, bN;
    |      |           ^~
    |      |           |
    |      |           (1) region created on stack here
    |   35 |   switch (ctl) {
    |      |   ~~~~~~
    |      |   |
    |      |   (2) following 'default:' branch...
    |......
    |   51 |   default:
    |      |   ~~~~~~~
    |      |   |
    |      |   (3) ...to here
    |......
    |   56 |   repaint(aN, bN);
    |      |   ~~~~~~~~~~~~~~~
    |      |   |
    |      |   (4) use of uninitialized value 'bN' here
    |
uninit-CWE-457-examples.c: In function 'example_3_bad_code':
uninit-CWE-457-examples.c:95:3: warning: use of uninitialized value 
'test_string' [CWE-457] [-Wanalyzer-use-of-uninitialized-value]
   95 |   printf("%s", test_string);
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~
  'example_3_bad_code': events 1-4
    |
    |   90 |   char *test_string;
    |      |         ^~~~~~~~~~~
    |      |         |
    |      |         (1) region created on stack here
    |   91 |   if (i != err_val)
    |      |      ~
    |      |      |
    |      |      (2) following 'false' branch (when 'i == err_val')...
    |......
    |   95 |   printf("%s", test_string);
    |      |   ~~~~~~~~~~~~~~~~~~~~~~~~~
    |      |   |
    |      |   (3) ...to here
    |      |   (4) use of uninitialized value 'test_string' here
    |

Successfully regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-7157-g91b27d984ce174.

gcc/testsuite/ChangeLog:
        * gcc.dg/analyzer/uninit-1.c: Add test coverage for shifts,
        comparisons, +, -, *, /, and __builtin_strlen.
        * gcc.dg/analyzer/uninit-CWE-457-examples.c: New test.

Signed-off-by: David Malcolm <dmalc...@redhat.com>
---
 gcc/testsuite/gcc.dg/analyzer/uninit-1.c      |  85 +++++++++++++
 .../gcc.dg/analyzer/uninit-CWE-457-examples.c | 119 ++++++++++++++++++
 2 files changed, 204 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-CWE-457-examples.c

diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-1.c 
b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c
index cb7b252ef45..9a6576e1b0a 100644
--- a/gcc/testsuite/gcc.dg/analyzer/uninit-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c
@@ -1,4 +1,5 @@
 #include "analyzer-decls.h"
+typedef __SIZE_TYPE__ size_t;
 
 int test_1 (void)
 {
@@ -42,3 +43,87 @@ int test_6 (int i)
   int arr[10]; /* { dg-message "region created on stack here" } */
   return arr[i]; /* { dg-warning "use of uninitialized value 'arr\\\[i\\\]'" } 
*/
 }
+
+int test_rshift_rhs (int i)
+{
+  int j; /* { dg-message "region created on stack here" } */
+  return i >> j; /* { dg-warning "use of uninitialized value 'j'" } */
+}
+
+int test_lshift_rhs (int i)
+{
+  int j; /* { dg-message "region created on stack here" } */
+  return i << j; /* { dg-warning "use of uninitialized value 'j'" } */
+}
+
+int test_rshift_lhs (int i)
+{
+  int j; /* { dg-message "region created on stack here" } */
+  return j >> i; /* { dg-warning "use of uninitialized value 'j'" } */
+}
+
+int test_lshift_lhs (int i)
+{
+  int j; /* { dg-message "region created on stack here" } */
+  return j << i; /* { dg-warning "use of uninitialized value 'j'" } */
+}
+
+int test_cmp (int i)
+{
+  int j; /* { dg-message "region created on stack here" } */
+  return i < j; /* { dg-warning "use of uninitialized value 'j'" } */
+}
+
+float test_plus_rhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return x + y; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+float test_plus_lhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return y + x; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+float test_minus_rhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return x - y; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+float test_minus_lhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return y - x; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+float test_times_rhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return x * y; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+float test_times_lhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return y * x; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+float test_divide_rhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return x / y; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+float test_divide_lhs (float x)
+{
+  float y; /* { dg-message "region created on stack here" } */
+  return y / x; /* { dg-warning "use of uninitialized value 'y'" } */
+}
+
+size_t test_builtin_strlen (void)
+{
+  const char *ptr; /* { dg-message "region created on stack here" } */
+  return __builtin_strlen (ptr); /* { dg-warning "use of uninitialized value 
'ptr'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-CWE-457-examples.c 
b/gcc/testsuite/gcc.dg/analyzer/uninit-CWE-457-examples.c
new file mode 100644
index 00000000000..47d9c89d773
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/uninit-CWE-457-examples.c
@@ -0,0 +1,119 @@
+/* Examples adapted from https://cwe.mitre.org/data/definitions/457.html
+   which states "Copyright © 2006–2022, The MITRE Corporation. CWE, CWSS, 
CWRAF, and the CWE logo are trademarks of The MITRE Corporation."
+   and which has this on:
+     https://cwe.mitre.org/about/termsofuse.html
+
+   Terms of Use
+
+   CWE™ is free to use by any organization or individual for any research, 
development, and/or commercial purposes, per these CWE Terms of Use. The MITRE 
Corporation ("MITRE") has copyrighted the CWE List, Top 25, CWSS, and CWRAF for 
the benefit of the community in order to ensure each remains a free and open 
standard, as well as to legally protect the ongoing use of it and any resulting 
content by government, vendors, and/or users. CWE is a trademark of MITRE. 
Please contact c...@mitre.org if you require further clarification on this 
issue.
+
+   LICENSE
+
+   CWE Submissions: By submitting materials to The MITRE Corporation’s 
("MITRE") Common Weakness Enumeration Program (CWE™), you hereby grant to MITRE 
a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable 
copyright license to use, reproduce, prepare derivative works of, publicly 
display, publicly perform, sublicense, and distribute your submitted materials 
and derivative works. Unless otherwise required by applicable law or agreed to 
in writing, it is understood that you are providing such materials on an "AS 
IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
implied, including, without limitation, any warranties or conditions of TITLE, 
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+
+   CWE Usage: MITRE hereby grants you a non-exclusive, royalty-free license to 
use CWE for research, development, and commercial purposes. Any copy you make 
for such purposes is authorized on the condition that you reproduce MITRE’s 
copyright designation and this license in any such copy.
+
+   DISCLAIMERS
+
+   ALL DOCUMENTS AND THE INFORMATION CONTAINED IN THE CWE ARE PROVIDED ON AN 
"AS IS" BASIS AND THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS 
SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, 
AGENTS, AND EMPLOYEES, DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING 
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL 
NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS 
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+
+   IN NO EVENT SHALL THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS 
SPONSORED BY (IF ANY), THE MITRE CORPORATION, ITS BOARD OF TRUSTEES, OFFICERS, 
AGENTS, AND EMPLOYEES BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
CONNECTION WITH THE INFORMATION OR THE USE OR OTHER DEALINGS IN THE CWE.  */
+
+#include <stdio.h>
+
+/* (example 1 from the page is written in PHP).  */
+
+/* Example 2.  */
+
+extern int repaint(int, int);
+
+#define NEXT_SZ 42
+
+void example_2_bad_code (int ctl, int i)
+{
+  int aN, bN; /* { dg-message "11: region created on stack here" } */
+  switch (ctl) { /* { dg-message "following 'default:' branch\\.\\.\\." } */
+  case -1:
+    aN = 0;
+    bN = 0;
+    break;
+
+  case 0:
+    aN = i;
+    bN = -i;
+    break;
+
+  case 1:
+    aN = i + NEXT_SZ;
+    bN = i - NEXT_SZ;
+    break;
+
+  default:
+    aN = -1;
+    aN = -1;
+    break;
+  }
+  repaint(aN, bN); /* { dg-warning "use of uninitialized value 'bN'" } */
+}
+
+void example_2_fixed (int ctl, int i)
+{
+  int aN, bN;
+  switch (ctl) {
+  case -1:
+    aN = 0;
+    bN = 0;
+    break;
+
+  case 0:
+    aN = i;
+    bN = -i;
+    break;
+
+  case 1:
+    aN = i + NEXT_SZ;
+    bN = i - NEXT_SZ;
+    break;
+
+  default:
+    aN = -1;
+    bN = -1; /* (fixing bN/aN typo)  */
+    break;
+  }
+  repaint(aN, bN);
+}
+
+/* Example 3.  */
+
+void example_3_bad_code (int i, int err_val)
+{
+  char *test_string; /* { dg-message "9: region created on stack here" } */
+  if (i != err_val)  /* { dg-message "following 'false' branch \\(when 'i == 
err_val'\\)\\.\\.\\." } */
+  {
+      test_string = "Hello World!";
+  }
+  printf("%s", test_string); /* { dg-warning "use of uninitialized value 
'test_string'" } */
+}
+
+void example_3_fix_a (int i, int err_val)
+{
+  char *test_string = "Done at the beginning";
+  if (i != err_val)
+  {
+      test_string = "Hello World!";
+  }
+  printf("%s", test_string);
+}
+
+void example_3_fix_b (int i, int err_val)
+{
+  char *test_string;
+  if (i != err_val)
+  {
+      test_string = "Hello World!";
+  }
+  else {
+    test_string = "Done on the other side!";
+  }
+  printf("%s", test_string);
+}
-- 
2.26.3

Reply via email to