svn commit: r325954 - in head: . share/mk sys/conf usr.sbin/config

Bruce Evans brde at optusnet.com.au
Sat Nov 18 10:42:34 UTC 2017


On Fri, 17 Nov 2017, Warner Losh wrote:

> On Fri, Nov 17, 2017 at 6:34 PM, Rodney W. Grimes <
> freebsd at pdx.rh.cn85.dnsmgr.net> wrote:
>
>> [ Charset UTF-8 unsupported, converting... ]
>>> Kib@ posted to arch that we were removing it, nobody objected, we
>> removed
>>> it. If it was a working feature that might have a few users, that's one
>>> thing. But I don't think make lint has actually worked in at least a
>> decade.
>>
>> Thats a sad state of affairs.
>
> Indeed.

The bugs are mostly in system sources outside of lint, and user errors.

>> When I try it today, I get dozens of warnings, and several syntax errors:
>>>
>>> types.h(289): syntax error [249]

This only happens with _KERNEL defined.  It shows a bug in types.h.  Debugged
below.

>>> nvme.h(79): syntax error [249]
>>> nvme.h(105): syntax error [249]
>>> nvme.h(137): syntax error [249]
>>> nvme.h(160): syntax error [249]
>>> nvme.h(160): cannot recover from previous errors [224]

nvme.h could easily have lots more bugs than sys/types.h, since it is not
designed to support C90 or applications or be very portable.

>>> since it flags all c99 and newer usages as syntax errors. We've been

This shouldn't break use of lint on K&R or C90 sources.  But types.h is
broken.  It no longer supports K&R, C90, or most other things that are
upposed to be controlled by the visibility ifdefs in it.

>> using
>>> c99 for the kernel since about 8.x, and in the base longer than that.
>> xlint
>>> hasn't been useful since we started doing this. The types.h change went
>> in:
>>> c217b5c12e71 (       mdf 2011-12-12 18:44:17 +0000 289)typedef _Bool
>> bool;
>>> which as far as I can make out was between 8.x being branched and 9.x
>> being
>>> branched. This feature has therefore been broken for 3 major releases
>>> without any announcement, or even any bug reports coming in. Not exactly
>> a
>>> feature that has an audience that needs to be informed of anything...

It was sys/types.h that was broken then.  lint just detects the bug.

The bug in sys/types.h is that iff _KERNEL is defined, it uses _Bool without
declaring it unless
__STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER__).
stdbool.h uses the same ifdef for defining _Bool.  However, stdbool.h
uses a different definition of bool that hides the bug unless bool is
actually used -- sttdef.h #defines bool as _Bool, while sys/types.h
typedefs bool as _Bool.

The ifdef is fragile and works and fails as follows:
- when __STDC_VERSION__ >= 199901L, _Bool must be defined by the compiler
   and there is no problem.
- gcc-4.2.1 defaults to c90 so __STDC_VERSION__ is undefined and is equivalent
   to 0 (modulo the bug of the existence of -Wundef).  But __GNUC__ is 4, so
   the ifdef is not satisified anyway.  It is important to not typedef _Bool
   since it is a builtin in gcc-4 even with c90.  The __GNUC__ < 3 test is what
   implements this.
- icc apparently defines __GNUC__ as < 3, but defines _Bool, so it is important
   to not typedef _Bool for icc too.  The !defined(__INTEL_COMPILER__) test is
   what implements this.  Most __INTEL_COMPILER__ tests are used because icc
   doesn't emulate being gcc very well.
- clang is very incompatible and defaults to c11, so the ifdef is not
   satisfied by default.  When c90 is forced, clang is less incompatible and
   the ifdef works like for gcc-4 (clang sets __GNUC__ to 4 despite its
   incompatibility, and the incompatibility is not large enough to break this
   test.)

Then in lint, there is a problem getting __STDC_VERSION__ and even __GNUC__
defined correctly.  __GNUC__ should not be defined without the lint option
-g.  lint uses cc -E... instead of cpp to reduce unportabilities, but this
turns out to be fairly unportable too, due to the clang incompatiblity.
The main bugs are that lint doesn't use -std at all, and clang is incompatible.
lint only supports c90 and c90 with some gcc extensions, so should use
-std=c89 or -std=gnu90 to restrict the headers to what it supports.  The
default -std=c89 still works for gcc, but clang gives -std=c11.

lint's main CFLAGS passed to cc are:
     -E -x c  (OK so far)
     #if 0
     bogus null -D__attribute__(()) and -D__extension__(())
     #else
     -U__GNUC__  (perhaps even worse than the null definitions)
     #endif
     -Wp,-C -Wcomment (perhaps OK)
     -D__LINT__ -Dlint (OK)
-p adds:
     -Wtraditional -Wnosystem-headers
-s adds:
     -trigraphs -Wtrigraphs -pedantic -D__STRICT_ANSI__
-t adds:
     -traditional -D${MACHINE} -D${MACHINE_ARCH}
-d adds:
     -nostdinc -idirafter

>> Something larger.  Just because the src tree use of lint is failing
>> does not meant that someone out there is not using lint in some
>> other capacity.  The depreication policy is there to notify them
>> that lint well be removed as a program in the next release.
>
> Without a working sys/types.h, nothing  non-trivial will work.

