18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci///Find conditions where if and else branch are functionally
38c2ecf20Sopenharmony_ci// identical.
48c2ecf20Sopenharmony_ci//
58c2ecf20Sopenharmony_ci// There can be false positives in cases where the positional
68c2ecf20Sopenharmony_ci// information is used (as with lockdep) or where the identity
78c2ecf20Sopenharmony_ci// is a placeholder for not yet handled cases.
88c2ecf20Sopenharmony_ci// Unfortunately there also seems to be a tendency to use
98c2ecf20Sopenharmony_ci// the last if else/else as a "default behavior" - which some
108c2ecf20Sopenharmony_ci// might consider a legitimate coding pattern. From discussion
118c2ecf20Sopenharmony_ci// on kernelnewbies though it seems that this is not really an
128c2ecf20Sopenharmony_ci// accepted pattern and if at all it would need to be commented
138c2ecf20Sopenharmony_ci//
148c2ecf20Sopenharmony_ci// In the Linux kernel it does not seem to actually report
158c2ecf20Sopenharmony_ci// false positives except for those that were documented as
168c2ecf20Sopenharmony_ci// being intentional.
178c2ecf20Sopenharmony_ci// the two known cases are:
188c2ecf20Sopenharmony_ci//   arch/sh/kernel/traps_64.c:read_opcode()
198c2ecf20Sopenharmony_ci//        } else if ((pc & 1) == 0) {
208c2ecf20Sopenharmony_ci//              /* SHcompact */
218c2ecf20Sopenharmony_ci//              /* TODO : provide handling for this.  We don't really support
228c2ecf20Sopenharmony_ci//                 user-mode SHcompact yet, and for a kernel fault, this would
238c2ecf20Sopenharmony_ci//                 have to come from a module built for SHcompact.  */
248c2ecf20Sopenharmony_ci//              return -EFAULT;
258c2ecf20Sopenharmony_ci//      } else {
268c2ecf20Sopenharmony_ci//              /* misaligned */
278c2ecf20Sopenharmony_ci//              return -EFAULT;
288c2ecf20Sopenharmony_ci//      }
298c2ecf20Sopenharmony_ci//   fs/kernfs/file.c:kernfs_fop_open()
308c2ecf20Sopenharmony_ci//       * Both paths of the branch look the same.  They're supposed to
318c2ecf20Sopenharmony_ci//       * look that way and give @of->mutex different static lockdep keys.
328c2ecf20Sopenharmony_ci//       */
338c2ecf20Sopenharmony_ci//      if (has_mmap)
348c2ecf20Sopenharmony_ci//              mutex_init(&of->mutex);
358c2ecf20Sopenharmony_ci//      else
368c2ecf20Sopenharmony_ci//              mutex_init(&of->mutex);
378c2ecf20Sopenharmony_ci//
388c2ecf20Sopenharmony_ci// All other cases look like bugs or at least lack of documentation
398c2ecf20Sopenharmony_ci//
408c2ecf20Sopenharmony_ci// Confidence: Moderate
418c2ecf20Sopenharmony_ci// Copyright: (C) 2016 Nicholas Mc Guire, OSADL.
428c2ecf20Sopenharmony_ci// Comments:
438c2ecf20Sopenharmony_ci// Options: --no-includes --include-headers
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_civirtual org
468c2ecf20Sopenharmony_civirtual report
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci@cond@
498c2ecf20Sopenharmony_cistatement S1;
508c2ecf20Sopenharmony_ciposition p;
518c2ecf20Sopenharmony_ci@@
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci* if@p (...) S1 else S1
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci@script:python depends on org@
568c2ecf20Sopenharmony_cip << cond.p;
578c2ecf20Sopenharmony_ci@@
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cicocci.print_main("WARNING: possible condition with no effect (if == else)",p)
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci@script:python depends on report@
628c2ecf20Sopenharmony_cip << cond.p;
638c2ecf20Sopenharmony_ci@@
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cicoccilib.report.print_report(p[0],"WARNING: possible condition with no effect (if == else)")
66