gcc/contrib/dg-lint
David Malcolm 8d6de758cc contrib: add dg-lint and libgdiagnostics.py [PR116163]
Changed in v2:
- eliminated COMMON_MISSPELLINGS in favor of retesting with a regexp
  that adds underscores
- add a list of KNOWN_DIRECTIVES, and complain if we see a directive
  that isn't in the list
- various refactorings to reduce the nesting within the script
- skip more kinds of file ('README', 'Makefile.am', 'Makefile.in',
  'gen_directive_tests')
- keep track of the number of files scanned and report it and the end
  with a note

This patch adds a new dg-lint subdirectory below contrib, containing
a "dg-lint" script for detecting common mistakes made in our DejaGnu
tests.

Specifically, DejaGnu's dg.exp's dg-get-options has a regexp for
detecting dg- directives
  https://git.savannah.gnu.org/gitweb/?p=dejagnu.git;a=blob;f=lib/dg.exp
here's the current:

    set tmp [grep $prog "{\[ \t\]\+dg-\[-a-z\]\+\[ \t\]\+.*\[ \t\]\+}" line]

which if I'm reading it right requires a "{", then one or more tab/space
chars, then a "dg-" directive name, then one of more tab/space
characters, then anything (for arguments to the directive), then one of
more tab/space character, then a "}".

There are numerous places in our testsuite which look like attempts to
use a directive, but which don't match this regexp.

The script warns about such places, along with a list of misspelled
directives (currently just "dg_options" for "dg-options"), and a warning
if a dg-do appears after a dg-require-* (as per
https://gcc.gnu.org/onlinedocs/gccint/Directives.html
"This directive must appear after any dg-do directive in the test
and before any dg-additional-sources directive." for
dg-require-effective-target.

dg-lint uses libgdiagnostics to report its results; the patch adds a
new libgdiagnostics.py script below contrib/dg-lint.  This uses Python's
ctypes module to expose libgdianostics.so to Python via FFI.  Hence
the warnings have colorization, quote the pertinent parts of the tested
file, can have fix-it hints, etc.  Here's the output from the tests, run
from the top-level directory:

$ LD_LIBRARY_PATH=../build/gcc/ ./contrib/dg-lint/dg-lint contrib/dg-lint/test-*.c
contrib/dg-lint/test-1.c:6:6: warning: misspelled directive: 'dg_final'; did you mean 'dg-final'?
    6 | /* { dg_final { scan_assembler_times "vmsumudm" 2 } } */
      |      ^~~~~~~~
      |      dg-final
contrib/dg-lint/test-1.c:15:4: warning: directive 'dg-output-file' appears not to match dg.exp's regexp
   15 |    dg-output-file "m4.out"
      |    ^~~~~~~~~~~~~~
contrib/dg-lint/test-1.c:18:4: warning: directive 'dg-output-file' appears not to match dg.exp's regexp
   18 |    dg-output-file "m4.out" }
      |    ^~~~~~~~~~~~~~
contrib/dg-lint/test-1.c:21:6: warning: directive 'dg-output-file' appears not to match dg.exp's regexp
   21 |    { dg-output-file "m4.out"
      |      ^~~~~~~~~~~~~~
contrib/dg-lint/test-1.c:24:5: warning: directive 'dg-output-file' appears not to match dg.exp's regexp
   24 |    {dg-output-file "m4.out"}
      |     ^~~~~~~~~~~~~~
contrib/dg-lint/test-1.c:27:6: warning: directive 'dg-output-file' appears not to match dg.exp's regexp
   27 |    { dg-output-file, "m4.out" }
      |      ^~~~~~~~~~~~~~
contrib/dg-lint/test-2.c:4:6: warning: 'dg-do' after 'dg-require-effective-target'
    4 | /* { dg-do compile } */
      |      ^~~~~
contrib/dg-lint/test-2.c:3:6: note: 'dg-require-effective-target' was here
    3 | /* { dg-require-effective-target c++11 } */
      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~

I don't yet have a way to verify these tests (clearly we can't use
DejaGnu for this).

These Python bindings could be used by other projects, but so far I only
implemented what I needed for dg-lint.

Running the test on the GCC source tree finds dozens of issues, which
followup patches address.

Tested with Python 3.8

contrib/ChangeLog:
	PR testsuite/116163
	* dg-lint/dg-lint: New file.
	* dg-lint/libgdiagnostics.py: New file.
	* dg-lint/test-1.c: New file.
	* dg-lint/test-2.c: New file.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2025-03-27 19:46:41 -04:00
..
dg-lint
libgdiagnostics.py
test-1.c
test-2.c