Even C90 support is broken.

> Lint is totally totally broken. It's a rotting corpse that needs to be just
> gone. Since it has been totally broken for several major releases, I see no

Less broken than in 1993 for the 1990 language that its supports.  Its support
was never complete, but FreeBSD fixed all the headers to support this
language.  The headers are broken again, but not as badly as in 1993.

Full list of bugs found by lint on sys/types.h:

X _types.h(104): warning: c89 C does not support 'long long' [265]

Lint bug: doesn't give full pathnames.  Who knows where _types.h is today?
Well, it is sys/_types.h.

Headers bug: the long long abomination is hard-coded as that in the declaration
of __max_align_t.  Using the abomination is wronger than usual here.
sys/_types.h is supposed to be MI, but the abomination is MD.  Except ABIs
defeat the point of having long long (a hack to avoid expanding long) by
forcing it to be precisely 64 bits, so it is not really MD.  But since it
is not MD, it has little to do with alignment.  Using __intmax_t would fix
all of these bugs.

I fixed the corresponding bug in the definition of __intmax_t itself
(actually __int64_t) using __attribute__(__mode__(__DI__)) for gcc and icc,
and long long otherwise.  Except lint's #undef of __GNUC__ breaks detection
of gcc, and lint can't do anything good with __attribute__(()) anyway.  lint
was later fixed using ugly LONGLONG markup.  Recent axing didn't remove this
markup AFAIR.  Later, the __attribute__(()) was removed.

X endian.h(122): warning: extra bits set to 0 in conversion of 'unsigned int' to 'unsigned long long', op & [309]
X endian.h(122): warning: conversion to 'unsigned int' due to prototype, arg #1 [259]
X endian.h(122): warning: conversion to 'unsigned int' due to prototype, arg #1 [259]
X types.h(355): warning: conversion to 'unsigned int' due to prototype, arg #1 [259]
X types.h(355): warning: conversion to 'unsigned int' due to prototype, arg #1 [259]

Non-useful lint warnings.  lint doesn't trust prototypes.  -Wconversion in
gcc does much the same, but is not the default.

X _types.h(62): warning: struct __timer never defined [233]
X _types.h(63): warning: struct __mq never defined [233]

Worse non-useful lint warnings.  lint doesn't understand forward declarations
of structs.  These are a recondite C90 feature needed mainly to support
prototypes.

X endian.h(111): warning: static function __bswap64_var unused [236]

A serious problem.  The function is inline, but inline functions are not in
C90, so lint defines away the inline keyword (it is spelled __inline).
Plain static functions in header files are unusual but not wrong.

X _pthreadtypes.h(44): warning: struct pthread never defined [233]
X _pthreadtypes.h(45): warning: struct pthread_attr never defined [233]
X _pthreadtypes.h(46): warning: struct pthread_cond never defined [233]
X _pthreadtypes.h(47): warning: struct pthread_cond_attr never defined [233]
X _pthreadtypes.h(48): warning: struct pthread_mutex never defined [233]
X _pthreadtypes.h(49): warning: struct pthread_mutex_attr never defined [233]
X _pthreadtypes.h(51): warning: struct pthread_rwlock never defined [233]
X _pthreadtypes.h(52): warning: struct pthread_rwlockattr never defined [233]
X _pthreadtypes.h(53): warning: struct pthread_barrier never defined [233]
X _pthreadtypes.h(54): warning: struct pthread_barrier_attr never defined [233]
X _pthreadtypes.h(55): warning: struct pthread_spinlock never defined [233]
X _pthreadtypes.h(78): warning: struct pthread_barrierattr never defined [233]
X types.h(247): warning: struct cap_rights never defined [233]

Lots more of lint not understanding forward declarations.

X types.h(313): warning: static function __bitcount16 unused [236]
X types.h(352): warning: static function __bitcount64 unused [236]
X Lint pass2:

More of lint not understanding static inline functions.

That was without __KERNEL.  There was only 1 real bug (misuse of the long
long abomination).  Missing lint markup was a feature since it allowed lint
to detect the bug.

Extra errors with _KERNEL:

X types.h(289): syntax error [249]
X [... 2 more undefined structs]

That is only 1 extra and already debugged.

It was mostly a user error to use lint on non-C90 code.  sys/types.h should
be C90 if _ANSI_SOURCE or _POSIX_SOURCE is defined.  But defining them makes
no difference to lint warnings.

-Wno-system-headers is supposed to be the default, so adding it for -p should
have no effect, but it actually increases the number of warnings by 5.  These
are all "bitwise operation on signed value possibly unportable" in
sys/endian.h and sys/types.h.  Now it is clang than doesn't understand C90.
In __bswap16_var() and __bitcount16() we start with uint16_t and
unsign-extend to signed int for use in expressions, then do bitwise
operations.  C90's broken as designed value-preserving extension rules
give the signed int, and clang doesn't understand there are no problems
with the sign bit because the expressions barely need more than 16 bits
so they don't go near the sign bit.

Also, clang doesn't support -Wtraditional and lint doesn't have enough
control to select a working cpp.  Lint supports a -B option, but this
only allows using alternative executables for the lint passes and not
the cpp pass.

Bruce


More information about the svn-src-all mailing list