Index: ObsoleteFiles.inc =================================================================== --- ObsoleteFiles.inc +++ ObsoleteFiles.inc @@ -38,6 +38,15 @@ # xargs -n1 | sort | uniq -d; # done +# 2017XXXX: lint(1) removal +OLD_FILES+=usr/bin/lint +OLD_FILES+=usr/libexec/lint1 +OLD_FILES+=usr/libexec/lint2 +OLD_FILES+=usr/libdata/lint/llib-lposix.ln +OLD_FILES+=usr/libdata/lint/llib-lstdc.ln +OLD_FILES+=usr/share/man/man1/lint.1.gz +OLD_FILES+=usr/share/man/man7/lint.7.gz +OLD_DIRS+=usr/libdata/lint # 20171108: badsect(8) removal OLD_FILES+=sbin/badsect OLD_FILES+=rescue/badsect Index: etc/mtree/BSD.usr.dist =================================================================== --- etc/mtree/BSD.usr.dist +++ etc/mtree/BSD.usr.dist @@ -56,8 +56,6 @@ .. ldscripts .. - lint - .. pkgconfig .. .. Index: share/man/man7/hier.7 =================================================================== --- share/man/man7/hier.7 +++ share/man/man7/hier.7 @@ -364,10 +364,6 @@ linker scripts; see .Xr ld 1 -.It Pa lint/ -various prebuilt lint libraries; -see -.Xr lint 1 .El .Pp .It Pa libexec/ Index: share/man/man9/style.9 =================================================================== --- share/man/man9/style.9 +++ share/man/man9/style.9 @@ -867,14 +867,11 @@ compliant in the repository must not diverge from compliance. .Pp Whenever possible, code should be run through a code checker -(e.g., -.Xr lint 1 -or +(e.g., various static analyzers or .Nm cc Fl Wall ) and produce minimal warnings. .Sh SEE ALSO .Xr indent 1 , -.Xr lint 1 , .Xr err 3 , .Xr warn 3 , .Xr style.Makefile 5 Index: targets/pseudo/hosttools/Makefile.depend.host =================================================================== --- targets/pseudo/hosttools/Makefile.depend.host +++ targets/pseudo/hosttools/Makefile.depend.host @@ -15,7 +15,6 @@ usr.bin/mkcsmapper_static \ usr.bin/mkesdb_static \ usr.bin/xinstall \ - usr.bin/xlint/xlint \ usr.bin/yacc \ usr.sbin/config \ usr.sbin/crunch/crunchgen \ Index: targets/pseudo/userland/Makefile.depend =================================================================== --- targets/pseudo/userland/Makefile.depend +++ targets/pseudo/userland/Makefile.depend @@ -417,10 +417,6 @@ usr.bin/write \ usr.bin/xargs \ usr.bin/xinstall \ - usr.bin/xlint/lint1 \ - usr.bin/xlint/lint2 \ - usr.bin/xlint/llib \ - usr.bin/xlint/xlint \ usr.bin/xo \ usr.bin/xstr \ usr.bin/xz \ Index: usr.bin/Makefile =================================================================== --- usr.bin/Makefile +++ usr.bin/Makefile @@ -278,9 +278,6 @@ SUBDIR.${MK_TOOLCHAIN}+= unifdef SUBDIR.${MK_TOOLCHAIN}+= size SUBDIR.${MK_TOOLCHAIN}+= strings -.if ${MACHINE_ARCH} != "aarch64" # ARM64TODO xlint does not build -SUBDIR.${MK_TOOLCHAIN}+= xlint -.endif SUBDIR.${MK_TOOLCHAIN}+= xstr SUBDIR.${MK_TOOLCHAIN}+= yacc SUBDIR.${MK_VI}+= vi Index: usr.bin/xlint/Makefile =================================================================== --- usr.bin/xlint/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $NetBSD: Makefile,v 1.2 1995/07/03 21:23:45 cgd Exp $ -# $FreeBSD$ - -.if ${LINT} == "lint" -_llib= llib -.else -_llib= -.endif - -SUBDIR= lint1 lint2 xlint ${_llib} - -.include Index: usr.bin/xlint/Makefile.inc =================================================================== --- usr.bin/xlint/Makefile.inc +++ /dev/null @@ -1,15 +0,0 @@ -# $NetBSD: Makefile.inc,v 1.8 2002/02/04 00:18:32 thorpej Exp $ -# $FreeBSD$ - -WARNS?= 0 - -.PATH: ${.CURDIR}/../common - -.if exists(${.CURDIR}/../arch/${MACHINE_ARCH}) -CFLAGS+= -I${.CURDIR}/../arch/${MACHINE_ARCH} -.else -CFLAGS+= -I${.CURDIR}/../arch/${MACHINE_CPUARCH} -.endif -CFLAGS+= -I${.CURDIR}/../common - -OBJECT_FMT= ELF Index: usr.bin/xlint/arch/aarch64/targparam.h =================================================================== --- usr.bin/xlint/arch/aarch64/targparam.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2014/08/10 05:47:38 matt Exp $ */ - -/*- - * Copyright (c) 2014 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Matt Thomas of 3am Software Foundry. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ -#include "lp64.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (16 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/amd64/targparam.h =================================================================== --- usr.bin/xlint/arch/amd64/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.2 2002/01/30 06:55:00 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "lp64.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (16 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/arm/targparam.h =================================================================== --- usr.bin/xlint/arch/arm/targparam.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:19 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#if defined(TARGET_OBJFMT_ELF) -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 -#else -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#endif - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#if defined(TARGET_OBJFMT_ELF) -/* XXX ARM ELF ABI says packed enums -- variable size! */ -#define ENUM_SIZE (4 * CHAR_BIT) -#else -#define ENUM_SIZE (4 * CHAR_BIT) -#endif Index: usr.bin/xlint/arch/i386/targparam.h =================================================================== --- usr.bin/xlint/arch/i386/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:19 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (12 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/m68000/targparam.h =================================================================== --- usr.bin/xlint/arch/m68000/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/m68k/targparam.h =================================================================== --- usr.bin/xlint/arch/m68k/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:19 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (12 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/mips/targparam.h =================================================================== --- usr.bin/xlint/arch/mips/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:19 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/ns32k/targparam.h =================================================================== --- usr.bin/xlint/arch/ns32k/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:20 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (12 * CHAR_BIT) /* XXX double-check */ - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/powerpc/targparam.h =================================================================== --- usr.bin/xlint/arch/powerpc/targparam.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:20 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/powerpc64/targparam.h =================================================================== --- usr.bin/xlint/arch/powerpc64/targparam.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:20 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "lp64.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/riscv/targparam.h =================================================================== --- usr.bin/xlint/arch/riscv/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.2 2002/01/30 06:55:00 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "lp64.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (16 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/sh3/targparam.h =================================================================== --- usr.bin/xlint/arch/sh3/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:20 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/sparc/targparam.h =================================================================== --- usr.bin/xlint/arch/sparc/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:21 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/sparc64/targparam.h =================================================================== --- usr.bin/xlint/arch/sparc64/targparam.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $NetBSD: targparam.h,v 1.3 2002/01/31 23:31:34 he Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "lp64.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (16 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/vax/targparam.h =================================================================== --- usr.bin/xlint/arch/vax/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:22 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "ilp32.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (8 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/arch/x86_64/targparam.h =================================================================== --- usr.bin/xlint/arch/x86_64/targparam.h +++ /dev/null @@ -1,53 +0,0 @@ -/* $NetBSD: targparam.h,v 1.1 2002/01/18 20:39:22 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Machine-dependent target parameters for lint1. - */ - -#include "lp64.h" - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. Note this MUST be - * kept in sync with the compiler! - */ - -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 - -#define FLOAT_SIZE (4 * CHAR_BIT) -#define DOUBLE_SIZE (8 * CHAR_BIT) -#define LDOUBLE_SIZE (16 * CHAR_BIT) - -#define ENUM_SIZE (4 * CHAR_BIT) Index: usr.bin/xlint/common/emit.c =================================================================== --- usr.bin/xlint/common/emit.c +++ /dev/null @@ -1,234 +0,0 @@ -/* $NetBSD: emit.c,v 1.2 2002/01/21 19:49:51 tv Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: emit.c,v 1.2 2002/01/21 19:49:51 tv Exp $"); -#endif - -#include -#include -#include - -#include "lint.h" - -/* name and handle of output file */ -static const char *loname; -static FILE *lout; - -/* output buffer data */ -ob_t ob; - -static void outxbuf(void); - - -/* - * initialize output - */ -void -outopen(const char *name) -{ - - loname = name; - - /* Open output file */ - if ((lout = fopen(name, "w")) == NULL) - err(1, "cannot open '%s'", name); - - /* Create output buffer */ - ob.o_len = 1024; - ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len; -} - -/* - * flush output buffer and close file - */ -void -outclose(void) -{ - - outclr(); - if (fclose(lout) == EOF) - err(1, "cannot close '%s'", loname); -} - -/* - * resize output buffer - */ -static void -outxbuf(void) -{ - ptrdiff_t coffs; - - coffs = ob.o_nxt - ob.o_buf; - ob.o_len *= 2; - ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len; - ob.o_nxt = ob.o_buf + coffs; -} - -/* - * reset output buffer - * if it is not empty, it is flushed - */ -void -outclr(void) -{ - size_t sz; - - if (ob.o_buf != ob.o_nxt) { - outchar('\n'); - sz = ob.o_nxt - ob.o_buf; - if (sz > ob.o_len) - errx(1, "internal error: outclr() 1"); - if (fwrite(ob.o_buf, sz, 1, lout) != 1) - err(1, "cannot write to %s", loname); - ob.o_nxt = ob.o_buf; - } -} - -/* - * write a character to the output buffer - */ -void -outchar(int c) -{ - - if (ob.o_nxt == ob.o_end) - outxbuf(); - *ob.o_nxt++ = (char)c; -} - -/* - * write a character to the output buffer, qouted if necessary - */ -void -outqchar(int c) -{ - - if (isprint(c) && c != '\\' && c != '"' && c != '\'') { - outchar(c); - } else { - outchar('\\'); - switch (c) { - case '\\': - outchar('\\'); - break; - case '"': - outchar('"'); - break; - case '\'': - outchar('\''); - break; - case '\b': - outchar('b'); - break; - case '\t': - outchar('t'); - break; - case '\n': - outchar('n'); - break; - case '\f': - outchar('f'); - break; - case '\r': - outchar('r'); - break; - case '\v': - outchar('v'); - break; - case '\a': - outchar('a'); - break; - default: - outchar((((u_int)c >> 6) & 07) + '0'); - outchar((((u_int)c >> 3) & 07) + '0'); - outchar((c & 07) + '0'); - break; - } - } -} - -/* - * write a strint to the output buffer - * the string must not contain any characters which - * should be quoted - */ -void -outstrg(const char *s) -{ - - while (*s != '\0') { - if (ob.o_nxt == ob.o_end) - outxbuf(); - *ob.o_nxt++ = *s++; - } -} - -/* - * write an integer value to toe output buffer - */ -void -outint(int i) -{ - - if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int)) - outxbuf(); - ob.o_nxt += sprintf(ob.o_nxt, "%d", i); -} - -/* - * write the name of a symbol to the output buffer - * the name is preceded by its length - */ -void -outname(const char *name) -{ - - if (name == NULL) - errx(1, "internal error: outname() 1"); - outint((int)strlen(name)); - outstrg(name); -} - -/* - * write the name of the .c source - */ -void -outsrc(const char *name) -{ - - outclr(); - outchar('S'); - outstrg(name); -} Index: usr.bin/xlint/common/externs.h =================================================================== --- usr.bin/xlint/common/externs.h +++ /dev/null @@ -1,66 +0,0 @@ -/* $NetBSD: externs.h,v 1.1 2002/01/18 20:39:23 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * main[12].c - */ -extern int pflag; - -/* - * inittyp.c - */ -extern void inittyp(void); - -/* - * mem.c - */ -extern void *xmalloc(size_t); -extern void *xcalloc(size_t, size_t); -extern void *xrealloc(void *, size_t); -extern char *xstrdup(const char *); -extern void nomem(void); - -/* - * emit.c - */ -extern ob_t ob; - -extern void outopen(const char *); -extern void outclose(void); -extern void outclr(void); -extern void outchar(int); -extern void outqchar(int); -extern void outstrg(const char *); -extern void outint(int); -extern void outname(const char *); -extern void outsrc(const char *); Index: usr.bin/xlint/common/ilp32.h =================================================================== --- usr.bin/xlint/common/ilp32.h +++ /dev/null @@ -1,59 +0,0 @@ -/* $NetBSD: ilp32.h,v 1.1 2002/01/18 20:39:23 thorpej Exp $ */ - -/* - * Copyright (c) 2001 Wasabi Systems, Inc. - * All rights reserved. - * - * Written by Jason R. Thorpe for Wasabi Systems, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the NetBSD Project by - * Wasabi Systems, Inc. - * 4. The name of Wasabi Systems, Inc. may not be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Type sizes for IPL32 platforms (int, long, pointer: 32-bit) - */ - -#define CHAR_SIZE (CHAR_BIT) -#define SHORT_SIZE (2 * CHAR_BIT) -#define INT_SIZE (4 * CHAR_BIT) -#define LONG_SIZE (4 * CHAR_BIT) -#define QUAD_SIZE (8 * CHAR_BIT) -#define PTR_SIZE (4 * CHAR_BIT) - -#define TARG_INT_MAX ((int32_t) (((uint32_t) -1) >> 1)) -#define TARG_INT_MIN ((-TARG_INT_MAX) - 1) -#define TARG_UINT_MAX ((uint32_t) -1) - -#define TARG_LONG_MAX TARG_INT_MAX -#define TARG_LONG_MIN TARG_INT_MIN -#define TARG_ULONG_MAX TARG_UINT_MAX - -#define TARG_QUAD_MAX ((int64_t) (((uint64_t) -1) >> 1)) -#define TARG_QUAD_MIN ((-TARG_QUAD_MAX) - 1) -#define TARG_UQUAD_MAX ((uint64_t) -1) Index: usr.bin/xlint/common/inittyp.c =================================================================== --- usr.bin/xlint/common/inittyp.c +++ /dev/null @@ -1,133 +0,0 @@ -/* $NetBSD: inittyp.c,v 1.3 2002/01/30 06:55:02 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: inittyp.c,v 1.3 2002/01/30 06:55:02 thorpej Exp $"); -#endif - -#include -#include -#include - -#include "lint.h" - -/* various type information */ -ttab_t ttab[NTSPEC]; - -void -inittyp(void) -{ - int i; - static const struct { - tspec_t it_tspec; - ttab_t it_ttab; - } ittab[NTSPEC] = { - { SIGNED, { 0, 0, - SIGNED, UNSIGN, - 0, 0, 0, 0, 0, "signed" } }, - { UNSIGN, { 0, 0, - SIGNED, UNSIGN, - 0, 0, 0, 0, 0, "unsigned" } }, - { CHAR, { CHAR_SIZE, CHAR_BIT, - SCHAR, UCHAR, - 1, 0, 0, 1, 1, "char" } }, - { SCHAR, { CHAR_SIZE, CHAR_BIT, - SCHAR, UCHAR, - 1, 0, 0, 1, 1, "signed char" } }, - { UCHAR, { CHAR_SIZE, CHAR_BIT, - SCHAR, UCHAR, - 1, 1, 0, 1, 1, "unsigned char" } }, - { SHORT, { SHORT_SIZE, 2 * CHAR_BIT, - SHORT, USHORT, - 1, 0, 0, 1, 1, "short" } }, - { USHORT, { SHORT_SIZE, 2 * CHAR_BIT, - SHORT, USHORT, - 1, 1, 0, 1, 1, "unsigned short" } }, - { INT, { INT_SIZE, 3 * CHAR_BIT, - INT, UINT, - 1, 0, 0, 1, 1, "int" } }, - { UINT, { INT_SIZE, 3 * CHAR_BIT, - INT, UINT, - 1, 1, 0, 1, 1, "unsigned int" } }, - { LONG, { LONG_SIZE, 4 * CHAR_BIT, - LONG, ULONG, - 1, 0, 0, 1, 1, "long" } }, - { ULONG, { LONG_SIZE, 4 * CHAR_BIT, - LONG, ULONG, - 1, 1, 0, 1, 1, "unsigned long" } }, - { QUAD, { QUAD_SIZE, 8 * CHAR_BIT, - QUAD, UQUAD, - 1, 0, 0, 1, 1, "long long" } }, - { UQUAD, { QUAD_SIZE, 8 * CHAR_BIT, - QUAD, UQUAD, - 1, 1, 0, 1, 1, "unsigned long long" } }, - { FLOAT, { FLOAT_SIZE, 4 * CHAR_BIT, - FLOAT, FLOAT, - 0, 0, 1, 1, 1, "float" } }, - { DOUBLE, { DOUBLE_SIZE, 8 * CHAR_BIT, - DOUBLE, DOUBLE, - 0, 0, 1, 1, 1, "double" } }, - { LDOUBLE, { LDOUBLE_SIZE, 10 * CHAR_BIT, - LDOUBLE, LDOUBLE, - 0, 0, 1, 1, 1, "long double" } }, - { VOID, { -1, -1, - VOID, VOID, - 0, 0, 0, 0, 0, "void" } }, - { STRUCT, { -1, -1, - STRUCT, STRUCT, - 0, 0, 0, 0, 0, "struct" } }, - { UNION, { -1, -1, - UNION, UNION, - 0, 0, 0, 0, 0, "union" } }, - { ENUM, { ENUM_SIZE, 3 * CHAR_BIT, - ENUM, ENUM, - 1, 0, 0, 1, 1, "enum" } }, - { PTR, { PTR_SIZE, 4 * CHAR_BIT, - PTR, PTR, - 0, 1, 0, 0, 1, "pointer" } }, - { ARRAY, { -1, -1, - ARRAY, ARRAY, - 0, 0, 0, 0, 0, "array" } }, - { FUNC, { -1, -1, - FUNC, FUNC, - 0, 0, 0, 0, 0, "function" } }, - }; - - for (i = 0; i < sizeof (ittab) / sizeof (ittab[0]); i++) - STRUCT_ASSIGN(ttab[ittab[i].it_tspec], ittab[i].it_ttab); - if (!pflag) { - for (i = 0; i < NTSPEC; i++) - ttab[i].tt_psz = ttab[i].tt_sz; - } -} Index: usr.bin/xlint/common/lint.h =================================================================== --- usr.bin/xlint/common/lint.h +++ /dev/null @@ -1,128 +0,0 @@ -/* $NetBSD: lint.h,v 1.7 2003/10/27 00:12:44 lukem Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#if HAVE_CONFIG_H -#include "config.h" -#else -#define HAVE_DECL_SYS_SIGNAME 1 -#endif - -#include -#include -#include -#include -#include - -#include "param.h" - -/* - * Type specifiers, used in type structures (type_t) and otherwere. - */ -typedef enum { - NOTSPEC = 0, - SIGNED, /* keyword "signed", only used in the parser */ - UNSIGN, /* keyword "unsigned", only used in the parser */ - CHAR, /* char */ - SCHAR, /* signed char */ - UCHAR, /* unsigned char */ - SHORT, /* (signed) short */ - USHORT, /* unsigned short */ - INT, /* (signed) int */ - UINT, /* unsigned int */ - LONG, /* (signed) long */ - ULONG, /* unsigned long */ - QUAD, /* (signed) long long */ - UQUAD, /* unsigned long long */ - FLOAT, /* float */ - DOUBLE, /* double or, with tflag, long float */ - LDOUBLE, /* long double */ - VOID, /* void */ - STRUCT, /* structure tag */ - UNION, /* union tag */ - ENUM, /* enum tag */ - PTR, /* pointer */ - ARRAY, /* array */ - FUNC, /* function */ - NTSPEC -} tspec_t; - -/* - * size of types, name and classification - */ -typedef struct { - int tt_sz; /* size in bits */ - int tt_psz; /* size, different from tt_sz - if pflag is set */ - tspec_t tt_styp; /* signed counterpart */ - tspec_t tt_utyp; /* unsigned counterpart */ - u_int tt_isityp : 1; /* 1 if integer type */ - u_int tt_isutyp : 1; /* 1 if unsigned integer type */ - u_int tt_isftyp : 1; /* 1 if floating point type */ - u_int tt_isatyp : 1; /* 1 if arithmetic type */ - u_int tt_issclt : 1; /* 1 if scalar type */ - const char *tt_name; /* Bezeichnung des Typs */ -} ttab_t; - -#define size(t) (ttab[t].tt_sz) -#define psize(t) (ttab[t].tt_psz) -#define styp(t) (ttab[t].tt_styp) -#define utyp(t) (ttab[t].tt_utyp) -#define isityp(t) (ttab[t].tt_isityp) -#define isutyp(t) (ttab[t].tt_isutyp) -#define isftyp(t) (ttab[t].tt_isftyp) -#define isatyp(t) (ttab[t].tt_isatyp) -#define issclt(t) (ttab[t].tt_issclt) - -extern ttab_t ttab[]; - - -typedef enum { - NODECL, /* until now not declared */ - DECL, /* declared */ - TDEF, /* tentative defined */ - DEF /* defined */ -} def_t; - -/* - * Following structure contains some data used for the output buffer. - */ -typedef struct ob { - char *o_buf; /* buffer */ - char *o_end; /* first byte after buffer */ - size_t o_len; /* length of buffer */ - char *o_nxt; /* next free byte in buffer */ -} ob_t; - -#include "externs.h" Index: usr.bin/xlint/common/lp64.h =================================================================== --- usr.bin/xlint/common/lp64.h +++ /dev/null @@ -1,59 +0,0 @@ -/* $NetBSD: lp64.h,v 1.1 2002/01/18 20:39:23 thorpej Exp $ */ - -/* - * Copyright (c) 2001 Wasabi Systems, Inc. - * All rights reserved. - * - * Written by Jason R. Thorpe for Wasabi Systems, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the NetBSD Project by - * Wasabi Systems, Inc. - * 4. The name of Wasabi Systems, Inc. may not be used to endorse - * or promote products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Type sizes for LP64 platforms (long, pointer: 64-bit) - */ - -#define CHAR_SIZE (CHAR_BIT) -#define SHORT_SIZE (2 * CHAR_BIT) -#define INT_SIZE (4 * CHAR_BIT) -#define LONG_SIZE (8 * CHAR_BIT) -#define QUAD_SIZE (8 * CHAR_BIT) -#define PTR_SIZE (8 * CHAR_BIT) - -#define TARG_INT_MAX ((int32_t) (((uint32_t) -1) >> 1)) -#define TARG_INT_MIN ((-TARG_INT_MAX) - 1) -#define TARG_UINT_MAX ((uint32_t) -1) - -#define TARG_QUAD_MAX ((int64_t) (((uint64_t) -1) >> 1)) -#define TARG_QUAD_MIN ((-TARG_QUAD_MAX) - 1) -#define TARG_UQUAD_MAX ((uint64_t) -1) - -#define TARG_LONG_MAX TARG_QUAD_MAX -#define TARG_LONG_MIN TARG_QUAD_MIN -#define TARG_ULONG_MAX TARG_UQUAD_MAX Index: usr.bin/xlint/common/mem.c =================================================================== --- usr.bin/xlint/common/mem.c +++ /dev/null @@ -1,93 +0,0 @@ -/* $NetBSD: mem.c,v 1.4 2003/10/16 06:35:26 itojun Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: mem.c,v 1.4 2003/10/16 06:35:26 itojun Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include - -#include "lint.h" - -void * -xmalloc(size_t s) -{ - void *p; - - if ((p = malloc(s)) == NULL) - nomem(); - return (p); -} - -void * -xcalloc(size_t n, size_t s) -{ - void *p; - - if ((p = calloc(n, s)) == NULL) - nomem(); - return (p); -} - -void * -xrealloc(void *p, size_t s) -{ - void *n; - - if ((n = realloc(p, s)) == NULL) { - free(p); - nomem(); - } - p = n; - return (p); -} - -char * -xstrdup(const char *s) -{ - char *s2; - - if ((s2 = strdup(s)) == NULL) - nomem(); - return (s2); -} - -void -nomem(void) -{ - - errx(1, "virtual memory exhausted"); -} Index: usr.bin/xlint/common/param.h =================================================================== --- usr.bin/xlint/common/param.h +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: param.h,v 1.2 2002/02/05 03:04:26 thorpej Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Minimun size of string buffer. If this is not enough, the buffer - * is enlarged in steps of STRBLEN bytes. - */ -#define STRBLEN 256 - -/* - * This defines the size of memory blocks which are used to allocate - * memory in larger chunks. - */ -#define MBLKSIZ ((size_t)0x4000) - -/* - * Sizes of hash tables - * Should be a prime. Possible primes are - * 307, 401, 503, 601, 701, 809, 907, 1009, 1103, 1201, 1301, 1409, 1511. - * - * HSHSIZ1 symbol table 1st pass - * HSHSIZ2 symbol table 2nd pass - * THSHSIZ2 type table 2nd pass - */ -#define HSHSIZ1 503 -#define HSHSIZ2 1009 -#define THSHSIZ2 1009 - -/* - * Pull in target-specific parameters. - */ -#include "targparam.h" - -/* - * Make sure this matches wchar_t. - */ -#define WCHAR INT - -/* - * And the sparc64 long double code generation is broken. - */ -#if !defined(__sparc64__) -typedef long double ldbl_t; -#else -typedef double ldbl_t; -#endif - -/* - * Some traditional compilers are not able to assign structures. - */ -#define STRUCT_ASSIGN(dest, src) (dest) = (src) Index: usr.bin/xlint/lint1/Makefile =================================================================== --- usr.bin/xlint/lint1/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $NetBSD: Makefile,v 1.3 1995/07/04 01:53:05 cgd Exp $ -# $FreeBSD$ - -PROG= lint1 -SRCS= cgram.y scan.l mem1.c mem.c err.c main1.c decl.c tree.c func.c \ - init.c emit.c emit1.c inittyp.c -MAN= lint.7 -CLEANFILES= lint.7 - -LIBADD= l m -CFLAGS+= -I. -I${.CURDIR} -LINTFLAGS=-aehpz - -BINDIR= ${LIBEXECDIR} - -.PATH: ${.CURDIR}/../common - -lint.7: makeman - sh ${.CURDIR}/makeman ${DESTDIR}${BINDIR}/${PROG} -m >${.TARGET} - -.include Index: usr.bin/xlint/lint1/Makefile.depend =================================================================== --- usr.bin/xlint/lint1/Makefile.depend +++ /dev/null @@ -1,20 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/msun \ - usr.bin/lex/lib \ - usr.bin/yacc.host \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.bin/xlint/lint1/cgram.y =================================================================== --- usr.bin/xlint/lint1/cgram.y +++ /dev/null @@ -1,1893 +0,0 @@ -%{ -/* $NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: cgram.y,v 1.40 2008/04/25 17:18:24 christos Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include "lint1.h" - -/* - * Contains the level of current declaration. 0 is extern. - * Used for symbol table entries. - */ -int blklev; - -/* - * level for memory allocation. Normaly the same as blklev. - * An exeption is the declaration of arguments in prototypes. Memory - * for these can't be freed after the declaration, but symbols must - * be removed from the symbol table after the declaration. - */ -int mblklev; - -/* - * Save the no-warns state and restore it to avoid the problem where - * if (expr) { stmt } / * NOLINT * / stmt; - */ -static int onowarn = -1; - -static int toicon(tnode_t *, int); -static void idecl(sym_t *, int, sbuf_t *); -static void ignuptorp(void); - -#ifdef DEBUG -static inline void CLRWFLGS(void); -static inline void CLRWFLGS(void) -{ - printf("%s, %d: clear flags %s %d\n", curr_pos.p_file, - curr_pos.p_line, __FILE__, __LINE__); - clrwflgs(); - onowarn = -1; -} - -static inline void SAVE(void); -static inline void SAVE(void) -{ - if (onowarn != -1) - abort(); - printf("%s, %d: save flags %s %d = %d\n", curr_pos.p_file, - curr_pos.p_line, __FILE__, __LINE__, nowarn); - onowarn = nowarn; -} - -static inline void RESTORE(void); -static inline void RESTORE(void) -{ - if (onowarn != -1) { - nowarn = onowarn; - printf("%s, %d: restore flags %s %d = %d\n", curr_pos.p_file, - curr_pos.p_line, __FILE__, __LINE__, nowarn); - onowarn = -1; - } else - CLRWFLGS(); -} -#else -#define CLRWFLGS() clrwflgs(), onowarn = -1 -#define SAVE() onowarn = nowarn -#define RESTORE() (void)(onowarn == -1 ? (clrwflgs(), 0) : (nowarn = onowarn)) -#endif -%} - -%expect 1 - -%union { - int y_int; - val_t *y_val; - sbuf_t *y_sb; - sym_t *y_sym; - op_t y_op; - scl_t y_scl; - tspec_t y_tspec; - tqual_t y_tqual; - type_t *y_type; - tnode_t *y_tnode; - range_t y_range; - strg_t *y_strg; - pqinf_t *y_pqinf; -}; - -%token T_LBRACE T_RBRACE T_LBRACK T_RBRACK T_LPARN T_RPARN -%token T_STROP -%token T_UNOP -%token T_INCDEC -%token T_SIZEOF -%token T_MULT -%token T_DIVOP -%token T_ADDOP -%token T_SHFTOP -%token T_RELOP -%token T_EQOP -%token T_AND -%token T_XOR -%token T_OR -%token T_LOGAND -%token T_LOGOR -%token T_QUEST -%token T_COLON -%token T_ASSIGN -%token T_OPASS -%token T_COMMA -%token T_SEMI -%token T_ELLIPSE - -/* storage classes (extern, static, auto, register and typedef) */ -%token T_SCLASS - -/* types (char, int, short, long, unsigned, signed, float, double, void) */ -%token T_TYPE - -/* qualifiers (const, volatile) */ -%token T_QUAL - -/* struct or union */ -%token T_SOU - -/* enum */ -%token T_ENUM - -/* remaining keywords */ -%token T_CASE -%token T_DEFAULT -%token T_IF -%token T_ELSE -%token T_SWITCH -%token T_DO -%token T_WHILE -%token T_FOR -%token T_GOTO -%token T_CONTINUE -%token T_BREAK -%token T_RETURN -%token T_ASM -%token T_SYMBOLRENAME - -%left T_COMMA -%right T_ASSIGN T_OPASS -%right T_QUEST T_COLON -%left T_LOGOR -%left T_LOGAND -%left T_OR -%left T_XOR -%left T_AND -%left T_EQOP -%left T_RELOP -%left T_SHFTOP -%left T_ADDOP -%left T_MULT T_DIVOP -%right T_UNOP T_INCDEC T_SIZEOF -%left T_LPARN T_LBRACK T_STROP - -%token T_NAME -%token T_TYPENAME -%token T_CON -%token T_STRING - -%type func_decl -%type notype_decl -%type type_decl -%type typespec -%type clrtyp_typespec -%type notype_typespec -%type struct_spec -%type enum_spec -%type struct_tag -%type enum_tag -%type struct -%type struct_declaration -%type identifier -%type member_declaration_list_with_rbrace -%type member_declaration_list -%type member_declaration -%type notype_member_decls -%type type_member_decls -%type notype_member_decl -%type type_member_decl -%type constant -%type enum_declaration -%type enums_with_opt_comma -%type enums -%type enumerator -%type ename -%type notype_direct_decl -%type type_direct_decl -%type pointer -%type asterisk -%type param_decl -%type param_list -%type abs_decl_param_list -%type direct_param_decl -%type notype_param_decl -%type direct_notype_param_decl -%type type_qualifier_list -%type type_qualifier -%type identifier_list -%type abs_decl -%type direct_abs_decl -%type vararg_parameter_type_list -%type parameter_type_list -%type parameter_declaration -%type expr -%type expr_stmnt_val -%type expr_stmnt_list -%type term -%type func_arg_list -%type point_or_arrow -%type type_name -%type abstract_declaration -%type do_while_expr -%type opt_expr -%type string -%type string2 -%type opt_asm_or_symbolrename -%type range -%type lorange - - -%% - -program: - /* empty */ { - if (sflag) { - /* empty translation unit */ - error(272); - } else if (!tflag) { - /* empty translation unit */ - warning(272); - } - } - | translation_unit - ; - -translation_unit: - ext_decl - | translation_unit ext_decl - ; - -ext_decl: - asm_stmnt - | func_def { - glclup(0); - CLRWFLGS(); - } - | data_def { - glclup(0); - CLRWFLGS(); - } - ; - -data_def: - T_SEMI { - if (sflag) { - /* syntax error: empty declaration */ - error(0); - } else if (!tflag) { - /* syntax error: empty declaration */ - warning(0); - } - } - | clrtyp deftyp notype_init_decls T_SEMI { - if (sflag) { - /* old style declaration; add "int" */ - error(1); - } else if (!tflag) { - /* old style declaration; add "int" */ - warning(1); - } - } - | declmods deftyp T_SEMI { - if (dcs->d_scl == TYPEDEF) { - /* typedef declares no type name */ - warning(72); - } else { - /* empty declaration */ - warning(2); - } - } - | declmods deftyp notype_init_decls T_SEMI - | declspecs deftyp T_SEMI { - if (dcs->d_scl == TYPEDEF) { - /* typedef declares no type name */ - warning(72); - } else if (!dcs->d_nedecl) { - /* empty declaration */ - warning(2); - } - } - | declspecs deftyp type_init_decls T_SEMI - | error T_SEMI { - globclup(); - } - | error T_RBRACE { - globclup(); - } - ; - -func_def: - func_decl { - if ($1->s_type->t_tspec != FUNC) { - /* syntax error */ - error(249); - YYERROR; - } - if ($1->s_type->t_typedef) { - /* ()-less function definition */ - error(64); - YYERROR; - } - funcdef($1); - blklev++; - pushdecl(ARG); - } opt_arg_declaration_list { - popdecl(); - blklev--; - cluparg(); - pushctrl(0); - } comp_stmnt { - funcend(); - popctrl(0); - } - ; - -func_decl: - clrtyp deftyp notype_decl { - $$ = $3; - } - | declmods deftyp notype_decl { - $$ = $3; - } - | declspecs deftyp type_decl { - $$ = $3; - } - ; - -opt_arg_declaration_list: - /* empty */ - | arg_declaration_list - ; - -arg_declaration_list: - arg_declaration - | arg_declaration_list arg_declaration - /* XXX or better "arg_declaration error" ? */ - | error - ; - -/* - * "arg_declaration" is separated from "declaration" because it - * needs other error handling. - */ - -arg_declaration: - declmods deftyp T_SEMI { - /* empty declaration */ - warning(2); - } - | declmods deftyp notype_init_decls T_SEMI - | declspecs deftyp T_SEMI { - if (!dcs->d_nedecl) { - /* empty declaration */ - warning(2); - } else { - tspec_t ts = dcs->d_type->t_tspec; - /* %s declared in argument declaration list */ - warning(3, ts == STRUCT ? "struct" : - (ts == UNION ? "union" : "enum")); - } - } - | declspecs deftyp type_init_decls T_SEMI { - if (dcs->d_nedecl) { - tspec_t ts = dcs->d_type->t_tspec; - /* %s declared in argument declaration list */ - warning(3, ts == STRUCT ? "struct" : - (ts == UNION ? "union" : "enum")); - } - } - | declmods error - | declspecs error - ; - -declaration: - declmods deftyp T_SEMI { - if (dcs->d_scl == TYPEDEF) { - /* typedef declares no type name */ - warning(72); - } else { - /* empty declaration */ - warning(2); - } - } - | declmods deftyp notype_init_decls T_SEMI - | declspecs deftyp T_SEMI { - if (dcs->d_scl == TYPEDEF) { - /* typedef declares no type name */ - warning(72); - } else if (!dcs->d_nedecl) { - /* empty declaration */ - warning(2); - } - } - | declspecs deftyp type_init_decls T_SEMI - | error T_SEMI - ; - -clrtyp: - { - clrtyp(); - } - ; - -deftyp: - /* empty */ { - deftyp(); - } - ; - -declspecs: - clrtyp_typespec { - addtype($1); - } - | declmods typespec { - addtype($2); - } - | declspecs declmod - | declspecs notype_typespec { - addtype($2); - } - ; - -declmods: - clrtyp T_QUAL { - addqual($2); - } - | clrtyp T_SCLASS { - addscl($2); - } - | declmods declmod - ; - -declmod: - T_QUAL { - addqual($1); - } - | T_SCLASS { - addscl($1); - } - ; - -clrtyp_typespec: - clrtyp notype_typespec { - $$ = $2; - } - | T_TYPENAME clrtyp { - $$ = getsym($1)->s_type; - } - ; - -typespec: - notype_typespec { - $$ = $1; - } - | T_TYPENAME { - $$ = getsym($1)->s_type; - } - ; - -notype_typespec: - T_TYPE { - $$ = gettyp($1); - } - | struct_spec { - popdecl(); - $$ = $1; - } - | enum_spec { - popdecl(); - $$ = $1; - } - ; - -struct_spec: - struct struct_tag { - /* - * STDC requires that "struct a;" always introduces - * a new tag if "a" is not declared at current level - * - * yychar is valid because otherwise the parser would - * not been able to deceide if he must shift or reduce - */ - $$ = mktag($2, $1, 0, yychar == T_SEMI); - } - | struct struct_tag { - dcs->d_tagtyp = mktag($2, $1, 1, 0); - } struct_declaration { - $$ = compltag(dcs->d_tagtyp, $4); - } - | struct { - dcs->d_tagtyp = mktag(NULL, $1, 1, 0); - } struct_declaration { - $$ = compltag(dcs->d_tagtyp, $3); - } - | struct error { - symtyp = FVFT; - $$ = gettyp(INT); - } - ; - -struct: - T_SOU { - symtyp = FTAG; - pushdecl($1 == STRUCT ? MOS : MOU); - dcs->d_offset = 0; - dcs->d_stralign = CHAR_BIT; - $$ = $1; - } - ; - -struct_tag: - identifier { - $$ = getsym($1); - } - ; - -struct_declaration: - struct_decl_lbrace member_declaration_list_with_rbrace { - $$ = $2; - } - ; - -struct_decl_lbrace: - T_LBRACE { - symtyp = FVFT; - } - ; - -member_declaration_list_with_rbrace: - member_declaration_list T_SEMI T_RBRACE { - $$ = $1; - } - | member_declaration_list T_RBRACE { - if (sflag) { - /* syntax req. ";" after last struct/union member */ - error(66); - } else { - /* syntax req. ";" after last struct/union member */ - warning(66); - } - $$ = $1; - } - | T_RBRACE { - $$ = NULL; - } - ; - -member_declaration_list: - member_declaration { - $$ = $1; - } - | member_declaration_list T_SEMI member_declaration { - $$ = lnklst($1, $3); - } - ; - -member_declaration: - noclass_declmods deftyp { - /* too late, i know, but getsym() compensates it */ - symtyp = FMOS; - } notype_member_decls { - symtyp = FVFT; - $$ = $4; - } - | noclass_declspecs deftyp { - symtyp = FMOS; - } type_member_decls { - symtyp = FVFT; - $$ = $4; - } - | noclass_declmods deftyp { - /* struct or union member must be named */ - warning(49); - $$ = NULL; - } - | noclass_declspecs deftyp { - /* struct or union member must be named */ - warning(49); - $$ = NULL; - } - | error { - symtyp = FVFT; - $$ = NULL; - } - ; - -noclass_declspecs: - clrtyp_typespec { - addtype($1); - } - | noclass_declmods typespec { - addtype($2); - } - | noclass_declspecs T_QUAL { - addqual($2); - } - | noclass_declspecs notype_typespec { - addtype($2); - } - ; - -noclass_declmods: - clrtyp T_QUAL { - addqual($2); - } - | noclass_declmods T_QUAL { - addqual($2); - } - ; - -notype_member_decls: - notype_member_decl { - $$ = decl1str($1); - } - | notype_member_decls { - symtyp = FMOS; - } T_COMMA type_member_decl { - $$ = lnklst($1, decl1str($4)); - } - ; - -type_member_decls: - type_member_decl { - $$ = decl1str($1); - } - | type_member_decls { - symtyp = FMOS; - } T_COMMA type_member_decl { - $$ = lnklst($1, decl1str($4)); - } - ; - -notype_member_decl: - notype_decl { - $$ = $1; - } - | notype_decl T_COLON constant { - $$ = bitfield($1, toicon($3, 1)); - } - | { - symtyp = FVFT; - } T_COLON constant { - $$ = bitfield(NULL, toicon($3, 1)); - } - ; - -type_member_decl: - type_decl { - $$ = $1; - } - | type_decl T_COLON constant { - $$ = bitfield($1, toicon($3, 1)); - } - | { - symtyp = FVFT; - } T_COLON constant { - $$ = bitfield(NULL, toicon($3, 1)); - } - ; - -enum_spec: - enum enum_tag { - $$ = mktag($2, ENUM, 0, 0); - } - | enum enum_tag { - dcs->d_tagtyp = mktag($2, ENUM, 1, 0); - } enum_declaration { - $$ = compltag(dcs->d_tagtyp, $4); - } - | enum { - dcs->d_tagtyp = mktag(NULL, ENUM, 1, 0); - } enum_declaration { - $$ = compltag(dcs->d_tagtyp, $3); - } - | enum error { - symtyp = FVFT; - $$ = gettyp(INT); - } - ; - -enum: - T_ENUM { - symtyp = FTAG; - pushdecl(ENUMCON); - } - ; - -enum_tag: - identifier { - $$ = getsym($1); - } - ; - -enum_declaration: - enum_decl_lbrace enums_with_opt_comma T_RBRACE { - $$ = $2; - } - ; - -enum_decl_lbrace: - T_LBRACE { - symtyp = FVFT; - enumval = 0; - } - ; - -enums_with_opt_comma: - enums { - $$ = $1; - } - | enums T_COMMA { - if (sflag) { - /* trailing "," prohibited in enum declaration */ - error(54); - } else { - /* trailing "," prohibited in enum declaration */ - (void)gnuism(54); - } - $$ = $1; - } - ; - -enums: - enumerator { - $$ = $1; - } - | enums T_COMMA enumerator { - $$ = lnklst($1, $3); - } - | error { - $$ = NULL; - } - ; - -enumerator: - ename { - $$ = ename($1, enumval, 1); - } - | ename T_ASSIGN constant { - $$ = ename($1, toicon($3, 1), 0); - } - ; - -ename: - identifier { - $$ = getsym($1); - } - ; - - -notype_init_decls: - notype_init_decl - | notype_init_decls T_COMMA type_init_decl - ; - -type_init_decls: - type_init_decl - | type_init_decls T_COMMA type_init_decl - ; - -notype_init_decl: - notype_decl opt_asm_or_symbolrename { - idecl($1, 0, $2); - chksz($1); - } - | notype_decl opt_asm_or_symbolrename { - idecl($1, 1, $2); - } T_ASSIGN initializer { - chksz($1); - } - ; - -type_init_decl: - type_decl opt_asm_or_symbolrename { - idecl($1, 0, $2); - chksz($1); - } - | type_decl opt_asm_or_symbolrename { - idecl($1, 1, $2); - } T_ASSIGN initializer { - chksz($1); - } - ; - -notype_decl: - notype_direct_decl { - $$ = $1; - } - | pointer notype_direct_decl { - $$ = addptr($2, $1); - } - ; - -notype_direct_decl: - T_NAME { - $$ = dname(getsym($1)); - } - | T_LPARN type_decl T_RPARN { - $$ = $2; - } - | notype_direct_decl T_LBRACK T_RBRACK { - $$ = addarray($1, 0, 0); - } - | notype_direct_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3, 0)); - } - | notype_direct_decl param_list { - $$ = addfunc($1, $2); - popdecl(); - blklev--; - } - ; - -type_decl: - type_direct_decl { - $$ = $1; - } - | pointer type_direct_decl { - $$ = addptr($2, $1); - } - ; - -type_direct_decl: - identifier { - $$ = dname(getsym($1)); - } - | T_LPARN type_decl T_RPARN { - $$ = $2; - } - | type_direct_decl T_LBRACK T_RBRACK { - $$ = addarray($1, 0, 0); - } - | type_direct_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3, 0)); - } - | type_direct_decl param_list { - $$ = addfunc($1, $2); - popdecl(); - blklev--; - } - ; - -/* - * param_decl and notype_param_decl exist to avoid a conflict in - * argument lists. A typename enclosed in parens should always be - * treated as a typename, not an argument. - * "typedef int a; f(int (a));" is "typedef int a; f(int foo(a));" - * not "typedef int a; f(int a);" - */ -param_decl: - direct_param_decl { - $$ = $1; - } - | pointer direct_param_decl { - $$ = addptr($2, $1); - } - ; - -direct_param_decl: - identifier { - $$ = dname(getsym($1)); - } - | T_LPARN notype_param_decl T_RPARN { - $$ = $2; - } - | direct_param_decl T_LBRACK T_RBRACK { - $$ = addarray($1, 0, 0); - } - | direct_param_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3, 0)); - } - | direct_param_decl param_list { - $$ = addfunc($1, $2); - popdecl(); - blklev--; - } - ; - -notype_param_decl: - direct_notype_param_decl { - $$ = $1; - } - | pointer direct_notype_param_decl { - $$ = addptr($2, $1); - } - ; - -direct_notype_param_decl: - T_NAME { - $$ = dname(getsym($1)); - } - | T_LPARN notype_param_decl T_RPARN { - $$ = $2; - } - | direct_notype_param_decl T_LBRACK T_RBRACK { - $$ = addarray($1, 0, 0); - } - | direct_notype_param_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3, 0)); - } - | direct_notype_param_decl param_list { - $$ = addfunc($1, $2); - popdecl(); - blklev--; - } - ; - -pointer: - asterisk { - $$ = $1; - } - | asterisk type_qualifier_list { - $$ = mergepq($1, $2); - } - | asterisk pointer { - $$ = mergepq($1, $2); - } - | asterisk type_qualifier_list pointer { - $$ = mergepq(mergepq($1, $2), $3); - } - ; - -asterisk: - T_MULT { - $$ = xcalloc(1, sizeof (pqinf_t)); - $$->p_pcnt = 1; - } - ; - -type_qualifier_list: - type_qualifier { - $$ = $1; - } - | type_qualifier_list type_qualifier { - $$ = mergepq($1, $2); - } - ; - -type_qualifier: - T_QUAL { - $$ = xcalloc(1, sizeof (pqinf_t)); - if ($1 == CONST) { - $$->p_const = 1; - } else { - $$->p_volatile = 1; - } - } - ; - -param_list: - id_list_lparn identifier_list T_RPARN { - $$ = $2; - } - | abs_decl_param_list { - $$ = $1; - } - ; - -id_list_lparn: - T_LPARN { - blklev++; - pushdecl(PARG); - } - ; - -identifier_list: - T_NAME { - $$ = iname(getsym($1)); - } - | identifier_list T_COMMA T_NAME { - $$ = lnklst($1, iname(getsym($3))); - } - | identifier_list error { - $$ = $1; - } - ; - -abs_decl_param_list: - abs_decl_lparn T_RPARN { - $$ = NULL; - } - | abs_decl_lparn vararg_parameter_type_list T_RPARN { - dcs->d_proto = 1; - $$ = $2; - } - | abs_decl_lparn error T_RPARN { - $$ = NULL; - } - ; - -abs_decl_lparn: - T_LPARN { - blklev++; - pushdecl(PARG); - } - ; - -vararg_parameter_type_list: - parameter_type_list { - $$ = $1; - } - | parameter_type_list T_COMMA T_ELLIPSE { - dcs->d_vararg = 1; - $$ = $1; - } - | T_ELLIPSE { - if (sflag) { - /* ANSI C requires formal parameter before "..." */ - error(84); - } else if (!tflag) { - /* ANSI C requires formal parameter before "..." */ - warning(84); - } - dcs->d_vararg = 1; - $$ = NULL; - } - ; - -parameter_type_list: - parameter_declaration { - $$ = $1; - } - | parameter_type_list T_COMMA parameter_declaration { - $$ = lnklst($1, $3); - } - ; - -parameter_declaration: - declmods deftyp { - $$ = decl1arg(aname(), 0); - } - | declspecs deftyp { - $$ = decl1arg(aname(), 0); - } - | declmods deftyp notype_param_decl { - $$ = decl1arg($3, 0); - } - /* - * param_decl is needed because of following conflict: - * "typedef int a; f(int (a));" could be parsed as - * "function with argument a of type int", or - * "function with an abstract argument of type function". - * This grammar realizes the second case. - */ - | declspecs deftyp param_decl { - $$ = decl1arg($3, 0); - } - | declmods deftyp abs_decl { - $$ = decl1arg($3, 0); - } - | declspecs deftyp abs_decl { - $$ = decl1arg($3, 0); - } - ; - -opt_asm_or_symbolrename: /* expect only one */ - /* empty */ { - $$ = NULL; - } - | T_ASM T_LPARN T_STRING T_RPARN { - freeyyv(&$3, T_STRING); - $$ = NULL; - } - | T_SYMBOLRENAME T_LPARN T_NAME T_RPARN { - $$ = $3; - } - ; - -initializer: - init_expr - ; - -init_expr: - expr %prec T_COMMA { - mkinit($1); - } - | init_by_name init_expr %prec T_COMMA - | init_lbrace init_expr_list init_rbrace - | init_lbrace init_expr_list T_COMMA init_rbrace - | error - ; - -init_expr_list: - init_expr %prec T_COMMA - | init_expr_list T_COMMA init_expr - ; - -lorange: - constant T_ELLIPSE { - $$.lo = toicon($1, 1); - } - ; -range: - constant { - $$.lo = toicon($1, 1); - $$.hi = $$.lo + 1; - } - | lorange constant { - $$.lo = $1.lo; - $$.hi = toicon($2, 1); - } - ; - -init_by_name: - T_LBRACK range T_RBRACK T_ASSIGN { - if (!Sflag) - warning(321); - } - | point identifier T_ASSIGN { - if (!Sflag) - warning(313); - memberpush($2); - } - | identifier T_COLON { - gnuism(315); - memberpush($1); - } - ; - -init_lbrace: - T_LBRACE { - initlbr(); - } - ; - -init_rbrace: - T_RBRACE { - initrbr(); - } - ; - -type_name: - { - pushdecl(ABSTRACT); - } abstract_declaration { - popdecl(); - $$ = $2->s_type; - } - ; - -abstract_declaration: - noclass_declmods deftyp { - $$ = decl1abs(aname()); - } - | noclass_declspecs deftyp { - $$ = decl1abs(aname()); - } - | noclass_declmods deftyp abs_decl { - $$ = decl1abs($3); - } - | noclass_declspecs deftyp abs_decl { - $$ = decl1abs($3); - } - ; - -abs_decl: - pointer { - $$ = addptr(aname(), $1); - } - | direct_abs_decl { - $$ = $1; - } - | pointer direct_abs_decl { - $$ = addptr($2, $1); - } - ; - -direct_abs_decl: - T_LPARN abs_decl T_RPARN { - $$ = $2; - } - | T_LBRACK T_RBRACK { - $$ = addarray(aname(), 0, 0); - } - | T_LBRACK constant T_RBRACK { - $$ = addarray(aname(), 1, toicon($2, 0)); - } - | direct_abs_decl T_LBRACK T_RBRACK { - $$ = addarray($1, 0, 0); - } - | direct_abs_decl T_LBRACK constant T_RBRACK { - $$ = addarray($1, 1, toicon($3, 0)); - } - | abs_decl_param_list { - $$ = addfunc(aname(), $1); - popdecl(); - blklev--; - } - | direct_abs_decl abs_decl_param_list { - $$ = addfunc($1, $2); - popdecl(); - blklev--; - } - ; - -non_expr_stmnt: - labeled_stmnt - | comp_stmnt - | selection_stmnt - | iteration_stmnt - | jump_stmnt { - ftflg = 0; - } - | asm_stmnt - -stmnt: - expr_stmnt - | non_expr_stmnt - ; - -labeled_stmnt: - label stmnt - ; - -label: - identifier T_COLON { - symtyp = FLAB; - label(T_NAME, getsym($1), NULL); - } - | T_CASE constant T_COLON { - label(T_CASE, NULL, $2); - ftflg = 1; - } - | T_CASE constant T_ELLIPSE constant T_COLON { - /* XXX: We don't fill all cases */ - label(T_CASE, NULL, $2); - ftflg = 1; - } - | T_DEFAULT T_COLON { - label(T_DEFAULT, NULL, NULL); - ftflg = 1; - } - ; - -comp_stmnt: - comp_stmnt_lbrace declaration_list opt_stmnt_list comp_stmnt_rbrace - | comp_stmnt_lbrace opt_stmnt_list comp_stmnt_rbrace - ; - -comp_stmnt_lbrace: - T_LBRACE { - blklev++; - mblklev++; - pushdecl(AUTO); - } - ; - -comp_stmnt_rbrace: - T_RBRACE { - popdecl(); - freeblk(); - mblklev--; - blklev--; - ftflg = 0; - } - ; - -opt_stmnt_list: - /* empty */ - | stmnt_list - ; - -stmnt_list: - stmnt - | stmnt_list stmnt { - RESTORE(); - } - | stmnt_list error T_SEMI - ; - -expr_stmnt: - expr T_SEMI { - expr($1, 0, 0, 1); - ftflg = 0; - } - | T_SEMI { - ftflg = 0; - } - ; - -/* - * The following two productions are used to implement - * ({ [[decl-list] stmt-list] }). - * XXX: This is not well tested. - */ -expr_stmnt_val: - expr T_SEMI { - /* XXX: We should really do that only on the last name */ - if ($1->tn_op == NAME) - $1->tn_sym->s_used = 1; - $$ = $1; - expr($1, 0, 0, 0); - ftflg = 0; - } - | non_expr_stmnt { - $$ = getnode(); - $$->tn_type = gettyp(VOID); - } - ; - -expr_stmnt_list: - expr_stmnt_val - | expr_stmnt_list expr_stmnt_val { - $$ = $2; - } - | expr_stmnt_list expr_stmnt_val - ; - -selection_stmnt: - if_without_else { - SAVE(); - if2(); - if3(0); - } - | if_without_else T_ELSE { - SAVE(); - if2(); - } stmnt { - CLRWFLGS(); - if3(1); - } - | if_without_else T_ELSE error { - CLRWFLGS(); - if3(0); - } - | switch_expr stmnt { - CLRWFLGS(); - switch2(); - } - | switch_expr error { - CLRWFLGS(); - switch2(); - } - ; - -if_without_else: - if_expr stmnt - | if_expr error - ; - -if_expr: - T_IF T_LPARN expr T_RPARN { - if1($3); - CLRWFLGS(); - } - ; - -switch_expr: - T_SWITCH T_LPARN expr T_RPARN { - switch1($3); - CLRWFLGS(); - } - ; - -do_stmnt: - do stmnt { - CLRWFLGS(); - } - ; - -iteration_stmnt: - while_expr stmnt { - CLRWFLGS(); - while2(); - } - | while_expr error { - CLRWFLGS(); - while2(); - } - | do_stmnt do_while_expr { - do2($2); - ftflg = 0; - } - | do error { - CLRWFLGS(); - do2(NULL); - } - | for_exprs stmnt { - CLRWFLGS(); - for2(); - } - | for_exprs error { - CLRWFLGS(); - for2(); - } - ; - -while_expr: - T_WHILE T_LPARN expr T_RPARN { - while1($3); - CLRWFLGS(); - } - ; - -do: - T_DO { - do1(); - } - ; - -do_while_expr: - T_WHILE T_LPARN expr T_RPARN T_SEMI { - $$ = $3; - } - ; - -for_exprs: - T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN { - for1($3, $5, $7); - CLRWFLGS(); - } - ; - -opt_expr: - /* empty */ { - $$ = NULL; - } - | expr { - $$ = $1; - } - ; - -jump_stmnt: - goto identifier T_SEMI { - dogoto(getsym($2)); - } - | goto error T_SEMI { - symtyp = FVFT; - } - | T_CONTINUE T_SEMI { - docont(); - } - | T_BREAK T_SEMI { - dobreak(); - } - | T_RETURN T_SEMI { - doreturn(NULL); - } - | T_RETURN expr T_SEMI { - doreturn($2); - } - ; - -goto: - T_GOTO { - symtyp = FLAB; - } - ; - -asm_stmnt: - T_ASM T_LPARN read_until_rparn T_SEMI { - setasm(); - } - | T_ASM T_QUAL T_LPARN read_until_rparn T_SEMI { - setasm(); - } - | T_ASM error - ; - -read_until_rparn: - /* empty */ { - ignuptorp(); - } - ; - -declaration_list: - declaration { - CLRWFLGS(); - } - | declaration_list declaration { - CLRWFLGS(); - } - ; - -constant: - expr %prec T_COMMA { - $$ = $1; - } - ; - -expr: - expr T_MULT expr { - $$ = build(MULT, $1, $3); - } - | expr T_DIVOP expr { - $$ = build($2, $1, $3); - } - | expr T_ADDOP expr { - $$ = build($2, $1, $3); - } - | expr T_SHFTOP expr { - $$ = build($2, $1, $3); - } - | expr T_RELOP expr { - $$ = build($2, $1, $3); - } - | expr T_EQOP expr { - $$ = build($2, $1, $3); - } - | expr T_AND expr { - $$ = build(AND, $1, $3); - } - | expr T_XOR expr { - $$ = build(XOR, $1, $3); - } - | expr T_OR expr { - $$ = build(OR, $1, $3); - } - | expr T_LOGAND expr { - $$ = build(LOGAND, $1, $3); - } - | expr T_LOGOR expr { - $$ = build(LOGOR, $1, $3); - } - | expr T_QUEST expr T_COLON expr { - $$ = build(QUEST, $1, build(COLON, $3, $5)); - } - | expr T_ASSIGN expr { - $$ = build(ASSIGN, $1, $3); - } - | expr T_OPASS expr { - $$ = build($2, $1, $3); - } - | expr T_COMMA expr { - $$ = build(COMMA, $1, $3); - } - | term { - $$ = $1; - } - ; - -term: - T_NAME { - /* XXX really necessary? */ - if (yychar < 0) - yychar = yylex(); - $$ = getnnode(getsym($1), yychar); - } - | string { - $$ = getsnode($1); - } - | T_CON { - $$ = getcnode(gettyp($1->v_tspec), $1); - } - | T_LPARN expr T_RPARN { - if ($2 != NULL) - $2->tn_parn = 1; - $$ = $2; - } - | T_LPARN comp_stmnt_lbrace declaration_list expr_stmnt_list { - blklev--; - mblklev--; - initsym = mktempsym(duptyp($4->tn_type)); - mblklev++; - blklev++; - gnuism(320); - } comp_stmnt_rbrace T_RPARN { - $$ = getnnode(initsym, 0); - } - | T_LPARN comp_stmnt_lbrace expr_stmnt_list { - blklev--; - mblklev--; - initsym = mktempsym($3->tn_type); - mblklev++; - blklev++; - gnuism(320); - } comp_stmnt_rbrace T_RPARN { - $$ = getnnode(initsym, 0); - } - | term T_INCDEC { - $$ = build($2 == INC ? INCAFT : DECAFT, $1, NULL); - } - | T_INCDEC term { - $$ = build($1 == INC ? INCBEF : DECBEF, $2, NULL); - } - | T_MULT term { - $$ = build(STAR, $2, NULL); - } - | T_AND term { - $$ = build(AMPER, $2, NULL); - } - | T_UNOP term { - $$ = build($1, $2, NULL); - } - | T_ADDOP term { - if (tflag && $1 == PLUS) { - /* unary + is illegal in traditional C */ - warning(100); - } - $$ = build($1 == PLUS ? UPLUS : UMINUS, $2, NULL); - } - | term T_LBRACK expr T_RBRACK { - $$ = build(STAR, build(PLUS, $1, $3), NULL); - } - | term T_LPARN T_RPARN { - $$ = funccall($1, NULL); - } - | term T_LPARN func_arg_list T_RPARN { - $$ = funccall($1, $3); - } - | term point_or_arrow T_NAME { - if ($1 != NULL) { - sym_t *msym; - /* XXX strmemb should be integrated in build() */ - if ($2 == ARROW) { - /* must to this before strmemb is called */ - $1 = cconv($1); - } - msym = strmemb($1, $2, getsym($3)); - $$ = build($2, $1, getnnode(msym, 0)); - } else { - $$ = NULL; - } - } - | T_SIZEOF term %prec T_SIZEOF { - if (($$ = $2 == NULL ? NULL : bldszof($2->tn_type)) != NULL) - chkmisc($2, 0, 0, 0, 0, 0, 1); - } - | T_SIZEOF T_LPARN type_name T_RPARN %prec T_SIZEOF { - $$ = bldszof($3); - } - | T_LPARN type_name T_RPARN term %prec T_UNOP { - $$ = cast($4, $2); - } - | T_LPARN type_name T_RPARN %prec T_UNOP { - sym_t *tmp = mktempsym($2); - idecl(tmp, 1, NULL); - } init_lbrace init_expr_list init_rbrace { - if (!Sflag) - gnuism(319); - $$ = getnnode(initsym, 0); - } - ; - -string: - T_STRING { - $$ = $1; - } - | T_STRING string2 { - $$ = catstrg($1, $2); - } - ; - -string2: - T_STRING { - if (tflag) { - /* concatenated strings are illegal in traditional C */ - warning(219); - } - $$ = $1; - } - | string2 T_STRING { - $$ = catstrg($1, $2); - } - ; - -func_arg_list: - expr %prec T_COMMA { - $$ = funcarg(NULL, $1); - } - | func_arg_list T_COMMA expr { - $$ = funcarg($1, $3); - } - ; - -point_or_arrow: - T_STROP { - symtyp = FMOS; - $$ = $1; - } - ; - -point: - T_STROP { - if ($1 != POINT) - error(249); - } - ; - -identifier: - T_NAME { - $$ = $1; - } - | T_TYPENAME { - $$ = $1; - } - ; - -%% - -/* ARGSUSED */ -int -yyerror(char *msg) -{ - error(249); - if (++sytxerr >= 5) - norecover(); - return (0); -} - -static __inline int uq_gt(uint64_t, uint64_t); -static __inline int -uq_gt(uint64_t a, uint64_t b) -{ - - return (a > b); -} - -static __inline int q_gt(int64_t, int64_t); -static __inline int -q_gt(int64_t a, int64_t b) -{ - - return (a > b); -} - -#define q_lt(a, b) q_gt(b, a) - -/* - * Gets a node for a constant and returns the value of this constant - * as integer. - * Is the node not constant or too large for int or of type float, - * a warning will be printed. - * - * toicon() should be used only inside declarations. If it is used in - * expressions, it frees the memory used for the expression. - */ -static int -toicon(tnode_t *tn, int required) -{ - int i; - tspec_t t; - val_t *v; - - v = constant(tn, required); - - /* - * Abstract declarations are used inside expression. To free - * the memory would be a fatal error. - */ - if (dcs->d_ctx != ABSTRACT) - tfreeblk(); - - if ((t = v->v_tspec) == FLOAT || t == DOUBLE || t == LDOUBLE) { - i = (int)v->v_ldbl; - /* integral constant expression expected */ - error(55); - } else { - i = (int)v->v_quad; - if (isutyp(t)) { - if (uq_gt((uint64_t)v->v_quad, - (uint64_t)INT_MAX)) { - /* integral constant too large */ - warning(56); - } - } else { - if (q_gt(v->v_quad, (int64_t)INT_MAX) || - q_lt(v->v_quad, (int64_t)INT_MIN)) { - /* integral constant too large */ - warning(56); - } - } - } - free(v); - return (i); -} - -static void -idecl(sym_t *decl, int initflg, sbuf_t *rename) -{ - char *s; - - initerr = 0; - initsym = decl; - - switch (dcs->d_ctx) { - case EXTERN: - if (rename != NULL) { - if (decl->s_rename != NULL) - LERROR("idecl()"); - - s = getlblk(1, rename->sb_len + 1); - (void)memcpy(s, rename->sb_name, rename->sb_len + 1); - decl->s_rename = s; - freeyyv(&rename, T_NAME); - } - decl1ext(decl, initflg); - break; - case ARG: - if (rename != NULL) { - /* symbol renaming can't be used on function arguments */ - error(310); - freeyyv(&rename, T_NAME); - break; - } - (void)decl1arg(decl, initflg); - break; - case AUTO: - if (rename != NULL) { - /* symbol renaming can't be used on automatic variables */ - error(311); - freeyyv(&rename, T_NAME); - break; - } - decl1loc(decl, initflg); - break; - default: - LERROR("idecl()"); - } - - if (initflg && !initerr) - prepinit(); -} - -/* - * Discard all input tokens up to and including the next - * unmatched right paren - */ -static void -ignuptorp(void) -{ - int level; - - if (yychar < 0) - yychar = yylex(); - freeyyv(&yylval, yychar); - - level = 1; - while (yychar != T_RPARN || --level > 0) { - if (yychar == T_LPARN) { - level++; - } else if (yychar <= 0) { - break; - } - freeyyv(&yylval, yychar = yylex()); - } - - yyclearin; -} Index: usr.bin/xlint/lint1/decl.c =================================================================== --- usr.bin/xlint/lint1/decl.c +++ /dev/null @@ -1,3052 +0,0 @@ -/* $NetBSD: decl.c,v 1.33 2004/06/20 22:20:16 jmc Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: decl.c,v 1.33 2004/06/20 22:20:16 jmc Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include "lint1.h" - -const char *unnamed = ""; - -/* shared type structures for arithmtic types and void */ -static type_t *typetab; - -/* value of next enumerator during declaration of enum types */ -int enumval; - -/* - * pointer to top element of a stack which contains informations local - * to nested declarations - */ -dinfo_t *dcs; - -static type_t *tdeferr(type_t *, tspec_t); -static void settdsym(type_t *, sym_t *); -static tspec_t mrgtspec(tspec_t, tspec_t); -static void align(int, int); -static sym_t *newtag(sym_t *, scl_t, int, int); -static int eqargs(type_t *, type_t *, int *); -static int mnoarg(type_t *, int *); -static int chkosdef(sym_t *, sym_t *); -static int chkptdecl(sym_t *, sym_t *); -static sym_t *nsfunc(sym_t *, sym_t *); -static void osfunc(sym_t *, sym_t *); -static void ledecl(sym_t *); -static int chkinit(sym_t *); -static void chkausg(int, sym_t *); -static void chkvusg(int, sym_t *); -static void chklusg(sym_t *); -static void chktusg(sym_t *); -static void chkglvar(sym_t *); -static void glchksz(sym_t *); - -/* - * initializes all global vars used in declarations - */ -void -initdecl(void) -{ - int i; - - /* declaration stack */ - if ((dcs = calloc(1, sizeof (dinfo_t))) == NULL) - nomem(); - dcs->d_ctx = EXTERN; - dcs->d_ldlsym = &dcs->d_dlsyms; - - /* type information and classification */ - inittyp(); - - /* shared type structures */ - if ((typetab = calloc(NTSPEC, sizeof (type_t))) == NULL) - nomem(); - for (i = 0; i < NTSPEC; i++) - typetab[i].t_tspec = NOTSPEC; - typetab[CHAR].t_tspec = CHAR; - typetab[SCHAR].t_tspec = SCHAR; - typetab[UCHAR].t_tspec = UCHAR; - typetab[SHORT].t_tspec = SHORT; - typetab[USHORT].t_tspec = USHORT; - typetab[INT].t_tspec = INT; - typetab[UINT].t_tspec = UINT; - typetab[LONG].t_tspec = LONG; - typetab[ULONG].t_tspec = ULONG; - typetab[QUAD].t_tspec = QUAD; - typetab[UQUAD].t_tspec = UQUAD; - typetab[FLOAT].t_tspec = FLOAT; - typetab[DOUBLE].t_tspec = DOUBLE; - typetab[LDOUBLE].t_tspec = LDOUBLE; - typetab[VOID].t_tspec = VOID; - /* - * Next two are not real types. They are only used by the parser - * to return keywords "signed" and "unsigned" - */ - typetab[SIGNED].t_tspec = SIGNED; - typetab[UNSIGN].t_tspec = UNSIGN; -} - -/* - * Returns a shared type structure vor arithmetic types and void. - * - * It's important to duplicate this structure (using duptyp() or tdupdyp()) - * if it is to be modified (adding qualifiers or anything else). - */ -type_t * -gettyp(tspec_t t) -{ - - return (&typetab[t]); -} - -type_t * -duptyp(const type_t *tp) -{ - type_t *ntp; - - ntp = getblk(sizeof (type_t)); - STRUCT_ASSIGN(*ntp, *tp); - return (ntp); -} - -/* - * Use tduptyp() instead of duptyp() inside expressions (if the - * allocated memory should be freed after the expr). - */ -type_t * -tduptyp(const type_t *tp) -{ - type_t *ntp; - - ntp = tgetblk(sizeof (type_t)); - STRUCT_ASSIGN(*ntp, *tp); - return (ntp); -} - -/* - * Returns 1 if the argument is void or an incomplete array, - * struct, union or enum type. - */ -int -incompl(type_t *tp) -{ - tspec_t t; - - if ((t = tp->t_tspec) == VOID) { - return (1); - } else if (t == ARRAY) { - return (tp->t_aincompl); - } else if (t == STRUCT || t == UNION) { - return (tp->t_str->sincompl); - } else if (t == ENUM) { - return (tp->t_enum->eincompl); - } - return (0); -} - -/* - * Set the flag for (in)complete array, struct, union or enum - * types. - */ -void -setcompl(type_t *tp, int ic) -{ - tspec_t t; - - if ((t = tp->t_tspec) == ARRAY) { - tp->t_aincompl = ic; - } else if (t == STRUCT || t == UNION) { - tp->t_str->sincompl = ic; - } else { - if (t != ENUM) - LERROR("setcompl()"); - tp->t_enum->eincompl = ic; - } -} - -/* - * Remember the storage class of the current declaration in dcs->d_scl - * (the top element of the declaration stack) and detect multiple - * storage classes. - */ -void -addscl(scl_t sc) -{ - - if (sc == INLINE) { - if (dcs->d_inline) - /* duplicate '%s' */ - warning(10, "inline"); - dcs->d_inline = 1; - return; - } - if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC || - dcs->d_smod != NOTSPEC || dcs->d_lmod != NOTSPEC) { - /* storage class after type is obsolescent */ - warning(83); - } - if (dcs->d_scl == NOSCL) { - dcs->d_scl = sc; - } else { - /* - * multiple storage classes. An error will be reported in - * deftyp(). - */ - dcs->d_mscl = 1; - } -} - -/* - * Remember the type, modifier or typedef name returned by the parser - * in *dcs (top element of decl stack). This information is used in - * deftyp() to build the type used for all declarators in this - * declaration. - * - * Is tp->t_typedef 1, the type comes from a previously defined typename. - * Otherwise it comes from a type specifier (int, long, ...) or a - * struct/union/enum tag. - */ -void -addtype(type_t *tp) -{ - tspec_t t; - - if (tp->t_typedef) { - if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC || - dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) { - /* - * something like "typedef int a; int a b;" - * This should not happen with current grammar. - */ - LERROR("addtype()"); - } - dcs->d_type = tp; - return; - } - - t = tp->t_tspec; - - if (t == STRUCT || t == UNION || t == ENUM) { - /* - * something like "int struct a ..." - * struct/union/enum with anything else is not allowed - */ - if (dcs->d_type != NULL || dcs->d_atyp != NOTSPEC || - dcs->d_lmod != NOTSPEC || dcs->d_smod != NOTSPEC) { - /* - * remember that an error must be reported in - * deftyp(). - */ - dcs->d_terr = 1; - dcs->d_atyp = dcs->d_lmod = dcs->d_smod = NOTSPEC; - } - dcs->d_type = tp; - return; - } - - if (dcs->d_type != NULL && !dcs->d_type->t_typedef) { - /* - * something like "struct a int" - * struct/union/enum with anything else is not allowed - */ - dcs->d_terr = 1; - return; - } - - if (t == LONG && dcs->d_lmod == LONG) { - /* "long long" or "long ... long" */ - t = QUAD; - dcs->d_lmod = NOTSPEC; - if (!quadflg) - /* %s C does not support 'long long' */ - (void)c99ism(265, tflag ? "traditional" : "c89"); - } - - if (dcs->d_type != NULL && dcs->d_type->t_typedef) { - /* something like "typedef int a; a long ..." */ - dcs->d_type = tdeferr(dcs->d_type, t); - return; - } - - /* now it can be only a combination of arithmetic types and void */ - if (t == SIGNED || t == UNSIGN) { - /* remember specifiers "signed" and "unsigned" in dcs->d_smod */ - if (dcs->d_smod != NOTSPEC) - /* - * more than one "signed" and/or "unsigned"; print - * an error in deftyp() - */ - dcs->d_terr = 1; - dcs->d_smod = t; - } else if (t == SHORT || t == LONG || t == QUAD) { - /* - * remember specifiers "short", "long" and "long long" in - * dcs->d_lmod - */ - if (dcs->d_lmod != NOTSPEC) - /* more than one, print error in deftyp() */ - dcs->d_terr = 1; - dcs->d_lmod = t; - } else { - /* - * remember specifiers "void", "char", "int", "float" or - * "double" int dcs->d_atyp - */ - if (dcs->d_atyp != NOTSPEC) - /* more than one, print error in deftyp() */ - dcs->d_terr = 1; - dcs->d_atyp = t; - } -} - -/* - * called if a list of declaration specifiers contains a typedef name - * and other specifiers (except struct, union, enum, typedef name) - */ -static type_t * -tdeferr(type_t *td, tspec_t t) -{ - tspec_t t2; - - t2 = td->t_tspec; - - switch (t) { - case SIGNED: - case UNSIGN: - if (t2 == CHAR || t2 == SHORT || t2 == INT || t2 == LONG || - t2 == QUAD) { - if (!tflag) - /* modifying typedef with ... */ - warning(5, ttab[t].tt_name); - td = duptyp(gettyp(mrgtspec(t2, t))); - td->t_typedef = 1; - return (td); - } - break; - case SHORT: - if (t2 == INT || t2 == UINT) { - /* modifying typedef with ... */ - warning(5, "short"); - td = duptyp(gettyp(t2 == INT ? SHORT : USHORT)); - td->t_typedef = 1; - return (td); - } - break; - case LONG: - if (t2 == INT || t2 == UINT || t2 == LONG || t2 == ULONG || - t2 == FLOAT || t2 == DOUBLE) { - /* modifying typedef with ... */ - warning(5, "long"); - if (t2 == INT) { - td = gettyp(LONG); - } else if (t2 == UINT) { - td = gettyp(ULONG); - } else if (t2 == LONG) { - td = gettyp(QUAD); - } else if (t2 == ULONG) { - td = gettyp(UQUAD); - } else if (t2 == FLOAT) { - td = gettyp(DOUBLE); - } else if (t2 == DOUBLE) { - td = gettyp(LDOUBLE); - } - td = duptyp(td); - td->t_typedef = 1; - return (td); - } - break; - /* LINTED (enumeration values not handled in switch) */ - case NOTSPEC: - case USHORT: - case UCHAR: - case SCHAR: - case CHAR: - case FUNC: - case ARRAY: - case PTR: - case ENUM: - case UNION: - case STRUCT: - case VOID: - case LDOUBLE: - case DOUBLE: - case FLOAT: - case UQUAD: - case QUAD: - case ULONG: - case UINT: - case INT: - break; - } - - /* Anything other is not accepted. */ - - dcs->d_terr = 1; - return (td); -} - -/* - * Remember the symbol of a typedef name (2nd arg) in a struct, union - * or enum tag if the typedef name is the first defined for this tag. - * - * If the tag is unnamed, the typdef name is used for identification - * of this tag in lint2. Although its possible that more than one typedef - * name is defined for one tag, the first name defined should be unique - * if the tag is unnamed. - */ -static void -settdsym(type_t *tp, sym_t *sym) -{ - tspec_t t; - - if ((t = tp->t_tspec) == STRUCT || t == UNION) { - if (tp->t_str->stdef == NULL) - tp->t_str->stdef = sym; - } else if (t == ENUM) { - if (tp->t_enum->etdef == NULL) - tp->t_enum->etdef = sym; - } -} - -/* - * Remember a qualifier which is part of the declaration specifiers - * (and not the declarator) in the top element of the declaration stack. - * Also detect multiple qualifiers of the same kind. - - * The remembered qualifier is used by deftyp() to construct the type - * for all declarators. - */ -void -addqual(tqual_t q) -{ - - if (q == CONST) { - if (dcs->d_const) { - /* duplicate "%s" */ - warning(10, "const"); - } - dcs->d_const = 1; - } else { - if (q != VOLATILE) - LERROR("addqual()"); - if (dcs->d_volatile) { - /* duplicate "%s" */ - warning(10, "volatile"); - } - dcs->d_volatile = 1; - } -} - -/* - * Go to the next declaration level (structs, nested structs, blocks, - * argument declaration lists ...) - */ -void -pushdecl(scl_t sc) -{ - dinfo_t *di; - - if (dflag) - (void)printf("pushdecl(%d)\n", (int)sc); - - /* put a new element on the declaration stack */ - if ((di = calloc(1, sizeof (dinfo_t))) == NULL) - nomem(); - di->d_nxt = dcs; - dcs = di; - di->d_ctx = sc; - di->d_ldlsym = &di->d_dlsyms; -} - -/* - * Go back to previous declaration level - */ -void -popdecl(void) -{ - dinfo_t *di; - - if (dflag) - (void)printf("popdecl(%d)\n", (int)dcs->d_ctx); - - if (dcs->d_nxt == NULL) - LERROR("popdecl()"); - di = dcs; - dcs = di->d_nxt; - switch (di->d_ctx) { - case EXTERN: - /* there is nothing after external declarations */ - LERROR("popdecl()"); - /* NOTREACHED */ - case MOS: - case MOU: - case ENUMCON: - /* - * Symbols declared in (nested) structs or enums are - * part of the next level (they are removed from the - * symbol table if the symbols of the outher level are - * removed) - */ - if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL) - dcs->d_ldlsym = di->d_ldlsym; - break; - case ARG: - /* - * All symbols in dcs->d_dlsyms are introduced in old style - * argument declarations (it's not clean, but possible). - * They are appended to the list of symbols declared in - * an old style argument identifier list or a new style - * parameter type list. - */ - if (di->d_dlsyms != NULL) { - *di->d_ldlsym = dcs->d_fpsyms; - dcs->d_fpsyms = di->d_dlsyms; - } - break; - case ABSTRACT: - /* - * casts and sizeof - * Append all symbols declared in the abstract declaration - * to the list of symbols declared in the surrounding decl. - * or block. - * XXX I'm not sure whether they should be removed from the - * symbol table now or later. - */ - if ((*dcs->d_ldlsym = di->d_dlsyms) != NULL) - dcs->d_ldlsym = di->d_ldlsym; - break; - case AUTO: - /* check usage of local vars */ - chkusage(di); - /* FALLTHROUGH */ - case PARG: - /* usage of arguments will be checked by funcend() */ - rmsyms(di->d_dlsyms); - break; - default: - LERROR("popdecl()"); - } - free(di); -} - -/* - * Set flag d_asm in all declaration stack elements up to the - * outermost one. - * - * This is used to mark compound statements which have, possibly in - * nested compound statements, asm statements. For these compound - * statements no warnings about unused or unitialized variables are - * printed. - * - * There is no need to clear d_asm in dinfo structs with context AUTO, - * because these structs are freed at the end of the compound statement. - * But it must be cleard in the outermost dinfo struct, which has - * context EXTERN. This could be done in clrtyp() and would work for - * C, but not for C++ (due to mixed statements and declarations). Thus - * we clear it in glclup(), which is used to do some cleanup after - * global declarations/definitions. - */ -void -setasm(void) -{ - dinfo_t *di; - - for (di = dcs; di != NULL; di = di->d_nxt) - di->d_asm = 1; -} - -/* - * Clean all elements of the top element of declaration stack which - * will be used by the next declaration - */ -void -clrtyp(void) -{ - - dcs->d_atyp = dcs->d_smod = dcs->d_lmod = NOTSPEC; - dcs->d_scl = NOSCL; - dcs->d_type = NULL; - dcs->d_const = dcs->d_volatile = 0; - dcs->d_inline = 0; - dcs->d_mscl = dcs->d_terr = 0; - dcs->d_nedecl = 0; - dcs->d_notyp = 0; -} - -/* - * Create a type structure from the informations gathered in - * the declaration stack. - * Complain about storage classes which are not possible in current - * context. - */ -void -deftyp(void) -{ - tspec_t t, s, l; - type_t *tp; - scl_t scl; - - t = dcs->d_atyp; /* CHAR, INT, FLOAT, DOUBLE, VOID */ - s = dcs->d_smod; /* SIGNED, UNSIGNED */ - l = dcs->d_lmod; /* SHORT, LONG, QUAD */ - tp = dcs->d_type; - scl = dcs->d_scl; - - if (t == NOTSPEC && s == NOTSPEC && l == NOTSPEC && tp == NULL) - dcs->d_notyp = 1; - - if (tp != NULL && (t != NOTSPEC || s != NOTSPEC || l != NOTSPEC)) { - /* should never happen */ - LERROR("deftyp()"); - } - - if (tp == NULL) { - switch (t) { - case NOTSPEC: - t = INT; - /* FALLTHROUGH */ - case INT: - if (s == NOTSPEC) - s = SIGNED; - break; - case CHAR: - if (l != NOTSPEC) { - dcs->d_terr = 1; - l = NOTSPEC; - } - break; - case FLOAT: - if (l == LONG) { - l = NOTSPEC; - t = DOUBLE; - if (!tflag) - /* use 'double' instead of ... */ - warning(6); - } - break; - case DOUBLE: - if (l == LONG) { - l = NOTSPEC; - t = LDOUBLE; - if (tflag) - /* 'long double' is illegal in ... */ - warning(266); - } - break; - case VOID: - break; - default: - LERROR("deftyp()"); - } - if (t != INT && t != CHAR && (s != NOTSPEC || l != NOTSPEC)) { - dcs->d_terr = 1; - l = s = NOTSPEC; - } - if (l != NOTSPEC) - t = l; - dcs->d_type = gettyp(mrgtspec(t, s)); - } - - if (dcs->d_mscl) { - /* only one storage class allowed */ - error(7); - } - if (dcs->d_terr) { - /* illegal type combination */ - error(4); - } - - if (dcs->d_ctx == EXTERN) { - if (scl == REG || scl == AUTO) { - /* illegal storage class */ - error(8); - scl = NOSCL; - } - } else if (dcs->d_ctx == ARG || dcs->d_ctx == PARG) { - if (scl != NOSCL && scl != REG) { - /* only "register" valid ... */ - error(9); - scl = NOSCL; - } - } - - dcs->d_scl = scl; - - if (dcs->d_const && dcs->d_type->t_const) { - if (!dcs->d_type->t_typedef) - LERROR("deftyp()"); - /* typedef already qualified with "%s" */ - warning(68, "const"); - } - if (dcs->d_volatile && dcs->d_type->t_volatile) { - if (!dcs->d_type->t_typedef) - LERROR("deftyp()"); - /* typedef already qualified with "%s" */ - warning(68, "volatile"); - } - - if (dcs->d_const || dcs->d_volatile) { - dcs->d_type = duptyp(dcs->d_type); - dcs->d_type->t_const |= dcs->d_const; - dcs->d_type->t_volatile |= dcs->d_volatile; - } -} - -/* - * Merge type specifiers (char, ..., long long, signed, unsigned). - */ -static tspec_t -mrgtspec(tspec_t t, tspec_t s) -{ - - if (s == SIGNED || s == UNSIGN) { - if (t == CHAR) { - t = s == SIGNED ? SCHAR : UCHAR; - } else if (t == SHORT) { - t = s == SIGNED ? SHORT : USHORT; - } else if (t == INT) { - t = s == SIGNED ? INT : UINT; - } else if (t == LONG) { - t = s == SIGNED ? LONG : ULONG; - } else if (t == QUAD) { - t = s == SIGNED ? QUAD : UQUAD; - } - } - - return (t); -} - -/* - * Return the length of a type in bit. - * - * Printing a message if the outhermost dimension of an array is 0 must - * be done by the caller. All other problems are reported by length() - * if name is not NULL. - */ -int -length(type_t *tp, const char *name) -{ - int elem, elsz; - - elem = 1; - while (tp && tp->t_tspec == ARRAY) { - elem *= tp->t_dim; - tp = tp->t_subt; - } - if (tp == NULL) - return -1; - - switch (tp->t_tspec) { - case FUNC: - /* compiler takes size of function */ - LERROR("%s", msgs[12]); - /* NOTREACHED */ - case STRUCT: - case UNION: - if (incompl(tp) && name != NULL) { - /* incomplete structure or union %s: %s */ - error(31, tp->t_str->stag->s_name, name); - } - elsz = tp->t_str->size; - break; - case ENUM: - if (incompl(tp) && name != NULL) { - /* incomplete enum type: %s */ - warning(13, name); - } - /* FALLTHROUGH */ - default: - elsz = size(tp->t_tspec); - if (elsz <= 0) - LERROR("length()"); - break; - } - return (elem * elsz); -} - -/* - * Get the alignment of the given type in bits. - */ -int -getbound(type_t *tp) -{ - int a; - tspec_t t; - - while (tp && tp->t_tspec == ARRAY) - tp = tp->t_subt; - - if (tp == NULL) - return -1; - - if ((t = tp->t_tspec) == STRUCT || t == UNION) { - a = tp->t_str->align; - } else if (t == FUNC) { - /* compiler takes alignment of function */ - error(14); - a = LINT_ALIGN(1) * CHAR_BIT; - } else { - if ((a = size(t)) == 0) { - a = CHAR_BIT; - } else if (a > LINT_ALIGN(1) * CHAR_BIT) { - a = LINT_ALIGN(1) * CHAR_BIT; - } - } - if (a < CHAR_BIT || a > LINT_ALIGN(1) * CHAR_BIT) - LERROR("getbound()"); - return (a); -} - -/* - * Concatenate two lists of symbols by s_nxt. Used by declarations of - * struct/union/enum elements and parameters. - */ -sym_t * -lnklst(sym_t *l1, sym_t *l2) -{ - sym_t *l; - - if ((l = l1) == NULL) - return (l2); - while (l1->s_nxt != NULL) - l1 = l1->s_nxt; - l1->s_nxt = l2; - return (l); -} - -/* - * Check if the type of the given symbol is valid and print an error - * message if it is not. - * - * Invalid types are: - * - arrays of incomlete types or functions - * - functions returning arrays or functions - * - void types other than type of function or pointer - */ -void -chktyp(sym_t *sym) -{ - tspec_t to, t; - type_t **tpp, *tp; - - tpp = &sym->s_type; - to = NOTSPEC; - while ((tp = *tpp) != NULL) { - t = tp->t_tspec; - /* - * If this is the type of an old style function definition, - * a better warning is printed in funcdef(). - */ - if (t == FUNC && !tp->t_proto && - !(to == NOTSPEC && sym->s_osdef)) { - if (sflag && hflag) - /* function declaration is not a prototype */ - warning(287); - } - if (to == FUNC) { - if (t == FUNC || t == ARRAY) { - /* function returns illegal type */ - error(15); - if (t == FUNC) { - *tpp = incref(*tpp, PTR); - } else { - *tpp = incref((*tpp)->t_subt, PTR); - } - return; - } else if (tp->t_const || tp->t_volatile) { - if (sflag) { /* XXX oder better !tflag ? */ - /* function cannot return const... */ - warning(228); - } - } - } if (to == ARRAY) { - if (t == FUNC) { - /* array of function is illegal */ - error(16); - *tpp = gettyp(INT); - return; - } else if (t == ARRAY && tp->t_dim == 0) { - /* null dimension */ - error(17); - return; - } else if (t == VOID) { - /* illegal use of void */ - error(18); - *tpp = gettyp(INT); -#if 0 /* errors are produced by length() */ - } else if (incompl(tp)) { - /* array of incomplete type */ - if (sflag) { - error(301); - } else { - warning(301); - } -#endif - } - } else if (to == NOTSPEC && t == VOID) { - if (dcs->d_ctx == PARG) { - if (sym->s_scl != ABSTRACT) { - if (sym->s_name == unnamed) - LERROR("chktyp()"); - /* void param cannot have name: %s */ - error(61, sym->s_name); - *tpp = gettyp(INT); - } - } else if (dcs->d_ctx == ABSTRACT) { - /* ok */ - } else if (sym->s_scl != TYPEDEF) { - /* void type for %s */ - error(19, sym->s_name); - *tpp = gettyp(INT); - } - } - if (t == VOID && to != PTR) { - if (tp->t_const || tp->t_volatile) { - /* inappropriate qualifiers with "void" */ - warning(69); - tp->t_const = tp->t_volatile = 0; - } - } - tpp = &tp->t_subt; - to = t; - } -} - -/* - * Process the declarator of a struct/union element. - */ -sym_t * -decl1str(sym_t *dsym) -{ - type_t *tp; - tspec_t t; - int sz, len; - int o = 0; /* Appease gcc */ - scl_t sc; - - if ((sc = dsym->s_scl) != MOS && sc != MOU) - LERROR("decl1str()"); - - if (dcs->d_rdcsym != NULL) { - if ((sc = dcs->d_rdcsym->s_scl) != MOS && sc != MOU) - /* should be ensured by storesym() */ - LERROR("decl1str()"); - if (dsym->s_styp == dcs->d_rdcsym->s_styp) { - /* duplicate member name: %s */ - error(33, dsym->s_name); - rmsym(dcs->d_rdcsym); - } - } - - chktyp(dsym); - - t = (tp = dsym->s_type)->t_tspec; - - if (dsym->s_field) { - /* - * bit field - * - * only unsigned and signed int are portable bit-field types - * (at least in ANSI C, in traditional C only unsigned int) - */ - if (t == CHAR || t == UCHAR || t == SCHAR || - t == SHORT || t == USHORT || t == ENUM) { - if (bitfieldtype_ok == 0) { - if (sflag) { - char buf[64]; - /* - * bit-field type '%s' invalid in - * ANSI C - */ - warning(273, - tyname(buf, sizeof(buf), tp)); - } else if (pflag) { - /* nonportable bit-field type */ - warning(34); - } - } - } else if (t == INT && dcs->d_smod == NOTSPEC) { - if (pflag && bitfieldtype_ok == 0) { - /* nonportable bit-field type */ - warning(34); - } - } else if (t != INT && t != UINT) { - /* - * Non-integer types are always illegal for - * bitfields, regardless of BITFIELDTYPE. - * Integer types not dealt with above are - * okay only if BITFIELDTYPE is in effect. - */ - if (bitfieldtype_ok == 0 || isityp(t) == 0) { - /* illegal bit-field type */ - error(35); - sz = tp->t_flen; - dsym->s_type = tp = duptyp(gettyp(t = INT)); - if ((tp->t_flen = sz) > size(t)) - tp->t_flen = size(t); - } - } - if ((len = tp->t_flen) < 0 || len > size(t)) { - /* illegal bit-field size */ - error(36); - tp->t_flen = size(t); - } else if (len == 0 && dsym->s_name != unnamed) { - /* zero size bit-field */ - error(37); - tp->t_flen = size(t); - } - if (dsym->s_scl == MOU) { - /* illegal use of bit-field */ - error(41); - dsym->s_type->t_isfield = 0; - dsym->s_field = 0; - } - } else if (t == FUNC) { - /* function illegal in structure or union */ - error(38); - dsym->s_type = tp = incref(tp, t = PTR); - } - - /* - * bit-fields of length 0 are not warned about because length() - * does not return the length of the bit-field but the length - * of the type the bit-field is packed in (its ok) - */ - if ((sz = length(dsym->s_type, dsym->s_name)) == 0) { - if (t == ARRAY && dsym->s_type->t_dim == 0) { - /* illegal zero sized structure member: %s */ - c99ism(39, dsym->s_name); - } - } - - if (dcs->d_ctx == MOU) { - o = dcs->d_offset; - dcs->d_offset = 0; - } - if (dsym->s_field) { - align(getbound(tp), tp->t_flen); - dsym->s_value.v_quad = (dcs->d_offset / size(t)) * size(t); - tp->t_foffs = dcs->d_offset - (int)dsym->s_value.v_quad; - dcs->d_offset += tp->t_flen; - } else { - align(getbound(tp), 0); - dsym->s_value.v_quad = dcs->d_offset; - dcs->d_offset += sz; - } - if (dcs->d_ctx == MOU) { - if (o > dcs->d_offset) - dcs->d_offset = o; - } - - chkfdef(dsym, 0); - - /* - * Clear the BITFIELDTYPE indicator after processing each - * structure element. - */ - bitfieldtype_ok = 0; - - return (dsym); -} - -/* - * Aligns next structure element as required. - * - * al contains the required alignment, len the length of a bit-field. - */ -static void -align(int al, int len) -{ - int no; - - /* - * The alignment of the current element becomes the alignment of - * the struct/union if it is larger than the current alignment - * of the struct/union. - */ - if (al > dcs->d_stralign) - dcs->d_stralign = al; - - no = roundup2(dcs->d_offset, al); - if (len == 0 || dcs->d_offset + len > no) - dcs->d_offset = no; -} - -/* - * Remember the width of the field in its type structure. - */ -sym_t * -bitfield(sym_t *dsym, int len) -{ - - if (dsym == NULL) { - dsym = getblk(sizeof (sym_t)); - dsym->s_name = unnamed; - dsym->s_kind = FMOS; - dsym->s_scl = MOS; - dsym->s_type = gettyp(UINT); - dsym->s_blklev = -1; - } - dsym->s_type = duptyp(dsym->s_type); - dsym->s_type->t_isfield = 1; - dsym->s_type->t_flen = len; - dsym->s_field = 1; - return (dsym); -} - -/* - * Collect informations about a sequence of asterisks and qualifiers - * in a list of type pqinf_t. - * Qualifiers refer always to the left asterisk. The rightmost asterisk - * will be at the top of the list. - */ -pqinf_t * -mergepq(pqinf_t *p1, pqinf_t *p2) -{ - pqinf_t *p; - - if (p2->p_pcnt != 0) { - /* left '*' at the end of the list */ - for (p = p2; p->p_nxt != NULL; p = p->p_nxt) - continue; - p->p_nxt = p1; - return (p2); - } else { - if (p2->p_const) { - if (p1->p_const) { - /* duplicate %s */ - warning(10, "const"); - } - p1->p_const = 1; - } - if (p2->p_volatile) { - if (p1->p_volatile) { - /* duplicate %s */ - warning(10, "volatile"); - } - p1->p_volatile = 1; - } - free(p2); - return (p1); - } -} - -/* - * Followint 3 functions extend the type of a declarator with - * pointer, function and array types. - * - * The current type is the type built by deftyp() (dcs->d_type) and - * pointer, function and array types already added for this - * declarator. The new type extension is inserted between both. - */ -sym_t * -addptr(sym_t *decl, pqinf_t *pi) -{ - type_t **tpp, *tp; - pqinf_t *npi; - - tpp = &decl->s_type; - while (*tpp && *tpp != dcs->d_type) - tpp = &(*tpp)->t_subt; - if (*tpp == NULL) - return decl; - - while (pi != NULL) { - *tpp = tp = getblk(sizeof (type_t)); - tp->t_tspec = PTR; - tp->t_const = pi->p_const; - tp->t_volatile = pi->p_volatile; - *(tpp = &tp->t_subt) = dcs->d_type; - npi = pi->p_nxt; - free(pi); - pi = npi; - } - return (decl); -} - -/* - * If a dimension was specified, dim is 1, otherwise 0 - * n is the specified dimension - */ -sym_t * -addarray(sym_t *decl, int dim, int n) -{ - type_t **tpp, *tp; - - tpp = &decl->s_type; - while (*tpp && *tpp != dcs->d_type) - tpp = &(*tpp)->t_subt; - if (*tpp == NULL) - return decl; - - *tpp = tp = getblk(sizeof (type_t)); - tp->t_tspec = ARRAY; - tp->t_subt = dcs->d_type; - tp->t_dim = n; - - if (n < 0) { - /* negative array dimension */ - error(20, n); - n = 0; - } else if (n == 0 && dim) { - /* zero array dimension */ - c99ism(322, dim); - } else if (n == 0 && !dim) { - /* is incomplete type */ - setcompl(tp, 1); - } - - return (decl); -} - -sym_t * -addfunc(sym_t *decl, sym_t *args) -{ - type_t **tpp, *tp; - - if (dcs->d_proto) { - if (tflag) - /* function prototypes are illegal in traditional C */ - warning(270); - args = nsfunc(decl, args); - } else { - osfunc(decl, args); - } - - /* - * The symbols are removed from the symbol table by popdecl() after - * addfunc(). To be able to restore them if this is a function - * definition, a pointer to the list of all symbols is stored in - * dcs->d_nxt->d_fpsyms. Also a list of the arguments (concatenated - * by s_nxt) is stored in dcs->d_nxt->d_fargs. - * (dcs->d_nxt must be used because *dcs is the declaration stack - * element created for the list of params and is removed after - * addfunc()) - */ - if (dcs->d_nxt->d_ctx == EXTERN && - decl->s_type == dcs->d_nxt->d_type) { - dcs->d_nxt->d_fpsyms = dcs->d_dlsyms; - dcs->d_nxt->d_fargs = args; - } - - tpp = &decl->s_type; - while (*tpp && *tpp != dcs->d_nxt->d_type) - tpp = &(*tpp)->t_subt; - if (*tpp == NULL) - return decl; - - *tpp = tp = getblk(sizeof (type_t)); - tp->t_tspec = FUNC; - tp->t_subt = dcs->d_nxt->d_type; - if ((tp->t_proto = dcs->d_proto) != 0) - tp->t_args = args; - tp->t_vararg = dcs->d_vararg; - - return (decl); -} - -/* - * Called for new style function declarations. - */ -/* ARGSUSED */ -static sym_t * -nsfunc(sym_t *decl, sym_t *args) -{ - sym_t *arg, *sym; - scl_t sc; - int n; - - /* - * Declarations of structs/unions/enums in param lists are legal, - * but senseless. - */ - for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) { - sc = sym->s_scl; - if (sc == STRTAG || sc == UNIONTAG || sc == ENUMTAG) { - /* dubious tag declaration: %s %s */ - warning(85, scltoa(sc), sym->s_name); - } - } - - n = 1; - for (arg = args; arg != NULL; arg = arg->s_nxt) { - if (arg->s_type->t_tspec == VOID) { - if (n > 1 || arg->s_nxt != NULL) { - /* "void" must be sole parameter */ - error(60); - arg->s_type = gettyp(INT); - } - } - n++; - } - - /* return NULL if first param is VOID */ - return (args != NULL && args->s_type->t_tspec != VOID ? args : NULL); -} - -/* - * Called for old style function declarations. - */ -static void -osfunc(sym_t *decl, sym_t *args) -{ - - /* - * Remember list of params only if this is really seams to be - * a function definition. - */ - if (dcs->d_nxt->d_ctx == EXTERN && - decl->s_type == dcs->d_nxt->d_type) { - /* - * We assume that this becomes a function definition. If - * we are wrong, its corrected in chkfdef(). - */ - if (args != NULL) { - decl->s_osdef = 1; - decl->s_args = args; - } - } else { - if (args != NULL) - /* function prototype parameters must have types */ - warning(62); - } -} - -/* - * Lists of Identifiers in functions declarations are allowed only if - * its also a function definition. If this is not the case, print a - * error message. - */ -void -chkfdef(sym_t *sym, int msg) -{ - - if (sym->s_osdef) { - if (msg) { - /* incomplete or misplaced function definition */ - error(22); - } - sym->s_osdef = 0; - sym->s_args = NULL; - } -} - -/* - * Process the name in a declarator. - * If the symbol does already exists, a new one is created. - * The symbol becomes one of the storage classes EXTERN, STATIC, AUTO or - * TYPEDEF. - * s_def and s_reg are valid after dname(). - */ -sym_t * -dname(sym_t *sym) -{ - scl_t sc = NOSCL; - - if (sym->s_scl == NOSCL) { - dcs->d_rdcsym = NULL; - } else if (sym->s_defarg) { - sym->s_defarg = 0; - dcs->d_rdcsym = NULL; - } else { - dcs->d_rdcsym = sym; - sym = pushdown(sym); - } - - switch (dcs->d_ctx) { - case MOS: - case MOU: - /* Parent setzen */ - sym->s_styp = dcs->d_tagtyp->t_str; - sym->s_def = DEF; - sym->s_value.v_tspec = INT; - sc = dcs->d_ctx; - break; - case EXTERN: - /* - * static and external symbols without "extern" are - * considered to be tentative defined, external - * symbols with "extern" are declared, and typedef names - * are defined. Tentative defined and declared symbols - * may become defined if an initializer is present or - * this is a function definition. - */ - if ((sc = dcs->d_scl) == NOSCL) { - sc = EXTERN; - sym->s_def = TDEF; - } else if (sc == STATIC) { - sym->s_def = TDEF; - } else if (sc == TYPEDEF) { - sym->s_def = DEF; - } else if (sc == EXTERN) { - sym->s_def = DECL; - } else { - LERROR("dname()"); - } - break; - case PARG: - sym->s_arg = 1; - /* FALLTHROUGH */ - case ARG: - if ((sc = dcs->d_scl) == NOSCL) { - sc = AUTO; - } else if (sc == REG) { - sym->s_reg = 1; - sc = AUTO; - } else { - LERROR("dname()"); - } - sym->s_def = DEF; - break; - case AUTO: - if ((sc = dcs->d_scl) == NOSCL) { - /* - * XXX somewhat ugly because we dont know whether - * this is AUTO or EXTERN (functions). If we are - * wrong it must be corrected in decl1loc(), where - * we have the necessary type information. - */ - sc = AUTO; - sym->s_def = DEF; - } else if (sc == AUTO || sc == STATIC || sc == TYPEDEF) { - sym->s_def = DEF; - } else if (sc == REG) { - sym->s_reg = 1; - sc = AUTO; - sym->s_def = DEF; - } else if (sc == EXTERN) { - sym->s_def = DECL; - } else { - LERROR("dname()"); - } - break; - default: - LERROR("dname()"); - } - sym->s_scl = sc; - - sym->s_type = dcs->d_type; - - dcs->d_fpsyms = NULL; - - return (sym); -} - -/* - * Process a name in the list of formal params in an old style function - * definition. - */ -sym_t * -iname(sym_t *sym) -{ - - if (sym->s_scl != NOSCL) { - if (blklev == sym->s_blklev) { - /* redeclaration of formal parameter %s */ - error(21, sym->s_name); - if (!sym->s_defarg) - LERROR("iname()"); - } - sym = pushdown(sym); - } - sym->s_type = gettyp(INT); - sym->s_scl = AUTO; - sym->s_def = DEF; - sym->s_defarg = sym->s_arg = 1; - return (sym); -} - -/* - * Create the type of a tag. - * - * tag points to the symbol table entry of the tag - * kind is the kind of the tag (STRUCT/UNION/ENUM) - * decl is 1 if the type of the tag will be completed in this declaration - * (the following token is T_LBRACE) - * semi is 1 if the following token is T_SEMI - */ -type_t * -mktag(sym_t *tag, tspec_t kind, int decl, int semi) -{ - scl_t scl = NOSCL; - type_t *tp; - - if (kind == STRUCT) { - scl = STRTAG; - } else if (kind == UNION) { - scl = UNIONTAG; - } else if (kind == ENUM) { - scl = ENUMTAG; - } else { - LERROR("mktag()"); - } - - if (tag != NULL) { - if (tag->s_scl != NOSCL) { - tag = newtag(tag, scl, decl, semi); - } else { - /* a new tag, no empty declaration */ - dcs->d_nxt->d_nedecl = 1; - if (scl == ENUMTAG && !decl) { - if (!tflag && (sflag || pflag)) - /* forward reference to enum type */ - warning(42); - } - } - if (tag->s_scl == NOSCL) { - tag->s_scl = scl; - tag->s_type = tp = getblk(sizeof (type_t)); - } else { - tp = tag->s_type; - } - } else { - tag = getblk(sizeof (sym_t)); - tag->s_name = unnamed; - UNIQUE_CURR_POS(tag->s_dpos); - tag->s_kind = FTAG; - tag->s_scl = scl; - tag->s_blklev = -1; - tag->s_type = tp = getblk(sizeof (type_t)); - dcs->d_nxt->d_nedecl = 1; - } - - if (tp->t_tspec == NOTSPEC) { - tp->t_tspec = kind; - if (kind != ENUM) { - tp->t_str = getblk(sizeof (str_t)); - tp->t_str->align = CHAR_BIT; - tp->t_str->stag = tag; - } else { - tp->t_isenum = 1; - tp->t_enum = getblk(sizeof (enum_t)); - tp->t_enum->etag = tag; - } - /* is incomplete type */ - setcompl(tp, 1); - } - - return (tp); -} - -/* - * Checks all possible cases of tag redeclarations. - * decl is 1 if T_LBRACE follows - * semi is 1 if T_SEMI follows - */ -static sym_t * -newtag(sym_t *tag, scl_t scl, int decl, int semi) -{ - - if (tag->s_blklev < blklev) { - if (semi) { - /* "struct a;" */ - if (!tflag) { - if (!sflag) - /* decl. introduces new type ... */ - warning(44, scltoa(scl), tag->s_name); - tag = pushdown(tag); - } else if (tag->s_scl != scl) { - /* base type is really "%s %s" */ - warning(45, scltoa(tag->s_scl), tag->s_name); - } - dcs->d_nxt->d_nedecl = 1; - } else if (decl) { - /* "struct a { ... } " */ - if (hflag) - /* redefinition hides earlier one: %s */ - warning(43, tag->s_name); - tag = pushdown(tag); - dcs->d_nxt->d_nedecl = 1; - } else if (tag->s_scl != scl) { - /* base type is really "%s %s" */ - warning(45, scltoa(tag->s_scl), tag->s_name); - /* declaration introduces new type in ANSI C: %s %s */ - if (!sflag) - warning(44, scltoa(scl), tag->s_name); - tag = pushdown(tag); - dcs->d_nxt->d_nedecl = 1; - } - } else { - if (tag->s_scl != scl) { - /* (%s) tag redeclared */ - error(46, scltoa(tag->s_scl)); - prevdecl(-1, tag); - tag = pushdown(tag); - dcs->d_nxt->d_nedecl = 1; - } else if (decl && !incompl(tag->s_type)) { - /* (%s) tag redeclared */ - error(46, scltoa(tag->s_scl)); - prevdecl(-1, tag); - tag = pushdown(tag); - dcs->d_nxt->d_nedecl = 1; - } else if (semi || decl) { - dcs->d_nxt->d_nedecl = 1; - } - } - return (tag); -} - -const char * -scltoa(scl_t sc) -{ - const char *s; - - switch (sc) { - case EXTERN: s = "extern"; break; - case STATIC: s = "static"; break; - case AUTO: s = "auto"; break; - case REG: s = "register"; break; - case TYPEDEF: s = "typedef"; break; - case STRTAG: s = "struct"; break; - case UNIONTAG: s = "union"; break; - case ENUMTAG: s = "enum"; break; - default: LERROR("tagttoa()"); - } - return (s); -} - -/* - * Completes the type of a tag in a struct/union/enum declaration. - * tp points to the type of the, tag, fmem to the list of members/enums. - */ -type_t * -compltag(type_t *tp, sym_t *fmem) -{ - tspec_t t; - str_t *sp; - int n; - sym_t *mem; - - /* from now a complete type */ - setcompl(tp, 0); - - if ((t = tp->t_tspec) != ENUM) { - align(dcs->d_stralign, 0); - sp = tp->t_str; - sp->align = dcs->d_stralign; - sp->size = dcs->d_offset; - sp->memb = fmem; - if (sp->size == 0) { - /* zero sized %s */ - (void)c99ism(47, ttab[t].tt_name); - } else { - n = 0; - for (mem = fmem; mem != NULL; mem = mem->s_nxt) { - if (mem->s_name != unnamed) - n++; - } - if (n == 0) { - /* %s has no named members */ - warning(65, - t == STRUCT ? "structure" : "union"); - } - } - } else { - tp->t_enum->elem = fmem; - } - return (tp); -} - -/* - * Processes the name of an enumerator in en enum declaration. - * - * sym points to the enumerator - * val is the value of the enumerator - * impl is 1 if the value of the enumerator was not explicit specified. - */ -sym_t * -ename(sym_t *sym, int val, int impl) -{ - - if (sym->s_scl) { - if (sym->s_blklev == blklev) { - /* no hflag, because this is illegal!!! */ - if (sym->s_arg) { - /* enumeration constant hides parameter: %s */ - warning(57, sym->s_name); - } else { - /* redeclaration of %s */ - error(27, sym->s_name); - /* - * inside blocks it should not too complicated - * to find the position of the previous - * declaration - */ - if (blklev == 0) - prevdecl(-1, sym); - } - } else { - if (hflag) - /* redefinition hides earlier one: %s */ - warning(43, sym->s_name); - } - sym = pushdown(sym); - } - sym->s_scl = ENUMCON; - sym->s_type = dcs->d_tagtyp; - sym->s_value.v_tspec = INT; - sym->s_value.v_quad = val; - if (impl && val - 1 == INT_MAX) { - /* overflow in enumeration values: %s */ - warning(48, sym->s_name); - } - enumval = val + 1; - return (sym); -} - -/* - * Process a single external declarator. - */ -void -decl1ext(sym_t *dsym, int initflg) -{ - int warn, rval, redec; - sym_t *rdsym; - - chkfdef(dsym, 1); - - chktyp(dsym); - - if (initflg && !(initerr = chkinit(dsym))) - dsym->s_def = DEF; - - /* - * Declarations of functions are marked as "tentative" in dname(). - * This is wrong because there are no tentative function - * definitions. - */ - if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF) - dsym->s_def = DECL; - - if (dcs->d_inline) { - if (dsym->s_type->t_tspec == FUNC) { - dsym->s_inline = 1; - } else { - /* variable declared inline: %s */ - warning(268, dsym->s_name); - } - } - - /* Write the declaration into the output file */ - if (plibflg && llibflg && - dsym->s_type->t_tspec == FUNC && dsym->s_type->t_proto) { - /* - * With both LINTLIBRARY and PROTOLIB the prototype is - * written as a function definition to the output file. - */ - rval = dsym->s_type->t_subt->t_tspec != VOID; - outfdef(dsym, &dsym->s_dpos, rval, 0, NULL); - } else { - outsym(dsym, dsym->s_scl, dsym->s_def); - } - - if ((rdsym = dcs->d_rdcsym) != NULL) { - - /* - * If the old symbol stems from an old style function definition - * we have remembered the params in rdsmy->s_args and compare - * them with the params of the prototype. - */ - if (rdsym->s_osdef && dsym->s_type->t_proto) { - redec = chkosdef(rdsym, dsym); - } else { - redec = 0; - } - - if (!redec && !isredec(dsym, (warn = 0, &warn))) { - - if (warn) { - /* redeclaration of %s */ - (*(sflag ? error : warning))(27, dsym->s_name); - prevdecl(-1, rdsym); - } - - /* - * Overtake the remembered params if the new symbol - * is not a prototype. - */ - if (rdsym->s_osdef && !dsym->s_type->t_proto) { - dsym->s_osdef = rdsym->s_osdef; - dsym->s_args = rdsym->s_args; - STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos); - } - - /* - * Remember the position of the declaration if the - * old symbol was a prototype and the new is not. - * Also remember the position if the old symbol - * was defined and the new is not. - */ - if (rdsym->s_type->t_proto && !dsym->s_type->t_proto) { - STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos); - } else if (rdsym->s_def == DEF && dsym->s_def != DEF) { - STRUCT_ASSIGN(dsym->s_dpos, rdsym->s_dpos); - } - - /* - * Copy informations about usage of the name into - * the new symbol. - */ - cpuinfo(dsym, rdsym); - - /* Once a name is defined, it remains defined. */ - if (rdsym->s_def == DEF) - dsym->s_def = DEF; - - /* once a function is inline, it remains inline */ - if (rdsym->s_inline) - dsym->s_inline = 1; - - compltyp(dsym, rdsym); - - } - - rmsym(rdsym); - } - - if (dsym->s_scl == TYPEDEF) { - dsym->s_type = duptyp(dsym->s_type); - dsym->s_type->t_typedef = 1; - settdsym(dsym->s_type, dsym); - } - -} - -/* - * Copies informations about usage into a new symbol table entry of - * the same symbol. - */ -void -cpuinfo(sym_t *sym, sym_t *rdsym) -{ - - sym->s_spos = rdsym->s_spos; - sym->s_upos = rdsym->s_upos; - sym->s_set = rdsym->s_set; - sym->s_used = rdsym->s_used; -} - -/* - * Prints an error and returns 1 if a symbol is redeclared/redefined. - * Otherwise returns 0 and, in some cases of minor problems, prints - * a warning. - */ -int -isredec(sym_t *dsym, int *warn) -{ - sym_t *rsym; - - if ((rsym = dcs->d_rdcsym)->s_scl == ENUMCON) { - /* redeclaration of %s */ - error(27, dsym->s_name); - prevdecl(-1, rsym); - return (1); - } - if (rsym->s_scl == TYPEDEF) { - /* typedef redeclared: %s */ - error(89, dsym->s_name); - prevdecl(-1, rsym); - return (1); - } - if (dsym->s_scl == TYPEDEF) { - /* redeclaration of %s */ - error(27, dsym->s_name); - prevdecl(-1, rsym); - return (1); - } - if (rsym->s_def == DEF && dsym->s_def == DEF) { - /* redefinition of %s */ - error(28, dsym->s_name); - prevdecl(-1, rsym); - return(1); - } - if (!eqtype(rsym->s_type, dsym->s_type, 0, 0, warn)) { - /* redeclaration of %s */ - error(27, dsym->s_name); - prevdecl(-1, rsym); - return(1); - } - if (rsym->s_scl == EXTERN && dsym->s_scl == EXTERN) - return(0); - if (rsym->s_scl == STATIC && dsym->s_scl == STATIC) - return(0); - if (rsym->s_scl == STATIC && dsym->s_def == DECL) - return(0); - if (rsym->s_scl == EXTERN && rsym->s_def == DEF) { - /* - * All cases except "int a = 1; static int a;" are caught - * above with or without a warning - */ - /* redeclaration of %s */ - error(27, dsym->s_name); - prevdecl(-1, rsym); - return(1); - } - if (rsym->s_scl == EXTERN) { - /* previously declared extern, becomes static: %s */ - warning(29, dsym->s_name); - prevdecl(-1, rsym); - return(0); - } - /* - * Now its on of: - * "static a; int a;", "static a; int a = 1;", "static a = 1; int a;" - */ - /* redeclaration of %s; ANSI C requires "static" */ - if (sflag) { - warning(30, dsym->s_name); - prevdecl(-1, rsym); - } - dsym->s_scl = STATIC; - return (0); -} - -/* - * Checks if two types are compatible. Returns 0 if not, otherwise 1. - * - * ignqual ignore qualifiers of type; used for function params - * promot promote left type; used for comparison of params of - * old style function definitions with params of prototypes. - * *warn set to 1 if an old style function declaration is not - * compatible with a prototype - */ -int -eqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int *warn) -{ - tspec_t t; - - while (tp1 != NULL && tp2 != NULL) { - - t = tp1->t_tspec; - if (promot) { - if (t == FLOAT) { - t = DOUBLE; - } else if (t == CHAR || t == SCHAR) { - t = INT; - } else if (t == UCHAR) { - t = tflag ? UINT : INT; - } else if (t == SHORT) { - t = INT; - } else if (t == USHORT) { - /* CONSTCOND */ - t = INT_MAX < USHRT_MAX || tflag ? UINT : INT; - } - } - - if (t != tp2->t_tspec) - return (0); - - if (tp1->t_const != tp2->t_const && !ignqual && !tflag) - return (0); - - if (tp1->t_volatile != tp2->t_volatile && !ignqual && !tflag) - return (0); - - if (t == STRUCT || t == UNION) - return (tp1->t_str == tp2->t_str); - - if (t == ARRAY && tp1->t_dim != tp2->t_dim) { - if (tp1->t_dim != 0 && tp2->t_dim != 0) - return (0); - } - - /* dont check prototypes for traditional */ - if (t == FUNC && !tflag) { - if (tp1->t_proto && tp2->t_proto) { - if (!eqargs(tp1, tp2, warn)) - return (0); - } else if (tp1->t_proto) { - if (!mnoarg(tp1, warn)) - return (0); - } else if (tp2->t_proto) { - if (!mnoarg(tp2, warn)) - return (0); - } - } - - tp1 = tp1->t_subt; - tp2 = tp2->t_subt; - ignqual = promot = 0; - - } - - return (tp1 == tp2); -} - -/* - * Compares the parameter types of two prototypes. - */ -static int -eqargs(type_t *tp1, type_t *tp2, int *warn) -{ - sym_t *a1, *a2; - - if (tp1->t_vararg != tp2->t_vararg) - return (0); - - a1 = tp1->t_args; - a2 = tp2->t_args; - - while (a1 != NULL && a2 != NULL) { - - if (eqtype(a1->s_type, a2->s_type, 1, 0, warn) == 0) - return (0); - - a1 = a1->s_nxt; - a2 = a2->s_nxt; - - } - - return (a1 == a2); -} - -/* - * mnoarg() (matches functions with no argument type information) - * returns 1 if all parameters of a prototype are compatible with - * and old style function declaration. - * This is the case if following conditions are met: - * 1. the prototype must have a fixed number of parameters - * 2. no parameter is of type float - * 3. no parameter is converted to another type if integer promotion - * is applied on it - */ -static int -mnoarg(type_t *tp, int *warn) -{ - sym_t *arg; - tspec_t t; - - if (tp->t_vararg) { - if (warn != NULL) - *warn = 1; - } - for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) { - if ((t = arg->s_type->t_tspec) == FLOAT || - t == CHAR || t == SCHAR || t == UCHAR || - t == SHORT || t == USHORT) { - if (warn != NULL) - *warn = 1; - } - } - return (1); -} - -/* - * Compares a prototype declaration with the remembered arguments of - * a previous old style function definition. - */ -static int -chkosdef(sym_t *rdsym, sym_t *dsym) -{ - sym_t *args, *pargs, *arg, *parg; - int narg, nparg, n; - int warn, msg; - - args = rdsym->s_args; - pargs = dsym->s_type->t_args; - - msg = 0; - - narg = nparg = 0; - for (arg = args; arg != NULL; arg = arg->s_nxt) - narg++; - for (parg = pargs; parg != NULL; parg = parg->s_nxt) - nparg++; - if (narg != nparg) { - /* prototype does not match old-style definition */ - error(63); - msg = 1; - goto end; - } - - arg = args; - parg = pargs; - n = 1; - while (narg--) { - warn = 0; - /* - * If it does not match due to promotion and sflag is - * not set we print only a warning. - */ - if (!eqtype(arg->s_type, parg->s_type, 1, 1, &warn) || warn) { - /* prototype does not match old-style def., arg #%d */ - error(299, n); - msg = 1; - } - arg = arg->s_nxt; - parg = parg->s_nxt; - n++; - } - - end: - if (msg) - /* old style definition */ - prevdecl(300, rdsym); - - return (msg); -} - -/* - * Completes a type by copying the dimension and prototype information - * from a second compatible type. - * - * Following lines are legal: - * "typedef a[]; a b; a b[10]; a c; a c[20];" - * "typedef ft(); ft f; f(int); ft g; g(long);" - * This means that, if a type is completed, the type structure must - * be duplicated. - */ -void -compltyp(sym_t *dsym, sym_t *ssym) -{ - type_t **dstp, *src; - type_t *dst; - - dstp = &dsym->s_type; - src = ssym->s_type; - - while ((dst = *dstp) != NULL) { - if (src == NULL || dst->t_tspec != src->t_tspec) - LERROR("compltyp()"); - if (dst->t_tspec == ARRAY) { - if (dst->t_dim == 0 && src->t_dim != 0) { - *dstp = dst = duptyp(dst); - dst->t_dim = src->t_dim; - /* now a complete type */ - setcompl(dst, 0); - } - } else if (dst->t_tspec == FUNC) { - if (!dst->t_proto && src->t_proto) { - *dstp = dst = duptyp(dst); - dst->t_proto = 1; - dst->t_args = src->t_args; - } - } - dstp = &dst->t_subt; - src = src->t_subt; - } -} - -/* - * Completes the declaration of a single argument. - */ -sym_t * -decl1arg(sym_t *sym, int initflg) -{ - tspec_t t; - - chkfdef(sym, 1); - - chktyp(sym); - - if (dcs->d_rdcsym != NULL && dcs->d_rdcsym->s_blklev == blklev) { - /* redeclaration of formal parameter %s */ - error(237, sym->s_name); - rmsym(dcs->d_rdcsym); - sym->s_arg = 1; - } - - if (!sym->s_arg) { - /* declared argument %s is missing */ - error(53, sym->s_name); - sym->s_arg = 1; - } - - if (initflg) { - /* cannot initialize parameter: %s */ - error(52, sym->s_name); - initerr = 1; - } - - if ((t = sym->s_type->t_tspec) == ARRAY) { - sym->s_type = incref(sym->s_type->t_subt, PTR); - } else if (t == FUNC) { - if (tflag) - /* a function is declared as an argument: %s */ - warning(50, sym->s_name); - sym->s_type = incref(sym->s_type, PTR); - } else if (t == FLOAT) { - if (tflag) - sym->s_type = gettyp(DOUBLE); - } - - if (dcs->d_inline) - /* argument declared inline: %s */ - warning(269, sym->s_name); - - /* - * Arguments must have complete types. lengths() prints the needed - * error messages (null dimension is impossible because arrays are - * converted to pointers). - */ - if (sym->s_type->t_tspec != VOID) - (void)length(sym->s_type, sym->s_name); - - setsflg(sym); - - return (sym); -} - -/* - * Does some checks for lint directives which apply to functions. - * Processes arguments in old style function definitions which default - * to int. - * Checks compatibility of old style function definition with previous - * prototype. - */ -void -cluparg(void) -{ - sym_t *args, *arg, *pargs, *parg; - int narg, nparg, n, msg; - tspec_t t; - - args = funcsym->s_args; - pargs = funcsym->s_type->t_args; - - /* check for illegal combinations of lint directives */ - if (prflstrg != -1 && scflstrg != -1) { - /* can't be used together: ** PRINTFLIKE ** ** SCANFLIKE ** */ - warning(289); - prflstrg = scflstrg = -1; - } - if (nvararg != -1 && (prflstrg != -1 || scflstrg != -1)) { - /* dubious use of ** VARARGS ** with ** %s ** */ - warning(288, prflstrg != -1 ? "PRINTFLIKE" : "SCANFLIKE"); - nvararg = -1; - } - - /* - * check if the argument of a lint directive is compatible with the - * number of arguments. - */ - narg = 0; - for (arg = dcs->d_fargs; arg != NULL; arg = arg->s_nxt) - narg++; - if (nargusg > narg) { - /* argument number mismatch with directive: ** %s ** */ - warning(283, "ARGSUSED"); - nargusg = 0; - } - if (nvararg > narg) { - /* argument number mismatch with directive: ** %s ** */ - warning(283, "VARARGS"); - nvararg = 0; - } - if (prflstrg > narg) { - /* argument number mismatch with directive: ** %s ** */ - warning(283, "PRINTFLIKE"); - prflstrg = -1; - } else if (prflstrg == 0) { - prflstrg = -1; - } - if (scflstrg > narg) { - /* argument number mismatch with directive: ** %s ** */ - warning(283, "SCANFLIKE"); - scflstrg = -1; - } else if (scflstrg == 0) { - scflstrg = -1; - } - if (prflstrg != -1 || scflstrg != -1) { - narg = prflstrg != -1 ? prflstrg : scflstrg; - arg = dcs->d_fargs; - for (n = 1; n < narg; n++) - arg = arg->s_nxt; - if (arg->s_type->t_tspec != PTR || - ((t = arg->s_type->t_subt->t_tspec) != CHAR && - t != UCHAR && t != SCHAR)) { - /* arg. %d must be 'char *' for PRINTFLIKE/SCANFLIKE */ - warning(293, narg); - prflstrg = scflstrg = -1; - } - } - - /* - * print a warning for each argument of an old style function - * definition which defaults to int - */ - for (arg = args; arg != NULL; arg = arg->s_nxt) { - if (arg->s_defarg) { - /* argument type defaults to int: %s */ - warning(32, arg->s_name); - arg->s_defarg = 0; - setsflg(arg); - } - } - - /* - * If this is an old style function definition and a prototyp - * exists, compare the types of arguments. - */ - if (funcsym->s_osdef && funcsym->s_type->t_proto) { - /* - * If the number of arguments does not macht, we need not - * continue. - */ - narg = nparg = 0; - msg = 0; - for (parg = pargs; parg != NULL; parg = parg->s_nxt) - nparg++; - for (arg = args; arg != NULL; arg = arg->s_nxt) - narg++; - if (narg != nparg) { - /* parameter mismatch: %d declared, %d defined */ - error(51, nparg, narg); - msg = 1; - } else { - parg = pargs; - arg = args; - while (narg--) { - msg |= chkptdecl(arg, parg); - parg = parg->s_nxt; - arg = arg->s_nxt; - } - } - if (msg) - /* prototype declaration */ - prevdecl(285, dcs->d_rdcsym); - - /* from now the prototype is valid */ - funcsym->s_osdef = 0; - funcsym->s_args = NULL; - - } - -} - -/* - * Checks compatibility of an old style function definition with a previous - * prototype declaration. - * Returns 1 if the position of the previous declaration should be reported. - */ -static int -chkptdecl(sym_t *arg, sym_t *parg) -{ - type_t *tp, *ptp; - int warn, msg; - - tp = arg->s_type; - ptp = parg->s_type; - - msg = 0; - warn = 0; - - if (!eqtype(tp, ptp, 1, 1, &warn)) { - if (eqtype(tp, ptp, 1, 0, &warn)) { - /* type does not match prototype: %s */ - msg = gnuism(58, arg->s_name); - } else { - /* type does not match prototype: %s */ - error(58, arg->s_name); - msg = 1; - } - } else if (warn) { - /* type does not match prototype: %s */ - (*(sflag ? error : warning))(58, arg->s_name); - msg = 1; - } - - return (msg); -} - -/* - * Completes a single local declaration/definition. - */ -void -decl1loc(sym_t *dsym, int initflg) -{ - - /* Correct a mistake done in dname(). */ - if (dsym->s_type->t_tspec == FUNC) { - dsym->s_def = DECL; - if (dcs->d_scl == NOSCL) - dsym->s_scl = EXTERN; - } - - if (dsym->s_type->t_tspec == FUNC) { - if (dsym->s_scl == STATIC) { - /* dubious static function at block level: %s */ - warning(93, dsym->s_name); - dsym->s_scl = EXTERN; - } else if (dsym->s_scl != EXTERN && dsym->s_scl != TYPEDEF) { - /* function has illegal storage class: %s */ - error(94, dsym->s_name); - dsym->s_scl = EXTERN; - } - } - - /* - * functions may be declared inline at local scope, although - * this has no effect for a later definition of the same - * function. - * XXX it should have an effect if tflag is set. this would - * also be the way gcc behaves. - */ - if (dcs->d_inline) { - if (dsym->s_type->t_tspec == FUNC) { - dsym->s_inline = 1; - } else { - /* variable declared inline: %s */ - warning(268, dsym->s_name); - } - } - - chkfdef(dsym, 1); - - chktyp(dsym); - - if (dcs->d_rdcsym != NULL && dsym->s_scl == EXTERN) - ledecl(dsym); - - if (dsym->s_scl == EXTERN) { - /* - * XXX wenn die statische Variable auf Ebene 0 erst - * spaeter definiert wird, haben wir die Brille auf. - */ - if (dsym->s_xsym == NULL) { - outsym(dsym, EXTERN, dsym->s_def); - } else { - outsym(dsym, dsym->s_xsym->s_scl, dsym->s_def); - } - } - - if (dcs->d_rdcsym != NULL) { - - if (dcs->d_rdcsym->s_blklev == 0) { - - switch (dsym->s_scl) { - case AUTO: - /* automatic hides external declaration: %s */ - if (hflag) - warning(86, dsym->s_name); - break; - case STATIC: - /* static hides external declaration: %s */ - if (hflag) - warning(87, dsym->s_name); - break; - case TYPEDEF: - /* typedef hides external declaration: %s */ - if (hflag) - warning(88, dsym->s_name); - break; - case EXTERN: - /* - * Warnings and errors are printed in ledecl() - */ - break; - default: - LERROR("decl1loc()"); - } - - } else if (dcs->d_rdcsym->s_blklev == blklev) { - - /* no hflag, because its illegal! */ - if (dcs->d_rdcsym->s_arg) { - /* - * if !tflag, a "redeclaration of %s" error - * is produced below - */ - if (tflag) { - if (hflag) - /* decl. hides parameter: %s */ - warning(91, dsym->s_name); - rmsym(dcs->d_rdcsym); - } - } - - } else if (dcs->d_rdcsym->s_blklev < blklev) { - - if (hflag) - /* declaration hides earlier one: %s */ - warning(95, dsym->s_name); - - } - - if (dcs->d_rdcsym->s_blklev == blklev) { - - /* redeclaration of %s */ - error(27, dsym->s_name); - rmsym(dcs->d_rdcsym); - - } - - } - - if (initflg && !(initerr = chkinit(dsym))) { - dsym->s_def = DEF; - setsflg(dsym); - } - - if (dsym->s_scl == TYPEDEF) { - dsym->s_type = duptyp(dsym->s_type); - dsym->s_type->t_typedef = 1; - settdsym(dsym->s_type, dsym); - } - - /* - * Before we can check the size we must wait for an initialisation - * which may follow. - */ -} - -/* - * Processes (re)declarations of external Symbols inside blocks. - */ -static void -ledecl(sym_t *dsym) -{ - int eqt, warn; - sym_t *esym; - - /* look for a symbol with the same name */ - esym = dcs->d_rdcsym; - while (esym != NULL && esym->s_blklev != 0) { - while ((esym = esym->s_link) != NULL) { - if (esym->s_kind != FVFT) - continue; - if (strcmp(dsym->s_name, esym->s_name) == 0) - break; - } - } - if (esym == NULL) - return; - if (esym->s_scl != EXTERN && esym->s_scl != STATIC) { - /* gcc accepts this without a warning, pcc prints an error. */ - /* redeclaration of %s */ - warning(27, dsym->s_name); - prevdecl(-1, esym); - return; - } - - warn = 0; - eqt = eqtype(esym->s_type, dsym->s_type, 0, 0, &warn); - - if (!eqt || warn) { - if (esym->s_scl == EXTERN) { - /* inconsistent redeclaration of extern: %s */ - warning(90, dsym->s_name); - prevdecl(-1, esym); - } else { - /* inconsistent redeclaration of static: %s */ - warning(92, dsym->s_name); - prevdecl(-1, esym); - } - } - - if (eqt) { - /* - * Remember the external symbol so we can update usage - * information at the end of the block. - */ - dsym->s_xsym = esym; - } -} - -/* - * Print an error or a warning if the symbol can't be initialized due - * to type/storage class. Return value is 1 if an error has been - * detected. - */ -static int -chkinit(sym_t *sym) -{ - int err; - - err = 0; - - if (sym->s_type->t_tspec == FUNC) { - /* cannot initialize function: %s */ - error(24, sym->s_name); - err = 1; - } else if (sym->s_scl == TYPEDEF) { - /* cannot initialize typedef: %s */ - error(25, sym->s_name); - err = 1; - } else if (sym->s_scl == EXTERN && sym->s_def == DECL) { - /* cannot initialize "extern" declaration: %s */ - if (dcs->d_ctx == EXTERN) { - warning(26, sym->s_name); - } else { - error(26, sym->s_name); - err = 1; - } - } - - return (err); -} - -/* - * Create a symbol for an abstract declaration. - */ -sym_t * -aname(void) -{ - sym_t *sym; - - if (dcs->d_ctx != ABSTRACT && dcs->d_ctx != PARG) - LERROR("aname()"); - - sym = getblk(sizeof (sym_t)); - - sym->s_name = unnamed; - sym->s_def = DEF; - sym->s_scl = ABSTRACT; - sym->s_blklev = -1; - - if (dcs->d_ctx == PARG) - sym->s_arg = 1; - - sym->s_type = dcs->d_type; - dcs->d_rdcsym = NULL; - dcs->d_vararg = 0; - - return (sym); -} - -/* - * Removes anything which has nothing to do on global level. - */ -void -globclup(void) -{ - - while (dcs->d_nxt != NULL) - popdecl(); - - cleanup(); - blklev = 0; - mblklev = 0; - - /* - * remove all information about pending lint directives without - * warnings. - */ - glclup(1); -} - -/* - * Process an abstract type declaration - */ -sym_t * -decl1abs(sym_t *sym) -{ - - chkfdef(sym, 1); - chktyp(sym); - return (sym); -} - -/* - * Checks size after declarations of variables and their initialisation. - */ -void -chksz(sym_t *dsym) -{ - - /* - * check size only for symbols which are defined and no function and - * not typedef name - */ - if (dsym->s_def != DEF) - return; - if (dsym->s_scl == TYPEDEF) - return; - if (dsym->s_type->t_tspec == FUNC) - return; - - if (length(dsym->s_type, dsym->s_name) == 0 && - dsym->s_type->t_tspec == ARRAY && dsym->s_type->t_dim == 0) { - /* empty array declaration: %s */ - if (tflag) { - warning(190, dsym->s_name); - } else { - error(190, dsym->s_name); - } - } -} - -/* - * Mark an object as set if it is not already - */ -void -setsflg(sym_t *sym) -{ - - if (!sym->s_set) { - sym->s_set = 1; - UNIQUE_CURR_POS(sym->s_spos); - } -} - -/* - * Mark an object as used if it is not already - */ -void -setuflg(sym_t *sym, int fcall, int szof) -{ - - if (!sym->s_used) { - sym->s_used = 1; - UNIQUE_CURR_POS(sym->s_upos); - } - /* - * for function calls another record is written - * - * XXX Should symbols used in sizeof() treated as used or not? - * Probably not, because there is no sense to declare an - * external variable only to get their size. - */ - if (!fcall && !szof && sym->s_kind == FVFT && sym->s_scl == EXTERN) - outusg(sym); -} - -/* - * Prints warnings for a list of variables and labels (concatenated - * with s_dlnxt) if these are not used or only set. - */ -void -chkusage(dinfo_t *di) -{ - sym_t *sym; - int mknowarn; - - /* for this warnings LINTED has no effect */ - mknowarn = nowarn; - nowarn = 0; - - for (sym = di->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) - chkusg1(di->d_asm, sym); - - nowarn = mknowarn; -} - -/* - * Prints a warning for a single variable or label if it is not used or - * only set. - */ -void -chkusg1(int novar, sym_t *sym) -{ - pos_t cpos; - - if (sym->s_blklev == -1) - return; - - STRUCT_ASSIGN(cpos, curr_pos); - - if (sym->s_kind == FVFT) { - if (sym->s_arg) { - chkausg(novar, sym); - } else { - chkvusg(novar, sym); - } - } else if (sym->s_kind == FLAB) { - chklusg(sym); - } else if (sym->s_kind == FTAG) { - chktusg(sym); - } - - STRUCT_ASSIGN(curr_pos, cpos); -} - -static void -chkausg(int novar, sym_t *arg) -{ - - if (!arg->s_set) - LERROR("chkausg()"); - - if (novar) - return; - - if (!arg->s_used && vflag) { - STRUCT_ASSIGN(curr_pos, arg->s_dpos); - /* argument %s unused in function %s */ - warning(231, arg->s_name, funcsym->s_name); - } -} - -static void -chkvusg(int novar, sym_t *sym) -{ - scl_t sc; - sym_t *xsym; - - if (blklev == 0 || sym->s_blklev == 0) - LERROR("chkvusg()"); - - /* errors in expressions easily cause lots of these warnings */ - if (nerr != 0) - return; - - /* - * XXX Only variables are checkd, although types should - * probably also be checked - */ - if ((sc = sym->s_scl) != EXTERN && sc != STATIC && - sc != AUTO && sc != REG) { - return; - } - - if (novar) - return; - - if (sc == EXTERN) { - if (!sym->s_used && !sym->s_set) { - STRUCT_ASSIGN(curr_pos, sym->s_dpos); - /* %s unused in function %s */ - warning(192, sym->s_name, funcsym->s_name); - } - } else { - if (sym->s_set && !sym->s_used) { - STRUCT_ASSIGN(curr_pos, sym->s_spos); - /* %s set but not used in function %s */ - warning(191, sym->s_name, funcsym->s_name); - } else if (!sym->s_used) { - STRUCT_ASSIGN(curr_pos, sym->s_dpos); - /* %s unused in function %s */ - warning(192, sym->s_name, funcsym->s_name); - } - } - - if (sc == EXTERN) { - /* - * information about usage is taken over into the symbol - * tabel entry at level 0 if the symbol was locally declared - * as an external symbol. - * - * XXX This is wrong for symbols declared static at level 0 - * if the usage information stems from sizeof(). This is - * because symbols at level 0 only used in sizeof() are - * considered to not be used. - */ - if ((xsym = sym->s_xsym) != NULL) { - if (sym->s_used && !xsym->s_used) { - xsym->s_used = 1; - STRUCT_ASSIGN(xsym->s_upos, sym->s_upos); - } - if (sym->s_set && !xsym->s_set) { - xsym->s_set = 1; - STRUCT_ASSIGN(xsym->s_spos, sym->s_spos); - } - } - } -} - -static void -chklusg(sym_t *lab) -{ - - if (blklev != 1 || lab->s_blklev != 1) - LERROR("chklusg()"); - - if (lab->s_set && !lab->s_used) { - STRUCT_ASSIGN(curr_pos, lab->s_spos); - /* label %s unused in function %s */ - warning(192, lab->s_name, funcsym->s_name); - } else if (!lab->s_set) { - STRUCT_ASSIGN(curr_pos, lab->s_upos); - /* undefined label %s */ - warning(23, lab->s_name); - } -} - -static void -chktusg(sym_t *sym) -{ - - if (!incompl(sym->s_type)) - return; - - /* complain always about incomplete tags declared inside blocks */ - if (!zflag || dcs->d_ctx != EXTERN) - return; - - STRUCT_ASSIGN(curr_pos, sym->s_dpos); - switch (sym->s_type->t_tspec) { - case STRUCT: - /* struct %s never defined */ - warning(233, sym->s_name); - break; - case UNION: - /* union %s never defined */ - warning(234, sym->s_name); - break; - case ENUM: - /* enum %s never defined */ - warning(235, sym->s_name); - break; - default: - LERROR("chktusg()"); - } -} - -/* - * Called after the entire translation unit has been parsed. - * Changes tentative definitions in definitions. - * Performs some tests on global Symbols. Detected Problems are: - * - defined variables of incomplete type - * - constant variables which are not initialized - * - static symbols which are never used - */ -void -chkglsyms(void) -{ - sym_t *sym; - pos_t cpos; - - if (blklev != 0 || dcs->d_nxt != NULL) - norecover(); - - STRUCT_ASSIGN(cpos, curr_pos); - - for (sym = dcs->d_dlsyms; sym != NULL; sym = sym->s_dlnxt) { - if (sym->s_blklev == -1) - continue; - if (sym->s_kind == FVFT) { - chkglvar(sym); - } else if (sym->s_kind == FTAG) { - chktusg(sym); - } else { - if (sym->s_kind != FMOS) - LERROR("chkglsyms()"); - } - } - - STRUCT_ASSIGN(curr_pos, cpos); -} - -static void -chkglvar(sym_t *sym) -{ - - if (sym->s_scl == TYPEDEF || sym->s_scl == ENUMCON) - return; - - if (sym->s_scl != EXTERN && sym->s_scl != STATIC) - LERROR("chkglvar()"); - - glchksz(sym); - - if (sym->s_scl == STATIC) { - if (sym->s_type->t_tspec == FUNC) { - if (sym->s_used && sym->s_def != DEF) { - STRUCT_ASSIGN(curr_pos, sym->s_upos); - /* static func. called but not def.. */ - error(225, sym->s_name); - } - } - if (!sym->s_used) { - STRUCT_ASSIGN(curr_pos, sym->s_dpos); - if (sym->s_type->t_tspec == FUNC) { - if (sym->s_def == DEF) { - if (!sym->s_inline) - /* static function %s unused */ - warning(236, sym->s_name); - } else { - /* static function %s decl. but ... */ - warning(290, sym->s_name); - } - } else if (!sym->s_set) { - /* static variable %s unused */ - warning(226, sym->s_name); - } else { - /* static variable %s set but not used */ - warning(307, sym->s_name); - } - } - if (!tflag && sym->s_def == TDEF && sym->s_type->t_const) { - STRUCT_ASSIGN(curr_pos, sym->s_dpos); - /* const object %s should have initializer */ - warning(227, sym->s_name); - } - } -} - -static void -glchksz(sym_t *sym) -{ - - if (sym->s_def == TDEF) { - if (sym->s_type->t_tspec == FUNC) - /* - * this can happen if a syntax error occurred - * after a function declaration - */ - return; - STRUCT_ASSIGN(curr_pos, sym->s_dpos); - if (length(sym->s_type, sym->s_name) == 0 && - sym->s_type->t_tspec == ARRAY && sym->s_type->t_dim == 0) { - /* empty array declaration: %s */ - if (tflag || (sym->s_scl == EXTERN && !sflag)) { - warning(190, sym->s_name); - } else { - error(190, sym->s_name); - } - } - } -} - -/* - * Prints information about location of previous definition/declaration. - */ -void -prevdecl(int msg, sym_t *psym) -{ - pos_t cpos; - - if (!rflag) - return; - - STRUCT_ASSIGN(cpos, curr_pos); - STRUCT_ASSIGN(curr_pos, psym->s_dpos); - if (msg != -1) { - message(msg, psym->s_name); - } else if (psym->s_def == DEF || psym->s_def == TDEF) { - /* previous definition of %s */ - message(261, psym->s_name); - } else { - /* previous declaration of %s */ - message(260, psym->s_name); - } - STRUCT_ASSIGN(curr_pos, cpos); -} Index: usr.bin/xlint/lint1/emit.c =================================================================== --- usr.bin/xlint/lint1/emit.c +++ /dev/null @@ -1,243 +0,0 @@ -/* $NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef lint -static char rcsid[] = "$NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $"; -#endif - -#include -#include -#include -#include - -#include "lint.h" - -/* name and handle of output file */ -static const char *loname; -static FILE *lout; - -/* output buffer data */ -ob_t ob; - -static void outxbuf(void); - - -/* - * initialize output - */ -void -outopen(name) - const char *name; -{ - loname = name; - - /* Ausgabedatei oeffnen */ - if ((lout = fopen(name, "w")) == NULL) - err(1, "cannot open '%s'", name); - - /* Ausgabepuffer anlegen */ - ob.o_len = 1024; - ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len; -} - -/* - * flush output buffer and close file - */ -void -outclose() -{ - outclr(); - if (fclose(lout) == EOF) - err(1, "cannot close '%s'", loname); -} - -/* - * resize output buffer - */ -static void -outxbuf() -{ - ptrdiff_t coffs; - - coffs = ob.o_nxt - ob.o_buf; - ob.o_len *= 2; - ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len; - ob.o_nxt = ob.o_buf + coffs; -} - -/* - * reset output buffer - * if it is not empty, it is flushed - */ -void -outclr() -{ - size_t sz; - - if (ob.o_buf != ob.o_nxt) { - outchar('\n'); - sz = ob.o_nxt - ob.o_buf; - if (sz > ob.o_len) - errx(1, "internal error: outclr() 1"); - if (fwrite(ob.o_buf, sz, 1, lout) != 1) - err(1, "cannot write to %s", loname); - ob.o_nxt = ob.o_buf; - } -} - -/* - * write a character to the output buffer - */ -void -outchar(c) - int c; -{ - if (ob.o_nxt == ob.o_end) - outxbuf(); - *ob.o_nxt++ = (char)c; -} - -/* - * write a character to the output buffer, qouted if necessary - */ -void -outqchar(c) - int c; -{ - if (isprint(c) && c != '\\' && c != '"' && c != '\'') { - outchar(c); - } else { - outchar('\\'); - switch (c) { - case '\\': - outchar('\\'); - break; - case '"': - outchar('"'); - break; - case '\'': - outchar('\''); - break; - case '\b': - outchar('b'); - break; - case '\t': - outchar('t'); - break; - case '\n': - outchar('n'); - break; - case '\f': - outchar('f'); - break; - case '\r': - outchar('r'); - break; -#ifdef __STDC__ - case '\v': -#else - case '\013': -#endif - outchar('v'); - break; -#ifdef __STDC__ - case '\a': -#else - case '\007': -#endif - outchar('a'); - break; - default: - outchar((((u_int)c >> 6) & 07) + '0'); - outchar((((u_int)c >> 3) & 07) + '0'); - outchar((c & 07) + '0'); - break; - } - } -} - -/* - * write a strint to the output buffer - * the string must not contain any characters which - * should be quoted - */ -void -outstrg(s) - const char *s; -{ - while (*s != '\0') { - if (ob.o_nxt == ob.o_end) - outxbuf(); - *ob.o_nxt++ = *s++; - } -} - -/* - * write an integer value to toe output buffer - */ -void -outint(i) - int i; -{ - if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int)) - outxbuf(); - ob.o_nxt += sprintf(ob.o_nxt, "%d", i); -} - -/* - * write the name of a symbol to the output buffer - * the name is preceded by its length - */ -void -outname(name) - const char *name; -{ - if (name == NULL) - errx(1, "internal error: outname() 1"); - outint((int)strlen(name)); - outstrg(name); -} - -/* - * write the name of the .c source - */ -void -outsrc(name) - const char *name; -{ - outclr(); - outchar('S'); - outstrg(name); -} Index: usr.bin/xlint/lint1/emit1.c =================================================================== --- usr.bin/xlint/lint1/emit1.c +++ /dev/null @@ -1,601 +0,0 @@ -/* $NetBSD: emit1.c,v 1.14 2004/06/20 22:20:16 jmc Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: emit1.c,v 1.14 2004/06/20 22:20:16 jmc Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include - -#include "lint1.h" - -static void outtt(sym_t *, sym_t *); -static void outfstrg(strg_t *); - -/* - * Write type into the output buffer. - * The type is written as a sequence of substrings, each of which describes a - * node of type type_t - * a node is coded as follows: - * char C - * signed char s C - * unsigned char u C - * short S - * unsigned short u S - * int I - * unsigned int u I - * long L - * unsigned long u L - * long long Q - * unsigned long long u Q - * float s D - * double D - * long double l D - * void V - * * P - * [n] A n - * () F - * (void) F 0 - * (n arguments) F n arg1 arg2 ... argn - * (n arguments, ...) F n arg1 arg2 ... argn-1 E - * (a, b, c, ...) f n arg1 arg2 ... - * enum tag e T tag_or_typename - * struct tag s T tag_or_typename - * union tag u T tag_or_typename - * - * tag_or_typename 0 no tag or type name - * 1 n tag Tag - * 2 n typename only type name - * - * spaces are only for better readability - * additionally it is possible to prepend the characters 'c' (for const) - * and 'v' (for volatile) - */ -void -outtype(type_t *tp) -{ - int t, s, na; - sym_t *arg; - tspec_t ts; - - while (tp != NULL) { - if ((ts = tp->t_tspec) == INT && tp->t_isenum) - ts = ENUM; - switch (ts) { - case CHAR: t = 'C'; s = '\0'; break; - case SCHAR: t = 'C'; s = 's'; break; - case UCHAR: t = 'C'; s = 'u'; break; - case SHORT: t = 'S'; s = '\0'; break; - case USHORT: t = 'S'; s = 'u'; break; - case INT: t = 'I'; s = '\0'; break; - case UINT: t = 'I'; s = 'u'; break; - case LONG: t = 'L'; s = '\0'; break; - case ULONG: t = 'L'; s = 'u'; break; - case QUAD: t = 'Q'; s = '\0'; break; - case UQUAD: t = 'Q'; s = 'u'; break; - case FLOAT: t = 'D'; s = 's'; break; - case DOUBLE: t = 'D'; s = '\0'; break; - case LDOUBLE: t = 'D'; s = 'l'; break; - case VOID: t = 'V'; s = '\0'; break; - case PTR: t = 'P'; s = '\0'; break; - case ARRAY: t = 'A'; s = '\0'; break; - case FUNC: t = 'F'; s = '\0'; break; - case ENUM: t = 'T'; s = 'e'; break; - case STRUCT: t = 'T'; s = 's'; break; - case UNION: t = 'T'; s = 'u'; break; - default: - LERROR("outtyp()"); - } - if (tp->t_const) - outchar('c'); - if (tp->t_volatile) - outchar('v'); - if (s != '\0') - outchar(s); - outchar(t); - if (ts == ARRAY) { - outint(tp->t_dim); - } else if (ts == ENUM) { - outtt(tp->t_enum->etag, tp->t_enum->etdef); - } else if (ts == STRUCT || ts == UNION) { - outtt(tp->t_str->stag, tp->t_str->stdef); - } else if (ts == FUNC && tp->t_proto) { - na = 0; - for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) - na++; - if (tp->t_vararg) - na++; - outint(na); - for (arg = tp->t_args; arg != NULL; arg = arg->s_nxt) - outtype(arg->s_type); - if (tp->t_vararg) - outchar('E'); - } - tp = tp->t_subt; - } -} - -/* - * type to string - * used for debugging output - * - * it uses its own output buffer for conversion - */ -const char * -ttos(type_t *tp) -{ - static ob_t tob; - ob_t tmp; - - if (tob.o_buf == NULL) { - tob.o_len = 64; - tob.o_buf = tob.o_nxt = xmalloc(tob.o_len); - tob.o_end = tob.o_buf + tob.o_len; - } - - tmp = ob; - ob = tob; - ob.o_nxt = ob.o_buf; - outtype(tp); - outchar('\0'); - tob = ob; - ob = tmp; - - return (tob.o_buf); -} - -/* - * write the name of a tag or typename - * - * if the tag is named, the name of the - * tag is written, otherwise, if a typename exists which - * refers to this tag, this typename is written - */ -static void -outtt(sym_t *tag, sym_t *tdef) -{ - - /* - * 0 is no longer used. - */ - if (tag->s_name != unnamed) { - outint(1); - outname(tag->s_name); - } else if (tdef != NULL) { - outint(2); - outname(tdef->s_name); - } else { - outint(3); - outint(tag->s_dpos.p_line); - outchar('.'); - outint(getfnid(tag->s_dpos.p_file)); - outchar('.'); - outint(tag->s_dpos.p_uniq); - } -} - -/* - * write information about a global declared/defined symbol - * with storage class extern - * - * informations about function definitions are written in outfdef(), - * not here - */ -void -outsym(sym_t *sym, scl_t sc, def_t def) -{ - - /* - * Static function declarations must also be written to the output - * file. Compatibility of function declarations (for both static - * and extern functions) must be checked in lint2. Lint1 can't do - * this, especially not, if functions are declared at block level - * before their first declaration at level 0. - */ - if (sc != EXTERN && !(sc == STATIC && sym->s_type->t_tspec == FUNC)) - return; - - /* reset buffer */ - outclr(); - - /* - * line number of .c source, 'd' for declaration, Id of current - * source (.c or .h), and line in current source. - */ - outint(csrc_pos.p_line); - outchar('d'); - outint(getfnid(sym->s_dpos.p_file)); - outchar('.'); - outint(sym->s_dpos.p_line); - - /* flags */ - - switch (def) { - case DEF: - /* defined */ - outchar('d'); - break; - case TDEF: - /* tentative defined */ - outchar('t'); - break; - case DECL: - /* declared */ - outchar('e'); - break; - default: - LERROR("outsym()"); - } - if (llibflg && def != DECL) { - /* - * mark it as used so we get no warnings from lint2 about - * unused symbols in libraries. - */ - outchar('u'); - } - - if (sc == STATIC) - outchar('s'); - - /* name of the symbol */ - outname(sym->s_name); - - /* renamed name of symbol, if necessary */ - if (sym->s_rename) { - outchar('r'); - outname(sym->s_rename); - } - - /* type of the symbol */ - outtype(sym->s_type); -} - -/* - * write information about function definition - * - * this is also done for static functions so we are able to check if - * they are called with proper argument types - */ -void -outfdef(sym_t *fsym, pos_t *posp, int rval, int osdef, sym_t *args) -{ - int narg; - sym_t *arg; - - /* reset the buffer */ - outclr(); - - /* - * line number of .c source, 'd' for declaration, Id of current - * source (.c or .h), and line in current source - * - * we are already at the end of the function. If we are in the - * .c source, posp->p_line is correct, otherwise csrc_pos.p_line - * (for functions defined in header files). - */ - if (posp->p_file == csrc_pos.p_file) { - outint(posp->p_line); - } else { - outint(csrc_pos.p_line); - } - outchar('d'); - outint(getfnid(posp->p_file)); - outchar('.'); - outint(posp->p_line); - - /* flags */ - - /* both SCANFLIKE and PRINTFLIKE imply VARARGS */ - if (prflstrg != -1) { - nvararg = prflstrg; - } else if (scflstrg != -1) { - nvararg = scflstrg; - } - - if (nvararg != -1) { - outchar('v'); - outint(nvararg); - } - if (scflstrg != -1) { - outchar('S'); - outint(scflstrg); - } - if (prflstrg != -1) { - outchar('P'); - outint(prflstrg); - } - nvararg = prflstrg = scflstrg = -1; - - outchar('d'); - - if (rval) - /* has return value */ - outchar('r'); - - if (llibflg) - /* - * mark it as used so lint2 does not complain about - * unused symbols in libraries - */ - outchar('u'); - - if (osdef) - /* old style function definition */ - outchar('o'); - - if (fsym->s_scl == STATIC) - outchar('s'); - - /* name of function */ - outname(fsym->s_name); - - /* renamed name of function, if necessary */ - if (fsym->s_rename) { - outchar('r'); - outname(fsym->s_rename); - } - - /* argument types and return value */ - if (osdef) { - narg = 0; - for (arg = args; arg != NULL; arg = arg->s_nxt) - narg++; - outchar('f'); - outint(narg); - for (arg = args; arg != NULL; arg = arg->s_nxt) - outtype(arg->s_type); - outtype(fsym->s_type->t_subt); - } else { - outtype(fsym->s_type); - } -} - -/* - * write out all information necessary for lint2 to check function - * calls - * - * rvused is set if the return value is used (asigned to a variable) - * rvdisc is set if the return value is not used and not ignored - * (casted to void) - */ -void -outcall(tnode_t *tn, int rvused, int rvdisc) -{ - tnode_t *args, *arg; - int narg, n, i; - int64_t q; - tspec_t t; - - /* reset buffer */ - outclr(); - - /* - * line number of .c source, 'c' for function call, Id of current - * source (.c or .h), and line in current source - */ - outint(csrc_pos.p_line); - outchar('c'); - outint(getfnid(curr_pos.p_file)); - outchar('.'); - outint(curr_pos.p_line); - - /* - * flags; 'u' and 'i' must be last to make sure a letter - * is between the numeric argument of a flag and the name of - * the function - */ - narg = 0; - args = tn->tn_right; - for (arg = args; arg != NULL; arg = arg->tn_right) - narg++; - /* informations about arguments */ - for (n = 1; n <= narg; n++) { - /* the last argument is the top one in the tree */ - for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) - continue; - arg = arg->tn_left; - if (arg->tn_op == CON) { - if (isityp(t = arg->tn_type->t_tspec)) { - /* - * XXX it would probably be better to - * explizitly test the sign - */ - if ((q = arg->tn_val->v_quad) == 0) { - /* zero constant */ - outchar('z'); - } else if (msb(q, t, 0) == 0) { - /* positive if casted to signed */ - outchar('p'); - } else { - /* negative if casted to signed */ - outchar('n'); - } - outint(n); - } - } else if (arg->tn_op == AMPER && - arg->tn_left->tn_op == STRING && - arg->tn_left->tn_strg->st_tspec == CHAR) { - /* constant string, write all format specifiers */ - outchar('s'); - outint(n); - outfstrg(arg->tn_left->tn_strg); - } - - } - /* return value discarded/used/ignored */ - outchar(rvdisc ? 'd' : (rvused ? 'u' : 'i')); - - /* name of the called function */ - outname(tn->tn_left->tn_left->tn_sym->s_name); - - /* types of arguments */ - outchar('f'); - outint(narg); - for (n = 1; n <= narg; n++) { - /* the last argument is the top one in the tree */ - for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) - continue; - outtype(arg->tn_left->tn_type); - } - /* expected type of return value */ - outtype(tn->tn_type); -} - -/* - * extracts potential format specifiers for printf() and scanf() and - * writes them, enclosed in "" and qouted if necessary, to the output buffer - */ -static void -outfstrg(strg_t *strg) -{ - int c, oc, first; - u_char *cp; - - if (strg->st_tspec != CHAR) - LERROR("outfstrg()"); - - cp = strg->st_cp; - - outchar('"'); - - c = *cp++; - - while (c != '\0') { - - if (c != '%') { - c = *cp++; - continue; - } - - outqchar('%'); - c = *cp++; - - /* flags for printf and scanf and *-fieldwidth for printf */ - while (c != '\0' && (c == '-' || c == '+' || c == ' ' || - c == '#' || c == '0' || c == '*')) { - outqchar(c); - c = *cp++; - } - - /* numeric field width */ - while (c != '\0' && isdigit(c)) { - outqchar(c); - c = *cp++; - } - - /* precision for printf */ - if (c == '.') { - outqchar(c); - if ((c = *cp++) == '*') { - outqchar(c); - c = *cp++; - } else { - while (c != '\0' && isdigit(c)) { - outqchar(c); - c = *cp++; - } - } - } - - /* h, l, L and q flags fpr printf and scanf */ - if (c == 'h' || c == 'l' || c == 'L' || c == 'q') { - outqchar(c); - c = *cp++; - } - - /* - * The last character. It is always written so we can detect - * invalid format specifiers. - */ - if (c != '\0') { - outqchar(c); - oc = c; - c = *cp++; - /* - * handle [ for scanf. [-] means that a minus sign - * was found at an undefined position. - */ - if (oc == '[') { - if (c == '^') - c = *cp++; - if (c == ']') - c = *cp++; - first = 1; - while (c != '\0' && c != ']') { - if (c == '-') { - if (!first && *cp != ']') - outqchar(c); - } - first = 0; - c = *cp++; - } - if (c == ']') { - outqchar(c); - c = *cp++; - } - } - } - - } - - outchar('"'); -} - -/* - * writes a record if sym was used - */ -void -outusg(sym_t *sym) -{ - /* reset buffer */ - outclr(); - - /* - * line number of .c source, 'u' for used, Id of current - * source (.c or .h), and line in current source - */ - outint(csrc_pos.p_line); - outchar('u'); - outint(getfnid(curr_pos.p_file)); - outchar('.'); - outint(curr_pos.p_line); - - /* necessary to delimit both numbers */ - outchar('x'); - - /* Den Namen des Symbols ausgeben */ - outname(sym->s_name); -} Index: usr.bin/xlint/lint1/err.c =================================================================== --- usr.bin/xlint/lint1/err.c +++ /dev/null @@ -1,552 +0,0 @@ -/* $NetBSD: err.c,v 1.40 2009/04/15 01:20:57 christos Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: err.c,v 1.40 2009/04/15 01:20:57 christos Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include "lint1.h" - -/* number of errors found */ -int nerr; - -/* number of syntax errors */ -int sytxerr; - - -static const char *lbasename(const char *); -static void verror(int, va_list); -static void vwarning(int, va_list); - - -const char *msgs[] = { - "syntax error: empty declaration", /* 0 */ - "old style declaration; add int", /* 1 */ - "empty declaration", /* 2 */ - "%s declared in argument declaration list", /* 3 */ - "illegal type combination", /* 4 */ - "modifying typedef with '%s'; only qualifiers allowed", /* 5 */ - "use 'double' instead of 'long float'", /* 6 */ - "only one storage class allowed", /* 7 */ - "illegal storage class", /* 8 */ - "only register valid as formal parameter storage class", /* 9 */ - "duplicate '%s'", /* 10 */ - "bit-field initializer out of range", /* 11 */ - "compiler takes size of function", /* 12 */ - "incomplete enum type: %s", /* 13 */ - "compiler takes alignment of function", /* 14 */ - "function returns illegal type", /* 15 */ - "array of function is illegal", /* 16 */ - "null dimension", /* 17 */ - "illegal use of 'void'", /* 18 */ - "void type for %s", /* 19 */ - "negative array dimension (%d)", /* 20 */ - "redeclaration of formal parameter %s", /* 21 */ - "incomplete or misplaced function definition", /* 22 */ - "undefined label %s", /* 23 */ - "cannot initialize function: %s", /* 24 */ - "cannot initialize typedef: %s", /* 25 */ - "cannot initialize extern declaration: %s", /* 26 */ - "redeclaration of %s", /* 27 */ - "redefinition of %s", /* 28 */ - "previously declared extern, becomes static: %s", /* 29 */ - "redeclaration of %s; ANSI C requires static", /* 30 */ - "incomplete structure or union %s: %s", /* 31 */ - "argument type defaults to 'int': %s", /* 32 */ - "duplicate member name: %s", /* 33 */ - "nonportable bit-field type", /* 34 */ - "illegal bit-field type", /* 35 */ - "illegal bit-field size", /* 36 */ - "zero size bit-field", /* 37 */ - "function illegal in structure or union", /* 38 */ - "zero sized array in struct is a C99 extension: %s", /* 39 */ - "unknown size: %s", /* 40 */ - "illegal use of bit-field", /* 41 */ - "forward reference to enum type", /* 42 */ - "redefinition hides earlier one: %s", /* 43 */ - "declaration introduces new type in ANSI C: %s %s", /* 44 */ - "base type is really '%s %s'", /* 45 */ - "(%s) tag redeclared", /* 46 */ - "zero sized %s is a C9X feature", /* 47 */ - "overflow in enumeration values: %s", /* 48 */ - "struct or union member must be named", /* 49 */ - "a function is declared as an argument: %s", /* 50 */ - "parameter mismatch: %d declared, %d defined", /* 51 */ - "cannot initialize parameter: %s", /* 52 */ - "declared argument %s is missing", /* 53 */ - "trailing ',' prohibited in enum declaration", /* 54 */ - "integral constant expression expected", /* 55 */ - "integral constant too large", /* 56 */ - "enumeration constant hides parameter: %s", /* 57 */ - "type does not match prototype: %s", /* 58 */ - "formal parameter lacks name: param #%d", /* 59 */ - "void must be sole parameter", /* 60 */ - "void parameter cannot have name: %s", /* 61 */ - "function prototype parameters must have types", /* 62 */ - "prototype does not match old-style definition", /* 63 */ - "()-less function definition", /* 64 */ - "%s has no named members", /* 65 */ - "syntax requires ';' after last struct/union member", /* 66 */ - "cannot return incomplete type", /* 67 */ - "typedef already qualified with '%s'", /* 68 */ - "inappropriate qualifiers with 'void'", /* 69 */ - "%soperand of '%s' is unsigned in ANSI C", /* 70 */ - "too many characters in character constant", /* 71 */ - "typedef declares no type name", /* 72 */ - "empty character constant", /* 73 */ - "no hex digits follow \\x", /* 74 */ - "overflow in hex escape", /* 75 */ - "character escape does not fit in character", /* 76 */ - "bad octal digit %c", /* 77 */ - "nonportable character escape", /* 78 */ - "dubious escape \\%c", /* 79 */ - "dubious escape \\%o", /* 80 */ - "\\a undefined in traditional C", /* 81 */ - "\\x undefined in traditional C", /* 82 */ - "storage class after type is obsolescent", /* 83 */ - "ANSI C requires formal parameter before '...'", /* 84 */ - "dubious tag declaration: %s %s", /* 85 */ - "automatic hides external declaration: %s", /* 86 */ - "static hides external declaration: %s", /* 87 */ - "typedef hides external declaration: %s", /* 88 */ - "typedef redeclared: %s", /* 89 */ - "inconsistent redeclaration of extern: %s", /* 90 */ - "declaration hides parameter: %s", /* 91 */ - "inconsistent redeclaration of static: %s", /* 92 */ - "dubious static function at block level: %s", /* 93 */ - "function has illegal storage class: %s", /* 94 */ - "declaration hides earlier one: %s", /* 95 */ - "cannot dereference non-pointer type", /* 96 */ - "suffix U is illegal in traditional C", /* 97 */ - "suffixes F and L are illegal in traditional C", /* 98 */ - "%s undefined", /* 99 */ - "unary + is illegal in traditional C", /* 100 */ - "undefined struct/union member: %s", /* 101 */ - "illegal member use: %s", /* 102 */ - "left operand of '.' must be struct/union object", /* 103 */ - "left operand of '->' must be pointer to struct/union", /* 104 */ - "non-unique member requires struct/union %s", /* 105 */ - "left operand of '->' must be pointer", /* 106 */ - "operands of '%s' have incompatible types", /* 107 */ - "operand of '%s' has incompatible type", /* 108 */ - "void type illegal in expression", /* 109 */ - "pointer to function is not allowed here", /* 110 */ - "unacceptable operand of '%s'", /* 111 */ - "cannot take address of bit-field", /* 112 */ - "cannot take address of register %s", /* 113 */ - "%soperand of '%s' must be lvalue", /* 114 */ - "%soperand of '%s' must be modifiable lvalue", /* 115 */ - "illegal pointer subtraction", /* 116 */ - "bitwise operation on signed value possibly nonportable", /* 117 */ - "semantics of '%s' change in ANSI C; use explicit cast", /* 118 */ - "conversion of '%s' to '%s' is out of range", /* 119 */ - "bitwise operation on signed value nonportable", /* 120 */ - "negative shift", /* 121 */ - "shift greater than size of object", /* 122 */ - "illegal combination of pointer and integer, op %s", /* 123 */ - "illegal pointer combination, op %s", /* 124 */ - "ANSI C forbids ordered comparisons of pointers to functions",/* 125 */ - "incompatible types in conditional", /* 126 */ - "'&' before array or function: ignored", /* 127 */ - "operands have incompatible pointer types, op %s", /* 128 */ - "expression has null effect", /* 129 */ - "enum type mismatch, op %s", /* 130 */ - "conversion to '%s' may sign-extend incorrectly", /* 131 */ - "conversion from '%s' to '%s' may lose accuracy", /* 132 */ - "conversion of pointer to '%s' loses bits", /* 133 */ - "conversion of pointer to '%s' may lose bits", /* 134 */ - "possible pointer alignment problem", /* 135 */ - "cannot do pointer arithmetic on operand of unknown size", /* 136 */ - "use of incomplete enum type, op %s", /* 137 */ - "unknown operand size, op %s", /* 138 */ - "division by 0", /* 139 */ - "modulus by 0", /* 140 */ - "integer overflow detected, op %s", /* 141 */ - "floating point overflow detected, op %s", /* 142 */ - "cannot take size of incomplete type", /* 143 */ - "cannot take size of function", /* 144 */ - "cannot take size of bit-field", /* 145 */ - "cannot take size of void", /* 146 */ - "invalid cast expression", /* 147 */ - "improper cast of void expression", /* 148 */ - "illegal function", /* 149 */ - "argument mismatch: %d arg%s passed, %d expected", /* 150 */ - "void expressions may not be arguments, arg #%d", /* 151 */ - "argument cannot have unknown size, arg #%d", /* 152 */ - "argument has incompatible pointer type, arg #%d", /* 153 */ - "illegal combination of pointer and integer, arg #%d", /* 154 */ - "argument is incompatible with prototype, arg #%d", /* 155 */ - "enum type mismatch, arg #%d", /* 156 */ - "ANSI C treats constant as unsigned", /* 157 */ - "%s may be used before set", /* 158 */ - "assignment in conditional context", /* 159 */ - "operator '==' found where '=' was expected", /* 160 */ - "constant in conditional context", /* 161 */ - "comparison of %s with %s, op %s", /* 162 */ - "a cast does not yield an lvalue", /* 163 */ - "assignment of negative constant to unsigned type", /* 164 */ - "constant truncated by assignment", /* 165 */ - "precision lost in bit-field assignment", /* 166 */ - "array subscript cannot be negative: %ld", /* 167 */ - "array subscript cannot be > %d: %ld", /* 168 */ - "precedence confusion possible: parenthesize!", /* 169 */ - "first operand must have scalar type, op ? :", /* 170 */ - "assignment type mismatch", /* 171 */ - "too many struct/union initializers", /* 172 */ - "too many array initializers", /* 173 */ - "too many initializers", /* 174 */ - "initialisation of an incomplete type", /* 175 */ - "invalid initializer type %s", /* 176 */ - "non-constant initializer", /* 177 */ - "initializer does not fit", /* 178 */ - "cannot initialize struct/union with no named member", /* 179 */ - "bit-field initializer does not fit", /* 180 */ - "{}-enclosed initializer required", /* 181 */ - "incompatible pointer types", /* 182 */ - "illegal combination of pointer and integer", /* 183 */ - "illegal pointer combination", /* 184 */ - "initialisation type mismatch", /* 185 */ - "bit-field initialisation is illegal in traditional C", /* 186 */ - "non-null byte ignored in string initializer", /* 187 */ - "no automatic aggregate initialization in traditional C", /* 188 */ - "assignment of struct/union illegal in traditional C", /* 189 */ - "empty array declaration: %s", /* 190 */ - "%s set but not used in function %s", /* 191 */ - "%s unused in function %s", /* 192 */ - "statement not reached", /* 193 */ - "label %s redefined", /* 194 */ - "case not in switch", /* 195 */ - "case label affected by conversion", /* 196 */ - "non-constant case expression", /* 197 */ - "non-integral case expression", /* 198 */ - "duplicate case in switch: %ld", /* 199 */ - "duplicate case in switch: %lu", /* 200 */ - "default outside switch", /* 201 */ - "duplicate default in switch", /* 202 */ - "case label must be of type `int' in traditional C", /* 203 */ - "controlling expressions must have scalar type", /* 204 */ - "switch expression must have integral type", /* 205 */ - "enumeration value(s) not handled in switch", /* 206 */ - "loop not entered at top", /* 207 */ - "break outside loop or switch", /* 208 */ - "continue outside loop", /* 209 */ - "enum type mismatch in initialisation", /* 210 */ - "return value type mismatch", /* 211 */ - "cannot return incomplete type", /* 212 */ - "void function %s cannot return value", /* 213 */ - "function %s expects to return value", /* 214 */ - "function implicitly declared to return int", /* 215 */ - "function %s has return (e); and return;", /* 216 */ - "function %s falls off bottom without returning value", /* 217 */ - "ANSI C treats constant as unsigned, op %s", /* 218 */ - "concatenated strings are illegal in traditional C", /* 219 */ - "fallthrough on case statement", /* 220 */ - "initialisation of unsigned with negative constant", /* 221 */ - "conversion of negative constant to unsigned type", /* 222 */ - "end-of-loop code not reached", /* 223 */ - "cannot recover from previous errors", /* 224 */ - "static function called but not defined: %s()", /* 225 */ - "static variable %s unused", /* 226 */ - "const object %s should have initializer", /* 227 */ - "function cannot return const or volatile object", /* 228 */ - "questionable conversion of function pointer", /* 229 */ - "nonportable character comparison, op %s", /* 230 */ - "argument %s unused in function %s", /* 231 */ - "label %s unused in function %s", /* 232 */ - "struct %s never defined", /* 233 */ - "union %s never defined", /* 234 */ - "enum %s never defined", /* 235 */ - "static function %s unused", /* 236 */ - "redeclaration of formal parameter %s", /* 237 */ - "initialisation of union is illegal in traditional C", /* 238 */ - "constant argument to NOT", /* 239 */ - "assignment of different structures", /* 240 */ - "dubious operation on enum, op %s", /* 241 */ - "combination of '%s' and '%s', op %s", /* 242 */ - "dubious comparison of enums, op %s", /* 243 */ - "illegal structure pointer combination", /* 244 */ - "illegal structure pointer combination, op %s", /* 245 */ - "dubious conversion of enum to '%s'", /* 246 */ - "pointer casts may be troublesome", /* 247 */ - "floating-point constant out of range", /* 248 */ - "syntax error", /* 249 */ - "unknown character \\%o", /* 250 */ - "malformed integer constant", /* 251 */ - "integer constant out of range", /* 252 */ - "unterminated character constant", /* 253 */ - "newline in string or char constant", /* 254 */ - "undefined or invalid # directive", /* 255 */ - "unterminated comment", /* 256 */ - "extra characters in lint comment", /* 257 */ - "unterminated string constant", /* 258 */ - "conversion to '%s' due to prototype, arg #%d", /* 259 */ - "previous declaration of %s", /* 260 */ - "previous definition of %s", /* 261 */ - "\\\" inside character constants undefined in traditional C", /* 262 */ - "\\? undefined in traditional C", /* 263 */ - "\\v undefined in traditional C", /* 264 */ - "%s C does not support 'long long'", /* 265 */ - "'long double' is illegal in traditional C", /* 266 */ - "shift equal to size of object", /* 267 */ - "variable declared inline: %s", /* 268 */ - "argument declared inline: %s", /* 269 */ - "function prototypes are illegal in traditional C", /* 270 */ - "switch expression must be of type `int' in traditional C", /* 271 */ - "empty translation unit", /* 272 */ - "bit-field type '%s' invalid in ANSI C", /* 273 */ - "ANSI C forbids comparison of %s with %s", /* 274 */ - "cast discards 'const' from pointer target type", /* 275 */ - "", /* 276 */ - "initialisation of '%s' with '%s'", /* 277 */ - "combination of '%s' and '%s', arg #%d", /* 278 */ - "combination of '%s' and '%s' in return", /* 279 */ - "must be outside function: /* %s */", /* 280 */ - "duplicate use of /* %s */", /* 281 */ - "must precede function definition: /* %s */", /* 282 */ - "argument number mismatch with directive: /* %s */", /* 283 */ - "fallthrough on default statement", /* 284 */ - "prototype declaration", /* 285 */ - "function definition is not a prototype", /* 286 */ - "function declaration is not a prototype", /* 287 */ - "dubious use of /* VARARGS */ with /* %s */", /* 288 */ - "can't be used together: /* PRINTFLIKE */ /* SCANFLIKE */", /* 289 */ - "static function %s declared but not defined", /* 290 */ - "invalid multibyte character", /* 291 */ - "cannot concatenate wide and regular string literals", /* 292 */ - "argument %d must be 'char *' for PRINTFLIKE/SCANFLIKE", /* 293 */ - "multi-character character constant", /* 294 */ - "conversion of '%s' to '%s' is out of range, arg #%d", /* 295 */ - "conversion of negative constant to unsigned type, arg #%d", /* 296 */ - "conversion to '%s' may sign-extend incorrectly, arg #%d", /* 297 */ - "conversion from '%s' to '%s' may lose accuracy, arg #%d", /* 298 */ - "prototype does not match old style definition, arg #%d", /* 299 */ - "old style definition", /* 300 */ - "array of incomplete type", /* 301 */ - "%s returns pointer to automatic object", /* 302 */ - "ANSI C forbids conversion of %s to %s", /* 303 */ - "ANSI C forbids conversion of %s to %s, arg #%d", /* 304 */ - "ANSI C forbids conversion of %s to %s, op %s", /* 305 */ - "constant truncated by conversion, op %s", /* 306 */ - "static variable %s set but not used", /* 307 */ - "", /* 308 */ - "extra bits set to 0 in conversion of '%s' to '%s', op %s", /* 309 */ - "symbol renaming can't be used on function arguments", /* 310 */ - "symbol renaming can't be used on automatic variables", /* 311 */ - "%s C does not support // comments", /* 312 */ - "struct or union member name in initializer is a C9X feature",/* 313 */ - "%s is not a structure or a union", /* 314 */ - "GCC style struct or union member name in initializer", /* 315 */ - "__FUNCTION__ is a GCC extension", /* 316 */ - "__func__ is a C9X feature", /* 317 */ - "variable array dimension is a C99/GCC extension", /* 318 */ - "compound literals are a C9X/GCC extension", /* 319 */ - "({ }) is a GCC extension", /* 320 */ - "array initializer with designators is a C9X feature", /* 321 */ - "zero sized array is a C99 extension", /* 322 */ -}; - -/* - * print a list of the messages with their ids - */ -void -msglist(void) -{ - size_t i; - - for (i = 0; i < sizeof(msgs) / sizeof(msgs[0]); i++) - printf("%zu\t%s\n", i, msgs[i]); -} - -/* - * If Fflag is not set lbasename() returns a pointer to the last - * component of the path, otherwise it returns the argument. - */ -static const char * -lbasename(const char *path) -{ - const char *cp, *cp1, *cp2; - - if (Fflag) - return (path); - - cp = cp1 = cp2 = path; - while (*cp != '\0') { - if (*cp++ == '/') { - cp2 = cp1; - cp1 = cp; - } - } - return (*cp1 == '\0' ? cp2 : cp1); -} - -static void -verror( int n, va_list ap) -{ - const char *fn; - - if (ERR_ISSET(n, &msgset)) - return; - - fn = lbasename(curr_pos.p_file); - (void)printf("%s(%d): ", fn, curr_pos.p_line); - (void)vprintf(msgs[n], ap); - (void)printf(" [%d]\n", n); - nerr++; -} - -static void -vwarning( int n, va_list ap) -{ - const char *fn; - - if (ERR_ISSET(n, &msgset)) - return; - - if (nowarn) - /* this warning is suppressed by a LINTED comment */ - return; - - fn = lbasename(curr_pos.p_file); - (void)printf("%s(%d): warning: ", fn, curr_pos.p_line); - (void)vprintf(msgs[n], ap); - (void)printf(" [%d]\n", n); - if (wflag) - nerr++; -} - -void -error(int n, ...) -{ - va_list ap; - - va_start(ap, n); - verror(n, ap); - va_end(ap); -} - -void -lerror(const char *file, int line, const char *msg, ...) -{ - va_list ap; - const char *fn; - - va_start(ap, msg); - fn = lbasename(curr_pos.p_file); - (void)fprintf(stderr, "%s(%d): lint error: %s, %d", fn, curr_pos.p_line, - file, line); - (void)vfprintf(stderr, msg, ap); - (void)fprintf(stderr, "\n"); - va_end(ap); - exit(1); -} - -void -warning(int n, ...) -{ - va_list ap; - - va_start(ap, n); - vwarning(n, ap); - va_end(ap); -} - -void -message(int n, ...) -{ - va_list ap; - const char *fn; - - if (ERR_ISSET(n, &msgset)) - return; - - va_start(ap, n); - fn = lbasename(curr_pos.p_file); - (void)printf("%s(%d): ", fn, curr_pos.p_line); - (void)vprintf(msgs[n], ap); - (void)printf(" [%d]\n", n); - va_end(ap); -} - -/* - * XXX I think the logic is possibly somewhat screwed up here. The - * question is, how do we want to interpret the -s and -S flags going - * forward? We need to answer that and then we can fix this to be - * "right"... [perry, 2 Nov 2002] -*/ -int -c99ism(int n, ...) -{ - va_list ap; - int msg; - - va_start(ap, n); - if (sflag && !(Sflag || gflag)) { - verror(n, ap); - msg = 1; - } else if (!sflag && (Sflag || gflag)) { - msg = 0; - } else { - vwarning(n, ap); - msg = 1; - } - va_end(ap); - - return (msg); -} - -int -gnuism(int n, ...) -{ - va_list ap; - int msg; - - va_start(ap, n); - if (sflag && !gflag) { - verror(n, ap); - msg = 1; - } else if (!sflag && gflag) { - msg = 0; - } else { - vwarning(n, ap); - msg = 1; - } - va_end(ap); - - return (msg); -} Index: usr.bin/xlint/lint1/externs1.h =================================================================== --- usr.bin/xlint/lint1/externs1.h +++ /dev/null @@ -1,292 +0,0 @@ -/* $NetBSD: externs1.h,v 1.20 2002/11/02 20:09:27 perry Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * main.c - */ -extern int aflag; -extern int bflag; -extern int cflag; -extern int dflag; -extern int eflag; -extern int Fflag; -extern int gflag; -extern int hflag; -extern int rflag; -extern int sflag; -extern int tflag; -extern int uflag; -extern int vflag; -extern int yflag; -extern int wflag; -extern int zflag; -extern int Sflag; - -extern void norecover(void); - -/* - * cgram.y - */ -extern int blklev; -extern int mblklev; -extern int yydebug; - -extern int yyerror(char *); -extern int yyparse(void); - -/* - * scan.l - */ -extern pos_t curr_pos; -extern pos_t csrc_pos; -extern symt_t symtyp; -extern FILE *yyin; -extern uint64_t qbmasks[], qlmasks[], qumasks[]; - -extern void initscan(void); -extern int sign(int64_t, tspec_t, int); -extern int msb(int64_t, tspec_t, int); -extern int64_t xsign(int64_t, tspec_t, int); -extern void clrwflgs(void); -extern sym_t *getsym(sbuf_t *); -extern void cleanup(void); -extern sym_t *pushdown(sym_t *); -extern sym_t *mktempsym(type_t *); -extern void rmsym(sym_t *); -extern void rmsyms(sym_t *); -extern void inssym(int, sym_t *); -extern void freeyyv(void *, int); -extern int yylex(void); - -/* - * mem1.c - */ -extern const char *fnalloc(const char *); -extern const char *fnnalloc(const char *, size_t); -extern int getfnid(const char *); - -extern void initmem(void); - -extern void *getblk(size_t); -extern void *getlblk(int, size_t); -extern void freeblk(void); -extern void freelblk(int); - -extern void *tgetblk(size_t); -extern tnode_t *getnode(void); -extern void tfreeblk(void); -extern struct mbl *tsave(void); -extern void trestor(struct mbl *); - -/* - * err.c - */ -extern int nerr; -extern int sytxerr; -extern const char *msgs[]; - -extern void msglist(void); -extern void error(int, ...); -extern void warning(int, ...); -extern void message(int, ...); -extern int gnuism(int, ...); -extern int c99ism(int, ...); -extern void lerror(const char *, int, const char *, ...) - __attribute__((__noreturn__,__format__(__printf__, 3, 4))); - -/* - * decl.c - */ -extern dinfo_t *dcs; -extern const char *unnamed; -extern int enumval; - -extern void initdecl(void); -extern type_t *gettyp(tspec_t); -extern type_t *duptyp(const type_t *); -extern type_t *tduptyp(const type_t *); -extern int incompl(type_t *); -extern void setcompl(type_t *, int); -extern void addscl(scl_t); -extern void addtype(type_t *); -extern void addqual(tqual_t); -extern void pushdecl(scl_t); -extern void popdecl(void); -extern void setasm(void); -extern void clrtyp(void); -extern void deftyp(void); -extern int length(type_t *, const char *); -extern int getbound(type_t *); -extern sym_t *lnklst(sym_t *, sym_t *); -extern void chktyp(sym_t *); -extern sym_t *decl1str(sym_t *); -extern sym_t *bitfield(sym_t *, int); -extern pqinf_t *mergepq(pqinf_t *, pqinf_t *); -extern sym_t *addptr(sym_t *, pqinf_t *); -extern sym_t *addarray(sym_t *, int, int); -extern sym_t *addfunc(sym_t *, sym_t *); -extern void chkfdef(sym_t *, int); -extern sym_t *dname(sym_t *); -extern sym_t *iname(sym_t *); -extern type_t *mktag(sym_t *, tspec_t, int, int); -extern const char *scltoa(scl_t); -extern type_t *compltag(type_t *, sym_t *); -extern sym_t *ename(sym_t *, int, int); -extern void decl1ext(sym_t *, int); -extern void cpuinfo(sym_t *, sym_t *); -extern int isredec(sym_t *, int *); -extern int eqtype(type_t *, type_t *, int, int, int *); -extern void compltyp(sym_t *, sym_t *); -extern sym_t *decl1arg(sym_t *, int); -extern void cluparg(void); -extern void decl1loc(sym_t *, int); -extern sym_t *aname(void); -extern void globclup(void); -extern sym_t *decl1abs(sym_t *); -extern void chksz(sym_t *); -extern void setsflg(sym_t *); -extern void setuflg(sym_t *, int, int); -extern void chkusage(dinfo_t *); -extern void chkusg1(int, sym_t *); -extern void chkglsyms(void); -extern void prevdecl(int, sym_t *); - -/* - * tree.c - */ -extern void initmtab(void); -extern type_t *incref(type_t *, tspec_t); -extern type_t *tincref(type_t *, tspec_t); -extern tnode_t *getcnode(type_t *, val_t *); -extern tnode_t *getnnode(sym_t *, int); -extern tnode_t *getsnode(strg_t *); -extern sym_t *strmemb(tnode_t *, op_t, sym_t *); -extern tnode_t *build(op_t, tnode_t *, tnode_t *); -extern tnode_t *cconv(tnode_t *); -extern int typeok(op_t, int, tnode_t *, tnode_t *); -extern tnode_t *promote(op_t, int, tnode_t *); -extern tnode_t *convert(op_t, int, type_t *, tnode_t *); -extern void cvtcon(op_t, int, type_t *, val_t *, val_t *); -extern const char *tyname(char *, size_t, type_t *); -extern const char *basictyname(tspec_t); -extern tnode_t *bldszof(type_t *); -extern tnode_t *cast(tnode_t *, type_t *); -extern tnode_t *funcarg(tnode_t *, tnode_t *); -extern tnode_t *funccall(tnode_t *, tnode_t *); -extern val_t *constant(tnode_t *, int); -extern void expr(tnode_t *, int, int, int); -extern void chkmisc(tnode_t *, int, int, int, int, int, int); -extern int conaddr(tnode_t *, sym_t **, ptrdiff_t *); -extern strg_t *catstrg(strg_t *, strg_t *); - -/* - * func.c - */ -extern sym_t *funcsym; -extern int reached; -extern int rchflg; -extern int ftflg; -extern int nargusg; -extern pos_t aupos; -extern int nvararg; -extern pos_t vapos; -extern int prflstrg; -extern pos_t prflpos; -extern int scflstrg; -extern pos_t scflpos; -extern int ccflg; -extern int llibflg; -extern int nowarn; -extern int bitfieldtype_ok; -extern int plibflg; -extern int quadflg; - -extern void pushctrl(int); -extern void popctrl(int); -extern void chkreach(void); -extern void funcdef(sym_t *); -extern void funcend(void); -extern void label(int, sym_t *, tnode_t *); -extern void if1(tnode_t *); -extern void if2(void); -extern void if3(int); -extern void switch1(tnode_t *); -extern void switch2(void); -extern void while1(tnode_t *); -extern void while2(void); -extern void do1(void); -extern void do2(tnode_t *); -extern void for1(tnode_t *, tnode_t *, tnode_t *); -extern void for2(void); -extern void dogoto(sym_t *); -extern void docont(void); -extern void dobreak(void); -extern void doreturn(tnode_t *); -extern void glclup(int); -extern void argsused(int); -extern void constcond(int); -extern void fallthru(int); -extern void notreach(int); -extern void lintlib(int); -extern void linted(int); -extern void varargs(int); -extern void printflike(int); -extern void scanflike(int); -extern void protolib(int); -extern void longlong(int); -extern void bitfieldtype(int); - -/* - * init.c - */ -extern int initerr; -extern sym_t *initsym; -extern int startinit; - -extern void prepinit(void); -extern void initrbr(void); -extern void initlbr(void); -extern void mkinit(tnode_t *); -extern void memberpush(sbuf_t *); - -/* - * emit.c - */ -extern void outtype(type_t *); -extern const char *ttos(type_t *); -extern void outsym(sym_t *, scl_t, def_t); -extern void outfdef(sym_t *, pos_t *, int, int, sym_t *); -extern void outcall(tnode_t *, int, int); -extern void outusg(sym_t *); Index: usr.bin/xlint/lint1/func.c =================================================================== --- usr.bin/xlint/lint1/func.c +++ /dev/null @@ -1,1288 +0,0 @@ -/* $NetBSD: func.c,v 1.22 2005/09/24 15:30:35 perry Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: func.c,v 1.16 2002/01/03 04:25:15 thorpej Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include - -#include "lint1.h" -#include "cgram.h" - -/* - * Contains a pointer to the symbol table entry of the current function - * definition. - */ -sym_t *funcsym; - -/* Is set as long as a statement can be reached. Must be set at level 0. */ -int reached = 1; - -/* - * Is set as long as NOTREACHED is in effect. - * Is reset everywhere where reached can become 0. - */ -int rchflg; - -/* - * In conjunction with reached controls printing of "fallthrough on ..." - * warnings. - * Reset by each statement and set by FALLTHROUGH, switch (switch1()) - * and case (label()). - * - * Control statements if, for, while and switch do not reset ftflg because - * this must be done by the controlled statement. At least for if this is - * important because ** FALLTHROUGH ** after "if (expr) stmnt" is evaluated - * before the following token, which causes reduction of above, is read. - * This means that ** FALLTHROUGH ** after "if ..." would always be ignored. - */ -int ftflg; - -/* Top element of stack for control statements */ -cstk_t *cstk; - -/* - * Number of arguments which will be checked for usage in following - * function definition. -1 stands for all arguments. - * - * The position of the last ARGSUSED comment is stored in aupos. - */ -int nargusg = -1; -pos_t aupos; - -/* - * Number of arguments of the following function definition whose types - * shall be checked by lint2. -1 stands for all arguments. - * - * The position of the last VARARGS comment is stored in vapos. - */ -int nvararg = -1; -pos_t vapos; - -/* - * Both prflstr and scflstrg contain the number of the argument which - * shall be used to check the types of remaining arguments (for PRINTFLIKE - * and SCANFLIKE). - * - * prflpos and scflpos are the positions of the last PRINTFLIKE or - * SCANFLIKE comment. - */ -int prflstrg = -1; -int scflstrg = -1; -pos_t prflpos; -pos_t scflpos; - -/* - * Are both plibflg and llibflg set, prototypes are written as function - * definitions to the output file. - */ -int plibflg; - -/* - * Nonzero means that no warnings about constants in conditional - * context are printed. - */ -int ccflg; - -/* - * llibflg is set if a lint library shall be created. The effect of - * llibflg is that all defined symbols are treated as used. - * (The LINTLIBRARY comment also resets vflag.) - */ -int llibflg; - -/* - * Nonzero if warnings are suppressed by a LINTED directive - */ -int nowarn; - -/* - * Nonzero if bitfield type errors are suppressed by a BITFIELDTYPE - * directive. - */ -int bitfieldtype_ok; - -/* - * Nonzero if complaints about use of "long long" are suppressed in - * the next statement or declaration. - */ -int quadflg; - -/* - * Puts a new element at the top of the stack used for control statements. - */ -void -pushctrl(int env) -{ - cstk_t *ci; - - if ((ci = calloc(1, sizeof (cstk_t))) == NULL) - nomem(); - ci->c_env = env; - ci->c_nxt = cstk; - cstk = ci; -} - -/* - * Removes the top element of the stack used for control statements. - */ -void -popctrl(int env) -{ - cstk_t *ci; - clst_t *cl; - - if (cstk == NULL || cstk->c_env != env) - LERROR("popctrl()"); - - cstk = (ci = cstk)->c_nxt; - - while ((cl = ci->c_clst) != NULL) { - ci->c_clst = cl->cl_nxt; - free(cl); - } - - if (ci->c_swtype != NULL) - free(ci->c_swtype); - - free(ci); -} - -/* - * Prints a warning if a statement cannot be reached. - */ -void -chkreach(void) -{ - if (!reached && !rchflg) { - /* statement not reached */ - warning(193); - reached = 1; - } -} - -/* - * Called after a function declaration which introduces a function definition - * and before an (optional) old style argument declaration list. - * - * Puts all symbols declared in the Prototype or in an old style argument - * list back to the symbol table. - * - * Does the usual checking of storage class, type (return value), - * redeclaration etc.. - */ -void -funcdef(sym_t *fsym) -{ - int n, warn; - sym_t *arg, *sym, *rdsym; - - funcsym = fsym; - - /* - * Put all symbols declared in the argument list back to the - * symbol table. - */ - for (sym = dcs->d_fpsyms; sym != NULL; sym = sym->s_dlnxt) { - if (sym->s_blklev != -1) { - if (sym->s_blklev != 1) - LERROR("funcdef()"); - inssym(1, sym); - } - } - - /* - * In osfunc() we did not know whether it is an old style function - * definition or only an old style declaration, if there are no - * arguments inside the argument list ("f()"). - */ - if (!fsym->s_type->t_proto && fsym->s_args == NULL) - fsym->s_osdef = 1; - - chktyp(fsym); - - /* - * chktyp() checks for almost all possible errors, but not for - * incomplete return values (these are allowed in declarations) - */ - if (fsym->s_type->t_subt->t_tspec != VOID && - incompl(fsym->s_type->t_subt)) { - /* cannot return incomplete type */ - error(67); - } - - fsym->s_def = DEF; - - if (fsym->s_scl == TYPEDEF) { - fsym->s_scl = EXTERN; - /* illegal storage class */ - error(8); - } - - if (dcs->d_inline) - fsym->s_inline = 1; - - /* - * Arguments in new style function declarations need a name. - * (void is already removed from the list of arguments) - */ - n = 1; - for (arg = fsym->s_type->t_args; arg != NULL; arg = arg->s_nxt) { - if (arg->s_scl == ABSTRACT) { - if (arg->s_name != unnamed) - LERROR("funcdef()"); - /* formal parameter lacks name: param #%d */ - error(59, n); - } else { - if (arg->s_name == unnamed) - LERROR("funcdef()"); - } - n++; - } - - /* - * We must also remember the position. s_dpos is overwritten - * if this is an old style definition and we had already a - * prototype. - */ - STRUCT_ASSIGN(dcs->d_fdpos, fsym->s_dpos); - - if ((rdsym = dcs->d_rdcsym) != NULL) { - - if (!isredec(fsym, (warn = 0, &warn))) { - - /* - * Print nothing if the newly defined function - * is defined in old style. A better warning will - * be printed in cluparg(). - */ - if (warn && !fsym->s_osdef) { - /* redeclaration of %s */ - (*(sflag ? error : warning))(27, fsym->s_name); - prevdecl(-1, rdsym); - } - - /* copy usage information */ - cpuinfo(fsym, rdsym); - - /* - * If the old symbol was a prototype and the new - * one is none, overtake the position of the - * declaration of the prototype. - */ - if (fsym->s_osdef && rdsym->s_type->t_proto) - STRUCT_ASSIGN(fsym->s_dpos, rdsym->s_dpos); - - /* complete the type */ - compltyp(fsym, rdsym); - - /* once a function is inline it remains inline */ - if (rdsym->s_inline) - fsym->s_inline = 1; - - } - - /* remove the old symbol from the symbol table */ - rmsym(rdsym); - - } - - if (fsym->s_osdef && !fsym->s_type->t_proto) { - if (sflag && hflag && strcmp(fsym->s_name, "main") != 0) - /* function definition is not a prototype */ - warning(286); - } - - if (dcs->d_notyp) - /* return value is implicitly declared to be int */ - fsym->s_rimpl = 1; - - reached = 1; -} - -/* - * Called at the end of a function definition. - */ -void -funcend(void) -{ - sym_t *arg; - int n; - - if (reached) { - cstk->c_noretval = 1; - if (funcsym->s_type->t_subt->t_tspec != VOID && - !funcsym->s_rimpl) { - /* func. %s falls off bottom without returning value */ - warning(217, funcsym->s_name); - } - } - - /* - * This warning is printed only if the return value was implicitly - * declared to be int. Otherwise the wrong return statement - * has already printed a warning. - */ - if (cstk->c_noretval && cstk->c_retval && funcsym->s_rimpl) - /* function %s has return (e); and return; */ - warning(216, funcsym->s_name); - - /* Print warnings for unused arguments */ - arg = dcs->d_fargs; - n = 0; - while (arg != NULL && (nargusg == -1 || n < nargusg)) { - chkusg1(dcs->d_asm, arg); - arg = arg->s_nxt; - n++; - } - nargusg = -1; - - /* - * write the information about the function definition to the - * output file - * inline functions explicitly declared extern are written as - * declarations only. - */ - if (dcs->d_scl == EXTERN && funcsym->s_inline) { - outsym(funcsym, funcsym->s_scl, DECL); - } else { - outfdef(funcsym, &dcs->d_fdpos, cstk->c_retval, - funcsym->s_osdef, dcs->d_fargs); - } - - /* - * remove all symbols declared during argument declaration from - * the symbol table - */ - if (dcs->d_nxt != NULL || dcs->d_ctx != EXTERN) - LERROR("funcend()"); - rmsyms(dcs->d_fpsyms); - - /* must be set on level 0 */ - reached = 1; -} - -/* - * Process a label. - * - * typ type of the label (T_NAME, T_DEFAULT or T_CASE). - * sym symbol table entry of label if typ == T_NAME - * tn expression if typ == T_CASE - */ -void -label(int typ, sym_t *sym, tnode_t *tn) -{ - cstk_t *ci; - clst_t *cl; - val_t *v; - val_t nv; - tspec_t t; - - switch (typ) { - - case T_NAME: - if (sym->s_set) { - /* label %s redefined */ - error(194, sym->s_name); - } else { - setsflg(sym); - } - break; - - case T_CASE: - - /* find the stack entry for the innermost switch statement */ - for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) - continue; - - if (ci == NULL) { - /* case not in switch */ - error(195); - tn = NULL; - } else if (tn != NULL && tn->tn_op != CON) { - /* non-constant case expression */ - error(197); - tn = NULL; - } else if (tn != NULL && !isityp(tn->tn_type->t_tspec)) { - /* non-integral case expression */ - error(198); - tn = NULL; - } - - if (tn != NULL) { - - if (ci->c_swtype == NULL) - LERROR("label()"); - - if (reached && !ftflg) { - if (hflag) - /* fallthrough on case statement */ - warning(220); - } - - t = tn->tn_type->t_tspec; - if (t == LONG || t == ULONG || - t == QUAD || t == UQUAD) { - if (tflag) - /* case label must be of type ... */ - warning(203); - } - - /* - * get the value of the expression and convert it - * to the type of the switch expression - */ - v = constant(tn, 1); - (void) memset(&nv, 0, sizeof nv); - cvtcon(CASE, 0, ci->c_swtype, &nv, v); - free(v); - - /* look if we had this value already */ - for (cl = ci->c_clst; cl != NULL; cl = cl->cl_nxt) { - if (cl->cl_val.v_quad == nv.v_quad) - break; - } - if (cl != NULL && isutyp(nv.v_tspec)) { - /* duplicate case in switch, %lu */ - error(200, (u_long)nv.v_quad); - } else if (cl != NULL) { - /* duplicate case in switch, %ld */ - error(199, (long)nv.v_quad); - } else { - /* - * append the value to the list of - * case values - */ - cl = xcalloc(1, sizeof (clst_t)); - STRUCT_ASSIGN(cl->cl_val, nv); - cl->cl_nxt = ci->c_clst; - ci->c_clst = cl; - } - } - tfreeblk(); - break; - - case T_DEFAULT: - - /* find the stack entry for the innermost switch statement */ - for (ci = cstk; ci != NULL && !ci->c_switch; ci = ci->c_nxt) - continue; - - if (ci == NULL) { - /* default outside switch */ - error(201); - } else if (ci->c_default) { - /* duplicate default in switch */ - error(202); - } else { - if (reached && !ftflg) { - if (hflag) - /* fallthrough on default statement */ - warning(284); - } - ci->c_default = 1; - } - break; - } - reached = 1; -} - -/* - * T_IF T_LPARN expr T_RPARN - */ -void -if1(tnode_t *tn) -{ - - if (tn != NULL) - tn = cconv(tn); - if (tn != NULL) - tn = promote(NOOP, 0, tn); - expr(tn, 0, 1, 1); - pushctrl(T_IF); -} - -/* - * if_without_else - * if_without_else T_ELSE - */ -void -if2(void) -{ - - cstk->c_rchif = reached ? 1 : 0; - reached = 1; -} - -/* - * if_without_else - * if_without_else T_ELSE stmnt - */ -void -if3(int els) -{ - - if (els) { - reached |= cstk->c_rchif; - } else { - reached = 1; - } - popctrl(T_IF); -} - -/* - * T_SWITCH T_LPARN expr T_RPARN - */ -void -switch1(tnode_t *tn) -{ - tspec_t t; - type_t *tp; - - if (tn != NULL) - tn = cconv(tn); - if (tn != NULL) - tn = promote(NOOP, 0, tn); - if (tn != NULL && !isityp(tn->tn_type->t_tspec)) { - /* switch expression must have integral type */ - error(205); - tn = NULL; - } - if (tn != NULL && tflag) { - t = tn->tn_type->t_tspec; - if (t == LONG || t == ULONG || t == QUAD || t == UQUAD) { - /* switch expr. must be of type `int' in trad. C */ - warning(271); - } - } - - /* - * Remember the type of the expression. Because its possible - * that (*tp) is allocated on tree memory the type must be - * duplicated. This is not too complicated because it is - * only an integer type. - */ - if ((tp = calloc(1, sizeof (type_t))) == NULL) - nomem(); - if (tn != NULL) { - tp->t_tspec = tn->tn_type->t_tspec; - if ((tp->t_isenum = tn->tn_type->t_isenum) != 0) - tp->t_enum = tn->tn_type->t_enum; - } else { - tp->t_tspec = INT; - } - - expr(tn, 1, 0, 1); - - pushctrl(T_SWITCH); - cstk->c_switch = 1; - cstk->c_swtype = tp; - - reached = rchflg = 0; - ftflg = 1; -} - -/* - * switch_expr stmnt - */ -void -switch2(void) -{ - int nenum = 0, nclab = 0; - sym_t *esym; - clst_t *cl; - - if (cstk->c_swtype == NULL) - LERROR("switch2()"); - - /* - * If the switch expression was of type enumeration, count the case - * labels and the number of enumerators. If both counts are not - * equal print a warning. - */ - if (cstk->c_swtype->t_isenum) { - nenum = nclab = 0; - if (cstk->c_swtype->t_enum == NULL) - LERROR("switch2()"); - for (esym = cstk->c_swtype->t_enum->elem; - esym != NULL; esym = esym->s_nxt) { - nenum++; - } - for (cl = cstk->c_clst; cl != NULL; cl = cl->cl_nxt) - nclab++; - if (hflag && eflag && nenum != nclab && !cstk->c_default) { - /* enumeration value(s) not handled in switch */ - warning(206); - } - } - - if (cstk->c_break) { - /* - * end of switch always reached (c_break is only set if the - * break statement can be reached). - */ - reached = 1; - } else if (!cstk->c_default && - (!hflag || !cstk->c_swtype->t_isenum || nenum != nclab)) { - /* - * there are possible values which are not handled in - * switch - */ - reached = 1; - } /* - * otherwise the end of the switch expression is reached - * if the end of the last statement inside it is reached. - */ - - popctrl(T_SWITCH); -} - -/* - * T_WHILE T_LPARN expr T_RPARN - */ -void -while1(tnode_t *tn) -{ - - if (!reached) { - /* loop not entered at top */ - warning(207); - reached = 1; - } - - if (tn != NULL) - tn = cconv(tn); - if (tn != NULL) - tn = promote(NOOP, 0, tn); - if (tn != NULL && !issclt(tn->tn_type->t_tspec)) { - /* controlling expressions must have scalar type */ - error(204); - tn = NULL; - } - - pushctrl(T_WHILE); - cstk->c_loop = 1; - if (tn != NULL && tn->tn_op == CON) { - if (isityp(tn->tn_type->t_tspec)) { - cstk->c_infinite = tn->tn_val->v_quad != 0; - } else { - cstk->c_infinite = tn->tn_val->v_ldbl != 0.0; - } - } - - expr(tn, 0, 1, 1); -} - -/* - * while_expr stmnt - * while_expr error - */ -void -while2(void) -{ - - /* - * The end of the loop can be reached if it is no endless loop - * or there was a break statement which was reached. - */ - reached = !cstk->c_infinite || cstk->c_break; - rchflg = 0; - - popctrl(T_WHILE); -} - -/* - * T_DO - */ -void -do1(void) -{ - - if (!reached) { - /* loop not entered at top */ - warning(207); - reached = 1; - } - - pushctrl(T_DO); - cstk->c_loop = 1; -} - -/* - * do stmnt do_while_expr - * do error - */ -void -do2(tnode_t *tn) -{ - - /* - * If there was a continue statement the expression controlling the - * loop is reached. - */ - if (cstk->c_cont) - reached = 1; - - if (tn != NULL) - tn = cconv(tn); - if (tn != NULL) - tn = promote(NOOP, 0, tn); - if (tn != NULL && !issclt(tn->tn_type->t_tspec)) { - /* controlling expressions must have scalar type */ - error(204); - tn = NULL; - } - - if (tn != NULL && tn->tn_op == CON) { - if (isityp(tn->tn_type->t_tspec)) { - cstk->c_infinite = tn->tn_val->v_quad != 0; - } else { - cstk->c_infinite = tn->tn_val->v_ldbl != 0.0; - } - } - - expr(tn, 0, 1, 1); - - /* - * The end of the loop is only reached if it is no endless loop - * or there was a break statement which could be reached. - */ - reached = !cstk->c_infinite || cstk->c_break; - rchflg = 0; - - popctrl(T_DO); -} - -/* - * T_FOR T_LPARN opt_expr T_SEMI opt_expr T_SEMI opt_expr T_RPARN - */ -void -for1(tnode_t *tn1, tnode_t *tn2, tnode_t *tn3) -{ - - /* - * If there is no initialisation expression it is possible that - * it is intended not to enter the loop at top. - */ - if (tn1 != NULL && !reached) { - /* loop not entered at top */ - warning(207); - reached = 1; - } - - pushctrl(T_FOR); - cstk->c_loop = 1; - - /* - * Store the tree memory for the reinitialisation expression. - * Also remember this expression itself. We must check it at - * the end of the loop to get "used but not set" warnings correct. - */ - cstk->c_fexprm = tsave(); - cstk->c_f3expr = tn3; - STRUCT_ASSIGN(cstk->c_fpos, curr_pos); - STRUCT_ASSIGN(cstk->c_cfpos, csrc_pos); - - if (tn1 != NULL) - expr(tn1, 0, 0, 1); - - if (tn2 != NULL) - tn2 = cconv(tn2); - if (tn2 != NULL) - tn2 = promote(NOOP, 0, tn2); - if (tn2 != NULL && !issclt(tn2->tn_type->t_tspec)) { - /* controlling expressions must have scalar type */ - error(204); - tn2 = NULL; - } - if (tn2 != NULL) - expr(tn2, 0, 1, 1); - - if (tn2 == NULL) { - cstk->c_infinite = 1; - } else if (tn2->tn_op == CON) { - if (isityp(tn2->tn_type->t_tspec)) { - cstk->c_infinite = tn2->tn_val->v_quad != 0; - } else { - cstk->c_infinite = tn2->tn_val->v_ldbl != 0.0; - } - } - - /* Checking the reinitialisation expression is done in for2() */ - - reached = 1; -} - -/* - * for_exprs stmnt - * for_exprs error - */ -void -for2(void) -{ - pos_t cpos, cspos; - tnode_t *tn3; - - if (cstk->c_cont) - reached = 1; - - STRUCT_ASSIGN(cpos, curr_pos); - STRUCT_ASSIGN(cspos, csrc_pos); - - /* Restore the tree memory for the reinitialisation expression */ - trestor(cstk->c_fexprm); - tn3 = cstk->c_f3expr; - STRUCT_ASSIGN(curr_pos, cstk->c_fpos); - STRUCT_ASSIGN(csrc_pos, cstk->c_cfpos); - - /* simply "statement not reached" would be confusing */ - if (!reached && !rchflg) { - /* end-of-loop code not reached */ - warning(223); - reached = 1; - } - - if (tn3 != NULL) { - expr(tn3, 0, 0, 1); - } else { - tfreeblk(); - } - - STRUCT_ASSIGN(curr_pos, cpos); - STRUCT_ASSIGN(csrc_pos, cspos); - - /* An endless loop without break will never terminate */ - reached = cstk->c_break || !cstk->c_infinite; - rchflg = 0; - - popctrl(T_FOR); -} - -/* - * T_GOTO identifier T_SEMI - * T_GOTO error T_SEMI - */ -void -dogoto(sym_t *lab) -{ - - setuflg(lab, 0, 0); - - chkreach(); - - reached = rchflg = 0; -} - -/* - * T_BREAK T_SEMI - */ -void -dobreak(void) -{ - cstk_t *ci; - - ci = cstk; - while (ci != NULL && !ci->c_loop && !ci->c_switch) - ci = ci->c_nxt; - - if (ci == NULL) { - /* break outside loop or switch */ - error(208); - } else { - if (reached) - ci->c_break = 1; - } - - if (bflag) - chkreach(); - - reached = rchflg = 0; -} - -/* - * T_CONTINUE T_SEMI - */ -void -docont(void) -{ - cstk_t *ci; - - for (ci = cstk; ci != NULL && !ci->c_loop; ci = ci->c_nxt) - continue; - - if (ci == NULL) { - /* continue outside loop */ - error(209); - } else { - ci->c_cont = 1; - } - - chkreach(); - - reached = rchflg = 0; -} - -/* - * T_RETURN T_SEMI - * T_RETURN expr T_SEMI - */ -void -doreturn(tnode_t *tn) -{ - tnode_t *ln, *rn; - cstk_t *ci; - op_t op; - - for (ci = cstk; ci->c_nxt != NULL; ci = ci->c_nxt) - continue; - - if (tn != NULL) { - ci->c_retval = 1; - } else { - ci->c_noretval = 1; - } - - if (tn != NULL && funcsym->s_type->t_subt->t_tspec == VOID) { - /* void function %s cannot return value */ - error(213, funcsym->s_name); - tfreeblk(); - tn = NULL; - } else if (tn == NULL && funcsym->s_type->t_subt->t_tspec != VOID) { - /* - * Assume that the function has a return value only if it - * is explicitly declared. - */ - if (!funcsym->s_rimpl) - /* function %s expects to return value */ - warning(214, funcsym->s_name); - } - - if (tn != NULL) { - - /* Create a temporary node for the left side */ - ln = tgetblk(sizeof (tnode_t)); - ln->tn_op = NAME; - ln->tn_type = tduptyp(funcsym->s_type->t_subt); - ln->tn_type->t_const = 0; - ln->tn_lvalue = 1; - ln->tn_sym = funcsym; /* better than nothing */ - - tn = build(RETURN, ln, tn); - - if (tn != NULL) { - rn = tn->tn_right; - while ((op = rn->tn_op) == CVT || op == PLUS) - rn = rn->tn_left; - if (rn->tn_op == AMPER && rn->tn_left->tn_op == NAME && - rn->tn_left->tn_sym->s_scl == AUTO) { - /* %s returns pointer to automatic object */ - warning(302, funcsym->s_name); - } - } - - expr(tn, 1, 0, 1); - - } else { - - chkreach(); - - } - - reached = rchflg = 0; -} - -/* - * Do some cleanup after a global declaration or definition. - * Especially remove informations about unused lint comments. - */ -void -glclup(int silent) -{ - pos_t cpos; - - STRUCT_ASSIGN(cpos, curr_pos); - - if (nargusg != -1) { - if (!silent) { - STRUCT_ASSIGN(curr_pos, aupos); - /* must precede function definition: %s */ - warning(282, "ARGSUSED"); - } - nargusg = -1; - } - if (nvararg != -1) { - if (!silent) { - STRUCT_ASSIGN(curr_pos, vapos); - /* must precede function definition: %s */ - warning(282, "VARARGS"); - } - nvararg = -1; - } - if (prflstrg != -1) { - if (!silent) { - STRUCT_ASSIGN(curr_pos, prflpos); - /* must precede function definition: %s */ - warning(282, "PRINTFLIKE"); - } - prflstrg = -1; - } - if (scflstrg != -1) { - if (!silent) { - STRUCT_ASSIGN(curr_pos, scflpos); - /* must precede function definition: %s */ - warning(282, "SCANFLIKE"); - } - scflstrg = -1; - } - - STRUCT_ASSIGN(curr_pos, cpos); - - dcs->d_asm = 0; -} - -/* - * ARGSUSED comment - * - * Only the first n arguments of the following function are checked - * for usage. A missing argument is taken to be 0. - */ -void -argsused(int n) -{ - - if (n == -1) - n = 0; - - if (dcs->d_ctx != EXTERN) { - /* must be outside function: ** %s ** */ - warning(280, "ARGSUSED"); - return; - } - if (nargusg != -1) { - /* duplicate use of ** %s ** */ - warning(281, "ARGSUSED"); - } - nargusg = n; - STRUCT_ASSIGN(aupos, curr_pos); -} - -/* - * VARARGS comment - * - * Makes that lint2 checks only the first n arguments for compatibility - * to the function definition. A missing argument is taken to be 0. - */ -void -varargs(int n) -{ - - if (n == -1) - n = 0; - - if (dcs->d_ctx != EXTERN) { - /* must be outside function: ** %s ** */ - warning(280, "VARARGS"); - return; - } - if (nvararg != -1) { - /* duplicate use of ** %s ** */ - warning(281, "VARARGS"); - } - nvararg = n; - STRUCT_ASSIGN(vapos, curr_pos); -} - -/* - * PRINTFLIKE comment - * - * Check all arguments until the (n-1)-th as usual. The n-th argument is - * used the check the types of remaining arguments. - */ -void -printflike(int n) -{ - - if (n == -1) - n = 0; - - if (dcs->d_ctx != EXTERN) { - /* must be outside function: ** %s ** */ - warning(280, "PRINTFLIKE"); - return; - } - if (prflstrg != -1) { - /* duplicate use of ** %s ** */ - warning(281, "PRINTFLIKE"); - } - prflstrg = n; - STRUCT_ASSIGN(prflpos, curr_pos); -} - -/* - * SCANFLIKE comment - * - * Check all arguments until the (n-1)-th as usual. The n-th argument is - * used the check the types of remaining arguments. - */ -void -scanflike(int n) -{ - - if (n == -1) - n = 0; - - if (dcs->d_ctx != EXTERN) { - /* must be outside function: ** %s ** */ - warning(280, "SCANFLIKE"); - return; - } - if (scflstrg != -1) { - /* duplicate use of ** %s ** */ - warning(281, "SCANFLIKE"); - } - scflstrg = n; - STRUCT_ASSIGN(scflpos, curr_pos); -} - -/* - * Set the linenumber for a CONSTCOND comment. At this and the following - * line no warnings about constants in conditional contexts are printed. - */ -/* ARGSUSED */ -void -constcond(int n) -{ - - ccflg = 1; -} - -/* - * Suppress printing of "fallthrough on ..." warnings until next - * statement. - */ -/* ARGSUSED */ -void -fallthru(int n) -{ - - ftflg = 1; -} - -/* - * Stop warnings about statements which cannot be reached. Also tells lint - * that the following statements cannot be reached (e.g. after exit()). - */ -/* ARGSUSED */ -void -notreach(int n) -{ - - reached = 0; - rchflg = 1; -} - -/* ARGSUSED */ -void -lintlib(int n) -{ - - if (dcs->d_ctx != EXTERN) { - /* must be outside function: ** %s ** */ - warning(280, "LINTLIBRARY"); - return; - } - llibflg = 1; - vflag = 0; -} - -/* - * Suppress most warnings at the current and the following line. - */ -/* ARGSUSED */ -void -linted(int n) -{ - -#ifdef DEBUG - printf("%s, %d: nowarn = 1\n", curr_pos.p_file, curr_pos.p_line); -#endif - nowarn = 1; -} - -/* - * Suppress bitfield type errors on the current line. - */ -/* ARGSUSED */ -void -bitfieldtype(int n) -{ - -#ifdef DEBUG - printf("%s, %d: bitfieldtype_ok = 1\n", curr_pos.p_file, - curr_pos.p_line); -#endif - bitfieldtype_ok = 1; -} - -/* - * PROTOTLIB in conjunction with LINTLIBRARY can be used to handle - * prototypes like function definitions. This is done if the argument - * to PROTOLIB is nonzero. Otherwise prototypes are handled normaly. - */ -void -protolib(int n) -{ - - if (dcs->d_ctx != EXTERN) { - /* must be outside function: ** %s ** */ - warning(280, "PROTOLIB"); - return; - } - plibflg = n == 0 ? 0 : 1; -} - -/* - * Set quadflg to nonzero which means that the next statement/declaration - * may use "long long" without an error or warning. - */ -/* ARGSUSED */ -void -longlong(int n) -{ - - quadflg = 1; -} Index: usr.bin/xlint/lint1/init.c =================================================================== --- usr.bin/xlint/lint1/init.c +++ /dev/null @@ -1,656 +0,0 @@ -/* $NetBSD: init.c,v 1.10 2002/01/31 19:36:54 tv Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: init.c,v 1.10 2002/01/31 19:36:54 tv Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include "lint1.h" - -/* - * initerr is set as soon as a fatal error occurred in an initialisation. - * The effect is that the rest of the initialisation is ignored (parsed - * by yacc, expression trees built, but no initialisation takes place). - */ -int initerr; - -/* Pointer to the symbol which is to be initialized. */ -sym_t *initsym; - -/* Points to the top element of the initialisation stack. */ -istk_t *initstk; - -typedef struct namlist { - const char *n_name; - struct namlist *n_prev; - struct namlist *n_next; -} namlist_t; - -/* Points to a c9x named member; */ -namlist_t *namedmem = NULL; - - -static void popi2(void); -static void popinit(int); -static void pushinit(void); -static void testinit(void); -static void nextinit(int); -static int strginit(tnode_t *); -static void memberpop(void); - -#ifndef DEBUG -#define DPRINTF(a) -#else -#define DPRINTF(a) printf a -#endif - -void -memberpush(sb) - sbuf_t *sb; -{ - namlist_t *nam = xcalloc(1, sizeof (namlist_t)); - nam->n_name = sb->sb_name; - DPRINTF(("memberpush = %s\n", nam->n_name)); - if (namedmem == NULL) { - nam->n_prev = nam->n_next = nam; - namedmem = nam; - } else { - namedmem->n_prev->n_next = nam; - nam->n_prev = namedmem->n_prev; - nam->n_next = namedmem; - namedmem->n_prev = nam; - } -#if 0 - nam->n_next = namedmem; - namedmem = nam; -#endif -} - -static void -memberpop() -{ - DPRINTF(("memberpop = %s\n", namedmem->n_name)); - if (namedmem->n_next == namedmem) { - free(namedmem); - namedmem = NULL; - } else { - namlist_t *nam = namedmem; - namedmem = namedmem->n_next; - free(nam); - } -#if 0 - namedmem = namedmem->n_next; - free(nam); -#endif -} - - -/* - * Initialize the initialisation stack by putting an entry for the variable - * which is to be initialized on it. - */ -void -prepinit(void) -{ - istk_t *istk; - - if (initerr) - return; - - /* free memory used in last initialisation */ - while ((istk = initstk) != NULL) { - initstk = istk->i_nxt; - free(istk); - } - - /* - * If the type which is to be initialized is an incomplete type, - * it must be duplicated. - */ - if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type)) - initsym->s_type = duptyp(initsym->s_type); - - istk = initstk = xcalloc(1, sizeof (istk_t)); - istk->i_subt = initsym->s_type; - istk->i_cnt = 1; - -} - -static void -popi2(void) -{ -#ifdef DEBUG - char buf[64]; -#endif - istk_t *istk; - sym_t *m; - - initstk = (istk = initstk)->i_nxt; - if (initstk == NULL) - LERROR("popi2()"); - free(istk); - - istk = initstk; - - istk->i_cnt--; - if (istk->i_cnt < 0) - LERROR("popi2()"); - - DPRINTF(("popi2(): %d %s\n", istk->i_cnt, - namedmem ? namedmem->n_name : "*null*")); - if (istk->i_cnt >= 0 && namedmem != NULL) { - DPRINTF(("popi2(): %d %s %s\n", istk->i_cnt, - tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name)); - for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) { - if (m->s_field && m->s_name == unnamed) - continue; - if (strcmp(m->s_name, namedmem->n_name) == 0) { - istk->i_subt = m->s_type; - istk->i_cnt++; - memberpop(); - return; - } - } - error(101, namedmem->n_name); - memberpop(); - istk->i_namedmem = 1; - return; - } - /* - * If the removed element was a structure member, we must go - * to the next structure member. - */ - if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT && - !istk->i_namedmem) { - do { - m = istk->i_mem = istk->i_mem->s_nxt; - if (m == NULL) - LERROR("popi2()"); - } while (m->s_field && m->s_name == unnamed); - istk->i_subt = m->s_type; - } -} - -static void -popinit(int brace) -{ - DPRINTF(("popinit(%d)\n", brace)); - - if (brace) { - /* - * Take all entries, including the first which requires - * a closing brace, from the stack. - */ - do { - brace = initstk->i_brace; - popi2(); - } while (!brace); - } else { - /* - * Take all entries which cannot be used for further - * initializers from the stack, but do this only if - * they do not require a closing brace. - */ - while (!initstk->i_brace && - initstk->i_cnt == 0 && !initstk->i_nolimit) { - popi2(); - } - } -} - -static void -pushinit(void) -{ -#ifdef DEBUG - char buf[64]; -#endif - istk_t *istk; - int cnt; - sym_t *m; - - istk = initstk; - - /* Extend an incomplete array type by one element */ - if (istk->i_cnt == 0) { - DPRINTF(("pushinit(extend) %s\n", tyname(buf, sizeof(buf), - istk->i_type))); - /* - * Inside of other aggregate types must not be an incomplete - * type. - */ - if (istk->i_nxt->i_nxt != NULL) - LERROR("pushinit()"); - istk->i_cnt = 1; - if (istk->i_type->t_tspec != ARRAY) - LERROR("pushinit()"); - istk->i_type->t_dim++; - /* from now its a complete type */ - setcompl(istk->i_type, 0); - } - - if (istk->i_cnt <= 0) - LERROR("pushinit()"); - if (istk->i_type != NULL && issclt(istk->i_type->t_tspec)) - LERROR("pushinit() 4"); - - initstk = xcalloc(1, sizeof (istk_t)); - initstk->i_nxt = istk; - initstk->i_type = istk->i_subt; - if (initstk->i_type->t_tspec == FUNC) - LERROR("pushinit()"); - -again: - istk = initstk; - - DPRINTF(("pushinit(%s)\n", tyname(buf, sizeof(buf), istk->i_type))); - switch (istk->i_type->t_tspec) { - case ARRAY: - if (namedmem) { - DPRINTF(("pushinit ARRAY %s\n", namedmem->n_name)); - free(istk); - initstk = initstk->i_nxt; - goto again; - } - if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) { - /* initialisation of an incomplete type */ - error(175); - initerr = 1; - return; - } - istk->i_subt = istk->i_type->t_subt; - istk->i_nolimit = incompl(istk->i_type); - istk->i_cnt = istk->i_type->t_dim; - DPRINTF(("elements array %s[%d] %s\n", - tyname(buf, sizeof(buf), istk->i_subt), istk->i_cnt, - namedmem ? namedmem->n_name : "*none*")); - break; - case UNION: - if (tflag) - /* initialisation of union is illegal in trad. C */ - warning(238); - /* FALLTHROUGH */ - case STRUCT: - if (incompl(istk->i_type)) { - /* initialisation of an incomplete type */ - error(175); - initerr = 1; - return; - } - cnt = 0; - DPRINTF(("2. member lookup %s %s\n", - tyname(buf, sizeof(buf), istk->i_type), - namedmem ? namedmem->n_name : "*none*")); - for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) { - if (m->s_field && m->s_name == unnamed) - continue; - if (namedmem != NULL) { - DPRINTF(("pushinit():[member:%s, looking:%s]\n", - m->s_name, namedmem->n_name)); - if (strcmp(m->s_name, namedmem->n_name) == 0) { - cnt++; - break; - } else - continue; - } - if (++cnt == 1) { - istk->i_mem = m; - istk->i_subt = m->s_type; - } - } - if (namedmem != NULL) { - istk->i_namedmem = 1; - if (m == NULL) { - error(101, namedmem->n_name); - initerr = 1; - } else { - istk->i_mem = m; - istk->i_subt = m->s_type; - } - memberpop(); - cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1; - } - if (cnt == 0) { - /* cannot init. struct/union with no named member */ - error(179); - initerr = 1; - return; - } - istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1; - break; - default: - if (namedmem) { - DPRINTF(("pushinit(): pop\n")); - free(istk); - initstk = initstk->i_nxt; - goto again; - } - istk->i_cnt = 1; - break; - } -} - -static void -testinit(void) -{ - istk_t *istk; - - istk = initstk; - - /* - * If a closing brace is expected we have at least one initializer - * too much. - */ - if (istk->i_cnt == 0 && !istk->i_nolimit && !istk->i_namedmem) { - switch (istk->i_type->t_tspec) { - case ARRAY: - /* too many array initializers */ - error(173); - break; - case STRUCT: - case UNION: - /* too many struct/union initializers */ - error(172); - break; - default: - /* too many initializers */ - error(174); - break; - } - initerr = 1; - } -} - -static void -nextinit(int brace) -{ - char buf[64]; - - DPRINTF(("nextinit(%d)\n", brace)); - if (!brace) { - if (initstk->i_type == NULL && - !issclt(initstk->i_subt->t_tspec)) { - /* {}-enclosed initializer required */ - error(181); - } - /* - * Make sure an entry with a scalar type is at the top - * of the stack. - */ - if (!initerr) - testinit(); - while (!initerr && (initstk->i_type == NULL || - !issclt(initstk->i_type->t_tspec))) { - if (!initerr) - pushinit(); - } - } else { - if (initstk->i_type != NULL && - issclt(initstk->i_type->t_tspec)) { - /* invalid initializer */ - error(176); - initerr = 1; - } - if (!initerr) - testinit(); - if (!initerr) - pushinit(); - if (!initerr) - initstk->i_brace = 1; - } -} - -void -initlbr(void) -{ - - if (initerr) - return; - - if ((initsym->s_scl == AUTO || initsym->s_scl == REG) && - initstk->i_nxt == NULL) { - if (tflag && !issclt(initstk->i_subt->t_tspec)) - /* no automatic aggregate initialization in trad. C*/ - warning(188); - } - - /* - * Remove all entries which cannot be used for further initializers - * and do not expect a closing brace. - */ - popinit(0); - - nextinit(1); -} - -void -initrbr(void) -{ - - if (initerr) - return; - - popinit(1); -} - -void -mkinit(tnode_t *tn) -{ - ptrdiff_t offs; - sym_t *sym; - tspec_t lt, rt; - tnode_t *ln; - struct mbl *tmem; - scl_t sc; -#ifdef DEBUG - char buf[64]; -#endif - - DPRINTF(("mkinit(%s)\n", tyname(buf, sizeof(buf), tn->tn_type))); - if (initerr || tn == NULL) - goto end; - - sc = initsym->s_scl; - - /* - * Do not test for automatic aggregate initialisation. If the - * initializer starts with a brace we have the warning already. - * If not, an error will be printed that the initializer must - * be enclosed by braces. - */ - - /* - * Local initialisation of non-array-types with only one expression - * without braces is done by ASSIGN - */ - if ((sc == AUTO || sc == REG) && - initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) { - ln = getnnode(initsym, 0); - ln->tn_type = tduptyp(ln->tn_type); - ln->tn_type->t_const = 0; - tn = build(ASSIGN, ln, tn); - expr(tn, 0, 0, 1); - goto end; - } - - /* - * Remove all entries which cannot be used for further initializers - * and do not require a closing brace. - */ - popinit(0); - - /* Initialisations by strings are done in strginit(). */ - if (strginit(tn)) - goto end; - - nextinit(0); - if (initerr || tn == NULL) - goto end; - - initstk->i_cnt--; - DPRINTF(("mkinit() cnt=%d tn=%p\n", initstk->i_cnt, tn)); - /* Create a temporary node for the left side. */ - ln = tgetblk(sizeof (tnode_t)); - ln->tn_op = NAME; - ln->tn_type = tduptyp(initstk->i_type); - ln->tn_type->t_const = 0; - ln->tn_lvalue = 1; - ln->tn_sym = initsym; /* better than nothing */ - - tn = cconv(tn); - - lt = ln->tn_type->t_tspec; - rt = tn->tn_type->t_tspec; - - if (!issclt(lt)) - LERROR("mkinit()"); - - if (!typeok(INIT, 0, ln, tn)) - goto end; - - /* - * Store the tree memory. This is necessary because otherwise - * expr() would free it. - */ - tmem = tsave(); - expr(tn, 1, 0, 1); - trestor(tmem); - - if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) { - /* - * Bit-fields can be initialized in trad. C only by integer - * constants. - */ - if (tflag) - /* bit-field initialisation is illegal in trad. C */ - warning(186); - } - - if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON)) - tn = convert(INIT, 0, initstk->i_type, tn); - - if (tn != NULL && tn->tn_op != CON) { - sym = NULL; - offs = 0; - if (conaddr(tn, &sym, &offs) == -1) { - if (sc == AUTO || sc == REG) { - /* non-constant initializer */ - (void)gnuism(177); - } else { - /* non-constant initializer */ - error(177); - } - } - } - - end: - /* - * We only free the block, if we are not a compound declaration - * We know that the only symbols that start with a digit are the - * ones we allocate with mktempsym() for compound declarations - */ - if (!isdigit((unsigned char)initsym->s_name[0])) - tfreeblk(); -} - - -static int -strginit(tnode_t *tn) -{ - tspec_t t; - istk_t *istk; - int len; - strg_t *strg; - - if (tn->tn_op != STRING) - return (0); - - istk = initstk; - strg = tn->tn_strg; - - /* - * Check if we have an array type which can be initialized by - * the string. - */ - if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) { - t = istk->i_subt->t_subt->t_tspec; - if (!((strg->st_tspec == CHAR && - (t == CHAR || t == UCHAR || t == SCHAR)) || - (strg->st_tspec == WCHAR && t == WCHAR))) { - return (0); - } - /* Put the array at top of stack */ - pushinit(); - istk = initstk; - } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) { - t = istk->i_type->t_subt->t_tspec; - if (!((strg->st_tspec == CHAR && - (t == CHAR || t == UCHAR || t == SCHAR)) || - (strg->st_tspec == WCHAR && t == WCHAR))) { - return (0); - } - /* - * If the array is already partly initialized, we are - * wrong here. - */ - if (istk->i_cnt != istk->i_type->t_dim) - return (0); - } else { - return (0); - } - - /* Get length without trailing NUL character. */ - len = strg->st_len; - - if (istk->i_nolimit) { - istk->i_nolimit = 0; - istk->i_type->t_dim = len + 1; - /* from now complete type */ - setcompl(istk->i_type, 0); - } else { - if (istk->i_type->t_dim < len) { - /* non-null byte ignored in string initializer */ - warning(187); - } - } - - /* In every case the array is initialized completely. */ - istk->i_cnt = 0; - - return (1); -} Index: usr.bin/xlint/lint1/lint.h =================================================================== --- usr.bin/xlint/lint1/lint.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $NetBSD: lint.h,v 1.2 1995/07/03 21:24:18 cgd Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include - -#include "param.h" - -/* - * Type specifiers, used in type structures (type_t) and otherwere. - */ -typedef enum { - NOTSPEC, - SIGNED, /* keyword "signed", only used in the parser */ - UNSIGN, /* keyword "unsigned", only used in the parser */ - CHAR, /* char */ - SCHAR, /* signed char */ - UCHAR, /* unsigned char */ - SHORT, /* (signed) short */ - USHORT, /* unsigned short */ - INT, /* (signed) int */ - UINT, /* unsigned int */ - LONG, /* (signed) long */ - ULONG, /* unsigned long */ - QUAD, /* (signed) long long */ - UQUAD, /* unsigned long long */ - FLOAT, /* float */ - DOUBLE, /* double or, with tflag, long float */ - LDOUBLE, /* long double */ - VOID, /* void */ - STRUCT, /* structure tag */ - UNION, /* union tag */ - ENUM, /* enum tag */ - PTR, /* pointer */ - ARRAY, /* array */ - FUNC /* function */ -#define NTSPEC ((int)FUNC + 1) -} tspec_t; - -/* - * size of types, name and classification - */ -typedef struct { - int tt_sz; /* size in bits */ - int tt_psz; /* size, different from tt_sz - if pflag is set */ - tspec_t tt_styp; /* signed counterpart */ - tspec_t tt_utyp; /* unsigned counterpart */ - u_int tt_isityp : 1; /* 1 if integer type */ - u_int tt_isutyp : 1; /* 1 if unsigned integer type */ - u_int tt_isftyp : 1; /* 1 if floating point type */ - u_int tt_isatyp : 1; /* 1 if arithmetic type */ - u_int tt_issclt : 1; /* 1 if scalar type */ - char *tt_name; /* type name */ -} ttab_t; - -#define size(t) (ttab[t].tt_sz) -#define psize(t) (ttab[t].tt_psz) -#define styp(t) (ttab[t].tt_styp) -#define utyp(t) (ttab[t].tt_utyp) -#define isityp(t) (ttab[t].tt_isityp) -#define isutyp(t) (ttab[t].tt_isutyp) -#define isftyp(t) (ttab[t].tt_isftyp) -#define isatyp(t) (ttab[t].tt_isatyp) -#define issclt(t) (ttab[t].tt_issclt) - -extern ttab_t ttab[]; - - -typedef enum { - NODECL, /* until now not declared */ - DECL, /* declared */ - TDEF, /* tentative defined */ - DEF /* defined */ -} def_t; - -/* - * Following structure contains some data used for the output buffer. - */ -typedef struct ob { - char *o_buf; /* buffer */ - char *o_end; /* first byte after buffer */ - size_t o_len; /* length of buffer */ - char *o_nxt; /* next free byte in buffer */ -} ob_t; - -#include "externs.h" Index: usr.bin/xlint/lint1/lint1.h =================================================================== --- usr.bin/xlint/lint1/lint1.h +++ /dev/null @@ -1,424 +0,0 @@ -/* $NetBSD: lint1.h,v 1.16 2002/10/21 22:44:08 christos Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -__FBSDID("$FreeBSD$"); - -#include "lint.h" -#include "op.h" - -/* XXX - works for most systems, but the whole ALIGN thing needs to go away */ -#ifndef LINT_ALIGN -#define LINT_ALIGN(x) (((x) + 15) & ~15) -#endif - -/* - * Describes the position of a declaration or anything else. - */ -typedef struct { - int p_line; - const char *p_file; - int p_uniq; /* uniquifier */ -} pos_t; - -/* Copies curr_pos, keeping things unique. */ -#define UNIQUE_CURR_POS(pos) \ - do { \ - STRUCT_ASSIGN((pos), curr_pos); \ - curr_pos.p_uniq++; \ - if (curr_pos.p_file == csrc_pos.p_file) \ - csrc_pos.p_uniq++; \ - } while (0) - -/* - * Strings cannot be referenced to simply by a pointer to its first - * char. This is because strings can contain NUL characters other than the - * trailing NUL. - * - * Strings are stored with a trailing NUL. - */ -typedef struct strg { - tspec_t st_tspec; /* CHAR or WCHAR */ - size_t st_len; /* length without trailing NUL */ - union { - u_char *_st_cp; - wchar_t *_st_wcp; - } st_u; -} strg_t; - -#define st_cp st_u._st_cp -#define st_wcp st_u._st_wcp - -/* - * qualifiers (only for lex/yacc interface) - */ -typedef enum { - CONST, VOLATILE -} tqual_t; - -/* - * Integer and floating point values are stored in this structure - */ -typedef struct { - tspec_t v_tspec; - int v_ansiu; /* set if an integer constant is - unsigned in ANSI C */ - union { - int64_t _v_quad; /* integers */ - ldbl_t _v_ldbl; /* floats */ - } v_u; -} val_t; - -#define v_quad v_u._v_quad -#define v_ldbl v_u._v_ldbl - -/* - * Structures of type str_t uniqely identify structures. This can't - * be done in structures of type type_t, because these are copied - * if they must be modified. So it would not be possible to check - * if two structures are identical by comparing the pointers to - * the type structures. - * - * The typename is used if the structure is unnamed to identify - * the structure type in pass 2. - */ -typedef struct { - u_int size; /* size in bit */ - u_int align : 15; /* alignment in bit */ - u_int sincompl : 1; /* set if incomplete type */ - struct sym *memb; /* list of members */ - struct sym *stag; /* symbol table entry of tag */ - struct sym *stdef; /* symbol table entry of first typename */ -} str_t; - -/* - * same as above for enums - */ -typedef struct { - u_int eincompl : 1; /* incomplete enum type */ - struct sym *elem; /* list of enumerators */ - struct sym *etag; /* symbol table entry of tag */ - struct sym *etdef; /* symbol table entry of first typename */ -} enum_t; - -/* - * Types are represented by concatenation of structures of type type_t - * via t_subt. - */ -typedef struct type { - tspec_t t_tspec; /* type specifier */ - u_int t_aincompl : 1; /* incomplete array type */ - u_int t_const : 1; /* const modifier */ - u_int t_volatile : 1; /* volatile modifier */ - u_int t_proto : 1; /* function prototype (t_args valid) */ - u_int t_vararg : 1; /* prototype with ... */ - u_int t_typedef : 1; /* type defined with typedef */ - u_int t_isfield : 1; /* type is bitfield */ - u_int t_isenum : 1; /* type is (or was) enum (t_enum valid) */ - union { - int _t_dim; /* dimension */ - str_t *_t_str; /* struct/union tag */ - enum_t *_t_enum; /* enum tag */ - struct sym *_t_args; /* arguments (if t_proto) */ - } t_u; - struct { - u_int _t_flen : 8; /* length of bit-field */ - u_int _t_foffs : 24; /* offset of bit-field */ - } t_b; - struct type *t_subt; /* element type (arrays), return value - (functions), or type pointer points to */ -} type_t; - -#define t_dim t_u._t_dim -#define t_str t_u._t_str -#define t_field t_u._t_field -#define t_enum t_u._t_enum -#define t_args t_u._t_args -#define t_flen t_b._t_flen -#define t_foffs t_b._t_foffs - -/* - * types of symbols - */ -typedef enum { - FVFT, /* variables, functions, type names, enums */ - FMOS, /* members of structs or unions */ - FTAG, /* tags */ - FLAB /* labels */ -} symt_t; - -/* - * storage classes - */ -typedef enum { - NOSCL, - EXTERN, /* external symbols (indep. of decl_t) */ - STATIC, /* static symbols (local and global) */ - AUTO, /* automatic symbols (except register) */ - REG, /* register */ - TYPEDEF, /* typedef */ - STRTAG, - UNIONTAG, - ENUMTAG, - MOS, /* member of struct */ - MOU, /* member of union */ - ENUMCON, /* enumerator */ - ABSTRACT, /* abstract symbol (sizeof, casts, unnamed argument) */ - ARG, /* argument */ - PARG, /* used in declaration stack during prototype - declaration */ - INLINE /* only used by the parser */ -} scl_t; - -/* - * symbol table entry - */ -typedef struct sym { - const char *s_name; /* name */ - const char *s_rename; /* renamed symbol's given name */ - pos_t s_dpos; /* position of last (prototype)definition, - prototypedeclaration, no-prototype-def., - tentative definition or declaration, - in this order */ - pos_t s_spos; /* position of first initialisation */ - pos_t s_upos; /* position of first use */ - symt_t s_kind; /* type of symbol */ - u_int s_keyw : 1; /* keyword */ - u_int s_field : 1; /* bit-field */ - u_int s_set : 1; /* variable set, label defined */ - u_int s_used : 1; /* variable/label used */ - u_int s_arg : 1; /* symbol is function argument */ - u_int s_reg : 1; /* symbol is register variable */ - u_int s_defarg : 1; /* undefined symbol in old style function - definition */ - u_int s_rimpl : 1; /* return value of function implicit decl. */ - u_int s_osdef : 1; /* symbol stems from old style function def. */ - u_int s_inline : 1; /* true if this is an inline function */ - struct sym *s_xsym; /* for local declared external symbols pointer - to external symbol with same name */ - def_t s_def; /* declared, tentative defined, defined */ - scl_t s_scl; /* storage class */ - int s_blklev; /* level of declaration, -1 if not in symbol - table */ - type_t *s_type; /* type */ - val_t s_value; /* value (if enumcon) */ - union { - str_t *_s_st; /* tag, if it is a struct/union member */ - enum_t *_s_et; /* tag, if it is an enumerator */ - tspec_t _s_tsp; /* type (only for keywords) */ - tqual_t _s_tqu; /* qualifier (only for keywords) */ - struct sym *_s_args; /* arguments in old style function - definitions */ - } u; - struct sym *s_link; /* next symbol with same hash value */ - struct sym **s_rlink; /* pointer to s_link of prev. symbol */ - struct sym *s_nxt; /* next struct/union member, enumerator, - argument */ - struct sym *s_dlnxt; /* next symbol declared on same level */ -} sym_t; - -#define s_styp u._s_st -#define s_etyp u._s_et -#define s_tspec u._s_tsp -#define s_tqual u._s_tqu -#define s_args u._s_args - -/* - * Used to keep some informations about symbols before they are entered - * into the symbol table. - */ -typedef struct sbuf { - const char *sb_name; /* name of symbol */ - size_t sb_len; /* length (without '\0') */ - int sb_hash; /* hash value */ - sym_t *sb_sym; /* symbol table entry */ - struct sbuf *sb_nxt; /* for freelist */ -} sbuf_t; - - -/* - * tree node - */ -typedef struct tnode { - op_t tn_op; /* operator */ - type_t *tn_type; /* type */ - u_int tn_lvalue : 1; /* node is lvalue */ - u_int tn_cast : 1; /* if tn_op == CVT its an explicit cast */ - u_int tn_parn : 1; /* node parenthesized */ - union { - struct { - struct tnode *_tn_left; /* (left) operand */ - struct tnode *_tn_right; /* right operand */ - } tn_s; - sym_t *_tn_sym; /* symbol if op == NAME */ - val_t *_tn_val; /* value if op == CON */ - strg_t *_tn_strg; /* string if op == STRING */ - } tn_u; -} tnode_t; - -#define tn_left tn_u.tn_s._tn_left -#define tn_right tn_u.tn_s._tn_right -#define tn_sym tn_u._tn_sym -#define tn_val tn_u._tn_val -#define tn_strg tn_u._tn_strg - -/* - * For nested declarations a stack exists, which holds all information - * needed for the current level. dcs points to the top element of this - * stack. - * - * ctx describes the context of the current declaration. Its value is - * one of - * EXTERN global declarations - * MOS oder MOU declarations of struct or union members - * ENUMCON declarations of enums - * ARG declaration of arguments in old style function definitions - * PARG declaration of arguments in function prototypes - * AUTO declaration of local symbols - * ABSTRACT abstract declarations (sizeof, casts) - * - */ -typedef struct dinfo { - tspec_t d_atyp; /* VOID, CHAR, INT, FLOAT or DOUBLE */ - tspec_t d_smod; /* SIGNED or UNSIGN */ - tspec_t d_lmod; /* SHORT, LONG or QUAD */ - scl_t d_scl; /* storage class */ - type_t *d_type; /* after deftyp() pointer to the type used - for all declarators */ - sym_t *d_rdcsym; /* redeclared symbol */ - int d_offset; /* offset of next structure member */ - int d_stralign; /* alignment required for current structure */ - scl_t d_ctx; /* context of declaration */ - u_int d_const : 1; /* const in declaration specifiers */ - u_int d_volatile : 1; /* volatile in declaration specifiers */ - u_int d_inline : 1; /* inline in declaration specifiers */ - u_int d_mscl : 1; /* multiple storage classes */ - u_int d_terr : 1; /* invalid type combination */ - u_int d_nedecl : 1; /* 1 if at least a tag is declared */ - u_int d_vararg : 1; /* ... in current function decl. */ - u_int d_proto : 1; /* current funct. decl. is prototype */ - u_int d_notyp : 1; /* set if no type specifier was present */ - u_int d_asm : 1; /* set if d_ctx == AUTO and asm() present */ - type_t *d_tagtyp; /* tag during member declaration */ - sym_t *d_fargs; /* list of arguments during function def. */ - pos_t d_fdpos; /* position of function definition */ - sym_t *d_dlsyms; /* first symbol declared at this level */ - sym_t **d_ldlsym; /* points to s_dlnxt in last symbol decl. - at this level */ - sym_t *d_fpsyms; /* symbols defined in prototype */ - struct dinfo *d_nxt; /* next level */ -} dinfo_t; - -/* - * Type of stack which is used for initialisation of aggregate types. - */ -typedef struct istk { - type_t *i_type; /* type of initialisation */ - type_t *i_subt; /* type of next level */ - u_int i_brace : 1; /* need } for pop */ - u_int i_nolimit : 1; /* incomplete array type */ - u_int i_namedmem : 1; /* has c9x named members */ - sym_t *i_mem; /* next structure member */ - int i_cnt; /* # of remaining elements */ - struct istk *i_nxt; /* previous level */ -} istk_t; - -/* - * Used to collect information about pointers and qualifiers in - * declarators. - */ -typedef struct pqinf { - int p_pcnt; /* number of asterisks */ - u_int p_const : 1; - u_int p_volatile : 1; - struct pqinf *p_nxt; -} pqinf_t; - -/* - * Case values are stored in a list of type clst_t. - */ -typedef struct clst { - val_t cl_val; - struct clst *cl_nxt; -} clst_t; - -/* - * Used to keep informations about nested control statements. - */ -typedef struct cstk { - int c_env; /* type of statement (T_IF, ...) */ - u_int c_loop : 1; /* continue && break are valid */ - u_int c_switch : 1; /* case && break are valid */ - u_int c_break : 1; /* loop/switch has break */ - u_int c_cont : 1; /* loop has continue */ - u_int c_default : 1; /* switch has default */ - u_int c_infinite : 1; /* break condition always false - (for (;;), while (1)) */ - u_int c_rchif : 1; /* end of if-branch reached */ - u_int c_noretval : 1; /* had "return;" */ - u_int c_retval : 1; /* had "return (e);" */ - type_t *c_swtype; /* type of switch expression */ - clst_t *c_clst; /* list of case values */ - struct mbl *c_fexprm; /* saved memory for end of loop - expression in for() */ - tnode_t *c_f3expr; /* end of loop expr in for() */ - pos_t c_fpos; /* position of end of loop expr */ - pos_t c_cfpos; /* same for csrc_pos */ - struct cstk *c_nxt; /* outer control statement */ -} cstk_t; - -typedef struct { - size_t lo; - size_t hi; -} range_t; - -#include "externs1.h" - -#define ERR_SETSIZE 1024 -#define __NERRBITS (sizeof(unsigned int)) - -typedef struct err_set { - unsigned int errs_bits[(ERR_SETSIZE + __NERRBITS-1) / __NERRBITS]; -} err_set; - -#define ERR_SET(n, p) \ - ((p)->errs_bits[(n)/__NERRBITS] |= (1 << ((n) % __NERRBITS))) -#define ERR_CLR(n, p) \ - ((p)->errs_bits[(n)/__NERRBITS] &= ~(1 << ((n) % __NERRBITS))) -#define ERR_ISSET(n, p) \ - ((p)->errs_bits[(n)/__NERRBITS] & (1 << ((n) % __NERRBITS))) -#define ERR_ZERO(p) (void)memset((p), 0, sizeof(*(p))) - -#define LERROR(fmt, args...) lerror(__FILE__, __LINE__, fmt, ##args) - -extern err_set msgset; Index: usr.bin/xlint/lint1/main1.c =================================================================== --- usr.bin/xlint/lint1/main1.c +++ /dev/null @@ -1,230 +0,0 @@ -/* $NetBSD: main1.c,v 1.17 2006/11/08 18:31:15 christos Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: main1.c,v 1.17 2006/11/08 18:31:15 christos Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lint1.h" - -/* set yydebug to 1*/ -int yflag; - -/* - * Print warnings if an assignment of an integertype to another integertype - * causes an implicit narrowing conversion. If aflag is 1, these warnings - * are printed only if the source type is at least as wide as long. If aflag - * is greater than 1, they are always printed. - */ -int aflag; - -/* Print a warning if a break statement cannot be reached. */ -int bflag; - -/* Print warnings for pointer casts. */ -int cflag; - -/* Print various debug information. */ -int dflag; - -/* Perform stricter checking of enum types and operations on enum types. */ -int eflag; - -/* Print complete pathnames, not only the basename. */ -int Fflag; - -/* Enable some extensions of gcc */ -int gflag; - -/* Treat warnings as errors */ -int wflag; - -/* - * Apply a number of heuristic tests to attempt to intuit bugs, improve - * style, and reduce waste. - */ -int hflag; - -/* Attempt to check portability to other dialects of C. */ -int pflag; - -/* - * In case of redeclarations/redefinitions print the location of the - * previous declaration/definition. - */ -int rflag; - -/* Strict ANSI C mode. */ -int sflag; - -/* Traditional C mode. */ -int tflag; - -/* Enable C9X extensions */ -int Sflag; -/* - * Complain about functions and external variables used and not defined, - * or defined and not used. - */ -int uflag = 1; - -/* Complain about unused function arguments. */ -int vflag = 1; - -/* Complain about structures which are never defined. */ -int zflag = 1; - -err_set msgset; - -static void usage(void); - -int main(int, char *[]); - -int -main(int argc, char *argv[]) -{ - int c; - char *ptr; - - ERR_ZERO(&msgset); - while ((c = getopt(argc, argv, "abcdeghmprstuvwyzFSX:")) != -1) { - switch (c) { - case 'a': aflag++; break; - case 'b': bflag = 1; break; - case 'c': cflag = 1; break; - case 'd': dflag = 1; break; - case 'e': eflag = 1; break; - case 'F': Fflag = 1; break; - case 'g': gflag = 1; break; - case 'h': hflag = 1; break; - case 'p': pflag = 1; break; - case 'r': rflag = 1; break; - case 's': sflag = 1; break; - case 'S': Sflag = 1; break; - case 't': tflag = 1; break; - case 'u': uflag = 0; break; - case 'w': wflag = 1; break; - case 'v': vflag = 0; break; - case 'y': yflag = 1; break; - case 'z': zflag = 0; break; - - case 'm': - msglist(); - return(0); - - case 'X': - for (ptr = strtok(optarg, ","); ptr; - ptr = strtok(NULL, ",")) { - char *eptr; - long msg; - - errno = 0; - msg = strtol(ptr, &eptr, 0); - if ((msg == LONG_MIN || msg == LONG_MAX) && - errno == ERANGE) - err(1, "invalid error message id '%s'", - ptr); - if (*eptr || ptr == eptr || msg < 0 || - msg >= ERR_SETSIZE) - errx(1, "invalid error message id '%s'", - ptr); - ERR_SET(msg, &msgset); - } - break; - case '?': - default: - usage(); - break; - } - } - argc -= optind; - argv += optind; - - if (argc != 2) - usage(); - - /* open the input file */ - if ((yyin = fopen(argv[0], "r")) == NULL) - err(1, "cannot open '%s'", argv[0]); - - /* initialize output */ - outopen(argv[1]); - - if (yflag) - yydebug = 1; - - initmem(); - initdecl(); - initscan(); - initmtab(); - - yyparse(); - - /* Following warnings cannot be suppressed by LINTED */ - nowarn = 0; -#ifdef DEBUG - printf("%s, %d: nowarn = 0\n", curr_pos.p_file, curr_pos.p_line); -#endif - chkglsyms(); - - outclose(); - - return (nerr != 0); -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "usage: lint1 [-abcdeghmprstuvwyzFS] [-X [,]... src dest\n"); - exit(1); -} - -void -norecover(void) -{ - /* cannot recover from previous errors */ - error(224); - exit(1); -} Index: usr.bin/xlint/lint1/makeman =================================================================== --- usr.bin/xlint/lint1/makeman +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -# $NetBSD$ -# -# Copyright (c) 2000 The NetBSD Foundation, Inc. -# All rights reserved. -# -# This code is derived from software contributed to The NetBSD Foundation -# by Christos Zoulas. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. - - -cat << \__EOF -.\" $NetBSD$ -.\" -.\" Copyright (c) 2000 The NetBSD Foundation, Inc. -.\" All rights reserved. -.\" -.\" This code is derived from software contributed to The NetBSD Foundation -.\" by Christos Zoulas. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -.\" POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd July 5, 2000 -.Dt LINT 7 -.Os -.Sh NAME -.Nm lint -.Nd Lint error message list -.Sh DESCRIPTION -The following is a list of message IDs and messages produced by -.Xr lint 1 . -It is intended to be used with -.Fl X -flag of -.Xr lint 1 . -.Bl -column -offset indent "XXXX" -__EOF -"$@" | sed -e 's/\\/\\e/g' -e "s/'/\\'/" -echo ".El" Index: usr.bin/xlint/lint1/mem1.c =================================================================== --- usr.bin/xlint/lint1/mem1.c +++ /dev/null @@ -1,365 +0,0 @@ -/* $NetBSD: mem1.c,v 1.7 2002/01/31 19:36:54 tv Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: mem1.c,v 1.7 2002/01/31 19:36:54 tv Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include "lint1.h" - -/* - * Filenames allocated by fnalloc() and fnnalloc() are shared. - */ -typedef struct fn { - char *fn_name; - size_t fn_len; - int fn_id; - struct fn *fn_nxt; -} fn_t; - -static fn_t *fnames; - -static fn_t *srchfn(const char *, size_t); - -/* - * Look for a Filename of length l. - */ -static fn_t * -srchfn(const char *s, size_t len) -{ - fn_t *fn; - - for (fn = fnames; fn != NULL; fn = fn->fn_nxt) { - if (fn->fn_len == len && memcmp(fn->fn_name, s, len) == 0) - break; - } - return (fn); -} - -/* - * Return a shared string for filename s. - */ -const char * -fnalloc(const char *s) -{ - - return (s != NULL ? fnnalloc(s, strlen(s)) : NULL); -} - -const char * -fnnalloc(const char *s, size_t len) -{ - fn_t *fn; - - static int nxt_id = 0; - - if (s == NULL) - return (NULL); - - if ((fn = srchfn(s, len)) == NULL) { - if ((fn = malloc(sizeof (fn_t))) == NULL) - nomem(); - /* Do not used strdup() because string is not NUL-terminated.*/ - if ((fn->fn_name = malloc(len + 1)) == NULL) - nomem(); - (void)memcpy(fn->fn_name, s, len); - fn->fn_name[len] = '\0'; - fn->fn_len = len; - fn->fn_id = nxt_id++; - fn->fn_nxt = fnames; - fnames = fn; - /* Write id of this filename to the output file. */ - outclr(); - outint(fn->fn_id); - outchar('s'); - outstrg(fn->fn_name); - } - return (fn->fn_name); -} - -/* - * Get id of a filename. - */ -int -getfnid(const char *s) -{ - fn_t *fn; - - if (s == NULL || (fn = srchfn(s, strlen(s))) == NULL) - return (-1); - return (fn->fn_id); -} - -/* - * Memory for declarations and other things which must be available - * until the end of a block (or the end of the translation unit) - * are associated with the level (mblklev) of the block (or with 0). - * Because these memory is allocated in large blocks associated with - * a given level it can be freed easily at the end of a block. - */ -#define ML_INC ((size_t)32) /* Increment for length of *mblks */ - -typedef struct mbl { - void *blk; /* beginning of memory block */ - void *ffree; /* first free byte */ - size_t nfree; /* # of free bytes */ - size_t size; /* total size of memory block */ - struct mbl *nxt; /* next block */ -} mbl_t; - -/* - * Array of pointers to lists of memory blocks. mblklev is used as - * index into this array. - */ -static mbl_t **mblks; - -/* number of elements in *mblks */ -static size_t nmblks; - -/* free list for memory blocks */ -static mbl_t *frmblks; - -/* length of new allocated memory blocks */ -static size_t mblklen; - -static void *xgetblk(mbl_t **, size_t); -static void xfreeblk(mbl_t **); -static mbl_t *xnewblk(void); - -static mbl_t * -xnewblk(void) -{ - mbl_t *mb; - int prot, flags; - - if ((mb = malloc(sizeof (mbl_t))) == NULL) - nomem(); - - /* use mmap instead of malloc to avoid malloc's size overhead */ - - prot = PROT_READ | PROT_WRITE; - flags = MAP_ANON | MAP_PRIVATE; - mb->blk = mmap(NULL, mblklen, prot, flags, -1, (off_t)0); - if (mb->blk == (void *)MAP_FAILED) - err(1, "can't map memory"); - - mb->size = mblklen; - - return (mb); -} - -/* - * Allocate new memory. If the first block of the list has not enough - * free space, or there is no first block, get a new block. The new - * block is taken from the free list or, if there is no block on the - * free list, is allocated using xnewblk(). If a new block is allocated - * it is initialized with zero. Blocks taken from the free list are - * zero'd in xfreeblk(). - */ -static void * -xgetblk(mbl_t **mbp, size_t s) -{ - mbl_t *mb; - void *p; - size_t t = 0; - - s = LINT_ALIGN(s); - if ((mb = *mbp) == NULL || mb->nfree < s) { - if ((mb = frmblks) == NULL) { - if (s > mblklen) { - t = mblklen; - mblklen = s; - } - mb = xnewblk(); - if (t) - mblklen = t; - (void)memset(mb->blk, 0, mb->size); - } else { - frmblks = mb->nxt; - } - mb->ffree = mb->blk; - mb->nfree = mb->size; - mb->nxt = *mbp; - *mbp = mb; - } - p = mb->ffree; - mb->ffree = (char *)mb->ffree + s; - mb->nfree -= s; - return (p); -} - -/* - * Move all blocks from list *fmbp to free list. For each block, set all - * used memory to zero. - */ -static void -xfreeblk(mbl_t **fmbp) -{ - mbl_t *mb; - - while ((mb = *fmbp) != NULL) { - *fmbp = mb->nxt; - mb->nxt = frmblks; - frmblks = mb; - (void)memset(mb->blk, 0, mb->size - mb->nfree); - } -} - -void -initmem(void) -{ - int pgsz; - - pgsz = getpagesize(); - mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz; - - if ((mblks = calloc(nmblks = ML_INC, sizeof (mbl_t *))) == NULL) - nomem(); -} - - -/* - * Allocate memory associated with level l. - */ -void * -getlblk(int l, size_t s) -{ - - while (l >= nmblks) { - if ((mblks = realloc(mblks, (nmblks + ML_INC) * - sizeof (mbl_t *))) == NULL) - nomem(); - (void)memset(&mblks[nmblks], 0, ML_INC * sizeof (mbl_t *)); - nmblks += ML_INC; - } - return (xgetblk(&mblks[l], s)); -} - -void * -getblk(size_t s) -{ - - return (getlblk(mblklev, s)); -} - -/* - * Free all memory associated with level l. - */ -void -freelblk(int l) -{ - - xfreeblk(&mblks[l]); -} - -void -freeblk(void) -{ - - freelblk(mblklev); -} - -/* - * tgetblk() returns memory which is associated with the current - * expression. - */ -static mbl_t *tmblk; - -void * -tgetblk(size_t s) -{ - - return (xgetblk(&tmblk, s)); -} - -/* - * Get memory for a new tree node. - */ -tnode_t * -getnode(void) -{ - - return (tgetblk(sizeof (tnode_t))); -} - -/* - * Free all memory which is allocated by the current expression. - */ -void -tfreeblk(void) -{ - - xfreeblk(&tmblk); -} - -/* - * Save the memory which is used by the current expression. This memory - * is not freed by the next tfreeblk() call. The pointer returned can be - * used to restore the memory. - */ -mbl_t * -tsave(void) -{ - mbl_t *tmem; - - tmem = tmblk; - tmblk = NULL; - return (tmem); -} - -/* - * Free all memory used for the current expression and the memory used - * be a previous expression and saved by tsave(). The next call to - * tfreeblk() frees the restored memory. - */ -void -trestor(mbl_t *tmem) -{ - - tfreeblk(); - if (tmblk != NULL) { - free(tmblk->blk); - free(tmblk); - } - tmblk = tmem; -} Index: usr.bin/xlint/lint1/op.h =================================================================== --- usr.bin/xlint/lint1/op.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $NetBSD: op.h,v 1.2 1995/07/03 21:24:27 cgd Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Various information about operators - */ -typedef struct { - u_int m_binary : 1; /* binary op. */ - u_int m_logop : 1; /* logical op., result is int */ - u_int m_rqint : 1; /* operands must have integer type */ - u_int m_rqsclt : 1; /* operands must have scalar type */ - u_int m_rqatyp : 1; /* operands must have arithmetic type */ - u_int m_fold : 1; /* operands should be folded */ - u_int m_vctx : 1; /* value context for left operand */ - u_int m_tctx : 1; /* test context for left operand */ - u_int m_balance : 1; /* op. requires balancing */ - u_int m_sideeff : 1; /* op. has side effect */ - u_int m_tlansiu : 1; /* warning if left op. is unsign. in ANSI C */ - u_int m_transiu : 1; /* warning if right op. is unsign. in ANSI C */ - u_int m_tpconf : 1; /* test possible precedence confusion */ - u_int m_comp : 1; /* op. performs comparison */ - u_int m_enumop : 1; /* valid operation on enums */ - u_int m_badeop : 1; /* dubious operation on enums */ - u_int m_eqwarn : 1; /* warning if on operand stems from == */ - const char *m_name; /* name of op. */ -} mod_t; - -typedef enum { - NOOP = 0, - ARROW, - POINT, - NOT, - COMPL, - INC, - DEC, - INCBEF, - DECBEF, - INCAFT, - DECAFT, - UPLUS, - UMINUS, - STAR, - AMPER, - MULT, - DIV, - MOD, - PLUS, - MINUS, - SHL, - SHR, - LT, - LE, - GT, - GE, - EQ, - NE, - AND, - XOR, - OR, - LOGAND, - LOGOR, - QUEST, - COLON, - ASSIGN, - MULASS, - DIVASS, - MODASS, - ADDASS, - SUBASS, - SHLASS, - SHRASS, - ANDASS, - XORASS, - ORASS, - NAME, - CON, - STRING, - FSEL, - CALL, - COMMA, - CVT, - ICALL, - LOAD, - PUSH, - RETURN, - INIT, /* pseudo op, not used in trees */ - CASE, /* pseudo op, not used in trees */ - FARG /* pseudo op, not used in trees */ -#define NOPS ((int)FARG + 1) -} op_t; Index: usr.bin/xlint/lint1/param.h =================================================================== --- usr.bin/xlint/lint1/param.h +++ /dev/null @@ -1,143 +0,0 @@ -/* $NetBSD: param.h,v 1.4 1995/07/23 18:14:41 ragge Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Minimun size of string buffer. If this is not enough, the buffer - * is enlarged in steps of STRBLEN bytes. - */ -#define STRBLEN 256 - -/* - * This defines the size of memory blocks which are used to allocate - * memory in larger chunks. - */ -#define MBLKSIZ ((size_t)0x4000) - -/* - * Sizes of hash tables - * Should be a prime. Possible primes are - * 307, 401, 503, 601, 701, 809, 907, 1009, 1103, 1201, 1301, 1409, 1511. - * - * HSHSIZ1 symbol table 1st pass - * HSHSIZ2 symbol table 2nd pass - * THSHSIZ2 type table 2nd pass - */ -#define HSHSIZ1 503 -#define HSHSIZ2 1009 -#define THSHSIZ2 1009 - -/* - * Should be set to 1 if the difference of two pointers is of type long - * or the value of sizeof is of type unsigned long. - */ -#if __amd64__ -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 -#elif __alpha__ -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 -#elif __i386__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __m68k__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __ns32k__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __powerpc__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __riscv -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 -#elif __sparc__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __sparc64__ -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 -#elif __vax__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __arm__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __mips__ -#define PTRDIFF_IS_LONG 0 -#define SIZEOF_IS_ULONG 0 -#elif __aarch64__ -#define PTRDIFF_IS_LONG 1 -#define SIZEOF_IS_ULONG 1 -#else -#error unknown machine type -#endif - -/* - * Make sure this matches wchar_t. - */ -#define WCHAR SHORT - -#ifndef __GNUC__ -#ifndef lint -#ifndef QUAD_MAX /* necessary for mkdep */ -#define QUAD_MAX LONG_MAX -#define QUAD_MIN LONG_MIN -#define UQUAD_MAX ULONG_MAX -#endif -typedef long quad_t; -typedef u_long u_quad_t; -#endif -#endif - - -/* - * long double only in ANSI C. - */ -#ifdef __STDC__ -typedef long double ldbl_t; -#else -typedef double ldbl_t; -#endif - -/* - * Some traditional compilers are not able to assign structures. - */ -#ifdef __STDC__ -#define STRUCT_ASSIGN(dest, src) (dest) = (src) -#else -#define STRUCT_ASSIGN(dest, src) (void)memcpy(&(dest), &(src), \ - sizeof (dest)); -#endif Index: usr.bin/xlint/lint1/scan.l =================================================================== --- usr.bin/xlint/lint1/scan.l +++ /dev/null @@ -1,1531 +0,0 @@ -%{ -/* $NetBSD: scan.l,v 1.37 2007/02/06 00:08:31 he Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: scan.l,v 1.37 2007/02/06 00:08:31 he Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lint1.h" -#include "cgram.h" - -#define CHAR_MASK (~(~0 << CHAR_BIT)) - -/* Current position (its also updated when an included file is parsed) */ -pos_t curr_pos = { 1, "", 0 }; - -/* - * Current position in C source (not updated when an included file is - * parsed). - */ -pos_t csrc_pos = { 1, "", 0 }; - -static void incline(void); -static void badchar(int); -static sbuf_t *allocsb(void); -static void freesb(sbuf_t *); -static int inpc(void); -static int hash(const char *); -static sym_t *search(sbuf_t *); -static int name(void); -static int keyw(sym_t *); -static int icon(int); -static int fcon(void); -static int operator(int, op_t); -static int ccon(void); -static int wccon(void); -static int getescc(int); -static void directive(void); -static void comment(void); -static void slashslashcomment(void); -static int string(void); -static int wcstrg(void); - -%} - -%option nounput - -L [_A-Za-z] -D [0-9] -NZD [1-9] -OD [0-7] -HD [0-9A-Fa-f] -EX ([eE][+-]?[0-9]+) - -%% - -{L}({L}|{D})* return (name()); -0{OD}*[lLuU]* return (icon(8)); -{NZD}{D}*[lLuU]* return (icon(10)); -0[xX]{HD}+[lLuU]* return (icon(16)); -{D}+\.{D}*{EX}?[fFlL]? | -{D}+{EX}[fFlL]? | -0[xX]{HD}+p{HD}+[fFlL]? | -\.{D}+{EX}?[fFlL]? return (fcon()); -"=" return (operator(T_ASSIGN, ASSIGN)); -"*=" return (operator(T_OPASS, MULASS)); -"/=" return (operator(T_OPASS, DIVASS)); -"%=" return (operator(T_OPASS, MODASS)); -"+=" return (operator(T_OPASS, ADDASS)); -"-=" return (operator(T_OPASS, SUBASS)); -"<<=" return (operator(T_OPASS, SHLASS)); -">>=" return (operator(T_OPASS, SHRASS)); -"&=" return (operator(T_OPASS, ANDASS)); -"^=" return (operator(T_OPASS, XORASS)); -"|=" return (operator(T_OPASS, ORASS)); -"||" return (operator(T_LOGOR, LOGOR)); -"&&" return (operator(T_LOGAND, LOGAND)); -"|" return (operator(T_OR, OR)); -"&" return (operator(T_AND, AND)); -"^" return (operator(T_XOR, XOR)); -"==" return (operator(T_EQOP, EQ)); -"!=" return (operator(T_EQOP, NE)); -"<" return (operator(T_RELOP, LT)); -">" return (operator(T_RELOP, GT)); -"<=" return (operator(T_RELOP, LE)); -">=" return (operator(T_RELOP, GE)); -"<<" return (operator(T_SHFTOP, SHL)); -">>" return (operator(T_SHFTOP, SHR)); -"++" return (operator(T_INCDEC, INC)); -"--" return (operator(T_INCDEC, DEC)); -"->" return (operator(T_STROP, ARROW)); -"." return (operator(T_STROP, POINT)); -"+" return (operator(T_ADDOP, PLUS)); -"-" return (operator(T_ADDOP, MINUS)); -"*" return (operator(T_MULT, MULT)); -"/" return (operator(T_DIVOP, DIV)); -"%" return (operator(T_DIVOP, MOD)); -"!" return (operator(T_UNOP, NOT)); -"~" return (operator(T_UNOP, COMPL)); -"\"" return (string()); -"L\"" return (wcstrg()); -";" return (T_SEMI); -"{" return (T_LBRACE); -"}" return (T_RBRACE); -"," return (T_COMMA); -":" return (T_COLON); -"?" return (T_QUEST); -"[" return (T_LBRACK); -"]" return (T_RBRACK); -"(" return (T_LPARN); -")" return (T_RPARN); -"..." return (T_ELLIPSE); -"'" return (ccon()); -"L'" return (wccon()); -^#.*$ directive(); -\n incline(); -\t|" "|\f|\v ; -"/*" comment(); -"//" slashslashcomment(); -. badchar(yytext[0]); - -%% - -static void -incline(void) -{ - curr_pos.p_line++; - curr_pos.p_uniq = 0; - if (curr_pos.p_file == csrc_pos.p_file) { - csrc_pos.p_line++; - csrc_pos.p_uniq = 0; - } -} - -static void -badchar(int c) -{ - - /* unknown character \%o */ - error(250, c); -} - -/* - * Keywords. - * During initialisation they are written to the symbol table. - */ -static struct kwtab { - const char *kw_name; /* keyword */ - int kw_token; /* token returned by yylex() */ - scl_t kw_scl; /* storage class if kw_token T_SCLASS */ - tspec_t kw_tspec; /* type spec. if kw_token T_TYPE or T_SOU */ - tqual_t kw_tqual; /* type qual. fi kw_token T_QUAL */ - u_int kw_c89; /* c89 keyword */ - u_int kw_c99; /* c99 keyword */ - u_int kw_gcc; /* GCC keyword */ -} kwtab[] = { - { "asm", T_ASM, 0, 0, 0, 0, 0, 1 }, - { "__asm", T_ASM, 0, 0, 0, 0, 0, 0 }, - { "__asm__", T_ASM, 0, 0, 0, 0, 0, 0 }, - { "auto", T_SCLASS, AUTO, 0, 0, 0, 0, 0 }, - { "break", T_BREAK, 0, 0, 0, 0, 0, 0 }, - { "case", T_CASE, 0, 0, 0, 0, 0, 0 }, - { "char", T_TYPE, 0, CHAR, 0, 0, 0, 0 }, - { "const", T_QUAL, 0, 0, CONST, 1, 0, 0 }, - { "__const__", T_QUAL, 0, 0, CONST, 0, 0, 0 }, - { "__const", T_QUAL, 0, 0, CONST, 0, 0, 0 }, - { "continue", T_CONTINUE, 0, 0, 0, 0, 0, 0 }, - { "default", T_DEFAULT, 0, 0, 0, 0, 0, 0 }, - { "do", T_DO, 0, 0, 0, 0, 0, 0 }, - { "double", T_TYPE, 0, DOUBLE, 0, 0, 0, 0 }, - { "else", T_ELSE, 0, 0, 0, 0, 0, 0 }, - { "enum", T_ENUM, 0, 0, 0, 0, 0, 0 }, - { "extern", T_SCLASS, EXTERN, 0, 0, 0, 0, 0 }, - { "float", T_TYPE, 0, FLOAT, 0, 0, 0, 0 }, - { "for", T_FOR, 0, 0, 0, 0, 0, 0 }, - { "goto", T_GOTO, 0, 0, 0, 0, 0, 0 }, - { "if", T_IF, 0, 0, 0, 0, 0, 0 }, - { "inline", T_SCLASS, INLINE, 0, 0, 0, 1, 0 }, - { "__inline__", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, - { "__inline", T_SCLASS, INLINE, 0, 0, 0, 0, 0 }, - { "int", T_TYPE, 0, INT, 0, 0, 0, 0 }, - { "__symbolrename", T_SYMBOLRENAME, 0, 0, 0, 0, 0, 0 }, - { "long", T_TYPE, 0, LONG, 0, 0, 0, 0 }, - { "register", T_SCLASS, REG, 0, 0, 0, 0, 0 }, - { "return", T_RETURN, 0, 0, 0, 0, 0, 0 }, - { "short", T_TYPE, 0, SHORT, 0, 0, 0, 0 }, - { "signed", T_TYPE, 0, SIGNED, 0, 1, 0, 0 }, - { "__signed__", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, - { "__signed", T_TYPE, 0, SIGNED, 0, 0, 0, 0 }, - { "sizeof", T_SIZEOF, 0, 0, 0, 0, 0, 0 }, - { "static", T_SCLASS, STATIC, 0, 0, 0, 0, 0 }, - { "struct", T_SOU, 0, STRUCT, 0, 0, 0, 0 }, - { "switch", T_SWITCH, 0, 0, 0, 0, 0, 0 }, - { "typedef", T_SCLASS, TYPEDEF, 0, 0, 0, 0, 0 }, - { "union", T_SOU, 0, UNION, 0, 0, 0, 0 }, - { "unsigned", T_TYPE, 0, UNSIGN, 0, 0, 0, 0 }, - { "void", T_TYPE, 0, VOID, 0, 0, 0, 0 }, - { "volatile", T_QUAL, 0, 0, VOLATILE, 1, 0, 0 }, - { "__volatile__", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, - { "__volatile", T_QUAL, 0, 0, VOLATILE, 0, 0, 0 }, - { "while", T_WHILE, 0, 0, 0, 0, 0, 0 }, - { NULL, 0, 0, 0, 0, 0, 0, 0 } -}; - -/* Symbol table */ -static sym_t *symtab[HSHSIZ1]; - -/* bit i of the entry with index i is set */ -uint64_t qbmasks[sizeof(uint64_t) * CHAR_BIT]; - -/* least significant i bits are set in the entry with index i */ -uint64_t qlmasks[sizeof(uint64_t) * CHAR_BIT + 1]; - -/* least significant i bits are not set in the entry with index i */ -uint64_t qumasks[sizeof(uint64_t) * CHAR_BIT + 1]; - -/* free list for sbuf structures */ -static sbuf_t *sbfrlst; - -/* type of next expected symbol */ -symt_t symtyp; - - -/* - * All keywords are written to the symbol table. This saves us looking - * in an extra table for each name we found. - */ -void -initscan(void) -{ - struct kwtab *kw; - sym_t *sym; - int h, i; - uint64_t uq; - - for (kw = kwtab; kw->kw_name != NULL; kw++) { - if ((kw->kw_c89 || kw->kw_c99) && tflag) - continue; - if (kw->kw_c99 && !(Sflag || gflag)) - continue; - if (kw->kw_gcc && !gflag) - continue; - sym = getblk(sizeof (sym_t)); - sym->s_name = kw->kw_name; - sym->s_keyw = 1; - sym->s_value.v_quad = kw->kw_token; - if (kw->kw_token == T_TYPE || kw->kw_token == T_SOU) { - sym->s_tspec = kw->kw_tspec; - } else if (kw->kw_token == T_SCLASS) { - sym->s_scl = kw->kw_scl; - } else if (kw->kw_token == T_QUAL) { - sym->s_tqual = kw->kw_tqual; - } - h = hash(sym->s_name); - if ((sym->s_link = symtab[h]) != NULL) - symtab[h]->s_rlink = &sym->s_link; - (symtab[h] = sym)->s_rlink = &symtab[h]; - } - - /* initialize bit-masks for quads */ - for (i = 0; i < sizeof (uint64_t) * CHAR_BIT; i++) { - qbmasks[i] = (uint64_t)1 << i; - uq = ~(uint64_t)0 << i; - qumasks[i] = uq; - qlmasks[i] = ~uq; - } - qumasks[i] = 0; - qlmasks[i] = ~(uint64_t)0; -} - -/* - * Get a free sbuf structure, if possible from the free list - */ -static sbuf_t * -allocsb(void) -{ - sbuf_t *sb; - - if ((sb = sbfrlst) != NULL) { - sbfrlst = sb->sb_nxt; - } else { - if ((sb = malloc(sizeof (sbuf_t))) == NULL) - nomem(); - } - (void)memset(sb, 0, sizeof (*sb)); - return (sb); -} - -/* - * Put a sbuf structure to the free list - */ -static void -freesb(sbuf_t *sb) -{ - - sb->sb_nxt = sbfrlst; - sbfrlst = sb; -} - -/* - * Read a character and ensure that it is positive (except EOF). - * Increment line count(s) if necessary. - */ -static int -inpc(void) -{ - int c; - - if ((c = input()) != EOF && (c &= CHAR_MASK) == '\n') - incline(); - return (c); -} - -static int -hash(const char *s) -{ - u_int v; - const u_char *us; - - v = 0; - for (us = (const u_char *)s; *us != '\0'; us++) { - v = (v << sizeof (v)) + *us; - v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v)); - } - return (v % HSHSIZ1); -} - -/* - * Lex has found a letter followed by zero or more letters or digits. - * It looks for a symbol in the symbol table with the same name. This - * symbol must either be a keyword or a symbol of the type required by - * symtyp (label, member, tag, ...). - * - * If it is a keyword, the token is returned. In some cases it is described - * more deeply by data written to yylval. - * - * If it is a symbol, T_NAME is returned and the pointer to a sbuf struct - * is stored in yylval. This struct contains the name of the symbol, it's - * length and hash value. If there is already a symbol of the same name - * and type in the symbol table, the sbuf struct also contains a pointer - * to the symbol table entry. - */ -static int -name(void) -{ - char *s; - sbuf_t *sb; - sym_t *sym; - int tok; - - sb = allocsb(); - sb->sb_name = yytext; - sb->sb_len = yyleng; - sb->sb_hash = hash(yytext); - - if ((sym = search(sb)) != NULL && sym->s_keyw) { - freesb(sb); - return (keyw(sym)); - } - - sb->sb_sym = sym; - - if (sym != NULL) { - if (blklev < sym->s_blklev) - LERROR("name()"); - sb->sb_name = sym->s_name; - sb->sb_len = strlen(sym->s_name); - tok = sym->s_scl == TYPEDEF ? T_TYPENAME : T_NAME; - } else { - s = getblk(yyleng + 1); - (void)memcpy(s, yytext, yyleng + 1); - sb->sb_name = s; - sb->sb_len = yyleng; - tok = T_NAME; - } - - yylval.y_sb = sb; - return (tok); -} - -static sym_t * -search(sbuf_t *sb) -{ - sym_t *sym; - - for (sym = symtab[sb->sb_hash]; sym != NULL; sym = sym->s_link) { - if (strcmp(sym->s_name, sb->sb_name) == 0) { - if (sym->s_keyw || sym->s_kind == symtyp) - return (sym); - } - } - - return (NULL); -} - -static int -keyw(sym_t *sym) -{ - int t; - - if ((t = (int)sym->s_value.v_quad) == T_SCLASS) { - yylval.y_scl = sym->s_scl; - } else if (t == T_TYPE || t == T_SOU) { - yylval.y_tspec = sym->s_tspec; - } else if (t == T_QUAL) { - yylval.y_tqual = sym->s_tqual; - } - return (t); -} - -/* - * Convert a string representing an integer into internal representation. - * The value is returned in yylval. icon() (and yylex()) returns T_CON. - */ -static int -icon(int base) -{ - int l_suffix, u_suffix; - int len; - const char *cp; - char c, *eptr; - tspec_t typ; - u_long ul = 0; - uint64_t uq = 0; - int ansiu; - static tspec_t contypes[2][3] = { - { INT, LONG, QUAD }, - { UINT, ULONG, UQUAD } - }; - - cp = yytext; - len = yyleng; - - /* skip 0x */ - if (base == 16) { - cp += 2; - len -= 2; - } - - /* read suffixes */ - l_suffix = u_suffix = 0; - for ( ; ; ) { - if ((c = cp[len - 1]) == 'l' || c == 'L') { - l_suffix++; - } else if (c == 'u' || c == 'U') { - u_suffix++; - } else { - break; - } - len--; - } - if (l_suffix > 2 || u_suffix > 1) { - /* malformed integer constant */ - warning(251); - if (l_suffix > 2) - l_suffix = 2; - if (u_suffix > 1) - u_suffix = 1; - } - if (tflag && u_suffix != 0) { - /* suffix U is illegal in traditional C */ - warning(97); - } - typ = contypes[u_suffix][l_suffix]; - - errno = 0; - if (l_suffix < 2) { - ul = strtoul(cp, &eptr, base); - } else { - uq = strtouq(cp, &eptr, base); - } - if (eptr != cp + len) - LERROR("icon()"); - if (errno != 0) - /* integer constant out of range */ - warning(252); - - /* - * If the value is too big for the current type, we must choose - * another type. - */ - ansiu = 0; - switch (typ) { - case INT: - if (ul <= INT_MAX) { - /* ok */ - } else if (ul <= (unsigned)UINT_MAX && base != 10) { - typ = UINT; -#if INT_MAX != LONG_MAX - } else if (ul <= LONG_MAX) { - typ = LONG; -#endif - } else { - typ = ULONG; - } - if (typ == UINT || typ == ULONG) { - if (tflag) { - typ = LONG; - } else if (!sflag) { - /* - * Remember that the constant is unsigned - * only in ANSI C - */ - ansiu = 1; - } - } - break; - case UINT: - if (ul > (u_int)UINT_MAX) - typ = ULONG; - break; - case LONG: - if (ul > LONG_MAX && !tflag) { - typ = ULONG; - if (!sflag) - ansiu = 1; - } - break; - case QUAD: - if (uq > QUAD_MAX && !tflag) { - typ = UQUAD; - if (!sflag) - ansiu = 1; - } - break; - /* LINTED (enumeration values not handled in switch) */ - case STRUCT: - case VOID: - case LDOUBLE: - case FUNC: - case ARRAY: - case PTR: - case ENUM: - case UNION: - case SIGNED: - case NOTSPEC: - case DOUBLE: - case FLOAT: - case UQUAD: - case ULONG: - case USHORT: - case SHORT: - case UCHAR: - case SCHAR: - case CHAR: - case UNSIGN: - break; - } - - if (typ != QUAD && typ != UQUAD) { - if (isutyp(typ)) { - uq = ul; - } else { - uq = (int64_t)(long)ul; - } - } - - uq = (uint64_t)xsign((int64_t)uq, typ, -1); - - if ((yylval.y_val = calloc(1, sizeof(val_t))) == NULL) - nomem(); - yylval.y_val->v_tspec = typ; - yylval.y_val->v_ansiu = ansiu; - yylval.y_val->v_quad = (int64_t)uq; - - return (T_CON); -} - -/* - * Returns 1 if t is a signed type and the value is negative. - * - * len is the number of significant bits. If len is -1, len is set - * to the width of type t. - */ -int -sign(int64_t q, tspec_t t, int len) -{ - - if (t == PTR || isutyp(t)) - return (0); - return (msb(q, t, len)); -} - -int -msb(int64_t q, tspec_t t, int len) -{ - - if (len <= 0) - len = size(t); - return ((q & qbmasks[len - 1]) != 0); -} - -/* - * Extends the sign of q. - */ -int64_t -xsign(int64_t q, tspec_t t, int len) -{ - - if (len <= 0) - len = size(t); - - if (t == PTR || isutyp(t) || !sign(q, t, len)) { - q &= qlmasks[len]; - } else { - q |= qumasks[len]; - } - return (q); -} - -/* - * Convert a string representing a floating point value into its interal - * representation. Type and value are returned in yylval. fcon() - * (and yylex()) returns T_CON. - * XXX Currently it is not possible to convert constants of type - * long double which are greater than DBL_MAX. - */ -static int -fcon(void) -{ - const char *cp; - int len; - tspec_t typ; - char c, *eptr; - double d; - float f = 0; - - cp = yytext; - len = yyleng; - - if ((c = cp[len - 1]) == 'f' || c == 'F') { - typ = FLOAT; - len--; - } else if (c == 'l' || c == 'L') { - typ = LDOUBLE; - len--; - } else { - typ = DOUBLE; - } - - if (tflag && typ != DOUBLE) { - /* suffixes F and L are illegal in traditional C */ - warning(98); - } - - errno = 0; - d = strtod(cp, &eptr); - if (eptr != cp + len) { - switch (*eptr) { - /* - * XXX: non-native non-current strtod() may not handle hex - * floats, ignore the rest if we find traces of hex float - * syntax... - */ - case 'p': - case 'P': - case 'x': - case 'X': - d = 0; - errno = 0; - break; - default: - LERROR("fcon()"); - } - } - if (errno != 0) - /* floating-point constant out of range */ - warning(248); - - if (typ == FLOAT) { - f = (float)d; - if (!finite(f)) { - /* floating-point constant out of range */ - warning(248); - f = f > 0 ? FLT_MAX : -FLT_MAX; - } - } - - if ((yylval.y_val = calloc(1, sizeof (val_t))) == NULL) - nomem(); - yylval.y_val->v_tspec = typ; - if (typ == FLOAT) { - yylval.y_val->v_ldbl = f; - } else { - yylval.y_val->v_ldbl = d; - } - - return (T_CON); -} - -static int -operator(int t, op_t o) -{ - - yylval.y_op = o; - return (t); -} - -/* - * Called if lex found a leading \'. - */ -static int -ccon(void) -{ - int n, val, c; - char cv; - - n = 0; - val = 0; - while ((c = getescc('\'')) >= 0) { - val = (val << CHAR_BIT) + c; - n++; - } - if (c == -2) { - /* unterminated character constant */ - error(253); - } else { - if (n > sizeof (int) || (n > 1 && (pflag || hflag))) { - /* too many characters in character constant */ - error(71); - } else if (n > 1) { - /* multi-character character constant */ - warning(294); - } else if (n == 0) { - /* empty character constant */ - error(73); - } - } - if (n == 1) { - cv = (char)val; - val = cv; - } - - yylval.y_val = xcalloc(1, sizeof (val_t)); - yylval.y_val->v_tspec = INT; - yylval.y_val->v_quad = val; - - return (T_CON); -} - -/* - * Called if lex found a leading L\' - */ -static int -wccon(void) -{ - static char buf[MB_LEN_MAX + 1]; - int i, c; - wchar_t wc; - - i = 0; - while ((c = getescc('\'')) >= 0) { - if (i < MB_CUR_MAX) - buf[i] = (char)c; - i++; - } - - wc = 0; - - if (c == -2) { - /* unterminated character constant */ - error(253); - } else if (c == 0) { - /* empty character constant */ - error(73); - } else { - if (i > MB_CUR_MAX) { - i = MB_CUR_MAX; - /* too many characters in character constant */ - error(71); - } else { - buf[i] = '\0'; - (void)mbtowc(NULL, NULL, 0); - if (mbtowc(&wc, buf, MB_CUR_MAX) < 0) - /* invalid multibyte character */ - error(291); - } - } - - if ((yylval.y_val = calloc(1, sizeof (val_t))) == NULL) - nomem(); - yylval.y_val->v_tspec = WCHAR; - yylval.y_val->v_quad = wc; - - return (T_CON); -} - -/* - * Read a character which is part of a character constant or of a string - * and handle escapes. - * - * The Argument is the character which delimits the character constant or - * string. - * - * Returns -1 if the end of the character constant or string is reached, - * -2 if the EOF is reached, and the character otherwise. - */ -static int -getescc(int d) -{ - static int pbc = -1; - int n, c, v; - - if (pbc == -1) { - c = inpc(); - } else { - c = pbc; - pbc = -1; - } - if (c == d) - return (-1); - switch (c) { - case '\n': - if (tflag) { - /* newline in string or char constant */ - error(254); - return (-2); - } - return (c); - case EOF: - return (-2); - case '\\': - switch (c = inpc()) { - case '"': - if (tflag && d == '\'') - /* \" inside character constant undef. ... */ - warning(262); - return ('"'); - case '\'': - return ('\''); - case '?': - if (tflag) - /* \? undefined in traditional C */ - warning(263); - return ('?'); - case '\\': - return ('\\'); - case 'a': - if (tflag) - /* \a undefined in traditional C */ - warning(81); - return ('\a'); - case 'b': - return ('\b'); - case 'f': - return ('\f'); - case 'n': - return ('\n'); - case 'r': - return ('\r'); - case 't': - return ('\t'); - case 'v': - if (tflag) - /* \v undefined in traditional C */ - warning(264); - return ('\v'); - case '8': case '9': - /* bad octal digit %c */ - warning(77, c); - /* FALLTHROUGH */ - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - n = 3; - v = 0; - do { - v = (v << 3) + (c - '0'); - c = inpc(); - } while (--n && isdigit(c) && (tflag || c <= '7')); - if (tflag && n > 0 && isdigit(c)) - /* bad octal digit %c */ - warning(77, c); - pbc = c; - if (v > UCHAR_MAX) { - /* character escape does not fit in char. */ - warning(76); - v &= CHAR_MASK; - } - return (v); - case 'x': - if (tflag) - /* \x undefined in traditional C */ - warning(82); - v = 0; - n = 0; - while ((c = inpc()) >= 0 && isxdigit(c)) { - c = isdigit(c) ? - c - '0' : toupper(c) - 'A' + 10; - v = (v << 4) + c; - if (n >= 0) { - if ((v & ~CHAR_MASK) != 0) { - /* overflow in hex escape */ - warning(75); - n = -1; - } else { - n++; - } - } - } - pbc = c; - if (n == 0) { - /* no hex digits follow \x */ - error(74); - } if (n == -1) { - v &= CHAR_MASK; - } - return (v); - case '\n': - return (getescc(d)); - case EOF: - return (-2); - default: - if (isprint(c)) { - /* dubious escape \%c */ - warning(79, c); - } else { - /* dubious escape \%o */ - warning(80, c); - } - } - } - return (c); -} - -/* - * Called for preprocessor directives. Currently implemented are: - * # lineno - * # lineno "filename" - */ -static void -directive(void) -{ - const char *cp, *fn; - char c, *eptr; - size_t fnl; - long ln; - static int first = 1; - - /* Go to first non-whitespace after # */ - for (cp = yytext + 1; (c = *cp) == ' ' || c == '\t'; cp++) - continue; - - if (!isdigit((unsigned char)c)) { - error: - /* undefined or invalid # directive */ - warning(255); - return; - } - ln = strtol(--cp, &eptr, 10); - if (cp == eptr) - goto error; - if ((c = *(cp = eptr)) != ' ' && c != '\t' && c != '\0') - goto error; - while ((c = *cp++) == ' ' || c == '\t') - continue; - if (c != '\0') { - if (c != '"') - goto error; - fn = cp; - while ((c = *cp) != '"' && c != '\0') - cp++; - if (c != '"') - goto error; - if ((fnl = cp++ - fn) > PATH_MAX) - goto error; - while ((c = *cp++) == ' ' || c == '\t') - continue; -#if 0 - if (c != '\0') - warning("extra character(s) after directive"); -#endif - - /* empty string means stdin */ - if (fnl == 0) { - fn = "{standard input}"; - fnl = 16; /* strlen (fn) */ - } - curr_pos.p_file = fnnalloc(fn, fnl); - /* - * If this is the first directive, the name is the name - * of the C source file as specified at the command line. - * It is written to the output file. - */ - if (first) { - csrc_pos.p_file = curr_pos.p_file; - outsrc(curr_pos.p_file); - first = 0; - } - } - curr_pos.p_line = (int)ln - 1; - curr_pos.p_uniq = 0; - if (curr_pos.p_file == csrc_pos.p_file) { - csrc_pos.p_line = (int)ln - 1; - csrc_pos.p_uniq = 0; - } -} - -/* - * Handle lint comments. Following comments are currently understood: - * ARGSUSEDn - * BITFIELDTYPE - * CONSTCOND CONSTANTCOND CONSTANTCONDITION - * FALLTHRU FALLTHROUGH - * LINTLIBRARY - * LINTED NOSTRICT - * LONGLONG - * NOTREACHED - * PRINTFLIKEn - * PROTOLIB - * SCANFLIKEn - * VARARGSn - * If one of this comments is recognized, the arguments, if any, are - * parsed and a function which handles this comment is called. - */ -static void -comment(void) -{ - int c, lc; - static struct { - const char *keywd; - int arg; - void (*func)(int); - } keywtab[] = { - { "ARGSUSED", 1, argsused }, - { "BITFIELDTYPE", 0, bitfieldtype }, - { "CONSTCOND", 0, constcond }, - { "CONSTANTCOND", 0, constcond }, - { "CONSTANTCONDITION", 0, constcond }, - { "FALLTHRU", 0, fallthru }, - { "FALLTHROUGH", 0, fallthru }, - { "LINTLIBRARY", 0, lintlib }, - { "LINTED", 0, linted }, - { "LONGLONG", 0, longlong }, - { "NOSTRICT", 0, linted }, - { "NOTREACHED", 0, notreach }, - { "PRINTFLIKE", 1, printflike }, - { "PROTOLIB", 1, protolib }, - { "SCANFLIKE", 1, scanflike }, - { "VARARGS", 1, varargs }, - }; - char keywd[32]; - char arg[32]; - int l, i, a; - int eoc; - - eoc = 0; - - /* Skip white spaces after the start of the comment */ - while ((c = inpc()) != EOF && isspace(c)) - continue; - - /* Read the potential keyword to keywd */ - l = 0; - while (c != EOF && isupper(c) && l < sizeof (keywd) - 1) { - keywd[l++] = (char)c; - c = inpc(); - } - keywd[l] = '\0'; - - /* look for the keyword */ - for (i = 0; i < sizeof (keywtab) / sizeof (keywtab[0]); i++) { - if (strcmp(keywtab[i].keywd, keywd) == 0) - break; - } - if (i == sizeof (keywtab) / sizeof (keywtab[0])) - goto skip_rest; - - /* skip white spaces after the keyword */ - while (c != EOF && isspace(c)) - c = inpc(); - - /* read the argument, if the keyword accepts one and there is one */ - l = 0; - if (keywtab[i].arg) { - while (c != EOF && isdigit(c) && l < sizeof (arg) - 1) { - arg[l++] = (char)c; - c = inpc(); - } - } - arg[l] = '\0'; - a = l != 0 ? atoi(arg) : -1; - - /* skip white spaces after the argument */ - while (c != EOF && isspace(c)) - c = inpc(); - - if (c != '*' || (c = inpc()) != '/') { - if (keywtab[i].func != linted) - /* extra characters in lint comment */ - warning(257); - } else { - /* - * remember that we have already found the end of the - * comment - */ - eoc = 1; - } - - if (keywtab[i].func != NULL) - (*keywtab[i].func)(a); - - skip_rest: - while (!eoc) { - lc = c; - if ((c = inpc()) == EOF) { - /* unterminated comment */ - error(256); - break; - } - if (lc == '*' && c == '/') - eoc = 1; - } -} - -/* - * Handle // style comments - */ -static void -slashslashcomment(void) -{ - int c; - - if (!Sflag && !gflag) - /* // comments only supported in C99 */ - (void)gnuism(312, tflag ? "traditional" : "ANSI"); - - while ((c = inpc()) != EOF && c != '\n') - continue; -} - -/* - * Clear flags for lint comments LINTED, LONGLONG and CONSTCOND. - * clrwflgs() is called after function definitions and global and - * local declarations and definitions. It is also called between - * the controlling expression and the body of control statements - * (if, switch, for, while). - */ -void -clrwflgs(void) -{ - - nowarn = 0; - quadflg = 0; - ccflg = 0; -} - -/* - * Strings are stored in a dynamically alloceted buffer and passed - * in yylval.y_xstrg to the parser. The parser or the routines called - * by the parser are responsible for freeing this buffer. - */ -static int -string(void) -{ - u_char *s; - int c; - size_t len, max; - strg_t *strg; - - if ((s = malloc(max = 64)) == NULL) - nomem(); - - len = 0; - while ((c = getescc('"')) >= 0) { - /* +1 to reserve space for a trailing NUL character */ - if (len + 1 == max) - if ((s = realloc(s, max *= 2)) == NULL) - nomem(); - s[len++] = (char)c; - } - s[len] = '\0'; - if (c == -2) - /* unterminated string constant */ - error(258); - - if ((strg = calloc(1, sizeof (strg_t))) == NULL) - nomem(); - strg->st_tspec = CHAR; - strg->st_len = len; - strg->st_cp = s; - - yylval.y_strg = strg; - return (T_STRING); -} - -static int -wcstrg(void) -{ - char *s; - int c, i, n, wi; - size_t len, max, wlen; - wchar_t *ws; - strg_t *strg; - - if ((s = malloc(max = 64)) == NULL) - nomem(); - len = 0; - while ((c = getescc('"')) >= 0) { - /* +1 to save space for a trailing NUL character */ - if (len + 1 >= max) - if ((s = realloc(s, max *= 2)) == NULL) - nomem(); - s[len++] = (char)c; - } - s[len] = '\0'; - if (c == -2) - /* unterminated string constant */ - error(258); - - /* get length of wide character string */ - (void)mblen(NULL, 0); - for (i = 0, wlen = 0; i < len; i += n, wlen++) { - if ((n = mblen(&s[i], MB_CUR_MAX)) == -1) { - /* invalid multibyte character */ - error(291); - break; - } - if (n == 0) - n = 1; - } - - if ((ws = malloc((wlen + 1) * sizeof (wchar_t))) == NULL) - nomem(); - - /* convert from multibyte to wide char */ - (void)mbtowc(NULL, NULL, 0); - for (i = 0, wi = 0; i < len; i += n, wi++) { - if ((n = mbtowc(&ws[wi], &s[i], MB_CUR_MAX)) == -1) - break; - if (n == 0) - n = 1; - } - ws[wi] = 0; - free(s); - - if ((strg = calloc(1, sizeof (strg_t))) == NULL) - nomem(); - strg->st_tspec = WCHAR; - strg->st_len = wlen; - strg->st_wcp = ws; - - yylval.y_strg = strg; - return (T_STRING); -} - -/* - * As noted above the scanner does not create new symbol table entries - * for symbols it cannot find in the symbol table. This is to avoid - * putting undeclared symbols into the symbol table if a syntax error - * occurs. - * - * getsym() is called as soon as it is probably ok to put the symbol to - * the symbol table. This does not mean that it is not possible that - * symbols are put to the symbol table which are than not completely - * declared due to syntax errors. To avoid too many problems in this - * case symbols get type int in getsym(). - * - * XXX calls to getsym() should be delayed until decl1*() is called - */ -sym_t * -getsym(sbuf_t *sb) -{ - dinfo_t *di; - char *s; - sym_t *sym; - - sym = sb->sb_sym; - - /* - * During member declaration it is possible that name() looked - * for symbols of type FVFT, although it should have looked for - * symbols of type FTAG. Same can happen for labels. Both cases - * are compensated here. - */ - if (symtyp == FMOS || symtyp == FLAB) { - if (sym == NULL || sym->s_kind == FVFT) - sym = search(sb); - } - - if (sym != NULL) { - if (sym->s_kind != symtyp) - LERROR("storesym()"); - symtyp = FVFT; - freesb(sb); - return (sym); - } - - /* create a new symbol table entry */ - - /* labels must always be allocated at level 1 (outhermost block) */ - if (symtyp == FLAB) { - sym = getlblk(1, sizeof (sym_t)); - s = getlblk(1, sb->sb_len + 1); - (void)memcpy(s, sb->sb_name, sb->sb_len + 1); - sym->s_name = s; - sym->s_blklev = 1; - di = dcs; - while (di->d_nxt != NULL && di->d_nxt->d_nxt != NULL) - di = di->d_nxt; - if (di->d_ctx != AUTO) - LERROR("storesym()"); - } else { - sym = getblk(sizeof (sym_t)); - sym->s_name = sb->sb_name; - sym->s_blklev = blklev; - di = dcs; - } - - UNIQUE_CURR_POS(sym->s_dpos); - if ((sym->s_kind = symtyp) != FLAB) - sym->s_type = gettyp(INT); - - symtyp = FVFT; - - if ((sym->s_link = symtab[sb->sb_hash]) != NULL) - symtab[sb->sb_hash]->s_rlink = &sym->s_link; - (symtab[sb->sb_hash] = sym)->s_rlink = &symtab[sb->sb_hash]; - - *di->d_ldlsym = sym; - di->d_ldlsym = &sym->s_dlnxt; - - freesb(sb); - return (sym); -} - -/* - * Construct a temporary symbol. The symbol starts with a digit, so that - * it is illegal. - */ -sym_t * -mktempsym(type_t *t) -{ - static int n = 0; - int h; - char *s = getlblk(blklev, 64); - sym_t *sym = getblk(sizeof (sym_t)); - - (void)snprintf(s, 64, "%.8d_tmp", n++); - h = hash(s); - - sym->s_name = s; - sym->s_type = t; - sym->s_blklev = blklev; - sym->s_scl = AUTO; - sym->s_kind = FVFT; - sym->s_used = 1; - sym->s_set = 1; - - if ((sym->s_link = symtab[h]) != NULL) - symtab[h]->s_rlink = &sym->s_link; - (symtab[h] = sym)->s_rlink = &symtab[h]; - - *dcs->d_ldlsym = sym; - dcs->d_ldlsym = &sym->s_dlnxt; - - return sym; -} - -/* - * Remove a symbol forever from the symbol table. s_blklev - * is set to -1 to avoid that the symbol will later be put - * back to the symbol table. - */ -void -rmsym(sym_t *sym) -{ - - if ((*sym->s_rlink = sym->s_link) != NULL) - sym->s_link->s_rlink = sym->s_rlink; - sym->s_blklev = -1; - sym->s_link = NULL; -} - -/* - * Remove a list of symbols declared at one level from the symbol - * table. - */ -void -rmsyms(sym_t *syms) -{ - sym_t *sym; - - for (sym = syms; sym != NULL; sym = sym->s_dlnxt) { - if (sym->s_blklev != -1) { - if ((*sym->s_rlink = sym->s_link) != NULL) - sym->s_link->s_rlink = sym->s_rlink; - sym->s_link = NULL; - sym->s_rlink = NULL; - } - } -} - -/* - * Put a symbol into the symbol table - */ -void -inssym(int bl, sym_t *sym) -{ - int h; - - h = hash(sym->s_name); - if ((sym->s_link = symtab[h]) != NULL) - symtab[h]->s_rlink = &sym->s_link; - (symtab[h] = sym)->s_rlink = &symtab[h]; - sym->s_blklev = bl; - if (sym->s_link != NULL && sym->s_blklev < sym->s_link->s_blklev) - LERROR("inssym()"); -} - -/* - * Called at level 0 after syntax errors - * Removes all symbols which are not declared at level 0 from the - * symbol table. Also frees all memory which is not associated with - * level 0. - */ -void -cleanup(void) -{ - sym_t *sym, *nsym; - int i; - - for (i = 0; i < HSHSIZ1; i++) { - for (sym = symtab[i]; sym != NULL; sym = nsym) { - nsym = sym->s_link; - if (sym->s_blklev >= 1) { - if ((*sym->s_rlink = nsym) != NULL) - nsym->s_rlink = sym->s_rlink; - } - } - } - - for (i = mblklev; i > 0; i--) - freelblk(i); -} - -/* - * Create a new symbol with the name of an existing symbol. - */ -sym_t * -pushdown(sym_t *sym) -{ - int h; - sym_t *nsym; - - h = hash(sym->s_name); - nsym = getblk(sizeof (sym_t)); - if (sym->s_blklev > blklev) - LERROR("pushdown()"); - nsym->s_name = sym->s_name; - UNIQUE_CURR_POS(nsym->s_dpos); - nsym->s_kind = sym->s_kind; - nsym->s_blklev = blklev; - - if ((nsym->s_link = symtab[h]) != NULL) - symtab[h]->s_rlink = &nsym->s_link; - (symtab[h] = nsym)->s_rlink = &symtab[h]; - - *dcs->d_ldlsym = nsym; - dcs->d_ldlsym = &nsym->s_dlnxt; - - return (nsym); -} - -/* - * Free any dynamically allocated memory referenced by - * the value stack or yylval. - * The type of information in yylval is described by tok. - */ -void -freeyyv(void *sp, int tok) -{ - if (tok == T_NAME || tok == T_TYPENAME) { - sbuf_t *sb = *(sbuf_t **)sp; - freesb(sb); - } else if (tok == T_CON) { - val_t *val = *(val_t **)sp; - free(val); - } else if (tok == T_STRING) { - strg_t *strg = *(strg_t **)sp; - if (strg->st_tspec == CHAR) { - free(strg->st_cp); - } else if (strg->st_tspec == WCHAR) { - free(strg->st_wcp); - } else { - LERROR("fryylv()"); - } - free(strg); - } -} Index: usr.bin/xlint/lint1/tree.c =================================================================== --- usr.bin/xlint/lint1/tree.c +++ /dev/null @@ -1,4040 +0,0 @@ -/* $NetBSD: tree.c,v 1.45 2008/03/04 02:41:46 christos Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: tree.c,v 1.45 2008/03/04 02:41:46 christos Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include "lint1.h" -#include "cgram.h" - -/* Various flags for each operator. */ -static mod_t modtab[NOPS]; - -static tnode_t *getinode(tspec_t, int64_t); -static void ptrcmpok(op_t, tnode_t *, tnode_t *); -static int asgntypok(op_t, int, tnode_t *, tnode_t *); -static void chkbeop(op_t, tnode_t *, tnode_t *); -static void chkeop2(op_t, int, tnode_t *, tnode_t *); -static void chkeop1(op_t, int, tnode_t *, tnode_t *); -static tnode_t *mktnode(op_t, type_t *, tnode_t *, tnode_t *); -static void balance(op_t, tnode_t **, tnode_t **); -static void incompat(op_t, tspec_t, tspec_t); -static void illptrc(mod_t *, type_t *, type_t *); -static void mrgqual(type_t **, type_t *, type_t *); -static int conmemb(type_t *); -static void ptconv(int, tspec_t, tspec_t, type_t *, tnode_t *); -static void iiconv(op_t, int, tspec_t, tspec_t, type_t *, tnode_t *); -static void piconv(op_t, tspec_t, type_t *, tnode_t *); -static void ppconv(op_t, tnode_t *, type_t *); -static tnode_t *bldstr(op_t, tnode_t *, tnode_t *); -static tnode_t *bldincdec(op_t, tnode_t *); -static tnode_t *bldamper(tnode_t *, int); -static tnode_t *bldplmi(op_t, tnode_t *, tnode_t *); -static tnode_t *bldshft(op_t, tnode_t *, tnode_t *); -static tnode_t *bldcol(tnode_t *, tnode_t *); -static tnode_t *bldasgn(op_t, tnode_t *, tnode_t *); -static tnode_t *plength(type_t *); -static tnode_t *fold(tnode_t *); -static tnode_t *foldtst(tnode_t *); -static tnode_t *foldflt(tnode_t *); -static tnode_t *chkfarg(type_t *, tnode_t *); -static tnode_t *parg(int, type_t *, tnode_t *); -static void nulleff(tnode_t *); -static void displexpr(tnode_t *, int); -static void chkaidx(tnode_t *, int); -static void chkcomp(op_t, tnode_t *, tnode_t *); -static void precconf(tnode_t *); - -/* - * Initialize mods of operators. - */ -void -initmtab(void) -{ - static struct { - op_t op; - mod_t m; - } imods[] = { - { ARROW, { 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - "->" } }, - { POINT, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - "." } }, - { NOT, { 0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,1,0, - "!" } }, - { COMPL, { 0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,1,1, - "~" } }, - { INCBEF, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, - "prefix++" } }, - { DECBEF, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, - "prefix--" } }, - { INCAFT, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, - "postfix++" } }, - { DECAFT, { 0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, - "postfix--" } }, - { UPLUS, { 0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1, - "unary +" } }, - { UMINUS, { 0,0,0,0,1,1,1,0,0,0,1,0,0,0,0,1,1, - "unary -" } }, - { STAR, { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - "unary *" } }, - { AMPER, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - "unary &" } }, - { MULT, { 1,0,0,0,1,1,1,0,1,0,0,1,0,0,0,1,1, - "*" } }, - { DIV, { 1,0,0,0,1,1,1,0,1,0,1,1,0,0,0,1,1, - "/" } }, - { MOD, { 1,0,1,0,0,1,1,0,1,0,1,1,0,0,0,1,1, - "%" } }, - { PLUS, { 1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0, - "+" } }, - { MINUS, { 1,0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0, - "-" } }, - { SHL, { 1,0,1,0,0,1,1,0,0,0,0,0,1,0,0,1,1, - "<<" } }, - { SHR, { 1,0,1,0,0,1,1,0,0,0,1,0,1,0,0,1,1, - ">>" } }, - { LT, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1, - "<" } }, - { LE, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1, - "<=" } }, - { GT, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1, - ">" } }, - { GE, { 1,1,0,1,0,1,1,0,1,0,1,1,0,1,1,0,1, - ">=" } }, - { EQ, { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,1, - "==" } }, - { NE, { 1,1,0,1,0,1,1,0,1,0,0,0,0,1,1,0,1, - "!=" } }, - { AND, { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0, - "&" } }, - { XOR, { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0, - "^" } }, - { OR, { 1,0,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0, - "|" } }, - { LOGAND, { 1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,1,0, - "&&" } }, - { LOGOR, { 1,1,0,1,0,1,0,1,0,0,0,0,1,0,0,1,0, - "||" } }, - { QUEST, { 1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, - "?" } }, - { COLON, { 1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0, - ":" } }, - { ASSIGN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, - "=" } }, - { MULASS, { 1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0, - "*=" } }, - { DIVASS, { 1,0,0,0,1,0,0,0,0,1,0,1,0,0,0,1,0, - "/=" } }, - { MODASS, { 1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0, - "%=" } }, - { ADDASS, { 1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, - "+=" } }, - { SUBASS, { 1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0, - "-=" } }, - { SHLASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0, - "<<=" } }, - { SHRASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0, - ">>=" } }, - { ANDASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0, - "&=" } }, - { XORASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0, - "^=" } }, - { ORASS, { 1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0, - "|=" } }, - { NAME, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - "NAME" } }, - { CON, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - "CON" } }, - { STRING, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - "STRING" } }, - { FSEL, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - "FSEL" } }, - { CALL, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - "CALL" } }, - { COMMA, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, - "," } }, - { CVT, { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - "CVT" } }, - { ICALL, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, - "ICALL" } }, - { LOAD, { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - "LOAD" } }, - { PUSH, { 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, - "PUSH" } }, - { RETURN, { 1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, - "RETURN" } }, - { INIT, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - "INIT" } }, - { FARG, { 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, - "FARG" } }, - { NOOP } - }; - int i; - - for (i = 0; imods[i].op != NOOP; i++) - STRUCT_ASSIGN(modtab[imods[i].op], imods[i].m); -} - -/* - * Increase degree of reference. - * This is most often used to change type "T" in type "pointer to T". - */ -type_t * -incref(type_t *tp, tspec_t t) -{ - type_t *tp2; - - tp2 = getblk(sizeof (type_t)); - tp2->t_tspec = t; - tp2->t_subt = tp; - return (tp2); -} - -/* - * same for use in expressions - */ -type_t * -tincref(type_t *tp, tspec_t t) -{ - type_t *tp2; - - tp2 = tgetblk(sizeof (type_t)); - tp2->t_tspec = t; - tp2->t_subt = tp; - return (tp2); -} - -/* - * Create a node for a constant. - */ -tnode_t * -getcnode(type_t *tp, val_t *v) -{ - tnode_t *n; - - n = getnode(); - n->tn_op = CON; - n->tn_type = tp; - n->tn_val = tgetblk(sizeof (val_t)); - n->tn_val->v_tspec = tp->t_tspec; - n->tn_val->v_ansiu = v->v_ansiu; - n->tn_val->v_u = v->v_u; - free(v); - return (n); -} - -/* - * Create a node for an integer constant. - */ -static tnode_t * -getinode(tspec_t t, int64_t q) -{ - tnode_t *n; - - n = getnode(); - n->tn_op = CON; - n->tn_type = gettyp(t); - n->tn_val = tgetblk(sizeof (val_t)); - n->tn_val->v_tspec = t; - n->tn_val->v_quad = q; - return (n); -} - -/* - * Create a node for a name (symbol table entry). - * ntok is the token which follows the name. - */ -tnode_t * -getnnode(sym_t *sym, int ntok) -{ - tnode_t *n; - - if (sym->s_scl == NOSCL) { - sym->s_scl = EXTERN; - sym->s_def = DECL; - if (ntok == T_LPARN) { - if (sflag) { - /* function implicitly declared to ... */ - warning(215); - } - /* - * XXX if tflag is set the symbol should be - * exported to level 0 - */ - sym->s_type = incref(sym->s_type, FUNC); - } else { - if (!blklev) { - /* %s undefined */ - error(99, sym->s_name); - } else { - int fixtype; - if (strcmp(sym->s_name, "__FUNCTION__") == 0) { - gnuism(316); - fixtype = 1; - } else if (strcmp(sym->s_name, "__func__") == 0) { - if (!Sflag) - warning(317); - fixtype = 1; - } else { - error(99, sym->s_name); - fixtype = 0; - } - if (fixtype) { - sym->s_type = incref(gettyp(CHAR), PTR); - sym->s_type->t_const = 1; - } - } - } - } - - if (sym->s_kind != FVFT && sym->s_kind != FMOS) - LERROR("getnnode()"); - - n = getnode(); - n->tn_type = sym->s_type; - if (sym->s_scl != ENUMCON) { - n->tn_op = NAME; - n->tn_sym = sym; - if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) - n->tn_lvalue = 1; - } else { - n->tn_op = CON; - n->tn_val = tgetblk(sizeof (val_t)); - *n->tn_val = sym->s_value; - } - - return (n); -} - -/* - * Create a node for a string. - */ -tnode_t * -getsnode(strg_t *strg) -{ - size_t len; - tnode_t *n; - - len = strg->st_len; - - n = getnode(); - - n->tn_op = STRING; - n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY); - n->tn_type->t_dim = len + 1; - n->tn_lvalue = 1; - - n->tn_strg = tgetblk(sizeof (strg_t)); - n->tn_strg->st_tspec = strg->st_tspec; - n->tn_strg->st_len = len; - - if (strg->st_tspec == CHAR) { - n->tn_strg->st_cp = tgetblk(len + 1); - (void)memcpy(n->tn_strg->st_cp, strg->st_cp, len + 1); - free(strg->st_cp); - } else { - n->tn_strg->st_wcp = tgetblk((len + 1) * sizeof (wchar_t)); - (void)memcpy(n->tn_strg->st_wcp, strg->st_wcp, - (len + 1) * sizeof (wchar_t)); - free(strg->st_wcp); - } - free(strg); - - return (n); -} - -/* - * Returns a symbol which has the same name as the msym argument and is a - * member of the struct or union specified by the tn argument. - */ -sym_t * -strmemb(tnode_t *tn, op_t op, sym_t *msym) -{ - str_t *str; - type_t *tp; - sym_t *sym, *csym; - int eq; - tspec_t t; - - /* - * Remove the member if it was unknown until now (Which means - * that no defined struct or union has a member with the same name). - */ - if (msym->s_scl == NOSCL) { - /* undefined struct/union member: %s */ - fprintf(stderr, "3. %s\n", msym->s_name); - error(101, msym->s_name); - rmsym(msym); - msym->s_kind = FMOS; - msym->s_scl = MOS; - msym->s_styp = tgetblk(sizeof (str_t)); - msym->s_styp->stag = tgetblk(sizeof (sym_t)); - msym->s_styp->stag->s_name = unnamed; - msym->s_value.v_tspec = INT; - return (msym); - } - - /* Set str to the tag of which msym is expected to be a member. */ - str = NULL; - t = (tp = tn->tn_type)->t_tspec; - if (op == POINT) { - if (t == STRUCT || t == UNION) - str = tp->t_str; - } else if (op == ARROW && t == PTR) { - t = (tp = tp->t_subt)->t_tspec; - if (t == STRUCT || t == UNION) - str = tp->t_str; - } - - /* - * If this struct/union has a member with the name of msym, return - * return this it. - */ - if (str != NULL) { - for (sym = msym; sym != NULL; sym = sym->s_link) { - if (sym->s_scl != MOS && sym->s_scl != MOU) - continue; - if (sym->s_styp != str) - continue; - if (strcmp(sym->s_name, msym->s_name) != 0) - continue; - return (sym); - } - } - - /* - * Set eq to 0 if there are struct/union members with the same name - * and different types and/or offsets. - */ - eq = 1; - for (csym = msym; csym != NULL; csym = csym->s_link) { - if (csym->s_scl != MOS && csym->s_scl != MOU) - continue; - if (strcmp(msym->s_name, csym->s_name) != 0) - continue; - for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) { - int w; - - if (sym->s_scl != MOS && sym->s_scl != MOU) - continue; - if (strcmp(csym->s_name, sym->s_name) != 0) - continue; - if (csym->s_value.v_quad != sym->s_value.v_quad) { - eq = 0; - break; - } - w = 0; - eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w; - if (!eq) - break; - if (csym->s_field != sym->s_field) { - eq = 0; - break; - } - if (csym->s_field) { - type_t *tp1, *tp2; - - tp1 = csym->s_type; - tp2 = sym->s_type; - if (tp1->t_flen != tp2->t_flen) { - eq = 0; - break; - } - if (tp1->t_foffs != tp2->t_foffs) { - eq = 0; - break; - } - } - } - if (!eq) - break; - } - - /* - * Now handle the case in which the left operand refers really - * to a struct/union, but the right operand is not member of it. - */ - if (str != NULL) { - /* illegal member use: %s */ - if (eq && tflag) { - warning(102, msym->s_name); - } else { - error(102, msym->s_name); - } - return (msym); - } - - /* - * Now the left operand of ARROW does not point to a struct/union - * or the left operand of POINT is no struct/union. - */ - if (eq) { - if (op == POINT) { - /* left operand of "." must be struct/union object */ - if (tflag) { - warning(103); - } else { - error(103); - } - } else { - /* left operand of "->" must be pointer to ... */ - if (tflag && tn->tn_type->t_tspec == PTR) { - warning(104); - } else { - error(104); - } - } - } else { - if (tflag) { - /* non-unique member requires struct/union %s */ - error(105, op == POINT ? "object" : "pointer"); - } else { - /* unacceptable operand of %s */ - error(111, modtab[op].m_name); - } - } - - return (msym); -} - -/* - * Create a tree node. Called for most operands except function calls, - * sizeof and casts. - * - * op operator - * ln left operand - * rn if not NULL, right operand - */ -tnode_t * -build(op_t op, tnode_t *ln, tnode_t *rn) -{ - mod_t *mp; - tnode_t *ntn; - type_t *rtp; - - mp = &modtab[op]; - - /* If there was an error in one of the operands, return. */ - if (ln == NULL || (mp->m_binary && rn == NULL)) - return (NULL); - - /* - * Apply class conversions to the left operand, but only if its - * value is needed or it is compared with null. - */ - if (mp->m_vctx || mp->m_tctx) - ln = cconv(ln); - /* - * The right operand is almost always in a test or value context, - * except if it is a struct or union member. - */ - if (mp->m_binary && op != ARROW && op != POINT) - rn = cconv(rn); - - /* - * Print some warnings for comparisons of unsigned values with - * constants lower than or equal to null. This must be done - * before promote() because otherwise unsigned char and unsigned - * short would be promoted to int. Also types are tested to be - * CHAR, which would also become int. - */ - if (mp->m_comp) - chkcomp(op, ln, rn); - - /* - * Promote the left operand if it is in a test or value context - */ - if (mp->m_vctx || mp->m_tctx) - ln = promote(op, 0, ln); - /* - * Promote the right operand, but only if it is no struct or - * union member, or if it is not to be assigned to the left operand - */ - if (mp->m_binary && op != ARROW && op != POINT && - op != ASSIGN && op != RETURN) { - rn = promote(op, 0, rn); - } - - /* - * If the result of the operation is different for signed or - * unsigned operands and one of the operands is signed only in - * ANSI C, print a warning. - */ - if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) { - /* ANSI C treats constant as unsigned, op %s */ - warning(218, mp->m_name); - ln->tn_val->v_ansiu = 0; - } - if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) { - /* ANSI C treats constant as unsigned, op %s */ - warning(218, mp->m_name); - rn->tn_val->v_ansiu = 0; - } - - /* Make sure both operands are of the same type */ - if (mp->m_balance || (tflag && (op == SHL || op == SHR))) - balance(op, &ln, &rn); - - /* - * Check types for compatibility with the operation and mutual - * compatibility. Return if there are serious problems. - */ - if (!typeok(op, 0, ln, rn)) - return (NULL); - - /* And now create the node. */ - switch (op) { - case POINT: - case ARROW: - ntn = bldstr(op, ln, rn); - break; - case INCAFT: - case DECAFT: - case INCBEF: - case DECBEF: - ntn = bldincdec(op, ln); - break; - case AMPER: - ntn = bldamper(ln, 0); - break; - case STAR: - ntn = mktnode(STAR, ln->tn_type->t_subt, ln, NULL); - break; - case PLUS: - case MINUS: - ntn = bldplmi(op, ln, rn); - break; - case SHL: - case SHR: - ntn = bldshft(op, ln, rn); - break; - case COLON: - ntn = bldcol(ln, rn); - break; - case ASSIGN: - case MULASS: - case DIVASS: - case MODASS: - case ADDASS: - case SUBASS: - case SHLASS: - case SHRASS: - case ANDASS: - case XORASS: - case ORASS: - case RETURN: - ntn = bldasgn(op, ln, rn); - break; - case COMMA: - case QUEST: - ntn = mktnode(op, rn->tn_type, ln, rn); - break; - default: - rtp = mp->m_logop ? gettyp(INT) : ln->tn_type; - if (!mp->m_binary && rn != NULL) - LERROR("build()"); - ntn = mktnode(op, rtp, ln, rn); - break; - } - - /* Return if an error occurred. */ - if (ntn == NULL) - return (NULL); - - /* Print a warning if precedence confusion is possible */ - if (mp->m_tpconf) - precconf(ntn); - - /* - * Print a warning if one of the operands is in a context where - * it is compared with null and if this operand is a constant. - */ - if (mp->m_tctx) { - if (ln->tn_op == CON || - ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { - if (hflag && !ccflg) - /* constant in conditional context */ - warning(161); - } - } - - /* Fold if the operator requires it */ - if (mp->m_fold) { - if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { - if (mp->m_tctx) { - ntn = foldtst(ntn); - } else if (isftyp(ntn->tn_type->t_tspec)) { - ntn = foldflt(ntn); - } else { - ntn = fold(ntn); - } - } else if (op == QUEST && ln->tn_op == CON) { - ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right; - } - } - - return (ntn); -} - -/* - * Perform class conversions. - * - * Arrays of type T are converted into pointers to type T. - * Functions are converted to pointers to functions. - * Lvalues are converted to rvalues. - */ -tnode_t * -cconv(tnode_t *tn) -{ - type_t *tp; - - /* - * Array-lvalue (array of type T) is converted into rvalue - * (pointer to type T) - */ - if (tn->tn_type->t_tspec == ARRAY) { - if (!tn->tn_lvalue) { - /* operand of '%s' must be lvalue */ - /* XXX print correct operator */ - (void)gnuism(114, "", modtab[AMPER].m_name); - } - tn = mktnode(AMPER, tincref(tn->tn_type->t_subt, PTR), - tn, NULL); - } - - /* - * Expression of type function (function with return value of type T) - * in rvalue-expression (pointer to function with return value - * of type T) - */ - if (tn->tn_type->t_tspec == FUNC) - tn = bldamper(tn, 1); - - /* lvalue to rvalue */ - if (tn->tn_lvalue) { - tp = tduptyp(tn->tn_type); - tp->t_const = tp->t_volatile = 0; - tn = mktnode(LOAD, tp, tn, NULL); - } - - return (tn); -} - -/* - * Perform most type checks. First the types are checked using - * information from modtab[]. After that it is done by hand for - * more complicated operators and type combinations. - * - * If the types are ok, typeok() returns 1, otherwise 0. - */ -int -typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) -{ - mod_t *mp; - tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC, olt = NOTSPEC, - ort = NOTSPEC; - type_t *ltp, *rtp = NULL, *lstp = NULL, *rstp = NULL; - tnode_t *tn; - - mp = &modtab[op]; - - if ((ltp = ln->tn_type) == NULL) - LERROR("typeok()"); - - if ((lt = ltp->t_tspec) == PTR) - lst = (lstp = ltp->t_subt)->t_tspec; - if (mp->m_binary) { - if ((rtp = rn->tn_type) == NULL) - LERROR("typeok()"); - if ((rt = rtp->t_tspec) == PTR) - rst = (rstp = rtp->t_subt)->t_tspec; - } - - if (mp->m_rqint) { - /* integer types required */ - if (!isityp(lt) || (mp->m_binary && !isityp(rt))) { - incompat(op, lt, rt); - return (0); - } - } else if (mp->m_rqsclt) { - /* scalar types required */ - if (!issclt(lt) || (mp->m_binary && !issclt(rt))) { - incompat(op, lt, rt); - return (0); - } - } else if (mp->m_rqatyp) { - /* arithmetic types required */ - if (!isatyp(lt) || (mp->m_binary && !isatyp(rt))) { - incompat(op, lt, rt); - return (0); - } - } - - if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) { - /* - * For these operations we need the types before promotion - * and balancing. - */ - for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) - continue; - olt = tn->tn_type->t_tspec; - for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) - continue; - ort = tn->tn_type->t_tspec; - } - - switch (op) { - case POINT: - /* - * Most errors required by ANSI C are reported in strmemb(). - * Here we only must check for totally wrong things. - */ - if (lt == FUNC || lt == VOID || ltp->t_isfield || - ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) { - /* Without tflag we already got an error */ - if (tflag) - /* unacceptable operand of %s */ - error(111, mp->m_name); - return (0); - } - /* Now we have an object we can create a pointer to */ - break; - case ARROW: - if (lt != PTR && !(tflag && isityp(lt))) { - /* Without tflag we got already an error */ - if (tflag) - /* unacceptable operand of %s */ - error(111, mp->m_name); - return (0); - } - break; - case INCAFT: - case DECAFT: - case INCBEF: - case DECBEF: - /* operands have scalar types (checked above) */ - if (!ln->tn_lvalue) { - if (ln->tn_op == CVT && ln->tn_cast && - ln->tn_left->tn_op == LOAD) { - /* a cast does not yield an lvalue */ - error(163); - } - /* operand of %s must be lvalue */ - error(114, "", mp->m_name); - return (0); - } else if (ltp->t_const) { - /* operand of %s must be modifiable lvalue */ - if (!tflag) - warning(115, "", mp->m_name); - } - break; - case AMPER: - if (lt == ARRAY || lt == FUNC) { - /* ok, a warning comes later (in bldamper()) */ - } else if (!ln->tn_lvalue) { - if (ln->tn_op == CVT && ln->tn_cast && - ln->tn_left->tn_op == LOAD) { - /* a cast does not yield an lvalue */ - error(163); - } - /* %soperand of %s must be lvalue */ - error(114, "", mp->m_name); - return (0); - } else if (issclt(lt)) { - if (ltp->t_isfield) { - /* cannot take address of bit-field */ - error(112); - return (0); - } - } else if (lt != STRUCT && lt != UNION) { - /* unacceptable operand of %s */ - error(111, mp->m_name); - return (0); - } - if (ln->tn_op == NAME && ln->tn_sym->s_reg) { - /* cannot take address of register %s */ - error(113, ln->tn_sym->s_name); - return (0); - } - break; - case STAR: - /* until now there were no type checks for this operator */ - if (lt != PTR) { - /* cannot dereference non-pointer type */ - error(96); - return (0); - } - break; - case PLUS: - /* operands have scalar types (checked above) */ - if ((lt == PTR && !isityp(rt)) || (rt == PTR && !isityp(lt))) { - incompat(op, lt, rt); - return (0); - } - break; - case MINUS: - /* operands have scalar types (checked above) */ - if (lt == PTR && (!isityp(rt) && rt != PTR)) { - incompat(op, lt, rt); - return (0); - } else if (rt == PTR && lt != PTR) { - incompat(op, lt, rt); - return (0); - } - if (lt == PTR && rt == PTR) { - if (!eqtype(lstp, rstp, 1, 0, NULL)) { - /* illegal pointer subtraction */ - error(116); - } - } - break; - case SHR: - /* operands have integer types (checked above) */ - if (pflag && !isutyp(lt)) { - /* - * The left operand is signed. This means that - * the operation is (possibly) nonportable. - */ - /* bitwise operation on signed value nonportable */ - if (ln->tn_op != CON) { - /* possibly nonportable */ - warning(117); - } else if (ln->tn_val->v_quad < 0) { - warning(120); - } - } else if (!tflag && !sflag && !isutyp(olt) && isutyp(ort)) { - /* - * The left operand would become unsigned in - * traditional C. - */ - if (hflag && - (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { - /* semantics of %s change in ANSI C; use ... */ - warning(118, mp->m_name); - } - } else if (!tflag && !sflag && !isutyp(olt) && !isutyp(ort) && - psize(lt) < psize(rt)) { - /* - * In traditional C the left operand would be extended, - * possibly with 1, and then shifted. - */ - if (hflag && - (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { - /* semantics of %s change in ANSI C; use ... */ - warning(118, mp->m_name); - } - } - goto shift; - case SHL: - /* - * ANSI C does not perform balancing for shift operations, - * but traditional C does. If the width of the right operand - * is greather than the width of the left operand, than in - * traditional C the left operand would be extendet to the - * width of the right operand. For SHL this may result in - * different results. - */ - if (psize(lt) < psize(rt)) { - /* - * XXX If both operands are constant make sure - * that there is really a differencs between - * ANSI C and traditional C. - */ - if (hflag) - /* semantics of %s change in ANSI C; use ... */ - warning(118, mp->m_name); - } - shift: - if (rn->tn_op == CON) { - if (!isutyp(rt) && rn->tn_val->v_quad < 0) { - /* negative shift */ - warning(121); - } else if ((uint64_t)rn->tn_val->v_quad == size(lt)) { - /* shift equal to size fo object */ - warning(267); - } else if ((uint64_t)rn->tn_val->v_quad > size(lt)) { - /* shift greater than size of object */ - warning(122); - } - } - break; - case EQ: - case NE: - /* - * Accept some things which are allowed with EQ and NE, - * but not with ordered comparisons. - */ - if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { - if (rn->tn_op == CON && rn->tn_val->v_quad == 0) - break; - } - if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { - if (ln->tn_op == CON && ln->tn_val->v_quad == 0) - break; - } - /* FALLTHROUGH */ - case LT: - case GT: - case LE: - case GE: - if ((lt == PTR || rt == PTR) && lt != rt) { - if (isityp(lt) || isityp(rt)) { - /* illegal comb. of pointer and int., op %s */ - warning(123, mp->m_name); - } else { - incompat(op, lt, rt); - return (0); - } - } else if (lt == PTR && rt == PTR) { - ptrcmpok(op, ln, rn); - } - break; - case QUEST: - if (!issclt(lt)) { - /* first operand must have scalar type, op ? : */ - error(170); - return (0); - } - while (rn->tn_op == CVT) - rn = rn->tn_left; - if (rn->tn_op != COLON) - LERROR("typeok()"); - break; - case COLON: - - if (isatyp(lt) && isatyp(rt)) - break; - - if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) - break; - if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) - break; - - /* combination of any pointer and 0, 0L or (void *)0 is ok */ - if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { - if (rn->tn_op == CON && rn->tn_val->v_quad == 0) - break; - } - if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { - if (ln->tn_op == CON && ln->tn_val->v_quad == 0) - break; - } - - if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) { - /* illegal comb. of ptr. and int., op %s */ - warning(123, mp->m_name); - break; - } - - if (lt == VOID || rt == VOID) { - if (lt != VOID || rt != VOID) - /* incompatible types in conditional */ - warning(126); - break; - } - - if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) || - (lst == FUNC && rst == VOID))) { - /* (void *)0 handled above */ - if (sflag) - /* ANSI C forbids conv. of %s to %s, op %s */ - warning(305, "function pointer", "'void *'", - mp->m_name); - break; - } - - if (rt == PTR && lt == PTR) { - if (!eqtype(lstp, rstp, 1, 0, NULL)) - illptrc(mp, ltp, rtp); - break; - } - - /* incompatible types in conditional */ - error(126); - return (0); - - case ASSIGN: - case INIT: - case FARG: - case RETURN: - if (!asgntypok(op, arg, ln, rn)) - return (0); - goto assign; - case MULASS: - case DIVASS: - case MODASS: - goto assign; - case ADDASS: - case SUBASS: - /* operands have scalar types (checked above) */ - if ((lt == PTR && !isityp(rt)) || rt == PTR) { - incompat(op, lt, rt); - return (0); - } - goto assign; - case SHLASS: - goto assign; - case SHRASS: - if (pflag && !isutyp(lt) && !(tflag && isutyp(rt))) { - /* bitwise operation on s.v. possibly nonportabel */ - warning(117); - } - goto assign; - case ANDASS: - case XORASS: - case ORASS: - goto assign; - assign: - if (!ln->tn_lvalue) { - if (ln->tn_op == CVT && ln->tn_cast && - ln->tn_left->tn_op == LOAD) { - /* a cast does not yield an lvalue */ - error(163); - } - /* %soperand of %s must be lvalue */ - error(114, "left ", mp->m_name); - return (0); - } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) && - conmemb(ltp))) { - /* %soperand of %s must be modifiable lvalue */ - if (!tflag) - warning(115, "left ", mp->m_name); - } - break; - case COMMA: - if (!modtab[ln->tn_op].m_sideeff) - nulleff(ln); - break; - /* LINTED (enumeration values not handled in switch) */ - case CON: - case CASE: - case PUSH: - case LOAD: - case ICALL: - case CVT: - case CALL: - case FSEL: - case STRING: - case NAME: - case LOGOR: - case LOGAND: - case OR: - case XOR: - case AND: - case MOD: - case DIV: - case MULT: - case UMINUS: - case UPLUS: - case DEC: - case INC: - case COMPL: - case NOT: - case NOOP: - break; - } - - if (mp->m_badeop && - (ltp->t_isenum || (mp->m_binary && rtp->t_isenum))) { - chkbeop(op, ln, rn); - } else if (mp->m_enumop && (ltp->t_isenum && rtp && rtp->t_isenum)) { - chkeop2(op, arg, ln, rn); - } else if (mp->m_enumop && (ltp->t_isenum || (rtp &&rtp->t_isenum))) { - chkeop1(op, arg, ln, rn); - } - - return (1); -} - -static void -ptrcmpok(op_t op, tnode_t *ln, tnode_t *rn) -{ - type_t *ltp, *rtp; - tspec_t lt, rt; - const char *lts, *rts; - - lt = (ltp = ln->tn_type)->t_subt->t_tspec; - rt = (rtp = rn->tn_type)->t_subt->t_tspec; - - if (lt == VOID || rt == VOID) { - if (sflag && (lt == FUNC || rt == FUNC)) { - /* (void *)0 already handled in typeok() */ - *(lt == FUNC ? <s : &rts) = "function pointer"; - *(lt == VOID ? <s : &rts) = "'void *'"; - /* ANSI C forbids comparison of %s with %s */ - warning(274, lts, rts); - } - return; - } - - if (!eqtype(ltp->t_subt, rtp->t_subt, 1, 0, NULL)) { - illptrc(&modtab[op], ltp, rtp); - return; - } - - if (lt == FUNC && rt == FUNC) { - if (sflag && op != EQ && op != NE) - /* ANSI C forbids ordered comp. of func ptr */ - warning(125); - } -} - -/* - * Checks type compatibility for ASSIGN, INIT, FARG and RETURN - * and prints warnings/errors if necessary. - * If the types are (almost) compatible, 1 is returned, otherwise 0. - */ -static int -asgntypok(op_t op, int arg, tnode_t *ln, tnode_t *rn) -{ - tspec_t lt, rt, lst = NOTSPEC, rst = NOTSPEC; - type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL; - mod_t *mp; - const char *lts, *rts; - - if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR) - lst = (lstp = ltp->t_subt)->t_tspec; - if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR) - rst = (rstp = rtp->t_subt)->t_tspec; - mp = &modtab[op]; - - if (isatyp(lt) && isatyp(rt)) - return (1); - - if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) - /* both are struct or union */ - return (ltp->t_str == rtp->t_str); - - /* 0, 0L and (void *)0 may be assigned to any pointer */ - if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { - if (rn->tn_op == CON && rn->tn_val->v_quad == 0) - return (1); - } - - if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID)) { - /* two pointers, at least one pointer to void */ - if (sflag && (lst == FUNC || rst == FUNC)) { - /* comb. of ptr to func and ptr to void */ - *(lst == FUNC ? <s : &rts) = "function pointer"; - *(lst == VOID ? <s : &rts) = "'void *'"; - switch (op) { - case INIT: - case RETURN: - /* ANSI C forbids conversion of %s to %s */ - warning(303, rts, lts); - break; - case FARG: - /* ANSI C forbids conv. of %s to %s, arg #%d */ - warning(304, rts, lts, arg); - break; - default: - /* ANSI C forbids conv. of %s to %s, op %s */ - warning(305, rts, lts, mp->m_name); - break; - } - } - } - - if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID || - eqtype(lstp, rstp, 1, 0, NULL))) { - /* compatible pointer types (qualifiers ignored) */ - if (!tflag && - ((!lstp->t_const && rstp->t_const) || - (!lstp->t_volatile && rstp->t_volatile))) { - /* left side has not all qualifiers of right */ - switch (op) { - case INIT: - case RETURN: - /* incompatible pointer types */ - warning(182); - break; - case FARG: - /* argument has incompat. ptr. type, arg #%d */ - warning(153, arg); - break; - default: - /* operands have incompat. ptr. types, op %s */ - warning(128, mp->m_name); - break; - } - } - return (1); - } - - if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) { - switch (op) { - case INIT: - case RETURN: - /* illegal combination of pointer and integer */ - warning(183); - break; - case FARG: - /* illegal comb. of ptr. and int., arg #%d */ - warning(154, arg); - break; - default: - /* illegal comb. of ptr. and int., op %s */ - warning(123, mp->m_name); - break; - } - return (1); - } - - if (lt == PTR && rt == PTR) { - switch (op) { - case INIT: - case RETURN: - illptrc(NULL, ltp, rtp); - break; - case FARG: - /* argument has incompatible pointer type, arg #%d */ - warning(153, arg); - break; - default: - illptrc(mp, ltp, rtp); - break; - } - return (1); - } - - switch (op) { - case INIT: - /* initialisation type mismatch */ - error(185); - break; - case RETURN: - /* return value type mismatch */ - error(211); - break; - case FARG: - /* argument is incompatible with prototype, arg #%d */ - warning(155, arg); - break; - default: - incompat(op, lt, rt); - break; - } - - return (0); -} - -/* - * Prints a warning if an operator, which should be senseless for an - * enum type, is applied to an enum type. - */ -static void -chkbeop(op_t op, tnode_t *ln, tnode_t *rn) -{ - mod_t *mp; - - if (!eflag) - return; - - mp = &modtab[op]; - - if (!(ln->tn_type->t_isenum || - (mp->m_binary && rn->tn_type->t_isenum))) { - return; - } - - /* - * Enum as offset to a pointer is an exception (otherwise enums - * could not be used as array indizes). - */ - if (op == PLUS && - ((ln->tn_type->t_isenum && rn->tn_type->t_tspec == PTR) || - (rn->tn_type->t_isenum && ln->tn_type->t_tspec == PTR))) { - return; - } - - /* dubious operation on enum, op %s */ - warning(241, mp->m_name); - -} - -/* - * Prints a warning if an operator is applied to two different enum types. - */ -static void -chkeop2(op_t op, int arg, tnode_t *ln, tnode_t *rn) -{ - mod_t *mp; - - mp = &modtab[op]; - - if (ln->tn_type->t_enum != rn->tn_type->t_enum) { - switch (op) { - case INIT: - /* enum type mismatch in initialisation */ - warning(210); - break; - case FARG: - /* enum type mismatch, arg #%d */ - warning(156, arg); - break; - case RETURN: - /* return value type mismatch */ - warning(211); - break; - default: - /* enum type mismatch, op %s */ - warning(130, mp->m_name); - break; - } -#if 0 - } else if (mp->m_comp && op != EQ && op != NE) { - if (eflag) - /* dubious comparisons of enums */ - warning(243, mp->m_name); -#endif - } -} - -/* - * Prints a warning if an operator has both enum end other integer - * types. - */ -static void -chkeop1(op_t op, int arg, tnode_t *ln, tnode_t *rn) -{ - char lbuf[64], rbuf[64]; - - if (!eflag) - return; - - switch (op) { - case INIT: - /* - * Initializations with 0 should be allowed. Otherwise, - * we should complain about all uninitialized enums, - * consequently. - */ - if (!rn->tn_type->t_isenum && rn->tn_op == CON && - isityp(rn->tn_type->t_tspec) && rn->tn_val->v_quad == 0) { - return; - } - /* initialisation of '%s' with '%s' */ - warning(277, tyname(lbuf, sizeof(lbuf), ln->tn_type), - tyname(rbuf, sizeof(rbuf), rn->tn_type)); - break; - case FARG: - /* combination of '%s' and '%s', arg #%d */ - warning(278, tyname(lbuf, sizeof(lbuf), ln->tn_type), - tyname(rbuf, sizeof(rbuf), rn->tn_type), arg); - break; - case RETURN: - /* combination of '%s' and '%s' in return */ - warning(279, tyname(lbuf, sizeof(lbuf), ln->tn_type), - tyname(rbuf, sizeof(rbuf), rn->tn_type)); - break; - default: - /* combination of '%s' and %s, op %s */ - warning(242, tyname(lbuf, sizeof(lbuf), ln->tn_type), - tyname(rbuf, sizeof(rbuf), rn->tn_type), - modtab[op].m_name); - break; - } -} - -/* - * Build and initialize a new node. - */ -static tnode_t * -mktnode(op_t op, type_t *type, tnode_t *ln, tnode_t *rn) -{ - tnode_t *ntn; - tspec_t t; - - ntn = getnode(); - - ntn->tn_op = op; - ntn->tn_type = type; - ntn->tn_left = ln; - ntn->tn_right = rn; - - if (op == STAR || op == FSEL) { - if (ln->tn_type->t_tspec == PTR) { - t = ln->tn_type->t_subt->t_tspec; - if (t != FUNC && t != VOID) - ntn->tn_lvalue = 1; - } else { - LERROR("mktnode()"); - } - } - - return (ntn); -} - -/* - * Performs usual conversion of operands to (unsigned) int. - * - * If tflag is set or the operand is a function argument with no - * type information (no prototype or variable # of args), convert - * float to double. - */ -tnode_t * -promote(op_t op, int farg, tnode_t *tn) -{ - tspec_t t; - type_t *ntp; - int len; - - t = tn->tn_type->t_tspec; - - if (!isatyp(t)) - return (tn); - - if (!tflag) { - /* - * ANSI C requires that the result is always of type INT - * if INT can represent all possible values of the previous - * type. - */ - if (tn->tn_type->t_isfield) { - len = tn->tn_type->t_flen; - if (size(INT) > len) { - t = INT; - } else { - if (size(INT) != len) - LERROR("promote()"); - if (isutyp(t)) { - t = UINT; - } else { - t = INT; - } - } - } else if (t == CHAR || t == UCHAR || t == SCHAR) { - t = (size(CHAR) < size(INT) || t != UCHAR) ? - INT : UINT; - } else if (t == SHORT || t == USHORT) { - t = (size(SHORT) < size(INT) || t == SHORT) ? - INT : UINT; - } else if (t == ENUM) { - t = INT; - } else if (farg && t == FLOAT) { - t = DOUBLE; - } - } else { - /* - * In traditional C, keep unsigned and promote FLOAT - * to DOUBLE. - */ - if (t == UCHAR || t == USHORT) { - t = UINT; - } else if (t == CHAR || t == SCHAR || t == SHORT) { - t = INT; - } else if (t == FLOAT) { - t = DOUBLE; - } else if (t == ENUM) { - t = INT; - } - } - - if (t != tn->tn_type->t_tspec) { - ntp = tduptyp(tn->tn_type); - ntp->t_tspec = t; - /* - * Keep t_isenum so we are later able to check compatibility - * of enum types. - */ - tn = convert(op, 0, ntp, tn); - } - - return (tn); -} - -/* - * Insert conversions which are necessary to give both operands the same - * type. This is done in different ways for traditional C and ANSI C. - */ -static void -balance(op_t op, tnode_t **lnp, tnode_t **rnp) -{ - tspec_t lt, rt, t; - int i, u; - type_t *ntp; - static tspec_t tl[] = { - LDOUBLE, DOUBLE, FLOAT, UQUAD, QUAD, ULONG, LONG, UINT, INT, - }; - - lt = (*lnp)->tn_type->t_tspec; - rt = (*rnp)->tn_type->t_tspec; - - if (!isatyp(lt) || !isatyp(rt)) - return; - - if (!tflag) { - if (lt == rt) { - t = lt; - } else if (lt == LDOUBLE || rt == LDOUBLE) { - t = LDOUBLE; - } else if (lt == DOUBLE || rt == DOUBLE) { - t = DOUBLE; - } else if (lt == FLOAT || rt == FLOAT) { - t = FLOAT; - } else { - /* - * If type A has more bits than type B it should - * be able to hold all possible values of type B. - */ - if (size(lt) > size(rt)) { - t = lt; - } else if (size(lt) < size(rt)) { - t = rt; - } else { - for (i = 3; tl[i] != INT; i++) { - if (tl[i] == lt || tl[i] == rt) - break; - } - if ((isutyp(lt) || isutyp(rt)) && - !isutyp(tl[i])) { - i--; - } - t = tl[i]; - } - } - } else { - /* Keep unsigned in traditional C */ - u = isutyp(lt) || isutyp(rt); - for (i = 0; tl[i] != INT; i++) { - if (lt == tl[i] || rt == tl[i]) - break; - } - t = tl[i]; - if (u && isityp(t) && !isutyp(t)) - t = utyp(t); - } - - if (t != lt) { - ntp = tduptyp((*lnp)->tn_type); - ntp->t_tspec = t; - *lnp = convert(op, 0, ntp, *lnp); - } - if (t != rt) { - ntp = tduptyp((*rnp)->tn_type); - ntp->t_tspec = t; - *rnp = convert(op, 0, ntp, *rnp); - } -} - -/* - * Insert a conversion operator, which converts the type of the node - * to another given type. - * If op is FARG, arg is the number of the argument (used for warnings). - */ -tnode_t * -convert(op_t op, int arg, type_t *tp, tnode_t *tn) -{ - tnode_t *ntn; - tspec_t nt, ot, ost = NOTSPEC; - - if (tn->tn_lvalue) - LERROR("convert()"); - - nt = tp->t_tspec; - if ((ot = tn->tn_type->t_tspec) == PTR) - ost = tn->tn_type->t_subt->t_tspec; - - if (!tflag && !sflag && op == FARG) - ptconv(arg, nt, ot, tp, tn); - if (isityp(nt) && isityp(ot)) { - iiconv(op, arg, nt, ot, tp, tn); - } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) && - tn->tn_op == CON && tn->tn_val->v_quad == 0) { - /* 0, 0L and (void *)0 may be assigned to any pointer. */ - } else if (isityp(nt) && ot == PTR) { - piconv(op, nt, tp, tn); - } else if (nt == PTR && ot == PTR) { - ppconv(op, tn, tp); - } - - ntn = getnode(); - ntn->tn_op = CVT; - ntn->tn_type = tp; - ntn->tn_cast = op == CVT; - if (tn->tn_op != CON || nt == VOID) { - ntn->tn_left = tn; - } else { - ntn->tn_op = CON; - ntn->tn_val = tgetblk(sizeof (val_t)); - cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val); - } - - return (ntn); -} - -/* - * Print a warning if a prototype causes a type conversion that is - * different from what would happen to the same argument in the - * absence of a prototype. - * - * Errors/Warnings about illegal type combinations are already printed - * in asgntypok(). - */ -static void -ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) -{ - tnode_t *ptn; - char buf[64]; - - if (!isatyp(nt) || !isatyp(ot)) - return; - - /* - * If the type of the formal parameter is char/short, a warning - * would be useless, because functions declared the old style - * can't expect char/short arguments. - */ - if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT) - return; - - /* get default promotion */ - ptn = promote(NOOP, 1, tn); - ot = ptn->tn_type->t_tspec; - - /* return if types are the same with and without prototype */ - if (nt == ot || (nt == ENUM && ot == INT)) - return; - - if (isftyp(nt) != isftyp(ot) || psize(nt) != psize(ot)) { - /* representation and/or width change */ - if (!isityp(ot) || psize(ot) > psize(INT)) { - /* conversion to '%s' due to prototype, arg #%d */ - warning(259, tyname(buf, sizeof(buf), tp), arg); - } - } else if (hflag) { - /* - * they differ in sign or base type (char, short, int, - * long, long long, float, double, long double) - * - * if they differ only in sign and the argument is a constant - * and the msb of the argument is not set, print no warning - */ - if (ptn->tn_op == CON && isityp(nt) && styp(nt) == styp(ot) && - msb(ptn->tn_val->v_quad, ot, -1) == 0) { - /* ok */ - } else { - /* conversion to '%s' due to prototype, arg #%d */ - warning(259, tyname(buf, sizeof(buf), tp), arg); - } - } -} - -/* - * Print warnings for conversions of integer types which may cause - * problems. - */ -/* ARGSUSED */ -static void -iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) -{ - char lbuf[64], rbuf[64]; - if (tn->tn_op == CON) - return; - - if (op == CVT) - return; - -#if 0 - if (psize(nt) > psize(ot) && isutyp(nt) != isutyp(ot)) { - /* conversion to %s may sign-extend incorrectly (, arg #%d) */ - if (aflag && pflag) { - if (op == FARG) { - warning(297, tyname(lbuf, sizeof(lbuf), tp), - arg); - } else { - warning(131, tyname(lbuf, sizeof(lbuf), tp)); - } - } - } -#endif - - if (psize(nt) < psize(ot) && - (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD || - aflag > 1)) { - /* conversion from '%s' may lose accuracy */ - if (aflag) { - if (op == FARG) { - warning(298, - tyname(rbuf, sizeof(rbuf), tn->tn_type), - tyname(lbuf, sizeof(lbuf), tp), - arg); - } else { - warning(132, - tyname(rbuf, sizeof(rbuf), tn->tn_type), - tyname(lbuf, sizeof(lbuf), tp)); - } - } - } -} - -/* - * Print warnings for dubious conversions of pointer to integer. - */ -static void -piconv(op_t op, tspec_t nt, type_t *tp, tnode_t *tn) -{ - char buf[64]; - - if (tn->tn_op == CON) - return; - - if (op != CVT) { - /* We already got an error. */ - return; - } - - if (psize(nt) < psize(PTR)) { - if (pflag && size(nt) >= size(PTR)) { - /* conv. of pointer to %s may lose bits */ - warning(134, tyname(buf, sizeof(buf), tp)); - } else { - /* conv. of pointer to %s loses bits */ - warning(133, tyname(buf, sizeof(buf), tp)); - } - } -} - -/* - * Print warnings for questionable pointer conversions. - */ -static void -ppconv(op_t op, tnode_t *tn, type_t *tp) -{ - tspec_t nt, ot; - const char *nts, *ots; - - /* - * We already got an error (pointers of different types - * without a cast) or we will not get a warning. - */ - if (op != CVT) - return; - - nt = tp->t_subt->t_tspec; - ot = tn->tn_type->t_subt->t_tspec; - - if (nt == VOID || ot == VOID) { - if (sflag && (nt == FUNC || ot == FUNC)) { - /* (void *)0 already handled in convert() */ - *(nt == FUNC ? &nts : &ots) = "function pointer"; - *(nt == VOID ? &nts : &ots) = "'void *'"; - /* ANSI C forbids conversion of %s to %s */ - warning(303, ots, nts); - } - return; - } else if (nt == FUNC && ot == FUNC) { - return; - } else if (nt == FUNC || ot == FUNC) { - /* questionable conversion of function pointer */ - warning(229); - return; - } - - if (getbound(tp->t_subt) > getbound(tn->tn_type->t_subt)) { - if (hflag) - /* possible pointer alignment problem */ - warning(135); - } - if (((nt == STRUCT || nt == UNION) && - tp->t_subt->t_str != tn->tn_type->t_subt->t_str) || - psize(nt) != psize(ot)) { - if (cflag) { - /* pointer casts may be troublesome */ - warning(247); - } - } -} - -/* - * Converts a typed constant in a constant of another type. - * - * op operator which requires conversion - * arg if op is FARG, # of argument - * tp type to which convert the constant - * nv new constant - * v old constant - */ -void -cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) -{ - char lbuf[64], rbuf[64]; - tspec_t ot, nt; - ldbl_t max = 0.0, min = 0.0; - int sz, rchk; - int64_t xmask, xmsk1; - int osz, nsz; - - ot = v->v_tspec; - nt = nv->v_tspec = tp->t_tspec; - rchk = 0; - - if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) { - switch (nt) { - case CHAR: - max = CHAR_MAX; min = CHAR_MIN; break; - case UCHAR: - max = UCHAR_MAX; min = 0; break; - case SCHAR: - max = SCHAR_MAX; min = SCHAR_MIN; break; - case SHORT: - max = SHRT_MAX; min = SHRT_MIN; break; - case USHORT: - max = USHRT_MAX; min = 0; break; - case ENUM: - case INT: - max = INT_MAX; min = INT_MIN; break; - case UINT: - max = (u_int)UINT_MAX; min = 0; break; - case LONG: - max = LONG_MAX; min = LONG_MIN; break; - case ULONG: - max = (u_long)ULONG_MAX; min = 0; break; - case QUAD: - max = QUAD_MAX; min = QUAD_MIN; break; - case UQUAD: - max = (uint64_t)UQUAD_MAX; min = 0; break; - case FLOAT: - max = FLT_MAX; min = -FLT_MAX; break; - case DOUBLE: - max = DBL_MAX; min = -DBL_MAX; break; - case PTR: - /* Already got an error because of float --> ptr */ - case LDOUBLE: - max = LDBL_MAX; min = -LDBL_MAX; break; - default: - LERROR("cvtcon()"); - } - if (v->v_ldbl > max || v->v_ldbl < min) { - if (nt == LDOUBLE) - LERROR("cvtcon()"); - if (op == FARG) { - /* conv. of %s to %s is out of rng., arg #%d */ - warning(295, tyname(lbuf, sizeof(lbuf), - gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), - arg); - } else { - /* conversion of %s to %s is out of range */ - warning(119, tyname(lbuf, sizeof(lbuf), - gettyp(ot)), - tyname(rbuf, sizeof(rbuf), tp)); - } - v->v_ldbl = v->v_ldbl > 0 ? max : min; - } - if (nt == FLOAT) { - nv->v_ldbl = (float)v->v_ldbl; - } else if (nt == DOUBLE) { - nv->v_ldbl = (double)v->v_ldbl; - } else if (nt == LDOUBLE) { - nv->v_ldbl = v->v_ldbl; - } else { - nv->v_quad = (nt == PTR || isutyp(nt)) ? - (uint64_t)v->v_ldbl : (int64_t)v->v_ldbl; - } - } else { - if (nt == FLOAT) { - nv->v_ldbl = (ot == PTR || isutyp(ot)) ? - (float)(uint64_t)v->v_quad : (float)v->v_quad; - } else if (nt == DOUBLE) { - nv->v_ldbl = (ot == PTR || isutyp(ot)) ? - (double)(uint64_t)v->v_quad : (double)v->v_quad; - } else if (nt == LDOUBLE) { - nv->v_ldbl = (ot == PTR || isutyp(ot)) ? - (ldbl_t)(uint64_t)v->v_quad : (ldbl_t)v->v_quad; - } else { - rchk = 1; /* Check for lost precision. */ - nv->v_quad = v->v_quad; - } - } - - if (v->v_ansiu && isftyp(nt)) { - /* ANSI C treats constant as unsigned */ - warning(157); - v->v_ansiu = 0; - } else if (v->v_ansiu && (isityp(nt) && !isutyp(nt) && - psize(nt) > psize(ot))) { - /* ANSI C treats constant as unsigned */ - warning(157); - v->v_ansiu = 0; - } - - if (nt != FLOAT && nt != DOUBLE && nt != LDOUBLE) { - sz = tp->t_isfield ? tp->t_flen : size(nt); - nv->v_quad = xsign(nv->v_quad, nt, sz); - } - - if (rchk && op != CVT) { - osz = size(ot); - nsz = tp->t_isfield ? tp->t_flen : size(nt); - xmask = qlmasks[nsz] ^ qlmasks[osz]; - xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1]; - /* - * For bitwise operations we are not interested in the - * value, but in the bits itself. - */ - if (op == ORASS || op == OR || op == XOR) { - /* - * Print a warning if bits which were set are - * lost due to the conversion. - * This can happen with operator ORASS only. - */ - if (nsz < osz && (v->v_quad & xmask) != 0) { - /* constant truncated by conv., op %s */ - warning(306, modtab[op].m_name); - } - } else if (op == ANDASS || op == AND) { - /* - * Print a warning if additional bits are not all 1 - * and the most significant bit of the old value is 1, - * or if at least one (but not all) removed bit was 0. - */ - if (nsz > osz && - (nv->v_quad & qbmasks[osz - 1]) != 0 && - (nv->v_quad & xmask) != xmask) { - /* - * extra bits set to 0 in conversion - * of '%s' to '%s', op %s - */ - warning(309, tyname(lbuf, sizeof(lbuf), - gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), - modtab[op].m_name); - } else if (nsz < osz && - (v->v_quad & xmask) != xmask && - (v->v_quad & xmask) != 0) { - /* const. truncated by conv., op %s */ - warning(306, modtab[op].m_name); - } - } else if ((nt != PTR && isutyp(nt)) && - (ot != PTR && !isutyp(ot)) && v->v_quad < 0) { - if (op == ASSIGN) { - /* assignment of negative constant to ... */ - warning(164); - } else if (op == INIT) { - /* initialisation of unsigned with neg. ... */ - warning(221); - } else if (op == FARG) { - /* conversion of neg. const. to ..., arg #%d */ - warning(296, arg); - } else if (modtab[op].m_comp) { - /* we get this warning already in chkcomp() */ - } else { - /* conversion of negative constant to ... */ - warning(222); - } - } else if (nv->v_quad != v->v_quad && nsz <= osz && - (v->v_quad & xmask) != 0 && - (isutyp(ot) || (v->v_quad & xmsk1) != xmsk1)) { - /* - * Loss of significant bit(s). All truncated bits - * of unsigned types or all truncated bits plus the - * msb of the target for signed types are considered - * to be significant bits. Loss of significant bits - * means that at least on of the bits was set in an - * unsigned type or that at least one, but not all of - * the bits was set in a signed type. - * Loss of significant bits means that it is not - * possible, also not with necessary casts, to convert - * back to the original type. An example for a - * necessary cast is: - * char c; int i; c = 128; - * i = c; ** yields -128 ** - * i = (unsigned char)c; ** yields 128 ** - */ - if (op == ASSIGN && tp->t_isfield) { - /* precision lost in bit-field assignment */ - warning(166); - } else if (op == ASSIGN) { - /* constant truncated by assignment */ - warning(165); - } else if (op == INIT && tp->t_isfield) { - /* bit-field initializer does not fit */ - warning(180); - } else if (op == INIT) { - /* initializer does not fit */ - warning(178); - } else if (op == CASE) { - /* case label affected by conversion */ - warning(196); - } else if (op == FARG) { - /* conv. of %s to %s is out of rng., arg #%d */ - warning(295, tyname(lbuf, sizeof(lbuf), - gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), - arg); - } else { - /* conversion of %s to %s is out of range */ - warning(119, tyname(lbuf, sizeof(lbuf), - gettyp(ot)), - tyname(rbuf, sizeof(rbuf), tp)); - } - } else if (nv->v_quad != v->v_quad) { - if (op == ASSIGN && tp->t_isfield) { - /* precision lost in bit-field assignment */ - warning(166); - } else if (op == INIT && tp->t_isfield) { - /* bit-field initializer out of range */ - warning(11); - } else if (op == CASE) { - /* case label affected by conversion */ - warning(196); - } else if (op == FARG) { - /* conv. of %s to %s is out of rng., arg #%d */ - warning(295, tyname(lbuf, sizeof(lbuf), - gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), - arg); - } else { - /* conversion of %s to %s is out of range */ - warning(119, tyname(lbuf, sizeof(lbuf), - gettyp(ot)), - tyname(rbuf, sizeof(rbuf), tp)); - } - } - } -} - -/* - * Called if incompatible types were detected. - * Prints an appropriate warning. - */ -static void -incompat(op_t op, tspec_t lt, tspec_t rt) -{ - mod_t *mp; - - mp = &modtab[op]; - - if (lt == VOID || (mp->m_binary && rt == VOID)) { - /* void type illegal in expression */ - error(109); - } else if (op == ASSIGN) { - if ((lt == STRUCT || lt == UNION) && - (rt == STRUCT || rt == UNION)) { - /* assignment of different structures */ - error(240); - } else { - /* assignment type mismatch */ - error(171); - } - } else if (mp->m_binary) { - /* operands of %s have incompatible types */ - error(107, mp->m_name); - } else { - /* operand of %s has incompatible type */ - error(108, mp->m_name); - } -} - -/* - * Called if incompatible pointer types are detected. - * Print an appropriate warning. - */ -static void -illptrc(mod_t *mp, type_t *ltp, type_t *rtp) -{ - tspec_t lt, rt; - - if (ltp->t_tspec != PTR || rtp->t_tspec != PTR) - LERROR("illptrc()"); - - lt = ltp->t_subt->t_tspec; - rt = rtp->t_subt->t_tspec; - - if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) { - if (mp == NULL) { - /* illegal structure pointer combination */ - warning(244); - } else { - /* illegal structure pointer combination, op %s */ - warning(245, mp->m_name); - } - } else { - if (mp == NULL) { - /* illegal pointer combination */ - warning(184); - } else { - /* illegal pointer combination, op %s */ - warning(124, mp->m_name); - } - } -} - -/* - * Make sure type (*tpp)->t_subt has at least the qualifiers - * of tp1->t_subt and tp2->t_subt. - */ -static void -mrgqual(type_t **tpp, type_t *tp1, type_t *tp2) -{ - - if ((*tpp)->t_tspec != PTR || - tp1->t_tspec != PTR || tp2->t_tspec != PTR) { - LERROR("mrgqual()"); - } - - if ((*tpp)->t_subt->t_const == - (tp1->t_subt->t_const | tp2->t_subt->t_const) && - (*tpp)->t_subt->t_volatile == - (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) { - return; - } - - *tpp = tduptyp(*tpp); - (*tpp)->t_subt = tduptyp((*tpp)->t_subt); - (*tpp)->t_subt->t_const = - tp1->t_subt->t_const | tp2->t_subt->t_const; - (*tpp)->t_subt->t_volatile = - tp1->t_subt->t_volatile | tp2->t_subt->t_volatile; -} - -/* - * Returns 1 if the given structure or union has a constant member - * (maybe recursively). - */ -static int -conmemb(type_t *tp) -{ - sym_t *m; - tspec_t t; - - if ((t = tp->t_tspec) != STRUCT && t != UNION) - LERROR("conmemb()"); - for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) { - tp = m->s_type; - if (tp->t_const) - return (1); - if ((t = tp->t_tspec) == STRUCT || t == UNION) { - if (conmemb(m->s_type)) - return (1); - } - } - return (0); -} - -const char * -basictyname(tspec_t t) -{ - switch (t) { - case CHAR: return "char"; - case UCHAR: return "unsigned char"; - case SCHAR: return "signed char"; - case SHORT: return "short"; - case USHORT: return "unsigned short"; - case INT: return "int"; - case UINT: return "unsigned int"; - case LONG: return "long"; - case ULONG: return "unsigned long"; - case QUAD: return "long long"; - case UQUAD: return "unsigned long long"; - case FLOAT: return "float"; - case DOUBLE: return "double"; - case LDOUBLE: return "long double"; - case PTR: return "pointer"; - case ENUM: return "enum"; - case STRUCT: return "struct"; - case UNION: return "union"; - case FUNC: return "function"; - case ARRAY: return "array"; - default: - LERROR("basictyname()"); - return NULL; - } -} - -const char * -tyname(char *buf, size_t bufsiz, type_t *tp) -{ - tspec_t t; - const char *s; - char lbuf[64]; - - if ((t = tp->t_tspec) == INT && tp->t_isenum) - t = ENUM; - - s = basictyname(t); - - - switch (t) { - case CHAR: - case UCHAR: - case SCHAR: - case SHORT: - case USHORT: - case INT: - case UINT: - case LONG: - case ULONG: - case QUAD: - case UQUAD: - case FLOAT: - case DOUBLE: - case LDOUBLE: - case FUNC: - (void)snprintf(buf, bufsiz, "%s", s); - break; - case PTR: - (void)snprintf(buf, bufsiz, "%s to %s", s, - tyname(lbuf, sizeof(lbuf), tp->t_subt)); - break; - case ENUM: - (void)snprintf(buf, bufsiz, "%s %s", s, - tp->t_enum->etag->s_name); - break; - case STRUCT: - case UNION: - (void)snprintf(buf, bufsiz, "%s %s", s, - tp->t_str->stag->s_name); - break; - case ARRAY: - (void)snprintf(buf, bufsiz, "%s of %s[%d]", s, - tyname(lbuf, sizeof(lbuf), tp->t_subt), tp->t_dim); - break; - default: - LERROR("tyname()"); - } - return (buf); -} - -/* - * Create a new node for one of the operators POINT and ARROW. - */ -static tnode_t * -bldstr(op_t op, tnode_t *ln, tnode_t *rn) -{ - tnode_t *ntn, *ctn; - int nolval; - - if (rn->tn_op != NAME) - LERROR("bldstr()"); - if (rn->tn_sym->s_value.v_tspec != INT) - LERROR("bldstr()"); - if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU) - LERROR("bldstr()"); - - /* - * Remember if the left operand is an lvalue (structure members - * are lvalues if and only if the structure itself is an lvalue). - */ - nolval = op == POINT && !ln->tn_lvalue; - - if (op == POINT) { - ln = bldamper(ln, 1); - } else if (ln->tn_type->t_tspec != PTR) { - if (!tflag || !isityp(ln->tn_type->t_tspec)) - LERROR("bldstr()"); - ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); - } - -#if PTRDIFF_IS_LONG - ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT); -#else - ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT); -#endif - - ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn); - if (ln->tn_op == CON) - ntn = fold(ntn); - - if (rn->tn_type->t_isfield) { - ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL); - } else { - ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL); - } - - if (nolval) - ntn->tn_lvalue = 0; - - return (ntn); -} - -/* - * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. - */ -static tnode_t * -bldincdec(op_t op, tnode_t *ln) -{ - tnode_t *cn, *ntn; - - if (ln == NULL) - LERROR("bldincdec()"); - - if (ln->tn_type->t_tspec == PTR) { - cn = plength(ln->tn_type); - } else { - cn = getinode(INT, (int64_t)1); - } - ntn = mktnode(op, ln->tn_type, ln, cn); - - return (ntn); -} - -/* - * Create a tree node for the & operator - */ -static tnode_t * -bldamper(tnode_t *tn, int noign) -{ - tnode_t *ntn; - tspec_t t; - - if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { - /* & before array or function: ignored */ - if (tflag) - warning(127); - return (tn); - } - - /* eliminate &* */ - if (tn->tn_op == STAR && - tn->tn_left->tn_type->t_tspec == PTR && - tn->tn_left->tn_type->t_subt == tn->tn_type) { - return (tn->tn_left); - } - - ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL); - - return (ntn); -} - -/* - * Create a node for operators PLUS and MINUS. - */ -static tnode_t * -bldplmi(op_t op, tnode_t *ln, tnode_t *rn) -{ - tnode_t *ntn, *ctn; - type_t *tp; - - /* If pointer and integer, then pointer to the lhs. */ - if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) { - ntn = ln; - ln = rn; - rn = ntn; - } - - if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { - - if (!isityp(rn->tn_type->t_tspec)) - LERROR("bldplmi()"); - - ctn = plength(ln->tn_type); - if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) - rn = convert(NOOP, 0, ctn->tn_type, rn); - rn = mktnode(MULT, rn->tn_type, rn, ctn); - if (rn->tn_left->tn_op == CON) - rn = fold(rn); - ntn = mktnode(op, ln->tn_type, ln, rn); - - } else if (rn->tn_type->t_tspec == PTR) { - - if (ln->tn_type->t_tspec != PTR || op != MINUS) - LERROR("bldplmi()"); -#if PTRDIFF_IS_LONG - tp = gettyp(LONG); -#else - tp = gettyp(INT); -#endif - ntn = mktnode(op, tp, ln, rn); - if (ln->tn_op == CON && rn->tn_op == CON) - ntn = fold(ntn); - ctn = plength(ln->tn_type); - balance(NOOP, &ntn, &ctn); - ntn = mktnode(DIV, tp, ntn, ctn); - - } else { - - ntn = mktnode(op, ln->tn_type, ln, rn); - - } - return (ntn); -} - -/* - * Create a node for operators SHL and SHR. - */ -static tnode_t * -bldshft(op_t op, tnode_t *ln, tnode_t *rn) -{ - tspec_t t; - tnode_t *ntn; - - if ((t = rn->tn_type->t_tspec) != INT && t != UINT) - rn = convert(CVT, 0, gettyp(INT), rn); - ntn = mktnode(op, ln->tn_type, ln, rn); - return (ntn); -} - -/* - * Create a node for COLON. - */ -static tnode_t * -bldcol(tnode_t *ln, tnode_t *rn) -{ - tspec_t lt, rt, pdt; - type_t *rtp; - tnode_t *ntn; - - lt = ln->tn_type->t_tspec; - rt = rn->tn_type->t_tspec; -#if PTRDIFF_IS_LONG - pdt = LONG; -#else - pdt = INT; -#endif - - /* - * Arithmetic types are balanced, all other type combinations - * still need to be handled. - */ - if (isatyp(lt) && isatyp(rt)) { - rtp = ln->tn_type; - } else if (lt == VOID || rt == VOID) { - rtp = gettyp(VOID); - } else if (lt == STRUCT || lt == UNION) { - /* Both types must be identical. */ - if (rt != STRUCT && rt != UNION) - LERROR("bldcol()"); - if (ln->tn_type->t_str != rn->tn_type->t_str) - LERROR("bldcol()"); - if (incompl(ln->tn_type)) { - /* unknown operand size, op %s */ - error(138, modtab[COLON].m_name); - return (NULL); - } - rtp = ln->tn_type; - } else if (lt == PTR && isityp(rt)) { - if (rt != pdt) { - rn = convert(NOOP, 0, gettyp(pdt), rn); - rt = pdt; - } - rtp = ln->tn_type; - } else if (rt == PTR && isityp(lt)) { - if (lt != pdt) { - ln = convert(NOOP, 0, gettyp(pdt), ln); - lt = pdt; - } - rtp = rn->tn_type; - } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { - if (rt != PTR) - LERROR("bldcol()"); - rtp = ln->tn_type; - mrgqual(&rtp, ln->tn_type, rn->tn_type); - } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { - if (lt != PTR) - LERROR("bldcol()"); - rtp = rn->tn_type; - mrgqual(&rtp, ln->tn_type, rn->tn_type); - } else { - if (lt != PTR || rt != PTR) - LERROR("bldcol()"); - /* - * XXX For now we simply take the left type. This is - * probably wrong, if one type contains a function prototype - * and the other one, at the same place, only an old style - * declaration. - */ - rtp = ln->tn_type; - mrgqual(&rtp, ln->tn_type, rn->tn_type); - } - - ntn = mktnode(COLON, rtp, ln, rn); - - return (ntn); -} - -/* - * Create a node for an assignment operator (both = and op= ). - */ -static tnode_t * -bldasgn(op_t op, tnode_t *ln, tnode_t *rn) -{ - tspec_t lt, rt; - tnode_t *ntn, *ctn; - - if (ln == NULL || rn == NULL) - LERROR("bldasgn()"); - - lt = ln->tn_type->t_tspec; - rt = rn->tn_type->t_tspec; - - if ((op == ADDASS || op == SUBASS) && lt == PTR) { - if (!isityp(rt)) - LERROR("bldasgn()"); - ctn = plength(ln->tn_type); - if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) - rn = convert(NOOP, 0, ctn->tn_type, rn); - rn = mktnode(MULT, rn->tn_type, rn, ctn); - if (rn->tn_left->tn_op == CON) - rn = fold(rn); - } - - if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { - if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str) - LERROR("bldasgn()"); - if (incompl(ln->tn_type)) { - if (op == RETURN) { - /* cannot return incomplete type */ - error(212); - } else { - /* unknown operand size, op %s */ - error(138, modtab[op].m_name); - } - return (NULL); - } - } - - if (op == SHLASS) { - if (psize(lt) < psize(rt)) { - if (hflag) - /* semantics of %s change in ANSI C; use ... */ - warning(118, "<<="); - } - } else if (op != SHRASS) { - if (op == ASSIGN || lt != PTR) { - if (lt != rt || - (ln->tn_type->t_isfield && rn->tn_op == CON)) { - rn = convert(op, 0, ln->tn_type, rn); - rt = lt; - } - } - } - - ntn = mktnode(op, ln->tn_type, ln, rn); - - return (ntn); -} - -/* - * Get length of type tp->t_subt. - */ -static tnode_t * -plength(type_t *tp) -{ - int elem, elsz; - tspec_t st; - - if (tp->t_tspec != PTR) - LERROR("plength()"); - tp = tp->t_subt; - - elem = 1; - elsz = 0; - - while (tp->t_tspec == ARRAY) { - elem *= tp->t_dim; - tp = tp->t_subt; - } - - switch (tp->t_tspec) { - case FUNC: - /* pointer to function is not allowed here */ - error(110); - break; - case VOID: - /* cannot do pointer arithmetic on operand of ... */ - (void)gnuism(136); - break; - case STRUCT: - case UNION: - if ((elsz = tp->t_str->size) == 0) - /* cannot do pointer arithmetic on operand of ... */ - error(136); - break; - case ENUM: - if (incompl(tp)) { - /* cannot do pointer arithmetic on operand of ... */ - warning(136); - } - /* FALLTHROUGH */ - default: - if ((elsz = size(tp->t_tspec)) == 0) { - /* cannot do pointer arithmetic on operand of ... */ - error(136); - } else if (elsz == -1) { - LERROR("plength()"); - } - break; - } - - if (elem == 0 && elsz != 0) { - /* cannot do pointer arithmetic on operand of ... */ - error(136); - } - - if (elsz == 0) - elsz = CHAR_BIT; - -#if PTRDIFF_IS_LONG - st = LONG; -#else - st = INT; -#endif - - return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); -} - -/* - * XXX - * Note: There appear to be a number of bugs in detecting overflow in - * this function. An audit and a set of proper regression tests are needed. - * --Perry Metzger, Nov. 16, 2001 - */ -/* - * Do only as much as necessary to compute constant expressions. - * Called only if the operator allows folding and (both) operands - * are constants. - */ -static tnode_t * -fold(tnode_t *tn) -{ - val_t *v; - tspec_t t; - int utyp, ovfl; - int64_t sl, sr = 0, q = 0, mask; - uint64_t ul, ur = 0; - tnode_t *cn; - - if ((v = calloc(1, sizeof (val_t))) == NULL) - nomem(); - v->v_tspec = t = tn->tn_type->t_tspec; - - utyp = t == PTR || isutyp(t); - ul = sl = tn->tn_left->tn_val->v_quad; - if (modtab[tn->tn_op].m_binary) - ur = sr = tn->tn_right->tn_val->v_quad; - - mask = qlmasks[size(t)]; - ovfl = 0; - - switch (tn->tn_op) { - case UPLUS: - q = sl; - break; - case UMINUS: - q = -sl; - if (msb(q, t, -1) == msb(sl, t, -1)) - ovfl = 1; - break; - case COMPL: - q = ~sl; - break; - case MULT: - if (utyp) { - q = ul * ur; - if (q != (q & mask)) - ovfl = 1; - else if ((ul != 0) && ((q / ul) != ur)) - ovfl = 1; - } else { - q = sl * sr; - if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) - ovfl = 1; - } - break; - case DIV: - if (sr == 0) { - /* division by 0 */ - error(139); - q = utyp ? UQUAD_MAX : QUAD_MAX; - } else { - q = utyp ? ul / ur : sl / sr; - } - break; - case MOD: - if (sr == 0) { - /* modulus by 0 */ - error(140); - q = 0; - } else { - q = utyp ? ul % ur : sl % sr; - } - break; - case PLUS: - q = utyp ? ul + ur : sl + sr; - if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { - if (msb(q, t, -1) == 0) - ovfl = 1; - } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { - if (msb(q, t, -1) != 0) - ovfl = 1; - } - break; - case MINUS: - q = utyp ? ul - ur : sl - sr; - if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { - if (msb(q, t, -1) == 0) - ovfl = 1; - } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { - if (msb(q, t, -1) != 0) - ovfl = 1; - } - break; - case SHL: - q = utyp ? ul << sr : sl << sr; - break; - case SHR: - /* - * The sign must be explicitly extended because - * shifts of signed values are implementation dependent. - */ - q = ul >> sr; - q = xsign(q, t, size(t) - (int)sr); - break; - case LT: - q = utyp ? ul < ur : sl < sr; - break; - case LE: - q = utyp ? ul <= ur : sl <= sr; - break; - case GE: - q = utyp ? ul >= ur : sl >= sr; - break; - case GT: - q = utyp ? ul > ur : sl > sr; - break; - case EQ: - q = utyp ? ul == ur : sl == sr; - break; - case NE: - q = utyp ? ul != ur : sl != sr; - break; - case AND: - q = utyp ? ul & ur : sl & sr; - break; - case XOR: - q = utyp ? ul ^ ur : sl ^ sr; - break; - case OR: - q = utyp ? ul | ur : sl | sr; - break; - default: - LERROR("fold()"); - } - - /* XXX does not work for quads. */ - if (ovfl || ((q | mask) != ~(uint64_t)0 && (q & ~mask) != 0)) { - if (hflag) - /* integer overflow detected, op %s */ - warning(141, modtab[tn->tn_op].m_name); - } - - v->v_quad = xsign(q, t, -1); - - cn = getcnode(tn->tn_type, v); - - return (cn); -} - -/* - * Same for operators whose operands are compared with 0 (test context). - */ -static tnode_t * -foldtst(tnode_t *tn) -{ - int l, r = 0; - val_t *v; - - if ((v = calloc(1, sizeof (val_t))) == NULL) - nomem(); - v->v_tspec = tn->tn_type->t_tspec; - if (tn->tn_type->t_tspec != INT) - LERROR("foldtst()"); - - if (isftyp(tn->tn_left->tn_type->t_tspec)) { - l = tn->tn_left->tn_val->v_ldbl != 0.0; - } else { - l = tn->tn_left->tn_val->v_quad != 0; - } - - if (modtab[tn->tn_op].m_binary) { - if (isftyp(tn->tn_right->tn_type->t_tspec)) { - r = tn->tn_right->tn_val->v_ldbl != 0.0; - } else { - r = tn->tn_right->tn_val->v_quad != 0; - } - } - - switch (tn->tn_op) { - case NOT: - if (hflag) - /* constant argument to NOT */ - warning(239); - v->v_quad = !l; - break; - case LOGAND: - v->v_quad = l && r; - break; - case LOGOR: - v->v_quad = l || r; - break; - default: - LERROR("foldtst()"); - } - - return (getcnode(tn->tn_type, v)); -} - -/* - * Same for operands with floating point type. - */ -static tnode_t * -foldflt(tnode_t *tn) -{ - val_t *v; - tspec_t t; - ldbl_t l, r = 0; - - if ((v = calloc(1, sizeof (val_t))) == NULL) - nomem(); - v->v_tspec = t = tn->tn_type->t_tspec; - - if (!isftyp(t)) - LERROR("foldflt()"); - - if (t != tn->tn_left->tn_type->t_tspec) - LERROR("foldflt()"); - if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec) - LERROR("foldflt()"); - - l = tn->tn_left->tn_val->v_ldbl; - if (modtab[tn->tn_op].m_binary) - r = tn->tn_right->tn_val->v_ldbl; - - switch (tn->tn_op) { - case UPLUS: - v->v_ldbl = l; - break; - case UMINUS: - v->v_ldbl = -l; - break; - case MULT: - v->v_ldbl = l * r; - break; - case DIV: - if (r == 0.0) { - /* division by 0 */ - error(139); - if (t == FLOAT) { - v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX; - } else if (t == DOUBLE) { - v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX; - } else { - v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX; - } - } else { - v->v_ldbl = l / r; - } - break; - case PLUS: - v->v_ldbl = l + r; - break; - case MINUS: - v->v_ldbl = l - r; - break; - case LT: - v->v_quad = l < r; - break; - case LE: - v->v_quad = l <= r; - break; - case GE: - v->v_quad = l >= r; - break; - case GT: - v->v_quad = l > r; - break; - case EQ: - v->v_quad = l == r; - break; - case NE: - v->v_quad = l != r; - break; - default: - LERROR("foldflt()"); - } - - if (isnan((double)v->v_ldbl)) - LERROR("foldflt()"); - if (!finite((double)v->v_ldbl) || - (t == FLOAT && - (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || - (t == DOUBLE && - (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { - /* floating point overflow detected, op %s */ - warning(142, modtab[tn->tn_op].m_name); - if (t == FLOAT) { - v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; - } else if (t == DOUBLE) { - v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; - } else { - v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; - } - } - - return (getcnode(tn->tn_type, v)); -} - -/* - * Create a constant node for sizeof. - */ -tnode_t * -bldszof(type_t *tp) -{ - int elem, elsz; - tspec_t st; - - elem = 1; - while (tp->t_tspec == ARRAY) { - elem *= tp->t_dim; - tp = tp->t_subt; - } - if (elem == 0) { - /* cannot take size of incomplete type */ - error(143); - elem = 1; - } - switch (tp->t_tspec) { - case FUNC: - /* cannot take size of function */ - error(144); - elsz = 1; - break; - case STRUCT: - case UNION: - if (incompl(tp)) { - /* cannot take size of incomplete type */ - error(143); - elsz = 1; - } else { - elsz = tp->t_str->size; - } - break; - case ENUM: - if (incompl(tp)) { - /* cannot take size of incomplete type */ - warning(143); - } - /* FALLTHROUGH */ - default: - if (tp->t_isfield) { - /* cannot take size of bit-field */ - error(145); - } - if (tp->t_tspec == VOID) { - /* cannot take size of void */ - error(146); - elsz = 1; - } else { - elsz = size(tp->t_tspec); - if (elsz <= 0) - LERROR("bldszof()"); - } - break; - } - -#if SIZEOF_IS_ULONG - st = ULONG; -#else - st = UINT; -#endif - - return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); -} - -/* - * Type casts. - */ -tnode_t * -cast(tnode_t *tn, type_t *tp) -{ - tspec_t nt, ot; - - if (tn == NULL) - return (NULL); - - tn = cconv(tn); - - nt = tp->t_tspec; - ot = tn->tn_type->t_tspec; - - if (nt == VOID) { - /* - * XXX ANSI C requires scalar types or void (Plauger&Brodie). - * But this seams really questionable. - */ - } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) { - /* invalid cast expression */ - error(147); - return (NULL); - } else if (ot == STRUCT || ot == UNION) { - /* invalid cast expression */ - error(147); - return (NULL); - } else if (ot == VOID) { - /* improper cast of void expression */ - error(148); - return (NULL); - } else if (isityp(nt) && issclt(ot)) { - /* ok */ - } else if (isftyp(nt) && isatyp(ot)) { - /* ok */ - } else if (nt == PTR && isityp(ot)) { - /* ok */ - } else if (nt == PTR && ot == PTR) { - if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { - if (hflag) - /* cast discards 'const' from ... */ - warning(275); - } - } else { - /* invalid cast expression */ - error(147); - return (NULL); - } - - tn = convert(CVT, 0, tp, tn); - tn->tn_cast = 1; - - return (tn); -} - -/* - * Create the node for a function argument. - * All necessary conversions and type checks are done in funccall(), because - * in funcarg() we have no information about expected argument types. - */ -tnode_t * -funcarg(tnode_t *args, tnode_t *arg) -{ - tnode_t *ntn; - - /* - * If there was a serious error in the expression for the argument, - * create a dummy argument so the positions of the remaining arguments - * will not change. - */ - if (arg == NULL) - arg = getinode(INT, (int64_t)0); - - ntn = mktnode(PUSH, arg->tn_type, arg, args); - - return (ntn); -} - -/* - * Create the node for a function call. Also check types of - * function arguments and insert conversions, if necessary. - */ -tnode_t * -funccall(tnode_t *func, tnode_t *args) -{ - tnode_t *ntn; - op_t fcop; - - if (func == NULL) - return (NULL); - - if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { - fcop = CALL; - } else { - fcop = ICALL; - } - - /* - * after cconv() func will always be a pointer to a function - * if it is a valid function designator. - */ - func = cconv(func); - - if (func->tn_type->t_tspec != PTR || - func->tn_type->t_subt->t_tspec != FUNC) { - /* illegal function */ - error(149); - return (NULL); - } - - args = chkfarg(func->tn_type->t_subt, args); - - ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args); - - return (ntn); -} - -/* - * Check types of all function arguments and insert conversions, - * if necessary. - */ -static tnode_t * -chkfarg(type_t *ftp, tnode_t *args) -{ - tnode_t *arg; - sym_t *asym; - tspec_t at; - int narg, npar, n, i; - - /* get # of args in the prototype */ - npar = 0; - for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt) - npar++; - - /* get # of args in function call */ - narg = 0; - for (arg = args; arg != NULL; arg = arg->tn_right) - narg++; - - asym = ftp->t_args; - if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { - /* argument mismatch: %d arg%s passed, %d expected */ - error(150, narg, narg > 1 ? "s" : "", npar); - asym = NULL; - } - - for (n = 1; n <= narg; n++) { - - /* - * The rightmost argument is at the top of the argument - * subtree. - */ - for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) - continue; - - /* some things which are always not allowd */ - if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { - /* void expressions may not be arguments, arg #%d */ - error(151, n); - return (NULL); - } else if ((at == STRUCT || at == UNION) && - incompl(arg->tn_left->tn_type)) { - /* argument cannot have unknown size, arg #%d */ - error(152, n); - return (NULL); - } else if (isityp(at) && arg->tn_left->tn_type->t_isenum && - incompl(arg->tn_left->tn_type)) { - /* argument cannot have unknown size, arg #%d */ - warning(152, n); - } - - /* class conversions (arg in value context) */ - arg->tn_left = cconv(arg->tn_left); - - if (asym != NULL) { - arg->tn_left = parg(n, asym->s_type, arg->tn_left); - } else { - arg->tn_left = promote(NOOP, 1, arg->tn_left); - } - arg->tn_type = arg->tn_left->tn_type; - - if (asym != NULL) - asym = asym->s_nxt; - } - - return (args); -} - -/* - * Compare the type of an argument with the corresponding type of a - * prototype parameter. If it is a valid combination, but both types - * are not the same, insert a conversion to convert the argument into - * the type of the parameter. - */ -static tnode_t * -parg( int n, /* pos of arg */ - type_t *tp, /* expected type (from prototype) */ - tnode_t *tn) /* argument */ -{ - tnode_t *ln; - int warn; - - if ((ln = calloc(1, sizeof (tnode_t))) == NULL) - nomem(); - ln->tn_type = tduptyp(tp); - ln->tn_type->t_const = 0; - ln->tn_lvalue = 1; - if (typeok(FARG, n, ln, tn)) { - if (!eqtype(tp, tn->tn_type, 1, 0, (warn = 0, &warn)) || warn) - tn = convert(FARG, n, tp, tn); - } - free(ln); - return (tn); -} - -/* - * Return the value of an integral constant expression. - * If the expression is not constant or its type is not an integer - * type, an error message is printed. - */ -val_t * -constant(tnode_t *tn, int required) -{ - val_t *v; - - if (tn != NULL) - tn = cconv(tn); - if (tn != NULL) - tn = promote(NOOP, 0, tn); - - if ((v = calloc(1, sizeof (val_t))) == NULL) - nomem(); - - if (tn == NULL) { - if (nerr == 0) - LERROR("constant()"); - v->v_tspec = INT; - v->v_quad = 1; - return (v); - } - - v->v_tspec = tn->tn_type->t_tspec; - - if (tn->tn_op == CON) { - if (tn->tn_type->t_tspec != tn->tn_val->v_tspec) - LERROR("constant()"); - if (isityp(tn->tn_val->v_tspec)) { - v->v_ansiu = tn->tn_val->v_ansiu; - v->v_quad = tn->tn_val->v_quad; - return (v); - } - v->v_quad = tn->tn_val->v_ldbl; - } else { - v->v_quad = 1; - } - - /* integral constant expression expected */ - if (required) - error(55); - else - c99ism(318); - - if (!isityp(v->v_tspec)) - v->v_tspec = INT; - - return (v); -} - -/* - * Perform some tests on expressions which can't be done in build() and - * functions called by build(). These tests must be done here because - * we need some information about the context in which the operations - * are performed. - * After all tests are performed, expr() frees the memory which is used - * for the expression. - */ -void -expr(tnode_t *tn, int vctx, int tctx, int freeblk) -{ - - if (tn == NULL && nerr == 0) - LERROR("expr()"); - - if (tn == NULL) { - tfreeblk(); - return; - } - - /* expr() is also called in global initialisations */ - if (dcs->d_ctx != EXTERN) - chkreach(); - - chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0); - if (tn->tn_op == ASSIGN) { - if (hflag && tctx) - /* assignment in conditional context */ - warning(159); - } else if (tn->tn_op == CON) { - if (hflag && tctx && !ccflg) - /* constant in conditional context */ - warning(161); - } - if (!modtab[tn->tn_op].m_sideeff) { - /* - * for left operands of COMMA this warning is already - * printed - */ - if (tn->tn_op != COMMA && !vctx && !tctx) - nulleff(tn); - } - if (dflag) - displexpr(tn, 0); - - /* free the tree memory */ - if (freeblk) - tfreeblk(); -} - -static void -nulleff(tnode_t *tn) -{ - - if (!hflag) - return; - - while (!modtab[tn->tn_op].m_sideeff) { - if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) { - tn = tn->tn_left; - } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) { - /* - * && and || have a side effect if the right operand - * has a side effect. - */ - tn = tn->tn_right; - } else if (tn->tn_op == QUEST) { - /* - * ? has a side effect if at least one of its right - * operands has a side effect - */ - tn = tn->tn_right; - } else if (tn->tn_op == COLON || tn->tn_op == COMMA) { - /* - * : has a side effect if at least one of its operands - * has a side effect - */ - if (modtab[tn->tn_left->tn_op].m_sideeff) { - tn = tn->tn_left; - } else if (modtab[tn->tn_right->tn_op].m_sideeff) { - tn = tn->tn_right; - } else { - break; - } - } else { - break; - } - } - if (!modtab[tn->tn_op].m_sideeff) - /* expression has null effect */ - warning(129); -} - -/* - * Dump an expression to stdout - * only used for debugging - */ -static void -displexpr(tnode_t *tn, int offs) -{ - uint64_t uq; - - if (tn == NULL) { - (void)printf("%*s%s\n", offs, "", "NULL"); - return; - } - (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); - - if (tn->tn_op == NAME) { - (void)printf("%s: %s ", - tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl)); - } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) { - (void)printf("%#g ", (double)tn->tn_val->v_ldbl); - } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) { - uq = tn->tn_val->v_quad; - (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl, - (long)uq & 0xffffffffl); - } else if (tn->tn_op == CON) { - if (tn->tn_type->t_tspec != PTR) - LERROR("displexpr()"); - (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), - (u_long)tn->tn_val->v_quad); - } else if (tn->tn_op == STRING) { - if (tn->tn_strg->st_tspec == CHAR) { - (void)printf("\"%s\"", tn->tn_strg->st_cp); - } else { - char *s; - size_t n; - n = MB_CUR_MAX * (tn->tn_strg->st_len + 1); - if ((s = malloc(n)) == NULL) - nomem(); - (void)wcstombs(s, tn->tn_strg->st_wcp, n); - (void)printf("L\"%s\"", s); - free(s); - } - (void)printf(" "); - } else if (tn->tn_op == FSEL) { - (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, - tn->tn_type->t_flen); - } - (void)printf("%s\n", ttos(tn->tn_type)); - if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) - return; - displexpr(tn->tn_left, offs + 2); - if (modtab[tn->tn_op].m_binary || - (tn->tn_op == PUSH && tn->tn_right != NULL)) { - displexpr(tn->tn_right, offs + 2); - } -} - -/* - * Called by expr() to recursively perform some tests. - */ -/* ARGSUSED */ -void -chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, - int szof) -{ - tnode_t *ln, *rn; - mod_t *mp; - int nrvdisc, cvctx, ctctx; - op_t op; - scl_t sc; - dinfo_t *di; - - if (tn == NULL) - return; - - ln = tn->tn_left; - rn = tn->tn_right; - mp = &modtab[op = tn->tn_op]; - - switch (op) { - case AMPER: - if (ln->tn_op == NAME && (reached || rchflg)) { - if (!szof) - setsflg(ln->tn_sym); - setuflg(ln->tn_sym, fcall, szof); - } - if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) - /* check the range of array indices */ - chkaidx(ln->tn_left, 1); - break; - case LOAD: - if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) - /* check the range of array indices */ - chkaidx(ln->tn_left, 0); - /* FALLTHROUGH */ - case PUSH: - case INCBEF: - case DECBEF: - case INCAFT: - case DECAFT: - case ADDASS: - case SUBASS: - case MULASS: - case DIVASS: - case MODASS: - case ANDASS: - case ORASS: - case XORASS: - case SHLASS: - case SHRASS: - if (ln->tn_op == NAME && (reached || rchflg)) { - sc = ln->tn_sym->s_scl; - /* - * Look if there was an asm statement in one of the - * compound statements we are in. If not, we don't - * print a warning. - */ - for (di = dcs; di != NULL; di = di->d_nxt) { - if (di->d_asm) - break; - } - if (sc != EXTERN && sc != STATIC && - !ln->tn_sym->s_set && !szof && di == NULL) { - /* %s may be used before set */ - warning(158, ln->tn_sym->s_name); - setsflg(ln->tn_sym); - } - setuflg(ln->tn_sym, 0, 0); - } - break; - case ASSIGN: - if (ln->tn_op == NAME && !szof && (reached || rchflg)) { - setsflg(ln->tn_sym); - if (ln->tn_sym->s_scl == EXTERN) - outusg(ln->tn_sym); - } - if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) - /* check the range of array indices */ - chkaidx(ln->tn_left, 0); - break; - case CALL: - if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) - LERROR("chkmisc()"); - if (!szof) - outcall(tn, vctx || tctx, rvdisc); - break; - case EQ: - /* equality operator "==" found where "=" was exp. */ - if (hflag && eqwarn) - warning(160); - break; - case CON: - case NAME: - case STRING: - return; - /* LINTED (enumeration values not handled in switch) */ - case OR: - case XOR: - case NE: - case GE: - case GT: - case LE: - case LT: - case SHR: - case SHL: - case MINUS: - case PLUS: - case MOD: - case DIV: - case MULT: - case STAR: - case UMINUS: - case UPLUS: - case DEC: - case INC: - case COMPL: - case NOT: - case POINT: - case ARROW: - case NOOP: - case AND: - case FARG: - case CASE: - case INIT: - case RETURN: - case ICALL: - case CVT: - case COMMA: - case FSEL: - case COLON: - case QUEST: - case LOGOR: - case LOGAND: - break; - } - - cvctx = mp->m_vctx; - ctctx = mp->m_tctx; - /* - * values of operands of ':' are not used if the type of at least - * one of the operands (for gcc compatibility) is void - * XXX test/value context of QUEST should probably be used as - * context for both operands of COLON - */ - if (op == COLON && tn->tn_type->t_tspec == VOID) - cvctx = ctctx = 0; - nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; - chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof); - - switch (op) { - case PUSH: - if (rn != NULL) - chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof); - break; - case LOGAND: - case LOGOR: - chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof); - break; - case COLON: - chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof); - break; - case COMMA: - chkmisc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof); - break; - default: - if (mp->m_binary) - chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof); - break; - } - -} - -/* - * Checks the range of array indices, if possible. - * amper is set if only the address of the element is used. This - * means that the index is allowed to refer to the first element - * after the array. - */ -static void -chkaidx(tnode_t *tn, int amper) -{ - int dim; - tnode_t *ln, *rn; - int elsz; - int64_t con; - - ln = tn->tn_left; - rn = tn->tn_right; - - /* We can only check constant indices. */ - if (rn->tn_op != CON) - return; - - /* Return if the left node does not stem from an array. */ - if (ln->tn_op != AMPER) - return; - if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) - return; - if (ln->tn_left->tn_type->t_tspec != ARRAY) - return; - - /* - * For incomplete array types, we can print a warning only if - * the index is negative. - */ - if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) - return; - - /* Get the size of one array element */ - if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) - return; - elsz /= CHAR_BIT; - - /* Change the unit of the index from bytes to element size. */ - if (isutyp(rn->tn_type->t_tspec)) { - con = (uint64_t)rn->tn_val->v_quad / elsz; - } else { - con = rn->tn_val->v_quad / elsz; - } - - dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); - - if (!isutyp(rn->tn_type->t_tspec) && con < 0) { - /* array subscript cannot be negative: %ld */ - warning(167, (long)con); - } else if (dim > 0 && (uint64_t)con >= dim) { - /* array subscript cannot be > %d: %ld */ - warning(168, dim - 1, (long)con); - } -} - -/* - * Check for ordered comparisons of unsigned values with 0. - */ -static void -chkcomp(op_t op, tnode_t *ln, tnode_t *rn) -{ - char buf[64]; - tspec_t lt, rt; - mod_t *mp; - - lt = ln->tn_type->t_tspec; - rt = rn->tn_type->t_tspec; - mp = &modtab[op]; - - if (ln->tn_op != CON && rn->tn_op != CON) - return; - - if (!isityp(lt) || !isityp(rt)) - return; - - if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && - (rn->tn_val->v_quad < 0 || - rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { - /* nonportable character comparison, op %s */ - warning(230, mp->m_name); - return; - } - if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && - (ln->tn_val->v_quad < 0 || - ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { - /* nonportable character comparison, op %s */ - warning(230, mp->m_name); - return; - } - if (isutyp(lt) && !isutyp(rt) && - rn->tn_op == CON && rn->tn_val->v_quad <= 0) { - if (rn->tn_val->v_quad < 0) { - /* comparison of %s with %s, op %s */ - warning(162, tyname(buf, sizeof(buf), ln->tn_type), - "negative constant", mp->m_name); - } else if (op == LT || op == GE || (hflag && op == LE)) { - /* comparison of %s with %s, op %s */ - warning(162, tyname(buf, sizeof(buf), ln->tn_type), - "0", mp->m_name); - } - return; - } - if (isutyp(rt) && !isutyp(lt) && - ln->tn_op == CON && ln->tn_val->v_quad <= 0) { - if (ln->tn_val->v_quad < 0) { - /* comparison of %s with %s, op %s */ - warning(162, "negative constant", - tyname(buf, sizeof(buf), rn->tn_type), mp->m_name); - } else if (op == GT || op == LE || (hflag && op == GE)) { - /* comparison of %s with %s, op %s */ - warning(162, "0", tyname(buf, sizeof(buf), rn->tn_type), - mp->m_name); - } - return; - } -} - -/* - * Takes an expression and returns 0 if this expression can be used - * for static initialisation, otherwise -1. - * - * Constant initialisation expressions must be constant or an address - * of a static object with an optional offset. In the first case, - * the result is returned in *offsp. In the second case, the static - * object is returned in *symp and the offset in *offsp. - * - * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and - * CON. Type conversions are allowed if they do not change binary - * representation (including width). - */ -int -conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) -{ - sym_t *sym; - ptrdiff_t offs1, offs2; - tspec_t t, ot; - - switch (tn->tn_op) { - case MINUS: - if (tn->tn_right->tn_op == CVT) - return conaddr(tn->tn_right, symp, offsp); - else if (tn->tn_right->tn_op != CON) - return (-1); - /* FALLTHROUGH */ - case PLUS: - offs1 = offs2 = 0; - if (tn->tn_left->tn_op == CON) { - offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; - if (conaddr(tn->tn_right, &sym, &offs2) == -1) - return (-1); - } else if (tn->tn_right->tn_op == CON) { - offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; - if (tn->tn_op == MINUS) - offs2 = -offs2; - if (conaddr(tn->tn_left, &sym, &offs1) == -1) - return (-1); - } else { - return (-1); - } - *symp = sym; - *offsp = offs1 + offs2; - break; - case AMPER: - if (tn->tn_left->tn_op == NAME) { - *symp = tn->tn_left->tn_sym; - *offsp = 0; - } else if (tn->tn_left->tn_op == STRING) { - /* - * If this would be the front end of a compiler we - * would return a label instead of 0. - */ - *offsp = 0; - } - break; - case CVT: - t = tn->tn_type->t_tspec; - ot = tn->tn_left->tn_type->t_tspec; - if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) - return (-1); - else if (psize(t) != psize(ot)) { - return (-1); - } - if (conaddr(tn->tn_left, symp, offsp) == -1) - return (-1); - break; - default: - return (-1); - } - return (0); -} - -/* - * Concatenate two string constants. - */ -strg_t * -catstrg(strg_t *strg1, strg_t *strg2) -{ - size_t len1, len2, len; - - if (strg1->st_tspec != strg2->st_tspec) { - /* cannot concatenate wide and regular string literals */ - error(292); - return (strg1); - } - - len = (len1 = strg1->st_len) + (len2 = strg2->st_len); - - if (strg1->st_tspec == CHAR) { - if ((strg1->st_cp = realloc(strg1->st_cp, len + 1)) == NULL) - nomem(); - (void)memcpy(strg1->st_cp + len1, strg2->st_cp, len2 + 1); - free(strg2->st_cp); - } else { - if ((strg1->st_wcp = realloc(strg1->st_wcp, (len + 1) * - sizeof (wchar_t))) == NULL) - nomem(); - (void)memcpy(strg1->st_wcp + len1, strg2->st_wcp, - (len2 + 1) * sizeof (wchar_t)); - free(strg2->st_wcp); - } - strg1->st_len = len; - free(strg2); - - return (strg1); -} - -/* - * Print a warning if the given node has operands which should be - * parenthesized. - * - * XXX Does not work if an operand is a constant expression. Constant - * expressions are already folded. - */ -static void -precconf(tnode_t *tn) -{ - tnode_t *ln, *rn; - op_t lop, rop = NOOP; - int lparn, rparn = 0; - mod_t *mp; - int warn; - - if (!hflag) - return; - - mp = &modtab[tn->tn_op]; - - lparn = 0; - for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) - lparn |= ln->tn_parn; - lparn |= ln->tn_parn; - lop = ln->tn_op; - - if (mp->m_binary) { - rparn = 0; - for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left) - rparn |= rn->tn_parn; - rparn |= rn->tn_parn; - rop = rn->tn_op; - } - - warn = 0; - - switch (tn->tn_op) { - case SHL: - case SHR: - if (!lparn && (lop == PLUS || lop == MINUS)) { - warn = 1; - } else if (!rparn && (rop == PLUS || rop == MINUS)) { - warn = 1; - } - break; - case LOGOR: - if (!lparn && lop == LOGAND) { - warn = 1; - } else if (!rparn && rop == LOGAND) { - warn = 1; - } - break; - case AND: - case XOR: - case OR: - if (!lparn && lop != tn->tn_op) { - if (lop == PLUS || lop == MINUS) { - warn = 1; - } else if (lop == AND || lop == XOR) { - warn = 1; - } - } - if (!warn && !rparn && rop != tn->tn_op) { - if (rop == PLUS || rop == MINUS) { - warn = 1; - } else if (rop == AND || rop == XOR) { - warn = 1; - } - } - break; - /* LINTED (enumeration values not handled in switch) */ - case DECAFT: - case XORASS: - case SHLASS: - case NOOP: - case ARROW: - case ORASS: - case POINT: - case NAME: - case NOT: - case COMPL: - case CON: - case INC: - case STRING: - case DEC: - case INCBEF: - case DECBEF: - case INCAFT: - case FSEL: - case CALL: - case COMMA: - case CVT: - case ICALL: - case LOAD: - case PUSH: - case RETURN: - case INIT: - case CASE: - case FARG: - case SUBASS: - case ADDASS: - case MODASS: - case DIVASS: - case MULASS: - case ASSIGN: - case COLON: - case QUEST: - case LOGAND: - case NE: - case EQ: - case GE: - case GT: - case LE: - case LT: - case MINUS: - case PLUS: - case MOD: - case DIV: - case MULT: - case AMPER: - case STAR: - case UMINUS: - case SHRASS: - case UPLUS: - case ANDASS: - break; - } - - if (warn) { - /* precedence confusion possible: parenthesize! */ - warning(169); - } - -} Index: usr.bin/xlint/lint2/Makefile =================================================================== --- usr.bin/xlint/lint2/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# $NetBSD: Makefile,v 1.2 1995/07/03 21:24:39 cgd Exp $ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../lint1 - -PROG= lint2 -SRCS= main2.c hash.c read.c mem.c mem2.c chk.c msg.c emit.c emit2.c inittyp.c -MAN= -CFLAGS+=-I${.CURDIR}/../lint1 -LINTFLAGS=-abehrz - -BINDIR= ${LIBEXECDIR} - -.include Index: usr.bin/xlint/lint2/Makefile.depend =================================================================== --- usr.bin/xlint/lint2/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.bin/xlint/lint2/chk.c =================================================================== --- usr.bin/xlint/lint2/chk.c +++ /dev/null @@ -1,1350 +0,0 @@ -/* $NetBSD: chk.c,v 1.15 2002/01/21 19:49:52 tv Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: chk.c,v 1.15 2002/01/21 19:49:52 tv Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include "lint2.h" - -static void chkund(hte_t *); -static void chkdnu(hte_t *); -static void chkdnud(hte_t *); -static void chkmd(hte_t *); -static void chkvtui(hte_t *, sym_t *, sym_t *); -static void chkvtdi(hte_t *, sym_t *, sym_t *); -static void chkfaui(hte_t *, sym_t *, sym_t *); -static void chkau(hte_t *, int, sym_t *, sym_t *, pos_t *, - fcall_t *, fcall_t *, type_t *, type_t *); -static void chkrvu(hte_t *, sym_t *); -static void chkadecl(hte_t *, sym_t *, sym_t *); -static void printflike(hte_t *,fcall_t *, int, const char *, type_t **); -static void scanflike(hte_t *, fcall_t *, int, const char *, type_t **); -static void badfmt(hte_t *, fcall_t *); -static void inconarg(hte_t *, fcall_t *, int); -static void tofewarg(hte_t *, fcall_t *); -static void tomanyarg(hte_t *, fcall_t *); -static int eqtype(type_t *, type_t *, int, int, int, int *); -static int eqargs(type_t *, type_t *, int *); -static int mnoarg(type_t *, int *); - - -/* - * If there is a symbol named "main", mark it as used. - */ -void -mainused(void) -{ - hte_t *hte; - - if ((hte = hsearch("main", 0)) != NULL) - hte->h_used = 1; -} - -/* - * Performs all tests for a single name - */ -void -chkname(hte_t *hte) -{ - sym_t *sym, *def, *pdecl, *decl; - - if (uflag) { - chkund(hte); - chkdnu(hte); - if (xflag) - chkdnud(hte); - } - chkmd(hte); - - /* Get definition, prototype declaration and declaration */ - def = pdecl = decl = NULL; - for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { - if (def == NULL && (sym->s_def == DEF || sym->s_def == TDEF)) - def = sym; - if (pdecl == NULL && sym->s_def == DECL && - TP(sym->s_type)->t_tspec == FUNC && - TP(sym->s_type)->t_proto) { - pdecl = sym; - } - if (decl == NULL && sym->s_def == DECL) - decl = sym; - } - - /* A prototype is better than an old style declaration. */ - if (pdecl != NULL) - decl = pdecl; - - chkvtui(hte, def, decl); - - chkvtdi(hte, def, decl); - - chkfaui(hte, def, decl); - - chkrvu(hte, def); - - chkadecl(hte, def, decl); -} - -/* - * Print a warning if the name has been used, but not defined. - */ -static void -chkund(hte_t *hte) -{ - fcall_t *fcall; - usym_t *usym; - - if (!hte->h_used || hte->h_def) - return; - - if ((fcall = hte->h_calls) != NULL) { - /* %s used( %s ), but not defined */ - msg(0, hte->h_name, mkpos(&fcall->f_pos)); - } else if ((usym = hte->h_usyms) != NULL) { - /* %s used( %s ), but not defined */ - msg(0, hte->h_name, mkpos(&usym->u_pos)); - } -} - -/* - * Print a warning if the name has been defined, but never used. - */ -static void -chkdnu(hte_t *hte) -{ - sym_t *sym; - - if (!hte->h_def || hte->h_used) - return; - - for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { - if (sym->s_def == DEF || sym->s_def == TDEF) { - /* %s defined( %s ), but never used */ - msg(1, hte->h_name, mkpos(&sym->s_pos)); - break; - } - } -} - -/* - * Print a warning if the variable has been declared, but is not used - * or defined. - */ -static void -chkdnud(hte_t *hte) -{ - sym_t *sym; - - if (hte->h_syms == NULL || hte->h_used || hte->h_def) - return; - - sym = hte->h_syms; - if (TP(sym->s_type)->t_tspec == FUNC) - return; - - if (sym->s_def != DECL) - errx(1, "internal error: chkdnud() 1"); - /* %s declared( %s ), but never used or defined */ - msg(2, hte->h_name, mkpos(&sym->s_pos)); -} - -/* - * Print a warning if there is more than one definition for - * this name. - */ -static void -chkmd(hte_t *hte) -{ - sym_t *sym, *def1; - char *pos1; - - if (!hte->h_def) - return; - - def1 = NULL; - for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { - /* - * ANSI C allows tentative definitions of the same name in - * only one compilation unit. - */ - if (sym->s_def != DEF && (!sflag || sym->s_def != TDEF)) - continue; - if (def1 == NULL) { - def1 = sym; - continue; - } - pos1 = xstrdup(mkpos(&def1->s_pos)); - /* %s multiply defined\t%s :: %s */ - msg(3, hte->h_name, pos1, mkpos(&sym->s_pos)); - free(pos1); - } -} - -/* - * Print a warning if the return value assumed for a function call - * differs from the return value of the function definition or - * function declaration. - * - * If no definition/declaration can be found, the assumed return values - * are always int. So there is no need to compare with another function - * call as it's done for function arguments. - */ -static void -chkvtui(hte_t *hte, sym_t *def, sym_t *decl) -{ - fcall_t *call; - char *pos1; - type_t *tp1, *tp2; - /* LINTED (automatic hides external declaration: warn) */ - int warn, eq; - tspec_t t1; - - if (hte->h_calls == NULL) - return; - - if (def == NULL) - def = decl; - if (def == NULL) - return; - - t1 = (tp1 = TP(def->s_type)->t_subt)->t_tspec; - for (call = hte->h_calls; call != NULL; call = call->f_nxt) { - tp2 = TP(call->f_type)->t_subt; - eq = eqtype(tp1, tp2, 1, 0, 0, (warn = 0, &warn)); - if (!call->f_rused) { - /* no return value used */ - if ((t1 == STRUCT || t1 == UNION) && !eq) { - /* - * If a function returns a struct or union it - * must be declared to return a struct or - * union, also if the return value is ignored. - * This is necessary because the caller must - * allocate stack space for the return value. - * If it does not, the return value would over- - * write other data. - * XXX Following massage may be confusing - * because it appears also if the return value - * was declared inconsistently. But this - * behaviour matches pcc based lint, so it is - * accepted for now. - */ - pos1 = xstrdup(mkpos(&def->s_pos)); - /* %s value must be decl. before use %s :: %s */ - msg(17, hte->h_name, - pos1, mkpos(&call->f_pos)); - free(pos1); - } - continue; - } - if (!eq || (sflag && warn)) { - pos1 = xstrdup(mkpos(&def->s_pos)); - /* %s value used inconsistenty\t%s :: %s */ - msg(4, hte->h_name, pos1, mkpos(&call->f_pos)); - free(pos1); - } - } -} - -/* - * Print a warning if a definition/declaration does not match another - * definition/declaration of the same name. For functions, only the - * types of return values are tested. - */ -static void -chkvtdi(hte_t *hte, sym_t *def, sym_t *decl) -{ - sym_t *sym; - type_t *tp1, *tp2; - /* LINTED (automatic hides external declaration: warn) */ - int eq, warn; - char *pos1; - - if (def == NULL) - def = decl; - if (def == NULL) - return; - - tp1 = TP(def->s_type); - for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { - if (sym == def) - continue; - tp2 = TP(sym->s_type); - warn = 0; - if (tp1->t_tspec == FUNC && tp2->t_tspec == FUNC) { - eq = eqtype(tp1->t_subt, tp2->t_subt, 1, 0, 0, &warn); - } else { - eq = eqtype(tp1, tp2, 0, 0, 0, &warn); - } - if (!eq || (sflag && warn)) { - pos1 = xstrdup(mkpos(&def->s_pos)); - /* %s value declared inconsistently\t%s :: %s */ - msg(5, hte->h_name, pos1, mkpos(&sym->s_pos)); - free(pos1); - } - } -} - -/* - * Print a warning if a function is called with arguments which does - * not match the function definition, declaration or another call - * of the same function. - */ -static void -chkfaui(hte_t *hte, sym_t *def, sym_t *decl) -{ - type_t *tp1, *tp2, **ap1, **ap2; - pos_t *pos1p = NULL; - fcall_t *calls, *call, *call1; - int n, as; - char *pos1; - arginf_t *ai; - - if ((calls = hte->h_calls) == NULL) - return; - - /* - * If we find a function definition, we use this for comparison, - * otherwise the first prototype we can find. If there is no - * definition or prototype declaration, the first function call - * is used. - */ - tp1 = NULL; - call1 = NULL; - if (def != NULL) { - if ((tp1 = TP(def->s_type))->t_tspec != FUNC) - return; - pos1p = &def->s_pos; - } else if (decl != NULL && TP(decl->s_type)->t_proto) { - if ((tp1 = TP(decl->s_type))->t_tspec != FUNC) - return; - pos1p = &decl->s_pos; - } - if (tp1 == NULL) { - call1 = calls; - calls = calls->f_nxt; - if ((tp1 = TP(call1->f_type))->t_tspec != FUNC) - return; - pos1p = &call1->f_pos; - } - - n = 1; - for (call = calls; call != NULL; call = call->f_nxt) { - if ((tp2 = TP(call->f_type))->t_tspec != FUNC) - continue; - ap1 = tp1->t_args; - ap2 = tp2->t_args; - n = 0; - while (*ap1 != NULL && *ap2 != NULL) { - if (def != NULL && def->s_va && n >= def->s_nva) - break; - n++; - chkau(hte, n, def, decl, pos1p, call1, call, - *ap1, *ap2); - ap1++; - ap2++; - } - if (*ap1 == *ap2) { - /* equal # of arguments */ - } else if (def != NULL && def->s_va && n >= def->s_nva) { - /* - * function definition with VARARGS; The # of - * arguments of the call must be at least as large - * as the parameter of VARARGS. - */ - } else if (*ap2 != NULL && tp1->t_proto && tp1->t_vararg) { - /* - * prototype with ... and function call with - * at least the same # of arguments as declared - * in the prototype. - */ - } else { - pos1 = xstrdup(mkpos(pos1p)); - /* %s: variable # of args\t%s :: %s */ - msg(7, hte->h_name, pos1, mkpos(&call->f_pos)); - free(pos1); - continue; - } - - /* perform SCANFLIKE/PRINTFLIKE tests */ - if (def == NULL || (!def->s_prfl && !def->s_scfl)) - continue; - as = def->s_prfl ? def->s_nprfl : def->s_nscfl; - for (ai = call->f_args; ai != NULL; ai = ai->a_nxt) { - if (ai->a_num == as) - break; - } - if (ai == NULL || !ai->a_fmt) - continue; - if (def->s_prfl) { - printflike(hte, call, n, ai->a_fstrg, ap2); - } else { - scanflike(hte, call, n, ai->a_fstrg, ap2); - } - } -} - -/* - * Check a single argument in a function call. - * - * hte a pointer to the hash table entry of the function - * n the number of the argument (1..) - * def the function definition or NULL - * decl prototype declaration, old style declaration or NULL - * pos1p position of definition, declaration of first call - * call1 first call, if both def and decl are old style def/decl - * call checked call - * arg1 currently checked argument of def/decl/call1 - * arg2 currently checked argument of call - * - */ -static void -chkau(hte_t *hte, int n, sym_t *def, sym_t *decl, pos_t *pos1p, - fcall_t *call1, fcall_t *call, type_t *arg1, type_t *arg2) -{ - /* LINTED (automatic hides external declaration: warn) */ - int promote, asgn, warn; - tspec_t t1, t2; - arginf_t *ai, *ai1; - char *pos1; - - /* - * If a function definition is available (def != NULL), we compare the - * function call (call) with the definition. Otherwise, if a function - * definition is available and it is not an old style definition - * (decl != NULL && TP(decl->s_type)->t_proto), we compare the call - * with this declaration. Otherwise we compare it with the first - * call we have found (call1). - */ - - /* arg1 must be promoted if it stems from an old style definition */ - promote = def != NULL && def->s_osdef; - - /* - * If we compare with a definition or declaration, we must perform - * the same checks for qualifiers in indirected types as in - * assignments. - */ - asgn = def != NULL || (decl != NULL && TP(decl->s_type)->t_proto); - - warn = 0; - if (eqtype(arg1, arg2, 1, promote, asgn, &warn) && (!sflag || !warn)) - return; - - /* - * Other lint implementations print warnings as soon as the type - * of an argument does not match exactly the expected type. The - * result are lots of warnings which are really not necessary. - * We print a warning only if - * (0) at least one type is not an integer type and types differ - * (1) hflag is set and types differ - * (2) types differ, except in signedness - * If the argument is an integer constant whose msb is not set, - * signedness is ignored (e.g. 0 matches both signed and unsigned - * int). This is with and without hflag. - * If the argument is an integer constant with value 0 and the - * expected argument is of type pointer and the width of the - * integer constant is the same as the width of the pointer, - * no warning is printed. - */ - t1 = arg1->t_tspec; - t2 = arg2->t_tspec; - if (isityp(t1) && isityp(t2) && !arg1->t_isenum && !arg2->t_isenum) { - if (promote) { - /* - * XXX Here is a problem: Although it is possible to - * pass an int where a char/short it expected, there - * may be loss in significant digits. We should first - * check for const arguments if they can be converted - * into the original parameter type. - */ - if (t1 == FLOAT) { - t1 = DOUBLE; - } else if (t1 == CHAR || t1 == SCHAR) { - t1 = INT; - } else if (t1 == UCHAR) { - t1 = tflag ? UINT : INT; - } else if (t1 == SHORT) { - t1 = INT; - } else if (t1 == USHORT) { - /* CONSTCOND */ - t1 = INT_MAX < USHRT_MAX || tflag ? UINT : INT; - } - } - - if (styp(t1) == styp(t2)) { - - /* - * types differ only in signedness; get information - * about arguments - */ - - /* - * treat a definition like a call with variable - * arguments - */ - ai1 = call1 != NULL ? call1->f_args : NULL; - - /* - * if two calls are compared, ai1 is set to the - * information for the n-th argument, if this was - * a constant, otherwise to NULL - */ - for ( ; ai1 != NULL; ai1 = ai1->a_nxt) { - if (ai1->a_num == n) - break; - } - /* - * ai is set to the information of the n-th arg - * of the (second) call, if this was a constant, - * otherwise to NULL - */ - for (ai = call->f_args; ai != NULL; ai = ai->a_nxt) { - if (ai->a_num == n) - break; - } - - if (ai1 == NULL && ai == NULL) { - /* no constant at all */ - if (!hflag) - return; - } else if (ai1 == NULL || ai == NULL) { - /* one constant */ - if (ai == NULL) - ai = ai1; - if (ai->a_zero || ai->a_pcon) - /* same value in signed and unsigned */ - return; - /* value (not representation) differently */ - } else { - /* - * two constants, one signed, one unsigned; - * if the msb of one of the constants is set, - * the argument is used inconsistently. - */ - if (!ai1->a_ncon && !ai->a_ncon) - return; - } - } - - } else if (t1 == PTR && isityp(t2)) { - for (ai = call->f_args; ai != NULL; ai = ai->a_nxt) { - if (ai->a_num == n) - break; - } - /* - * Vendor implementations of lint (e.g. HP-UX, Digital UNIX) - * don't care about the size of the integer argument, - * only whether or not it is zero. We do the same. - */ - if (ai != NULL && ai->a_zero) - return; - } - - pos1 = xstrdup(mkpos(pos1p)); - /* %s, arg %d used inconsistently\t%s :: %s */ - msg(6, hte->h_name, n, pos1, mkpos(&call->f_pos)); - free(pos1); -} - -/* - * Compare the types in the NULL-terminated array ap with the format - * string fmt. - */ -static void -printflike(hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap) -{ - const char *fp; - int fc; - int fwidth, prec, left, sign, space, alt, zero; - tspec_t sz, t1, t2 = NOTSPEC; - type_t *tp; - - fp = fmt; - fc = *fp++; - - for ( ; ; ) { - if (fc == '\0') { - if (*ap != NULL) - tomanyarg(hte, call); - break; - } - if (fc != '%') { - badfmt(hte, call); - break; - } - fc = *fp++; - fwidth = prec = left = sign = space = alt = zero = 0; - sz = NOTSPEC; - - /* Flags */ - for ( ; ; ) { - if (fc == '-') { - if (left) - break; - left = 1; - } else if (fc == '+') { - if (sign) - break; - sign = 1; - } else if (fc == ' ') { - if (space) - break; - space = 1; - } else if (fc == '#') { - if (alt) - break; - alt = 1; - } else if (fc == '0') { - if (zero) - break; - zero = 1; - } else { - break; - } - fc = *fp++; - } - - /* field width */ - if (isdigit(fc)) { - fwidth = 1; - do { fc = *fp++; } while (isdigit(fc)) ; - } else if (fc == '*') { - fwidth = 1; - fc = *fp++; - if ((tp = *ap++) == NULL) { - tofewarg(hte, call); - break; - } - n++; - if ((t1 = tp->t_tspec) != INT && (hflag || t1 != UINT)) - inconarg(hte, call, n); - } - - /* precision */ - if (fc == '.') { - fc = *fp++; - prec = 1; - if (isdigit(fc)) { - do { fc = *fp++; } while (isdigit(fc)); - } else if (fc == '*') { - fc = *fp++; - if ((tp = *ap++) == NULL) { - tofewarg(hte, call); - break; - } - n++; - if (tp->t_tspec != INT) - inconarg(hte, call, n); - } else { - badfmt(hte, call); - break; - } - } - - if (fc == 'h') { - sz = SHORT; - } else if (fc == 'l') { - sz = LONG; - } else if (fc == 'q') { - sz = QUAD; - } else if (fc == 'L') { - sz = LDOUBLE; - } - if (sz != NOTSPEC) - fc = *fp++; - - if (fc == '%') { - if (sz != NOTSPEC || left || sign || space || - alt || zero || prec || fwidth) { - badfmt(hte, call); - } - fc = *fp++; - continue; - } - - if (fc == '\0') { - badfmt(hte, call); - break; - } - - if ((tp = *ap++) == NULL) { - tofewarg(hte, call); - break; - } - n++; - if ((t1 = tp->t_tspec) == PTR) - t2 = tp->t_subt->t_tspec; - - if (fc == 'd' || fc == 'i') { - if (alt || sz == LDOUBLE) { - badfmt(hte, call); - break; - } - int_conv: - if (sz == LONG) { - if (t1 != LONG && (hflag || t1 != ULONG)) - inconarg(hte, call, n); - } else if (sz == QUAD) { - if (t1 != QUAD && (hflag || t1 != UQUAD)) - inconarg(hte, call, n); - } else { - /* - * SHORT is always promoted to INT, USHORT - * to INT or UINT. - */ - if (t1 != INT && (hflag || t1 != UINT)) - inconarg(hte, call, n); - } - } else if (fc == 'o' || fc == 'u' || fc == 'x' || fc == 'X') { - if ((alt && fc == 'u') || sz == LDOUBLE) - badfmt(hte, call); - uint_conv: - if (sz == LONG) { - if (t1 != ULONG && (hflag || t1 != LONG)) - inconarg(hte, call, n); - } else if (sz == QUAD) { - if (t1 != UQUAD && (hflag || t1 != QUAD)) - inconarg(hte, call, n); - } else if (sz == SHORT) { - /* USHORT was promoted to INT or UINT */ - if (t1 != UINT && t1 != INT) - inconarg(hte, call, n); - } else { - if (t1 != UINT && (hflag || t1 != INT)) - inconarg(hte, call, n); - } - } else if (fc == 'D' || fc == 'O' || fc == 'U') { - if ((alt && fc != 'O') || sz != NOTSPEC || !tflag) - badfmt(hte, call); - sz = LONG; - if (fc == 'D') { - goto int_conv; - } else { - goto uint_conv; - } - } else if (fc == 'f' || fc == 'e' || fc == 'E' || - fc == 'g' || fc == 'G') { - if (sz == NOTSPEC) - sz = DOUBLE; - if (sz != DOUBLE && sz != LDOUBLE) - badfmt(hte, call); - if (t1 != sz) - inconarg(hte, call, n); - } else if (fc == 'c') { - if (sz != NOTSPEC || alt || zero) - badfmt(hte, call); - if (t1 != INT) - inconarg(hte, call, n); - } else if (fc == 's') { - if (sz != NOTSPEC || alt || zero) - badfmt(hte, call); - if (t1 != PTR || - (t2 != CHAR && t2 != UCHAR && t2 != SCHAR)) { - inconarg(hte, call, n); - } - } else if (fc == 'p') { - if (fwidth || prec || sz != NOTSPEC || alt || zero) - badfmt(hte, call); - if (t1 != PTR || (hflag && t2 != VOID)) - inconarg(hte, call, n); - } else if (fc == 'n') { - if (fwidth || prec || alt || zero || sz == LDOUBLE) - badfmt(hte, call); - if (t1 != PTR) { - inconarg(hte, call, n); - } else if (sz == LONG) { - if (t2 != LONG && t2 != ULONG) - inconarg(hte, call, n); - } else if (sz == SHORT) { - if (t2 != SHORT && t2 != USHORT) - inconarg(hte, call, n); - } else { - if (t2 != INT && t2 != UINT) - inconarg(hte, call, n); - } - } else { - badfmt(hte, call); - break; - } - - fc = *fp++; - } -} - -/* - * Compare the types in the NULL-terminated array ap with the format - * string fmt. - */ -static void -scanflike(hte_t *hte, fcall_t *call, int n, const char *fmt, type_t **ap) -{ - const char *fp; - int fc; - int noasgn, fwidth; - tspec_t sz, t1 = NOTSPEC, t2 = NOTSPEC; - type_t *tp = NULL; - - fp = fmt; - fc = *fp++; - - for ( ; ; ) { - if (fc == '\0') { - if (*ap != NULL) - tomanyarg(hte, call); - break; - } - if (fc != '%') { - badfmt(hte, call); - break; - } - fc = *fp++; - - noasgn = fwidth = 0; - sz = NOTSPEC; - - if (fc == '*') { - noasgn = 1; - fc = *fp++; - } - - if (isdigit(fc)) { - fwidth = 1; - do { fc = *fp++; } while (isdigit(fc)); - } - - if (fc == 'h') { - sz = SHORT; - } else if (fc == 'l') { - sz = LONG; - } else if (fc == 'q') { - sz = QUAD; - } else if (fc == 'L') { - sz = LDOUBLE; - } - if (sz != NOTSPEC) - fc = *fp++; - - if (fc == '%') { - if (sz != NOTSPEC || noasgn || fwidth) - badfmt(hte, call); - fc = *fp++; - continue; - } - - if (!noasgn) { - if ((tp = *ap++) == NULL) { - tofewarg(hte, call); - break; - } - n++; - if ((t1 = tp->t_tspec) == PTR) - t2 = tp->t_subt->t_tspec; - } - - if (fc == 'd' || fc == 'i' || fc == 'n') { - if (sz == LDOUBLE) - badfmt(hte, call); - if (sz != SHORT && sz != LONG && sz != QUAD) - sz = INT; - conv: - if (!noasgn) { - if (t1 != PTR) { - inconarg(hte, call, n); - } else if (t2 != styp(sz)) { - inconarg(hte, call, n); - } else if (hflag && t2 != sz) { - inconarg(hte, call, n); - } else if (tp->t_subt->t_const) { - inconarg(hte, call, n); - } - } - } else if (fc == 'o' || fc == 'u' || fc == 'x') { - if (sz == LDOUBLE) - badfmt(hte, call); - if (sz == SHORT) { - sz = USHORT; - } else if (sz == LONG) { - sz = ULONG; - } else if (sz == QUAD) { - sz = UQUAD; - } else { - sz = UINT; - } - goto conv; - } else if (fc == 'D') { - if (sz != NOTSPEC || !tflag) - badfmt(hte, call); - sz = LONG; - goto conv; - } else if (fc == 'O') { - if (sz != NOTSPEC || !tflag) - badfmt(hte, call); - sz = ULONG; - goto conv; - } else if (fc == 'X') { - /* - * XXX valid in ANSI C, but in NetBSD's libc imple- - * mented as "lx". Thats why it should be avoided. - */ - if (sz != NOTSPEC || !tflag) - badfmt(hte, call); - sz = ULONG; - goto conv; - } else if (fc == 'E') { - /* - * XXX valid in ANSI C, but in NetBSD's libc imple- - * mented as "lf". Thats why it should be avoided. - */ - if (sz != NOTSPEC || !tflag) - badfmt(hte, call); - sz = DOUBLE; - goto conv; - } else if (fc == 'F') { - /* XXX only for backward compatibility */ - if (sz != NOTSPEC || !tflag) - badfmt(hte, call); - sz = DOUBLE; - goto conv; - } else if (fc == 'G') { - /* - * XXX valid in ANSI C, but in NetBSD's libc not - * implemented - */ - if (sz != NOTSPEC && sz != LONG && sz != LDOUBLE) - badfmt(hte, call); - goto fconv; - } else if (fc == 'e' || fc == 'f' || fc == 'g') { - fconv: - if (sz == NOTSPEC) { - sz = FLOAT; - } else if (sz == LONG) { - sz = DOUBLE; - } else if (sz != LDOUBLE) { - badfmt(hte, call); - sz = FLOAT; - } - goto conv; - } else if (fc == 's' || fc == '[' || fc == 'c') { - if (sz != NOTSPEC) - badfmt(hte, call); - if (fc == '[') { - if ((fc = *fp++) == '-') { - badfmt(hte, call); - fc = *fp++; - } - if (fc != ']') { - badfmt(hte, call); - if (fc == '\0') - break; - } - } - if (!noasgn) { - if (t1 != PTR) { - inconarg(hte, call, n); - } else if (t2 != CHAR && t2 != UCHAR && - t2 != SCHAR) { - inconarg(hte, call, n); - } - } - } else if (fc == 'p') { - if (sz != NOTSPEC) - badfmt(hte, call); - if (!noasgn) { - if (t1 != PTR || t2 != PTR) { - inconarg(hte, call, n); - } else if (tp->t_subt->t_subt->t_tspec!=VOID) { - if (hflag) - inconarg(hte, call, n); - } - } - } else { - badfmt(hte, call); - break; - } - - fc = *fp++; - } -} - -static void -badfmt(hte_t *hte, fcall_t *call) -{ - - /* %s: malformed format string\t%s */ - msg(13, hte->h_name, mkpos(&call->f_pos)); -} - -static void -inconarg(hte_t *hte, fcall_t *call, int n) -{ - - /* %s, arg %d inconsistent with format\t%s(%d) */ - msg(14, hte->h_name, n, mkpos(&call->f_pos)); -} - -static void -tofewarg(hte_t *hte, fcall_t *call) -{ - - /* %s: too few args for format \t%s */ - msg(15, hte->h_name, mkpos(&call->f_pos)); -} - -static void -tomanyarg(hte_t *hte, fcall_t *call) -{ - - /* %s: too many args for format \t%s */ - msg(16, hte->h_name, mkpos(&call->f_pos)); -} - - -/* - * Print warnings for return values which are used, but not returned, - * or return values which are always or sometimes ignored. - */ -static void -chkrvu(hte_t *hte, sym_t *def) -{ - fcall_t *call; - int used, ignored; - - if (def == NULL) - /* don't know wheter or not the functions returns a value */ - return; - - if (hte->h_calls == NULL) - return; - - if (def->s_rval) { - /* function has return value */ - used = ignored = 0; - for (call = hte->h_calls; call != NULL; call = call->f_nxt) { - used |= call->f_rused || call->f_rdisc; - ignored |= !call->f_rused && !call->f_rdisc; - } - /* - * XXX as soon as we are able to disable single warnings - * the following dependencies from hflag should be removed. - * but for now I do'nt want to be botherd by this warnings - * which are almost always useless. - */ - if (!used && ignored) { - if (hflag) - /* %s returns value which is always ignored */ - msg(8, hte->h_name); - } else if (used && ignored) { - if (hflag) - /* %s returns value which is sometimes ign. */ - msg(9, hte->h_name); - } - } else { - /* function has no return value */ - for (call = hte->h_calls; call != NULL; call = call->f_nxt) { - if (call->f_rused) - /* %s value is used( %s ), but none ret. */ - msg(10, hte->h_name, mkpos(&call->f_pos)); - } - } -} - -/* - * Print warnings for inconsistent argument declarations. - */ -static void -chkadecl(hte_t *hte, sym_t *def, sym_t *decl) -{ - /* LINTED (automatic hides external declaration: warn) */ - int osdef, eq, warn, n; - sym_t *sym1, *sym; - type_t **ap1, **ap2, *tp1, *tp2; - char *pos1; - const char *pos2; - - osdef = 0; - if (def != NULL) { - osdef = def->s_osdef; - sym1 = def; - } else if (decl != NULL && TP(decl->s_type)->t_proto) { - sym1 = decl; - } else { - return; - } - if (TP(sym1->s_type)->t_tspec != FUNC) - return; - - /* - * XXX Prototypes should also be compared with old style function - * declarations. - */ - - for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { - if (sym == sym1 || !TP(sym->s_type)->t_proto) - continue; - ap1 = TP(sym1->s_type)->t_args; - ap2 = TP(sym->s_type)->t_args; - n = 0; - while (*ap1 != NULL && *ap2 != NULL) { - warn = 0; - eq = eqtype(*ap1, *ap2, 1, osdef, 0, &warn); - if (!eq || warn) { - pos1 = xstrdup(mkpos(&sym1->s_pos)); - pos2 = mkpos(&sym->s_pos); - /* %s, arg %d declared inconsistently ... */ - msg(11, hte->h_name, n + 1, pos1, pos2); - free(pos1); - } - n++; - ap1++; - ap2++; - } - if (*ap1 == *ap2) { - tp1 = TP(sym1->s_type); - tp2 = TP(sym->s_type); - if (tp1->t_vararg == tp2->t_vararg) - continue; - if (tp2->t_vararg && - sym1->s_va && sym1->s_nva == n && !sflag) { - continue; - } - } - /* %s: variable # of args declared\t%s :: %s */ - pos1 = xstrdup(mkpos(&sym1->s_pos)); - msg(12, hte->h_name, pos1, mkpos(&sym->s_pos)); - free(pos1); - } -} - - -/* - * Check compatibility of two types. Returns 1 if types are compatible, - * otherwise 0. - * - * ignqual if set, ignore qualifiers of outhermost type; used for - * function arguments - * promote if set, promote left type before comparison; used for - * comparisons of arguments with parameters of old style - * definitions - * asgn left indirected type must have at least the same qualifiers - * like right indirected type (for assignments and function - * arguments) - * *warn set to 1 if an old style declaration was compared with - * an incompatible prototype declaration - */ -static int -eqtype(type_t *tp1, type_t *tp2, int ignqual, int promot, int asgn, int *warn) -{ - tspec_t t, to; - int indir; - - to = NOTSPEC; - indir = 0; - - while (tp1 != NULL && tp2 != NULL) { - - t = tp1->t_tspec; - if (promot) { - if (t == FLOAT) { - t = DOUBLE; - } else if (t == CHAR || t == SCHAR) { - t = INT; - } else if (t == UCHAR) { - t = tflag ? UINT : INT; - } else if (t == SHORT) { - t = INT; - } else if (t == USHORT) { - /* CONSTCOND */ - t = INT_MAX < USHRT_MAX || tflag ? UINT : INT; - } - } - - if (asgn && to == PTR) { - if (indir == 1 && (t == VOID || tp2->t_tspec == VOID)) - return (1); - } - - if (t != tp2->t_tspec) { - /* - * Give pointer to types which differ only in - * signedness a chance if not sflag and not hflag. - */ - if (sflag || hflag || to != PTR) - return (0); - if (styp(t) != styp(tp2->t_tspec)) - return (0); - } - - if (tp1->t_isenum && tp2->t_isenum) { - if (tp1->t_istag && tp2->t_istag) { - return (tp1->t_tag == tp2->t_tag); - } else if (tp1->t_istynam && tp2->t_istynam) { - return (tp1->t_tynam == tp2->t_tynam); - } else if (tp1->t_isuniqpos && tp2->t_isuniqpos) { - return (tp1->t_uniqpos.p_line == - tp2->t_uniqpos.p_line && - tp1->t_uniqpos.p_file == - tp2->t_uniqpos.p_file && - tp1->t_uniqpos.p_uniq == - tp2->t_uniqpos.p_uniq); - } else { - return (0); - } - } - - /* - * XXX Handle combinations of enum and int if eflag is set. - * But note: enum and 0 should be allowed. - */ - - if (asgn && indir == 1) { - if (!tp1->t_const && tp2->t_const) - return (0); - if (!tp1->t_volatile && tp2->t_volatile) - return (0); - } else if (!ignqual && !tflag) { - if (tp1->t_const != tp2->t_const) - return (0); - if (tp1->t_const != tp2->t_const) - return (0); - } - - if (t == STRUCT || t == UNION) { - if (tp1->t_istag && tp2->t_istag) { - return (tp1->t_tag == tp2->t_tag); - } else if (tp1->t_istynam && tp2->t_istynam) { - return (tp1->t_tynam == tp2->t_tynam); - } else if (tp1->t_isuniqpos && tp2->t_isuniqpos) { - return (tp1->t_uniqpos.p_line == - tp2->t_uniqpos.p_line && - tp1->t_uniqpos.p_file == - tp2->t_uniqpos.p_file && - tp1->t_uniqpos.p_uniq == - tp2->t_uniqpos.p_uniq); - } else { - return (0); - } - } - - if (t == ARRAY && tp1->t_dim != tp2->t_dim) { - if (tp1->t_dim != 0 && tp2->t_dim != 0) - return (0); - } - - if (t == FUNC) { - if (tp1->t_proto && tp2->t_proto) { - if (!eqargs(tp1, tp2, warn)) - return (0); - } else if (tp1->t_proto) { - if (!mnoarg(tp1, warn)) - return (0); - } else if (tp2->t_proto) { - if (!mnoarg(tp2, warn)) - return (0); - } - } - - tp1 = tp1->t_subt; - tp2 = tp2->t_subt; - ignqual = promot = 0; - to = t; - indir++; - - } - - return (tp1 == tp2); -} - -/* - * Compares arguments of two prototypes - */ -static int -eqargs(type_t *tp1, type_t *tp2, int *warn) -{ - type_t **a1, **a2; - - if (tp1->t_vararg != tp2->t_vararg) - return (0); - - a1 = tp1->t_args; - a2 = tp2->t_args; - - while (*a1 != NULL && *a2 != NULL) { - - if (eqtype(*a1, *a2, 1, 0, 0, warn) == 0) - return (0); - - a1++; - a2++; - - } - - return (*a1 == *a2); -} - -/* - * mnoarg() (matches functions with no argument type information) - * returns 1 if all parameters of a prototype are compatible with - * and old style function declaration. - * This is the case if following conditions are met: - * 1. the prototype must have a fixed number of parameters - * 2. no parameter is of type float - * 3. no parameter is converted to another type if integer promotion - * is applied on it - */ -static int -mnoarg(type_t *tp, int *warn) -{ - type_t **arg; - tspec_t t; - - if (tp->t_vararg && warn != NULL) - *warn = 1; - for (arg = tp->t_args; *arg != NULL; arg++) { - if ((t = (*arg)->t_tspec) == FLOAT) - return (0); - if (t == CHAR || t == SCHAR || t == UCHAR) - return (0); - if (t == SHORT || t == USHORT) - return (0); - } - return (1); -} Index: usr.bin/xlint/lint2/emit2.c =================================================================== --- usr.bin/xlint/lint2/emit2.c +++ /dev/null @@ -1,300 +0,0 @@ -/* $NetBSD: emit2.c,v 1.8 2002/01/21 19:49:52 tv Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: emit2.c,v 1.8 2002/01/21 19:49:52 tv Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include - -#include "lint2.h" - -static void outtype(type_t *); -static void outdef(hte_t *, sym_t *); -static void dumpname(hte_t *); -static void outfiles(void); - -/* - * Write type into the output buffer. - */ -static void -outtype(type_t *tp) -{ - int t, s, na; - tspec_t ts; - type_t **ap; - - while (tp != NULL) { - if ((ts = tp->t_tspec) == INT && tp->t_isenum) - ts = ENUM; - switch (ts) { - case CHAR: t = 'C'; s = '\0'; break; - case SCHAR: t = 'C'; s = 's'; break; - case UCHAR: t = 'C'; s = 'u'; break; - case SHORT: t = 'S'; s = '\0'; break; - case USHORT: t = 'S'; s = 'u'; break; - case INT: t = 'I'; s = '\0'; break; - case UINT: t = 'I'; s = 'u'; break; - case LONG: t = 'L'; s = '\0'; break; - case ULONG: t = 'L'; s = 'u'; break; - case QUAD: t = 'Q'; s = '\0'; break; - case UQUAD: t = 'Q'; s = 'u'; break; - case FLOAT: t = 'D'; s = 's'; break; - case DOUBLE: t = 'D'; s = '\0'; break; - case LDOUBLE: t = 'D'; s = 'l'; break; - case VOID: t = 'V'; s = '\0'; break; - case PTR: t = 'P'; s = '\0'; break; - case ARRAY: t = 'A'; s = '\0'; break; - case ENUM: t = 'T'; s = 'e'; break; - case STRUCT: t = 'T'; s = 's'; break; - case UNION: t = 'T'; s = 'u'; break; - case FUNC: - if (tp->t_args != NULL && !tp->t_proto) { - t = 'f'; - } else { - t = 'F'; - } - s = '\0'; - break; - default: - errx(1, "internal error: outtype() 1"); - } - if (tp->t_const) - outchar('c'); - if (tp->t_volatile) - outchar('v'); - if (s != '\0') - outchar(s); - outchar(t); - if (ts == ARRAY) { - outint(tp->t_dim); - } else if (ts == ENUM || ts == STRUCT || ts == UNION) { - if (tp->t_istag) { - outint(1); - outname(tp->t_tag->h_name); - } else if (tp->t_istynam) { - outint(2); - outname(tp->t_tynam->h_name); - } else if (tp->t_isuniqpos) { - outint(3); - outint(tp->t_uniqpos.p_line); - outchar('.'); - outint(tp->t_uniqpos.p_file); - outchar('.'); - outint(tp->t_uniqpos.p_uniq); - } else - errx(1, "internal error: outtype() 2"); - } else if (ts == FUNC && tp->t_args != NULL) { - na = 0; - for (ap = tp->t_args; *ap != NULL; ap++) - na++; - if (tp->t_vararg) - na++; - outint(na); - for (ap = tp->t_args; *ap != NULL; ap++) - outtype(*ap); - if (tp->t_vararg) - outchar('E'); - } - tp = tp->t_subt; - } -} - -/* - * Write a definition. - */ -static void -outdef(hte_t *hte, sym_t *sym) -{ - - /* reset output buffer */ - outclr(); - - /* line number in C source file */ - outint(0); - - /* this is a definition */ - outchar('d'); - - /* index of file where symbol was defined and line number of def. */ - outint(0); - outchar('.'); - outint(0); - - /* flags */ - if (sym->s_va) { - outchar('v'); /* varargs */ - outint(sym->s_nva); - } - if (sym->s_scfl) { - outchar('S'); /* scanflike */ - outint(sym->s_nscfl); - } - if (sym->s_prfl) { - outchar('P'); /* printflike */ - outint(sym->s_nprfl); - } - /* definition or tentative definition */ - outchar(sym->s_def == DEF ? 'd' : 't'); - if (TP(sym->s_type)->t_tspec == FUNC) { - if (sym->s_rval) - outchar('r'); /* fkt. has return value */ - if (sym->s_osdef) - outchar('o'); /* old style definition */ - } - outchar('u'); /* used (no warning if not used) */ - - /* name */ - outname(hte->h_name); - - /* type */ - outtype(TP(sym->s_type)); -} - -/* - * Write the first definition of a name into the lint library. - */ -static void -dumpname(hte_t *hte) -{ - sym_t *sym, *def; - - /* static and undefined symbols are not written */ - if (hte->h_static || !hte->h_def) - return; - - /* - * If there is a definition, write it. Otherwise write a tentative - * definition. This is necessary because more than one tentative - * definition is allowed (except with sflag). - */ - def = NULL; - for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { - if (sym->s_def == DEF) { - def = sym; - break; - } - if (sym->s_def == TDEF && def == NULL) - def = sym; - } - if (def == NULL) - errx(1, "internal error: dumpname() %s", hte->h_name); - - outdef(hte, def); -} - -/* - * Write a new lint library. - */ -void -outlib(const char *name) -{ - /* Open of output file and initialisation of the output buffer */ - outopen(name); - - /* write name of lint library */ - outsrc(name); - - /* name of lint lib has index 0 */ - outclr(); - outint(0); - outchar('s'); - outstrg(name); - - /* - * print the names of all files references by unnamed - * struct/union/enum declarations. - */ - outfiles(); - - /* write all definitions with external linkage */ - forall(dumpname); - - /* close the output */ - outclose(); -} - -/* - * Write out the name of a file referenced by a type. - */ -struct outflist { - short ofl_num; - struct outflist *ofl_next; -}; -static struct outflist *outflist; - -int -addoutfile(short num) -{ - struct outflist *ofl, **pofl; - int i; - - ofl = outflist; - pofl = &outflist; - i = 1; /* library is 0 */ - - while (ofl != NULL) { - if (ofl->ofl_num == num) - break; - - pofl = &ofl->ofl_next; - ofl = ofl->ofl_next; - i++; - } - - if (ofl == NULL) { - ofl = *pofl = xmalloc(sizeof (struct outflist)); - ofl->ofl_num = num; - ofl->ofl_next = NULL; - } - return (i); -} - -static void -outfiles(void) -{ - struct outflist *ofl; - int i; - - for (ofl = outflist, i = 1; ofl != NULL; ofl = ofl->ofl_next, i++) { - /* reset output buffer */ - outclr(); - - outint(i); - outchar('s'); - outstrg(fnames[ofl->ofl_num]); - } -} Index: usr.bin/xlint/lint2/externs2.h =================================================================== --- usr.bin/xlint/lint2/externs2.h +++ /dev/null @@ -1,93 +0,0 @@ -/* $NetBSD: externs2.h,v 1.7 2001/05/28 12:40:38 lukem Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * main.c - */ -extern int xflag; -extern int uflag; -extern int Cflag; -extern const char *libname; -extern int sflag; -extern int tflag; -extern int Hflag; -extern int hflag; -extern int Fflag; - - -/* - * hash.c - */ -extern void _inithash(hte_t ***); -extern hte_t *_hsearch(hte_t **, const char *, int); -extern void _forall(hte_t **, void (*)(hte_t *)); -extern void _destroyhash(hte_t **); - -#define inithash() _inithash(NULL); -#define hsearch(a, b) _hsearch(NULL, (a), (b)) -#define forall(a) _forall(NULL, (a)) - -/* - * read.c - */ -extern const char **fnames; -extern type_t **tlst; - -extern void readfile(const char *); -extern void mkstatic(hte_t *); - -/* - * mem2.c - */ -extern void initmem(void); -extern void *xalloc(size_t); - -/* - * chk.c - */ -extern void inittyp(void); -extern void mainused(void); -extern void chkname(hte_t *); - -/* - * msg.c - */ -extern void msg(int, ...); -extern const char *mkpos(pos_t *); - -/* - * emit2.c - */ -extern void outlib(const char *); -extern int addoutfile(short); Index: usr.bin/xlint/lint2/hash.c =================================================================== --- usr.bin/xlint/lint2/hash.c +++ /dev/null @@ -1,166 +0,0 @@ -/* $NetBSD: hash.c,v 1.7 2002/01/21 19:49:52 tv Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: hash.c,v 1.7 2002/01/21 19:49:52 tv Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -/* - * XXX Really need a generalized hash table package - */ - -#include -#include -#include -#include -#include - -#include "lint2.h" - -/* pointer to hash table, initialized in inithash() */ -static hte_t **htab; - -static int hash(const char *); - -/* - * Initialize hash table. - */ -void -_inithash(hte_t ***tablep) -{ - - if (tablep == NULL) - tablep = &htab; - - *tablep = xcalloc(HSHSIZ2, sizeof (hte_t *)); -} - -/* - * Compute hash value from a string. - */ -static int -hash(const char *s) -{ - u_int v; - const u_char *us; - - v = 0; - for (us = (const u_char *)s; *us != '\0'; us++) { - v = (v << sizeof (v)) + *us; - v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v)); - } - return (v % HSHSIZ2); -} - -/* - * Look for a hash table entry. If no hash table entry for the - * given name exists and mknew is set, create a new one. - */ -hte_t * -_hsearch(hte_t **table, const char *s, int mknew) -{ - int h; - hte_t *hte; - - if (table == NULL) - table = htab; - - h = hash(s); - for (hte = table[h]; hte != NULL; hte = hte->h_link) { - if (strcmp(hte->h_name, s) == 0) - break; - } - - if (hte != NULL || !mknew) - return (hte); - - /* create a new hte */ - hte = xmalloc(sizeof (hte_t)); - hte->h_name = xstrdup(s); - hte->h_used = 0; - hte->h_def = 0; - hte->h_static = 0; - hte->h_syms = NULL; - hte->h_lsym = &hte->h_syms; - hte->h_calls = NULL; - hte->h_lcall = &hte->h_calls; - hte->h_usyms = NULL; - hte->h_lusym = &hte->h_usyms; - hte->h_link = table[h]; - hte->h_hte = NULL; - table[h] = hte; - - return (hte); -} - -/* - * Call function f for each name in the hash table. - */ -void -_forall(hte_t **table, void (*f)(hte_t *)) -{ - int i; - hte_t *hte; - - if (table == NULL) - table = htab; - - for (i = 0; i < HSHSIZ2; i++) { - for (hte = table[i]; hte != NULL; hte = hte->h_link) - (*f)(hte); - } -} - -/* - * Free all contents of the hash table that this module allocated. - */ -void -_destroyhash(hte_t **table) -{ - int i; - hte_t *hte, *nexthte; - - if (table == NULL) - err(1, "_destroyhash called on main hash table"); - - for (i = 0; i < HSHSIZ2; i++) { - for (hte = table[i]; hte != NULL; hte = nexthte) { - free((void *)hte->h_name); - nexthte = hte->h_link; - free(hte); - } - } - free(table); -} Index: usr.bin/xlint/lint2/lint2.h =================================================================== --- usr.bin/xlint/lint2/lint2.h +++ /dev/null @@ -1,188 +0,0 @@ -/* $NetBSD: lint2.h,v 1.5 2000/06/14 06:49:23 cgd Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "lint.h" - -/* - * Types are described by structures of type type_t. - */ -typedef struct type { - tspec_t t_tspec; /* type specifier */ - u_int t_const : 1; /* constant */ - u_int t_volatile : 1; /* volatile */ - u_int t_vararg : 1; /* function has variable number of arguments */ - u_int t_isenum : 1; /* enum type */ - u_int t_proto : 1; /* this is a prototype */ - u_int t_istag : 1; /* tag with _t_tag valid */ - u_int t_istynam : 1; /* tag with _t_tynam valid */ - u_int t_isuniqpos : 1; /* tag with _t_uniqpos valid */ - union { - int _t_dim; /* if the type is an ARRAY than this - is the dimension of the array. */ - struct hte *_t_tag; /* hash table entry of tag if - t_isenum, STRUCT or UNION */ - struct hte *_t_tynam; /* hash table entry of typename if - t_isenum, STRUCT or UNION */ - struct { - int p_line; - short p_file; - int p_uniq; - } _t_uniqpos; /* unique position, for untagged - untyped STRUCTs, UNIONS, and ENUMs, - if t_isuniqpos */ - struct type **_t_args; /* list of argument types if this - is a prototype */ - } t_u; - struct type *t_subt; /* indirected type (array element, pointed to - type, type of return value) */ -} type_t; - -#define t_dim t_u._t_dim -#define t_tag t_u._t_tag -#define t_tynam t_u._t_tynam -#define t_uniqpos t_u._t_uniqpos -#define t_args t_u._t_args - -/* - * argument information - * - * Such a structure is created for each argument of a function call - * which is an integer constant or a constant string. - */ -typedef struct arginf { - int a_num; /* # of argument (1..) */ - u_int a_zero : 1; /* argument is 0 */ - u_int a_pcon : 1; /* msb of argument is not set */ - u_int a_ncon : 1; /* msb of argument is set */ - u_int a_fmt : 1; /* a_fstrg points to format string */ - char *a_fstrg; /* format string */ - struct arginf *a_nxt; /* information for next const. argument */ -} arginf_t; - -/* - * Keeps information about position in source file. - */ -typedef struct { - u_short p_src; /* index of name of translation unit - (the name which was specified at the - command line) */ - u_short p_line; /* line number in p_src */ - u_short p_isrc; /* index of (included) file */ - u_short p_iline; /* line number in p_iline */ -} pos_t; - -/* - * Used for definitions and declarations - * - * To save memory, variable sized structures are used. If - * all s_va, s_prfl and s_scfl are not set, the memory allocated - * for a symbol is only large enough to keep the first member of - * struct sym, s_s. - */ -typedef struct sym { - struct { - pos_t s_pos; /* pos of def./decl. */ -#ifndef lint - u_int s_def : 3; /* DECL, TDEF or DEF */ -#else - def_t s_def; -#endif - u_int s_rval : 1; /* function has return value */ - u_int s_osdef : 1; /* old style function definition */ - u_int s_static : 1; /* symbol is static */ - u_int s_va : 1; /* check only first s_nva arguments */ - u_int s_prfl : 1; /* printflike */ - u_int s_scfl : 1; /* scanflike */ - u_short s_type; /* type */ - struct sym *s_nxt; /* next symbol with same name */ - } s_s; - short s_nva; - short s_nprfl; - short s_nscfl; -} sym_t; - -#define s_pos s_s.s_pos -#define s_rval s_s.s_rval -#define s_osdef s_s.s_osdef -#define s_static s_s.s_static -#define s_def s_s.s_def -#define s_va s_s.s_va -#define s_prfl s_s.s_prfl -#define s_scfl s_s.s_scfl -#define s_type s_s.s_type -#define s_nxt s_s.s_nxt - -/* - * Used to store informations about function calls. - */ -typedef struct fcall { - pos_t f_pos; /* position of call */ - u_int f_rused : 1; /* return value used */ - u_int f_rdisc : 1; /* return value discarded (casted to void) */ - u_short f_type; /* types of expected return value and args */ - arginf_t *f_args; /* information about constant arguments */ - struct fcall *f_nxt; /* next call of same function */ -} fcall_t; - -/* - * Used to store information about usage of symbols other - * than for function calls. - */ -typedef struct usym { - pos_t u_pos; /* position */ - struct usym *u_nxt; /* next usage */ -} usym_t; - -/* - * hash table entry - */ -typedef struct hte { - const char *h_name; /* name */ - u_int h_used : 1; /* symbol is used */ - u_int h_def : 1; /* symbol is defined */ - u_int h_static : 1; /* static symbol */ - sym_t *h_syms; /* declarations and definitions */ - sym_t **h_lsym; /* points to s_nxt of last decl./def. */ - fcall_t *h_calls; /* function calls */ - fcall_t **h_lcall; /* points to f_nxt of last call */ - usym_t *h_usyms; /* usage info */ - usym_t **h_lusym; /* points to u_nxt of last usage info */ - struct hte *h_link; /* next hte with same hash function */ - struct hte *h_hte; /* pointer to other htes (for renames */ -} hte_t; - -/* maps type indices into pointers to type structs */ -#define TP(idx) (tlst[idx]) - -#include "externs2.h" Index: usr.bin/xlint/lint2/main2.c =================================================================== --- usr.bin/xlint/lint2/main2.c +++ /dev/null @@ -1,191 +0,0 @@ -/* $NetBSD: main2.c,v 1.5 2001/11/21 19:14:26 wiz Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: main2.c,v 1.5 2001/11/21 19:14:26 wiz Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include - -#include "lint2.h" - -/* warnings for symbols which are declared but not defined or used */ -int xflag; - -/* - * warnings for symbols which are used and not defined or defined - * and not used - */ -int uflag = 1; - -/* Create a lint library in the current directory with name libname. */ -int Cflag; -const char *libname; - -int pflag; - -/* - * warnings for (tentative) definitions of the same name in more than - * one translation unit - */ -int sflag; - -int tflag; - -/* - * If a complaint stems from an included file, print the name of the included - * file instead of the name spezified at the command line followed by '?' - */ -int Hflag; - -int hflag; - -/* Print full path names, not only the last component */ -int Fflag; - -/* - * List of libraries (from -l flag). These libraries are read after all - * other input files has been read and, for Cflag, after the new lint library - * has been written. - */ -const char **libs; - -static void usage(void); - -int main(int, char *[]); - -int -main(int argc, char *argv[]) -{ - int c, i; - size_t len; - char *lname; - - libs = xcalloc(1, sizeof (char *)); - - opterr = 0; - while ((c = getopt(argc, argv, "hpstxuC:HFl:")) != -1) { - switch (c) { - case 's': - sflag = 1; - break; - case 't': - tflag = 1; - break; - case 'u': - uflag = 0; - break; - case 'x': - xflag = 1; - break; - case 'p': - pflag = 1; - break; - case 'C': - len = strlen(optarg); - lname = xmalloc(len + 10); - (void)sprintf(lname, "llib-l%s.ln", optarg); - libname = lname; - Cflag = 1; - uflag = 0; - break; - case 'H': - Hflag = 1; - break; - case 'h': - hflag = 1; - break; - case 'F': - Fflag = 1; - break; - case 'l': - for (i = 0; libs[i] != NULL; i++) - continue; - libs = xrealloc(libs, (i + 2) * sizeof (char *)); - libs[i] = xstrdup(optarg); - libs[i + 1] = NULL; - break; - case '?': - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc == 0) - usage(); - - initmem(); - - /* initialize hash table */ - inithash(); - - inittyp(); - - for (i = 0; i < argc; i++) - readfile(argv[i]); - - /* write the lint library */ - if (Cflag) { - forall(mkstatic); - outlib(libname); - } - - /* read additional libraries */ - for (i = 0; libs[i] != NULL; i++) - readfile(libs[i]); - - forall(mkstatic); - - mainused(); - - /* perform all tests */ - forall(chkname); - - exit(0); - /* NOTREACHED */ -} - -static void -usage(void) -{ - (void)fprintf(stderr, - "usage: lint2 -hpstxuHF -Clib -l lib ... src1 ...\n"); - exit(1); -} Index: usr.bin/xlint/lint2/mem2.c =================================================================== --- usr.bin/xlint/lint2/mem2.c +++ /dev/null @@ -1,97 +0,0 @@ -/* $NetBSD: mem2.c,v 1.6 2002/01/21 19:49:52 tv Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: mem2.c,v 1.6 2002/01/21 19:49:52 tv Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include "lint2.h" - -/* length of new allocated memory blocks */ -static size_t mblklen; - -/* offset of next free byte in mbuf */ -static size_t nxtfree; - -/* current buffer to server memory requests from */ -static void *mbuf; - -void -initmem(void) -{ - int pgsz; - - pgsz = getpagesize(); - mblklen = ((MBLKSIZ + pgsz - 1) / pgsz) * pgsz; - - nxtfree = mblklen; -} - -/* - * Allocate memory in large chunks to avoid space and time overhead of - * malloc(). This is possible because memory allocated by xalloc() - * need never to be freed. - */ -void * -xalloc(size_t sz) -{ - void *ptr; - int prot, flags; - - /* Align to at least 8 bytes. */ - sz = (sz + 7) & ~7L; - if (nxtfree + sz > mblklen) { - /* use mmap() instead of malloc() to avoid malloc overhead. */ - prot = PROT_READ | PROT_WRITE; - flags = MAP_ANON | MAP_PRIVATE; - mbuf = mmap(NULL, mblklen, prot, flags, -1, (off_t)0); - if (mbuf == (void *)MAP_FAILED) - err(1, "can't map memory"); - (void)memset(mbuf, 0, mblklen); - nxtfree = 0; - } - - ptr = (char *)mbuf + nxtfree; - nxtfree += sz; - - return (ptr); -} Index: usr.bin/xlint/lint2/msg.c =================================================================== --- usr.bin/xlint/lint2/msg.c +++ /dev/null @@ -1,138 +0,0 @@ -/* $NetBSD: msg.c,v 1.6 2002/01/21 19:49:52 tv Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: msg.c,v 1.6 2002/01/21 19:49:52 tv Exp $"); -#endif - -#include -#include -#include - -#include "lint2.h" - -static const char *msgs[] = { - "%s used( %s ), but not defined", /* 0 */ - "%s defined( %s ), but never used", /* 1 */ - "%s declared( %s ), but never used or defined", /* 2 */ - "%s multiply defined \t%s :: %s", /* 3 */ - "%s value used inconsistently \t%s :: %s", /* 4 */ - "%s value declared inconsistently \t%s :: %s", /* 5 */ - "%s, arg %d used inconsistently \t%s :: %s", /* 6 */ - "%s: variable # of args \t%s :: %s", /* 7 */ - "%s returns value which is always ignored", /* 8 */ - "%s returns value which is sometimes ignored", /* 9 */ - "%s value is used( %s ), but none returned", /* 10 */ - "%s, arg %d declared inconsistently \t%s :: %s", /* 11 */ - "%s: variable # of args declared \t%s :: %s", /* 12 */ - "%s: malformed format string \t%s", /* 13 */ - "%s, arg %d inconsistent with format \t%s", /* 14 */ - "%s: too few args for format \t%s", /* 15 */ - "%s: too many args for format \t%s", /* 16 */ - "%s function value must be declared before use \t%s :: %s",/* 17 */ - "%s renamed multiple times \t%s :: %s", /* 18 */ -}; - -static const char *lbasename(const char *); - -void -msg(int n, ...) -{ - va_list ap; - - va_start(ap, n); - - (void)vprintf(msgs[n], ap); - (void)printf("\n"); - - va_end(ap); -} - -/* - * Return a pointer to the last component of a path. - */ -static const char * -lbasename(const char *path) -{ - const char *cp, *cp1, *cp2; - - if (Fflag) - return (path); - - cp = cp1 = cp2 = path; - while (*cp != '\0') { - if (*cp++ == '/') { - cp2 = cp1; - cp1 = cp; - } - } - return (*cp1 == '\0' ? cp2 : cp1); -} - -/* - * Create a string which describes a position in a source file. - */ -const char * -mkpos(pos_t *posp) -{ - size_t len; - const char *fn; - static char *buf; - static size_t blen = 0; - int qm, src, line; - - if (Hflag && posp->p_src != posp->p_isrc) { - src = posp->p_isrc; - line = posp->p_iline; - } else { - src = posp->p_src; - line = posp->p_line; - } - qm = !Hflag && posp->p_src != posp->p_isrc; - - len = strlen(fn = lbasename(fnames[src])); - len += 3 * sizeof (u_short) + 4; - - if (len > blen) - buf = xrealloc(buf, blen = len); - if (line != 0) { - (void)sprintf(buf, "%s%s(%d)", - fn, qm ? "?" : "", line); - } else { - (void)sprintf(buf, "%s", fn); - } - - return (buf); -} Index: usr.bin/xlint/lint2/read.c =================================================================== --- usr.bin/xlint/lint2/read.c +++ /dev/null @@ -1,1245 +0,0 @@ -/* $NetBSD: read.c,v 1.19 2007/09/28 21:53:50 uwe Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: read.c,v 1.19 2007/09/28 21:53:50 uwe Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include "lint2.h" - - -/* index of current (included) source file */ -static int srcfile; - -/* - * The array pointed to by inpfns maps the file name indices of input files - * to the file name indices used in lint2 - */ -static short *inpfns; -static size_t ninpfns; - -/* - * The array pointed to by *fnames maps file name indizes to file names. - * Indices of type short are used instead of pointers to save memory. - */ -const char **fnames; -static size_t nfnames; - -/* - * Types are shared (to save memory for the types itself) and accessed - * via indices (to save memory for references to types (indices are short)). - * To share types, an equal type must be located fast. This is done by a - * hash table. Access by indices is done via an array of pointers to the - * types. - */ -typedef struct thtab { - const char *th_name; - u_short th_idx; - struct thtab *th_nxt; -} thtab_t; -static thtab_t **thtab; /* hash table */ -type_t **tlst; /* array for indexed access */ -static size_t tlstlen; /* length of tlst */ - -static hte_t **renametab; - -/* index of current C source file (as spezified at the command line) */ -static int csrcfile; - - -#define inperr() inperror(__FILE__, __LINE__) -static void inperror(const char *, size_t); -static void setsrc(const char *); -static void setfnid(int, const char *); -static void funccall(pos_t *, const char *); -static void decldef(pos_t *, const char *); -static void usedsym(pos_t *, const char *); -static u_short inptype(const char *, const char **); -static int gettlen(const char *, const char **); -static u_short findtype(const char *, size_t, int); -static u_short storetyp(type_t *, const char *, size_t, int); -static int thash(const char *, size_t); -static char *inpqstrg(const char *, const char **); -static const char *inpname(const char *, const char **); -static int getfnidx(const char *); - -void -readfile(const char *name) -{ - FILE *inp; - size_t len; - const char *cp; - char *line, *eptr, rt = '\0'; - int cline, isrc, iline; - pos_t pos; - - if (inpfns == NULL) - if ((inpfns = calloc(ninpfns = 128, sizeof (short))) == NULL) - nomem(); - if (fnames == NULL) - if ((fnames = calloc(nfnames = 256, sizeof (char *))) == NULL) - nomem(); - if (tlstlen == 0) - if ((tlst = calloc(tlstlen = 256, sizeof (type_t *))) == NULL) - nomem(); - if (thtab == NULL) - if ((thtab = calloc(THSHSIZ2, sizeof (thtab_t))) == NULL) - nomem(); - - _inithash(&renametab); - - srcfile = getfnidx(name); - - if ((inp = fopen(name, "r")) == NULL) - err(1, "cannot open %s", name); - - while ((line = fgetln(inp, &len)) != NULL) { - - if (len == 0 || line[len - 1] != '\n') - inperr(); - line[len - 1] = '\0'; - cp = line; - - /* line number in csrcfile */ - cline = (int)strtol(cp, &eptr, 10); - if (cp == eptr) { - cline = -1; - } else { - cp = eptr; - } - - /* record type */ - if (*cp != '\0') { - rt = *cp++; - } else { - inperr(); - } - - if (rt == 'S') { - setsrc(cp); - continue; - } else if (rt == 's') { - setfnid(cline, cp); - continue; - } - - /* - * Index of (included) source file. If this index is - * different from csrcfile, it refers to an included - * file. - */ - isrc = (int)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - isrc = inpfns[isrc]; - - /* line number in isrc */ - if (*cp++ != '.') - inperr(); - iline = (int)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - - pos.p_src = (u_short)csrcfile; - pos.p_line = (u_short)cline; - pos.p_isrc = (u_short)isrc; - pos.p_iline = (u_short)iline; - - /* process rest of this record */ - switch (rt) { - case 'c': - funccall(&pos, cp); - break; - case 'd': - decldef(&pos, cp); - break; - case 'u': - usedsym(&pos, cp); - break; - default: - inperr(); - } - - } - - _destroyhash(renametab); - - if (ferror(inp)) - err(1, "read error on %s", name); - - (void)fclose(inp); -} - - -static void -inperror(const char *file, size_t line) -{ - - errx(1, "%s,%zd: input file error: %s", file, line, fnames[srcfile]); -} - -/* - * Set the name of the C source file of the .ln file which is - * currently read. - */ -static void -setsrc(const char *cp) -{ - - csrcfile = getfnidx(cp); -} - -/* - * setfnid() gets as input an index as used in an input file and the - * associated file name. If necessary, it creates a new lint2 file - * name index for this file name and creates the mapping of the index - * as used in the input file to the index used in lint2. - */ -static void -setfnid(int fid, const char *cp) -{ - - if (fid == -1) - inperr(); - - if (fid >= ninpfns) { - if ((inpfns = realloc(inpfns, (ninpfns * 2) * sizeof (short))) - == NULL) - nomem(); - (void)memset(inpfns + ninpfns, 0, ninpfns * sizeof (short)); - ninpfns *= 2; - } - /* - * Should always be true because indices written in the output - * file by lint1 are always the previous index + 1. - */ - if (fid >= ninpfns) - errx(1, "internal error: setfnid()"); - inpfns[fid] = (u_short)getfnidx(cp); -} - -/* - * Process a function call record (c-record). - */ -static void -funccall(pos_t *posp, const char *cp) -{ - arginf_t *ai, **lai; - char c, *eptr; - int rused, rdisc; - hte_t *hte; - fcall_t *fcall; - const char *name; - - fcall = xalloc(sizeof (fcall_t)); - STRUCT_ASSIGN(fcall->f_pos, *posp); - - /* read flags */ - rused = rdisc = 0; - lai = &fcall->f_args; - while ((c = *cp) == 'u' || c == 'i' || c == 'd' || - c == 'z' || c == 'p' || c == 'n' || c == 's') { - cp++; - switch (c) { - case 'u': - if (rused || rdisc) - inperr(); - rused = 1; - break; - case 'i': - if (rused || rdisc) - inperr(); - break; - case 'd': - if (rused || rdisc) - inperr(); - rdisc = 1; - break; - case 'z': - case 'p': - case 'n': - case 's': - ai = xalloc(sizeof (arginf_t)); - ai->a_num = (int)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - if (c == 'z') { - ai->a_pcon = ai->a_zero = 1; - } else if (c == 'p') { - ai->a_pcon = 1; - } else if (c == 'n') { - ai->a_ncon = 1; - } else { - ai->a_fmt = 1; - ai->a_fstrg = inpqstrg(cp, &cp); - } - *lai = ai; - lai = &ai->a_nxt; - break; - } - } - fcall->f_rused = rused; - fcall->f_rdisc = rdisc; - - /* read name of function */ - name = inpname(cp, &cp); - - /* first look it up in the renaming table, then in the normal table */ - hte = _hsearch(renametab, name, 0); - if (hte != NULL) - hte = hte->h_hte; - else - hte = hsearch(name, 1); - hte->h_used = 1; - - fcall->f_type = inptype(cp, &cp); - - *hte->h_lcall = fcall; - hte->h_lcall = &fcall->f_nxt; - - if (*cp != '\0') - inperr(); -} - -/* - * Process a declaration or definition (d-record). - */ -static void -decldef(pos_t *posp, const char *cp) -{ - sym_t *symp, sym; - char c, *ep, *pos1; - int used, renamed; - hte_t *hte, *renamehte = NULL; - const char *name, *rename; - - (void)memset(&sym, 0, sizeof (sym)); - STRUCT_ASSIGN(sym.s_pos, *posp); - sym.s_def = NODECL; - - used = 0; - - while (strchr("tdeurosvPS", (c = *cp)) != NULL) { - cp++; - switch (c) { - case 't': - if (sym.s_def != NODECL) - inperr(); - sym.s_def = TDEF; - break; - case 'd': - if (sym.s_def != NODECL) - inperr(); - sym.s_def = DEF; - break; - case 'e': - if (sym.s_def != NODECL) - inperr(); - sym.s_def = DECL; - break; - case 'u': - if (used) - inperr(); - used = 1; - break; - case 'r': - if (sym.s_rval) - inperr(); - sym.s_rval = 1; - break; - case 'o': - if (sym.s_osdef) - inperr(); - sym.s_osdef = 1; - break; - case 's': - if (sym.s_static) - inperr(); - sym.s_static = 1; - break; - case 'v': - if (sym.s_va) - inperr(); - sym.s_va = 1; - sym.s_nva = (short)strtol(cp, &ep, 10); - if (cp == ep) - inperr(); - cp = ep; - break; - case 'P': - if (sym.s_prfl) - inperr(); - sym.s_prfl = 1; - sym.s_nprfl = (short)strtol(cp, &ep, 10); - if (cp == ep) - inperr(); - cp = ep; - break; - case 'S': - if (sym.s_scfl) - inperr(); - sym.s_scfl = 1; - sym.s_nscfl = (short)strtol(cp, &ep, 10); - if (cp == ep) - inperr(); - cp = ep; - break; - } - } - - /* read symbol name, doing renaming if necessary */ - name = inpname(cp, &cp); - renamed = 0; - if (*cp == 'r') { - cp++; - name = xstrdup(name); - rename = inpname(cp, &cp); - - /* enter it and see if it's already been renamed */ - renamehte = _hsearch(renametab, name, 1); - if (renamehte->h_hte == NULL) { - hte = hsearch(rename, 1); - renamehte->h_hte = hte; - renamed = 1; - } else if (strcmp((hte = renamehte->h_hte)->h_name, rename)) { - pos1 = xstrdup(mkpos(&renamehte->h_syms->s_pos)); - /* %s renamed multiple times\t%s :: %s */ - msg(18, name, pos1, mkpos(&sym.s_pos)); - free(pos1); - } - free((char *)name); - } else { - /* it might be a previously-done rename */ - hte = _hsearch(renametab, name, 0); - if (hte != NULL) - hte = hte->h_hte; - else - hte = hsearch(name, 1); - } - hte->h_used |= used; - if (sym.s_def == DEF || sym.s_def == TDEF) - hte->h_def = 1; - - sym.s_type = inptype(cp, &cp); - - /* - * Allocate memory for this symbol only if it was not already - * declared or tentatively defined at the same location with - * the same type. Works only for symbols with external linkage, - * because static symbols, tentatively defined at the same location - * but in different translation units are really different symbols. - */ - for (symp = hte->h_syms; symp != NULL; symp = symp->s_nxt) { - if (symp->s_pos.p_isrc == sym.s_pos.p_isrc && - symp->s_pos.p_iline == sym.s_pos.p_iline && - symp->s_type == sym.s_type && - ((symp->s_def == DECL && sym.s_def == DECL) || - (!sflag && symp->s_def == TDEF && sym.s_def == TDEF)) && - !symp->s_static && !sym.s_static) { - break; - } - } - - if (symp == NULL) { - /* allocsym reserviert keinen Platz fuer s_nva */ - if (sym.s_va || sym.s_prfl || sym.s_scfl) { - symp = xalloc(sizeof (sym_t)); - STRUCT_ASSIGN(*symp, sym); - } else { - symp = xalloc(sizeof (symp->s_s)); - STRUCT_ASSIGN(symp->s_s, sym.s_s); - } - *hte->h_lsym = symp; - hte->h_lsym = &symp->s_nxt; - - /* XXX hack so we can remember where a symbol was renamed */ - if (renamed) - renamehte->h_syms = symp; - } - - if (*cp != '\0') - inperr(); -} - -/* - * Read an u-record (emitted by lint1 if a symbol was used). - */ -static void -usedsym(pos_t *posp, const char *cp) -{ - usym_t *usym; - hte_t *hte; - const char *name; - - usym = xalloc(sizeof (usym_t)); - STRUCT_ASSIGN(usym->u_pos, *posp); - - /* needed as delimiter between two numbers */ - if (*cp++ != 'x') - inperr(); - - name = inpname(cp, &cp); - hte = _hsearch(renametab, name, 0); - if (hte != NULL) - hte = hte->h_hte; - else - hte = hsearch(name, 1); - hte->h_used = 1; - - *hte->h_lusym = usym; - hte->h_lusym = &usym->u_nxt; -} - -/* - * Read a type and return the index of this type. - */ -static u_short -inptype(const char *cp, const char **epp) -{ - char c, s, *eptr; - const char *ep; - type_t *tp; - int narg, i, osdef = 0; - size_t tlen; - u_short tidx, sidx; - int h; - - /* If we have this type already, return it's index. */ - tlen = gettlen(cp, &ep); - h = thash(cp, tlen); - if ((tidx = findtype(cp, tlen, h)) != 0) { - *epp = ep; - return (tidx); - } - - /* No, we must create a new type. */ - tp = xalloc(sizeof (type_t)); - - tidx = storetyp(tp, cp, tlen, h); - - c = *cp++; - - while (c == 'c' || c == 'v') { - if (c == 'c') { - tp->t_const = 1; - } else { - tp->t_volatile = 1; - } - c = *cp++; - } - - if (c == 's' || c == 'u' || c == 'l' || c == 'e') { - s = c; - c = *cp++; - } else { - s = '\0'; - } - - switch (c) { - case 'C': - tp->t_tspec = s == 's' ? SCHAR : (s == 'u' ? UCHAR : CHAR); - break; - case 'S': - tp->t_tspec = s == 'u' ? USHORT : SHORT; - break; - case 'I': - tp->t_tspec = s == 'u' ? UINT : INT; - break; - case 'L': - tp->t_tspec = s == 'u' ? ULONG : LONG; - break; - case 'Q': - tp->t_tspec = s == 'u' ? UQUAD : QUAD; - break; - case 'D': - tp->t_tspec = s == 's' ? FLOAT : (s == 'l' ? LDOUBLE : DOUBLE); - break; - case 'V': - tp->t_tspec = VOID; - break; - case 'P': - tp->t_tspec = PTR; - break; - case 'A': - tp->t_tspec = ARRAY; - break; - case 'F': - case 'f': - osdef = c == 'f'; - tp->t_tspec = FUNC; - break; - case 'T': - tp->t_tspec = s == 'e' ? ENUM : (s == 's' ? STRUCT : UNION); - break; - } - - switch (tp->t_tspec) { - case ARRAY: - tp->t_dim = (int)strtol(cp, &eptr, 10); - cp = eptr; - sidx = inptype(cp, &cp); /* force seq. point! (ditto below) */ - tp->t_subt = TP(sidx); - break; - case PTR: - sidx = inptype(cp, &cp); - tp->t_subt = TP(sidx); - break; - case FUNC: - c = *cp; - if (isdigit((u_char)c)) { - if (!osdef) - tp->t_proto = 1; - narg = (int)strtol(cp, &eptr, 10); - cp = eptr; - if ((tp->t_args = calloc((size_t)(narg + 1), - sizeof (type_t *))) == NULL) - nomem(); - for (i = 0; i < narg; i++) { - if (i == narg - 1 && *cp == 'E') { - tp->t_vararg = 1; - cp++; - } else { - sidx = inptype(cp, &cp); - tp->t_args[i] = TP(sidx); - } - } - } - sidx = inptype(cp, &cp); - tp->t_subt = TP(sidx); - break; - case ENUM: - tp->t_tspec = INT; - tp->t_isenum = 1; - /* FALLTHROUGH */ - case STRUCT: - case UNION: - switch (*cp++) { - case '1': - tp->t_istag = 1; - tp->t_tag = hsearch(inpname(cp, &cp), 1); - break; - case '2': - tp->t_istynam = 1; - tp->t_tynam = hsearch(inpname(cp, &cp), 1); - break; - case '3': - tp->t_isuniqpos = 1; - tp->t_uniqpos.p_line = strtol(cp, &eptr, 10); - cp = eptr; - cp++; - /* xlate to 'global' file name. */ - tp->t_uniqpos.p_file = - addoutfile(inpfns[strtol(cp, &eptr, 10)]); - cp = eptr; - cp++; - tp->t_uniqpos.p_uniq = strtol(cp, &eptr, 10); - cp = eptr; - break; - } - break; - case LONG: - case VOID: - case LDOUBLE: - case DOUBLE: - case FLOAT: - case UQUAD: - case QUAD: - case ULONG: - case UINT: - case INT: - case USHORT: - case SHORT: - case UCHAR: - case SCHAR: - case CHAR: - case UNSIGN: - case SIGNED: - case NOTSPEC: - break; - } - - *epp = cp; - return (tidx); -} - -/* - * Get the length of a type string. - */ -static int -gettlen(const char *cp, const char **epp) -{ - const char *cp1; - char c, s, *eptr; - tspec_t t; - int narg, i, cm, vm; - - cp1 = cp; - - c = *cp++; - - cm = vm = 0; - - while (c == 'c' || c == 'v') { - if (c == 'c') { - if (cm) - inperr(); - cm = 1; - } else { - if (vm) - inperr(); - vm = 1; - } - c = *cp++; - } - - if (c == 's' || c == 'u' || c == 'l' || c == 'e') { - s = c; - c = *cp++; - } else { - s = '\0'; - } - - t = NOTSPEC; - - switch (c) { - case 'C': - if (s == 's') { - t = SCHAR; - } else if (s == 'u') { - t = UCHAR; - } else if (s == '\0') { - t = CHAR; - } - break; - case 'S': - if (s == 'u') { - t = USHORT; - } else if (s == '\0') { - t = SHORT; - } - break; - case 'I': - if (s == 'u') { - t = UINT; - } else if (s == '\0') { - t = INT; - } - break; - case 'L': - if (s == 'u') { - t = ULONG; - } else if (s == '\0') { - t = LONG; - } - break; - case 'Q': - if (s == 'u') { - t = UQUAD; - } else if (s == '\0') { - t = QUAD; - } - break; - case 'D': - if (s == 's') { - t = FLOAT; - } else if (s == 'l') { - t = LDOUBLE; - } else if (s == '\0') { - t = DOUBLE; - } - break; - case 'V': - if (s == '\0') - t = VOID; - break; - case 'P': - if (s == '\0') - t = PTR; - break; - case 'A': - if (s == '\0') - t = ARRAY; - break; - case 'F': - case 'f': - if (s == '\0') - t = FUNC; - break; - case 'T': - if (s == 'e') { - t = ENUM; - } else if (s == 's') { - t = STRUCT; - } else if (s == 'u') { - t = UNION; - } - break; - default: - inperr(); - } - - if (t == NOTSPEC) - inperr(); - - switch (t) { - case ARRAY: - (void)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - (void)gettlen(cp, &cp); - break; - case PTR: - (void)gettlen(cp, &cp); - break; - case FUNC: - c = *cp; - if (isdigit((u_char)c)) { - narg = (int)strtol(cp, &eptr, 10); - cp = eptr; - for (i = 0; i < narg; i++) { - if (i == narg - 1 && *cp == 'E') { - cp++; - } else { - (void)gettlen(cp, &cp); - } - } - } - (void)gettlen(cp, &cp); - break; - case ENUM: - case STRUCT: - case UNION: - switch (*cp++) { - case '1': - (void)inpname(cp, &cp); - break; - case '2': - (void)inpname(cp, &cp); - break; - case '3': - /* unique position: line.file.uniquifier */ - (void)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - if (*cp++ != '.') - inperr(); - (void)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - if (*cp++ != '.') - inperr(); - (void)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - break; - default: - inperr(); - } - break; - case FLOAT: - case USHORT: - case SHORT: - case UCHAR: - case SCHAR: - case CHAR: - case UNSIGN: - case SIGNED: - case NOTSPEC: - case INT: - case UINT: - case DOUBLE: - case LDOUBLE: - case VOID: - case ULONG: - case QUAD: - case UQUAD: - case LONG: - break; - } - - *epp = cp; - return (cp - cp1); -} - -/* - * Search a type by its type string. - */ -static u_short -findtype(const char *cp, size_t len, int h) -{ - thtab_t *thte; - - for (thte = thtab[h]; thte != NULL; thte = thte->th_nxt) { - if (strncmp(thte->th_name, cp, len) != 0) - continue; - if (thte->th_name[len] == '\0') - return (thte->th_idx); - } - - return (0); -} - -/* - * Store a type and it's type string so we can later share this type - * if we read the same type string from the input file. - */ -static u_short -storetyp(type_t *tp, const char *cp, size_t len, int h) -{ - static u_int tidx = 1; /* 0 is reserved */ - thtab_t *thte; - char *name; - - if (tidx >= USHRT_MAX) - errx(1, "sorry, too many types"); - - if (tidx == tlstlen - 1) { - if ((tlst = realloc(tlst, (tlstlen * 2) * sizeof (type_t *))) - == NULL) - nomem(); - (void)memset(tlst + tlstlen, 0, tlstlen * sizeof (type_t *)); - tlstlen *= 2; - } - - tlst[tidx] = tp; - - /* create a hash table entry */ - name = xalloc(len + 1); - (void)memcpy(name, cp, len); - name[len] = '\0'; - - thte = xalloc(sizeof (thtab_t)); - thte->th_name = name; - thte->th_idx = tidx; - thte->th_nxt = thtab[h]; - thtab[h] = thte; - - return ((u_short)tidx++); -} - -/* - * Hash function for types - */ -static int -thash(const char *s, size_t len) -{ - u_int v; - - v = 0; - while (len-- != 0) { - v = (v << sizeof (v)) + (u_char)*s++; - v ^= v >> (sizeof (v) * CHAR_BIT - sizeof (v)); - } - return (v % THSHSIZ2); -} - -/* - * Read a string enclosed by "". This string may contain quoted chars. - */ -static char * -inpqstrg(const char *src, const char **epp) -{ - char *strg, *dst; - size_t slen; - int c; - int v; - - if ((dst = strg = malloc(slen = 32)) == NULL) - nomem(); - - if ((c = *src++) != '"') - inperr(); - if ((c = *src++) == '\0') - inperr(); - - while (c != '"') { - if (c == '\\') { - if ((c = *src++) == '\0') - inperr(); - switch (c) { - case 'n': - c = '\n'; - break; - case 't': - c = '\t'; - break; - case 'v': - c = '\v'; - break; - case 'b': - c = '\b'; - break; - case 'r': - c = '\r'; - break; - case 'f': - c = '\f'; - break; - case 'a': - c = '\a'; - break; - case '\\': - c = '\\'; - break; - case '"': - c = '"'; - break; - case '\'': - c = '\''; - break; - case '0': case '1': case '2': case '3': - v = (c - '0') << 6; - if ((c = *src++) < '0' || c > '7') - inperr(); - v |= (c - '0') << 3; - if ((c = *src++) < '0' || c > '7') - inperr(); - v |= c - '0'; - c = (u_char)v; - break; - default: - inperr(); - } - } - /* keep space for trailing '\0' */ - if (dst - strg == slen - 1) { - if ((strg = realloc(strg, slen * 2)) == NULL) - nomem(); - dst = strg + (slen - 1); - slen *= 2; - } - *dst++ = (char)c; - if ((c = *src++) == '\0') - inperr(); - } - *dst = '\0'; - - *epp = src; - return (strg); -} - -/* - * Read the name of a symbol in static memory. - */ -static const char * -inpname(const char *cp, const char **epp) -{ - static char *buf; - static size_t blen = 0; - size_t len, i; - char *eptr, c; - - len = (int)strtol(cp, &eptr, 10); - if (cp == eptr) - inperr(); - cp = eptr; - if (len + 1 > blen) - if ((buf = realloc(buf, blen = len + 1)) == NULL) - nomem(); - for (i = 0; i < len; i++) { - c = *cp++; - if (!isalnum((unsigned char)c) && c != '_') - inperr(); - buf[i] = c; - } - buf[i] = '\0'; - - *epp = cp; - return (buf); -} - -/* - * Return the index of a file name. If the name cannot be found, create - * a new entry and return the index of the newly created entry. - */ -static int -getfnidx(const char *fn) -{ - int i; - - /* 0 ist reserved */ - for (i = 1; fnames[i] != NULL; i++) { - if (strcmp(fnames[i], fn) == 0) - break; - } - if (fnames[i] != NULL) - return (i); - - if (i == nfnames - 1) { - if ((fnames = realloc(fnames, (nfnames * 2) * sizeof (char *))) - == NULL) - nomem(); - (void)memset(fnames + nfnames, 0, nfnames * sizeof (char *)); - nfnames *= 2; - } - - if ((fnames[i] = strdup(fn)) == NULL) - nomem(); - return (i); -} - -/* - * Separate symbols with static and external linkage. - */ -void -mkstatic(hte_t *hte) -{ - sym_t *sym1, **symp, *sym; - fcall_t **callp, *call; - usym_t **usymp, *usym; - hte_t *nhte; - int ofnd; - - /* Look for first static definition */ - for (sym1 = hte->h_syms; sym1 != NULL; sym1 = sym1->s_nxt) { - if (sym1->s_static) - break; - } - if (sym1 == NULL) - return; - - /* Do nothing if this name is used only in one translation unit. */ - ofnd = 0; - for (sym = hte->h_syms; sym != NULL && !ofnd; sym = sym->s_nxt) { - if (sym->s_pos.p_src != sym1->s_pos.p_src) - ofnd = 1; - } - for (call = hte->h_calls; call != NULL && !ofnd; call = call->f_nxt) { - if (call->f_pos.p_src != sym1->s_pos.p_src) - ofnd = 1; - } - for (usym = hte->h_usyms; usym != NULL && !ofnd; usym = usym->u_nxt) { - if (usym->u_pos.p_src != sym1->s_pos.p_src) - ofnd = 1; - } - if (!ofnd) { - hte->h_used = 1; - /* errors about undef. static symbols are printed in lint1 */ - hte->h_def = 1; - hte->h_static = 1; - return; - } - - /* - * Create a new hash table entry - * - * XXX this entry should be put at the beginning of the list to - * avoid to process the same symbol twice. - */ - for (nhte = hte; nhte->h_link != NULL; nhte = nhte->h_link) - continue; - nhte->h_link = xmalloc(sizeof (hte_t)); - nhte = nhte->h_link; - nhte->h_name = hte->h_name; - nhte->h_used = 1; - nhte->h_def = 1; /* error in lint1 */ - nhte->h_static = 1; - nhte->h_syms = NULL; - nhte->h_lsym = &nhte->h_syms; - nhte->h_calls = NULL; - nhte->h_lcall = &nhte->h_calls; - nhte->h_usyms = NULL; - nhte->h_lusym = &nhte->h_usyms; - nhte->h_link = NULL; - nhte->h_hte = NULL; - - /* - * move all symbols used in this translation unit into the new - * hash table entry. - */ - for (symp = &hte->h_syms; (sym = *symp) != NULL; ) { - if (sym->s_pos.p_src == sym1->s_pos.p_src) { - sym->s_static = 1; - (*symp) = sym->s_nxt; - if (hte->h_lsym == &sym->s_nxt) - hte->h_lsym = symp; - sym->s_nxt = NULL; - *nhte->h_lsym = sym; - nhte->h_lsym = &sym->s_nxt; - } else { - symp = &sym->s_nxt; - } - } - for (callp = &hte->h_calls; (call = *callp) != NULL; ) { - if (call->f_pos.p_src == sym1->s_pos.p_src) { - (*callp) = call->f_nxt; - if (hte->h_lcall == &call->f_nxt) - hte->h_lcall = callp; - call->f_nxt = NULL; - *nhte->h_lcall = call; - nhte->h_lcall = &call->f_nxt; - } else { - callp = &call->f_nxt; - } - } - for (usymp = &hte->h_usyms; (usym = *usymp) != NULL; ) { - if (usym->u_pos.p_src == sym1->s_pos.p_src) { - (*usymp) = usym->u_nxt; - if (hte->h_lusym == &usym->u_nxt) - hte->h_lusym = usymp; - usym->u_nxt = NULL; - *nhte->h_lusym = usym; - nhte->h_lusym = &usym->u_nxt; - } else { - usymp = &usym->u_nxt; - } - } - - /* h_def must be recalculated for old hte */ - hte->h_def = nhte->h_def = 0; - for (sym = hte->h_syms; sym != NULL; sym = sym->s_nxt) { - if (sym->s_def == DEF || sym->s_def == TDEF) { - hte->h_def = 1; - break; - } - } - - mkstatic(hte); -} Index: usr.bin/xlint/llib/Makefile =================================================================== --- usr.bin/xlint/llib/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# $NetBSD: Makefile,v 1.7 2000/06/14 20:22:19 matt Exp $ -# $FreeBSD$ - -LIBS= llib-lposix.ln llib-lstdc.ln - -FILES= ${LIBS} -FILESDIR= ${LINTLIBDIR} - -CLEANFILES+= ${LIBS} - -llib-lposix.ln: llib-lposix - ${LINT} ${LINTFLAGS} -Cposix ${.ALLSRC} - -llib-lstdc.ln: llib-lstdc - ${LINT} ${LINTFLAGS} -Cstdc ${.ALLSRC} - -.include - -.if !empty(STAGE_INCLUDEDIR) -LINTFLAGS+= -I${STAGE_INCLUDEDIR} -.else -.if ${CFLAGS:M--sysroot=*} != "" -_sysroot?= ${CFLAGS:M--sysroot=*:[1]:C,^--sysroot=,,} -.elif ${CC:M--sysroot=*} != "" -_sysroot?= ${CC:M--sysroot=*:[1]:C,^--sysroot=,,} -.endif -.if !empty(_sysroot) -LINTFLAGS+= -I${_sysroot}/usr/include -.endif -.endif Index: usr.bin/xlint/llib/Makefile.depend =================================================================== --- usr.bin/xlint/llib/Makefile.depend +++ /dev/null @@ -1,14 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - include \ - lib/msun \ - usr.bin/xlint/xlint.host \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.bin/xlint/llib/llib-lposix =================================================================== --- usr.bin/xlint/llib/llib-lposix +++ /dev/null @@ -1,314 +0,0 @@ -/* $NetBSD: llib-lposix,v 1.2 1995/07/03 21:25:09 cgd Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* LINTLIBRARY */ - -#define _POSIX_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* PROTOLIB1 */ - - -void (abort)(void); -int (abs)(int j); -int (access)(const char *path, int amode); -double (acos)(double x); -unsigned (alarm)(unsigned seconds); -char *(asctime)(const struct tm *timeptr); -double (asin)(double x); -void (__assert)(const char *expression, const char *func, int line, - const char *file); -double (atan)(double x); -double (atan2)(double y, double x); -int (atexit)(void (*func)(void)); -double (atof)(const char *nptr); -int (atoi)(const char *nptr); -long (atol)(const char *nptr); -void *(bsearch)(const void *key, const void *base, size_t nmemb, - size_t size, int (*compar)(const void *, const void *)); -void *(calloc)(size_t nmemb, size_t size); -double (ceil)(double x); -speed_t (cfgetispeed)(const struct termios *p); -speed_t (cfgetospeed)(const struct termios *p); -int (cfsetispeed)(struct termios *p, speed_t speed); -int (cfsetospeed)(struct termios *p, speed_t speed); -int (chdir)(const char *path); -int (chmod)(const char *path, mode_t mode); -int (chown)(const char *path, uid_t owner, gid_t group); -void (clearerr)(FILE *stream); -clock_t (clock)(void); -int (close)(int fildes); -int (closedir)(DIR *dirp); -double (cos)(double x); -double (cosh)(double x); -int (creat)(const char *path, mode_t mode); -char *(ctermid)(char *s); -char *(ctime)(const time_t *timer); -char *(cuserid)(char *s); -double (difftime)(time_t time1, time_t time0); -div_t (div)(int numer, int denom); -int (dup)(int fildes); -int (dup2)(int fildes, int fildes2); -int (errno); -int (execl)(const char *path, const char *arg, ...); -int (execle)(const char *path, const char *arg, ...); -int (execlp)(const char *file, const char *arg, ...); -int (execv)(const char *path, char *const argv[]); -int (execve)(const char *path, char *const argv[], char *const *envp); -int (execvp)(const char *file, char *const argv[]); -void (exit)(int status); -void (_exit)(int status); -double (exp)(double x); -double (fabs)(double x); -int (fclose)(FILE *stream); -int (fcntl)(int fildes, int cmd, ...); -FILE *(fdopen)(int fildes, const char *type); -int (feof)(FILE *stream); -int (ferror)(FILE *stream); -int (fflush)(FILE *stream); -int (fgetc)(FILE *stream); -int (fgetpos)(FILE *stream, fpos_t *pos); -char *(fgets)(char *s, int n, FILE *stream); -int (fileno)(FILE *stream); -double (floor)(double x); -double (fmod)(double x, double y); -FILE *(fopen)(const char *filename, const char *mode); -pid_t (fork)(void); -long (fpathconf)(int fildes, int name); -/* PRINTFLIKE2 */ -int (fprintf)(FILE *stream, const char *format, ...); -int (fputc)(int c, FILE *stream); -int (fputs)(const char *s, FILE *stream); -size_t (fread)(void *ptr, size_t size, size_t nmemb, FILE *stream); -void (free)(void *ptr); -FILE *(freopen)(const char *filename, const char *mode, FILE *stream); -double (frepx)(double value, int *exp); -/* SCANFLIKE2 */ -int (fscanf)(FILE *stream, const char *format, ...); -int (fseek)(FILE *stream, long int offset, int whence); -int (fsetpos)(FILE *stream, const fpos_t *pos); -int (fstat)(int fildes, struct stat *buf); -long (ftell)(FILE *stream); -size_t (fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream); -int (getc)(FILE *stream); -int (getchar)(void); -char *(getcwd)(char *buf, size_t size); -gid_t (getegid)(void); -char *(getenv)(const char *name); -uid_t (geteuid)(void); -gid_t (getgid)(void); -struct group *(getgrgid)(gid_t gid); -struct group *(getgrnam)(const char *name); -int (getgroups)(int gidsetsize, gid_t grouplist[]); -char *(getlogin)(void); -pid_t (getpgrp)(void); -pid_t (getpid)(void); -pid_t (getppid)(void); -struct passwd *(getpwnam)(const char *name); -struct passwd *(getpwuid)(uid_t uid); -char *(gets)(char *s); -uid_t (getuid)(void); -struct tm *(gmtime)(const time_t *timer); -int (isalnum)(int c); -int (isalpha)(int c); -int (isatty)(int fildes); -int (iscntrl)(int c); -int (isdigit)(int c); -int (isgraph)(int c); -int (islower)(int c); -int (isprint)(int c); -int (ispunct)(int c); -int (isspace)(int c); -int (isupper)(int c); -int (isxdigit)(int c); -int (kill)(pid_t pid, int sig); -long (labs)(long j); -double (ldexp)(double x, int exp); -ldiv_t (ldiv)(long numer, long denom); -int (link)(const char *existing, const char *new); -struct lconv *(localeconv)(void); -struct tm *(localtime)(const time_t *timer); -double (log)(double x); -double (log10)(double x); -void (longjmp)(jmp_buf env, int val); -off_t (lseek)(int fildes, off_t offset, int whence); -void *(malloc)(size_t size); -int (mblen)(const char *s, size_t n); -size_t (mbstowcs)(wchar_t *pwcs, const char *s, size_t n); -int (mbtowc)(wchar_t *pwc, const char *s, size_t n); -void *(memchr)(const void *s, int c, size_t n); -int (memcmp)(const void *s1, const void *s2, size_t n); -void *(memcpy)(void *s1, const void *s2, size_t n); -void *(memmove)(void *s1, const void *s2, size_t n); -void *(memset)(void *s, int c, size_t n); -int (mkdir)(const char *path, mode_t mode); -int (mkfifo)(const char *path, mode_t mode); -time_t (mktime)(struct tm *timeptr); -double (modf)(double value, double *iptr); -int (open)(const char *path, int oflag, ...); -DIR *(opendir)(const char *dirname); -long (pathconf)(const char *path, int name); -int (pause)(void); -void (perror)(const char *s); -int (pipe)(int fildes[2]); -double (pow)(double x, double y); -/* PRINTFLIKE1 */ -int (printf)(const char *format, ...); -int (putc)(int c, FILE *stream); -int (putchar)(int c); -int (puts)(const char *s); -void (qsort)(void *base, size_t nmemb, size_t size, - int (*compar)(const void *, const void *)); -int (raise)(int sig); -int (rand)(void); -ssize_t (read)(int fildes, void *buf, size_t nbyte); -struct dirent *(readdir)(DIR *dirp); -void *(realloc)(void *ptr, size_t size); -int (remove)(const char *filename); -int (rename)(const char *old, const char *new); -void (rewind)(FILE *stream); -void (rewinddir)(DIR *dirp); -int (rmdir)(const char *path); -/* SCANFLIKE1 */ -int (scanf)(const char *format, ...); -void (setbuf)(FILE *stream, char *buf); -int (setgid)(gid_t gid); -int (setjmp)(jmp_buf env); -char *(setlocale)(int category, const char *locale); -int (setpgid)(pid_t pid, pid_t pgid); -pid_t (setsid)(void); -int (setuid)(uid_t uid); -int (setvbuf)(FILE *stream, char *buf, int mode, size_t size); -int (sigaction)(int sig, const struct sigaction *act, - struct sigaction *oact); -int (sigaddset)(sigset_t *set, int signo); -int (sigdelset)(sigset_t *set, int signo); -int (sigemptyset)(sigset_t *set); -int (sigfillset)(sigset_t *set); -int (sigismember)(const sigset_t *set, int signo); -void (siglongjmp)(sigjmp_buf env, int val); -void (*(signal)(int sig, void (*func)(int)))(int); -int (sigpending)(sigset_t *set); -int (sigprocmask)(int how, const sigset_t *set, sigset_t *oset); -int (sigsetjmp)(sigjmp_buf env, int savemask); -int (sigsuspend)(const sigset_t *sigmask); -double (sin)(double x); -double (sinh)(double x); -unsigned (sleep)(unsigned seconds); -/* PRINTFLIKE2 */ -int (sprintf)(char *s, const char *format, ...); -double (sqrt)(double x); -void (srand)(unsigned seed); -/* SCANFLIKE2 */ -int (sscanf)(const char *s, const char *format, ...); -int (stat)(const char *path, struct stat *buf); -char *(strcat)(char *s1, const char *s2); -char *(strchr)(const char *s, int c); -int (strcmp)(const char *s1, const char *s2); -int (strcoll)(const char *s1, const char *s2); -char *(strcpy)(char *s1, const char *s2); -size_t (strcspn)(const char *s1, const char *s2); -char *(strerror)(int errnum); -size_t (strftime)(char *s, size_t maxsize, const char *format, - const struct tm *timeptr); -size_t (strlen)(const char *s); -char *(strncat)(char *s1, const char *s2, size_t n); -int (strncmp)(const char *s1, const char *s2, size_t n); -char *(strncpy)(char *s1, const char *s2, size_t n); -char *(strpbrk)(const char *s1, const char *s2); -char *(strrchr)(const char *s, int c); -size_t (strspn)(const char *s1, const char *s2); -char *(strstr)(const char *s1, const char *s2); -double (strtod)(const char *nptr, char **endptr); -char *(strtok)(char *s1, const char *s2); -long (strtol)(const char *nptr, char **endptr, int base); -unsigned long (strtoul)(const char *nptr, char **endptr, int base); -size_t (strxfrm)(char *s1, const char *s2, size_t n); -long (sysconf)(int name); -int (system)(const char *string); -double (tan)(double x); -double (tanh)(double x); -int (tcdrain)(int fildes); -int (tcflow)(int fildes, int action); -int (tcflush)(int fildes, int queue_selector); -int (tcgetattr)(int fildes, struct termios *tp); -pid_t (tcgetpgrp)(int fildes); -int (tcsendbreak)(int fildes, int duration); -int (tcsetattr)(int fildes, int options, const struct termios *tp); -int (tcsetpgrp)(int fildes, pid_t pgrpid); -time_t (time)(time_t *timer); -clock_t (times)(struct tms *buffer); -FILE *(tmpfile)(void); -char *(tmpnam)(char *s); -int (tolower)(int c); -int (toupper)(int c); -char *(ttyname)(int filedes); -void (tzset)(void); -mode_t (umask)(mode_t cmask); -int (uname)(struct utsname *name); -int (ungetc)(int c, FILE *stream); -int (unlink)(const char *path); -int (utime)(const char *path, const struct utimbuf *times); -int (vfprintf)(FILE *stream, const char *format, va_list arg); -int (vprintf)(const char *format, va_list arg); -int (vsprintf)(char *s, const char *format, va_list arg); -pid_t (wait)(int *statloc); -pid_t (waitpid)(pid_t pid, int *stat_loc, int options); -size_t (wcstombs)(char *s, const wchar_t *pwcs, size_t n); -int (wctomb)(char *s, wchar_t wchar); -ssize_t (write)(int fildes, const void *buf, size_t nbyte); Index: usr.bin/xlint/llib/llib-lstdc =================================================================== --- usr.bin/xlint/llib/llib-lstdc +++ /dev/null @@ -1,254 +0,0 @@ -/* $NetBSD: llib-lstdc,v 1.2 1995/07/03 21:25:11 cgd Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* LINTLIBRARY */ - -#define _ANSI_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* PROTOLIB1 */ - -/* - * assert.h - */ -#ifdef __NetBSD__ -void (__assert)(const char *expression, int line, const char *file); -#else -void (assert)(int expression); -#endif - -/* - * ctype.h - */ -int (isalnum)(int c); -int (isalpha)(int c); -int (iscntrl)(int c); -int (isdigit)(int c); -int (isgraph)(int c); -int (islower)(int c); -int (isprint)(int c); -int (ispunct)(int c); -int (isspace)(int c); -int (isupper)(int c); -int (isxdigit)(int c); -int (tolower)(int c); -int (toupper)(int c); - -/* - * errno.h - */ -int (errno); - -/* - * locale.h - */ -char *(setlocale)(int category, const char *locale); -struct lconv *(localeconv)(void); - -/* - * math.h - */ -double (acos)(double x); -double (asin)(double x); -double (atan)(double x); -double (atan2)(double y, double x); -double (cos)(double x); -double (sin)(double x); -double (tan)(double x); -double (cosh)(double x); -double (sinh)(double x); -double (tanh)(double x); -double (exp)(double x); -double (frexp)(double value, int *exp); -double (ldexp)(double x, int exp); -double (log)(double x); -double (log10)(double x); -double (modf)(double value, double *iptr); -double (pow)(double x, double y); -double (sqrt)(double x); -double (ceil)(double x); -double (fabs)(double x); -double (floor)(double x); -double (fmod)(double x, double y); - -/* - * setjmp.h - */ -int (setjmp)(jmp_buf env); -void (longjmp)(jmp_buf env, int val); - -/* - * signal.h - */ -void (*(signal)(int sig, void (*func)(int)))(int); -int (raise)(int sig); - -/* - * stdio.h - */ -int (remove)(const char *filename); -int (rename)(const char *old, const char *new); -FILE *(tmpfile)(void); -char *(tmpnam)(char *s); -int (fclose)(FILE *stream); -int (fflush)(FILE *stream); -FILE *(fopen)(const char *filename, const char *mode); -FILE *(freopen)(const char *filename, const char *mode, FILE *stream); -void (setbuf)(FILE *stream, char *buf); -int (setvbuf)(FILE *stream, char *buf, int mode, size_t size); -/* PRINTFLIKE2 */ -int (fprintf)(FILE *stream, const char *format, ...); -/* SCANFLIKE2 */ -int (fscanf)(FILE *stream, const char *format, ...); -/* PRINTFLIKE1 */ -int (printf)(const char *format, ...); -/* SCANFLIKE1 */ -int (scanf)(const char *format, ...); -/* PRINTFLIKE2 */ -int (sprintf)(char *s, const char *format, ...); -/* SCANFLIKE2 */ -int (sscanf)(const char *s, const char *format, ...); -int (vfprintf)(FILE *stream, const char *format, va_list arg); -int (vprintf)(const char *format, va_list arg); -int (vsprintf)(char *s, const char *format, va_list arg); -int (fgetc)(FILE *stream); -char *(fgets)(char *s, int n, FILE *stream); -int (fputc)(int c, FILE *stream); -int (fputs)(const char *s, FILE *stream); -int (getc)(FILE *stream); -int (getchar)(void); -char *(gets)(char *s); -int (putc)(int c, FILE *stream); -int (putchar)(int c); -int (puts)(const char *s); -int (ungetc)(int c, FILE *stream); -size_t (fread)(void *ptr, size_t size, size_t nmemb, FILE *stream); -size_t (fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream); -int (fgetpos)(FILE *stream, fpos_t *pos); -int (fseek)(FILE *stream, long offset, int whence); -int (fsetpos)(FILE *stream, const fpos_t *pos); -long (ftell)(FILE *stream); -void (rewind)(FILE *stream); -void (clearerr)(FILE *stream); -int (feof)(FILE *stream); -int (ferror)(FILE *stream); -void (perror)(const char *s); - -/* - * stdlib.h - */ -double (atof)(const char *nptr); -int (atoi)(const char *nptr); -long (atol)(const char *nptr); -double (strtod)(const char *nptr, char **endptr); -long (strtol)(const char *nptr, char **endptr, int base); -unsigned long (strtoul)(const char *nptr, char **endptr, int base); -int (rand)(void); -void (srand)(unsigned seed); -void *(calloc)(size_t nmemb, size_t size); -void (free)(void *ptr); -void *(malloc)(size_t size); -void *(realloc)(void *ptr, size_t size); -void (abort)(void); -int (atexit)(void (*func)(void)); -void (exit)(int status); -char *(getenv)(const char *name); -int (system)(const char *string); -void *(bsearch)(const void *key, const void *base, size_t nmemb, - size_t size, int (*compar)(const void *, const void *)); -void (qsort)(void *base, size_t nmemb, size_t size, - int (*compar)(const void *, const void *)); -int (abs)(int j); -div_t (div)(int numer, int denom); -long (labs)(long j); -ldiv_t (ldiv)(long numer, long denom); -int (mblen)(const char *s, size_t n); -int (mbtowc)(wchar_t *PWC, const char *s, size_t n); -int (wctomb)(char *s, wchar_t wchar); -size_t (mbstowcs)(wchar_t *pwcs, const char *s, size_t n); -size_t (wcstombs)(char *s, const wchar_t *pwcs, size_t n); - -/* - * string.h - */ -void *(memcpy)(void *s1, const void *s2, size_t n); -void *(memmove)(void *s1, const void *s2, size_t n); -char *(strcpy)(char *s1, const char *s2); -char *(strncpy)(char *s1, const char *s2, size_t n); -char *(strcat)(char *s1, const char *s2); -char *(strncat)(char *s1, const char *s2, size_t n); -int (memcmp)(const void *s1, const void *s2, size_t n); -int (strcmp)(const char *s1, const char *s2); -int (strcoll)(const char *s1, const char *s2); -int (strncmp)(const char *s1, const char *s2, size_t n); -size_t (strxfrm)(char *s1, const char *s2, size_t n); -void *(memchr)(const void *s, int c, size_t n); -char *(strchr)(const char *s, int c); -size_t (strcspn)(const char *s1, const char *s2); -char *(strpbrk)(const char *s1, const char *s2); -char *(strrchr)(const char *s1, int c); -size_t (strspn)(const char *s1, const char *s2); -char *(strstr)(const char *s1, const char *s2); -char *(strtok)(char *s1, const char *s2); -void *(memset)(void *s, int c, size_t n); -char *(strerror)(int errnom); -size_t (strlen)(const char *s); - -/* - * time.h - */ -clock_t (clock)(void); -double (difftime)(time_t time1, time_t time2); -time_t (mktime)(struct tm *timeptr); -time_t (time)(time_t *timer); -char *(asctime)(const struct tm *timeptr); -char *(ctime)(const time_t *timer); -struct tm *(gmtime)(const time_t *timer); -struct tm *(localtime)(const time_t *timer); -size_t (strftime)(char *s, size_t maxsize, const char *format, - const struct tm *timeptr); Index: usr.bin/xlint/xlint/Makefile =================================================================== --- usr.bin/xlint/xlint/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $NetBSD: Makefile,v 1.2 1995/07/03 21:25:14 cgd Exp $ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../lint1 - -PROG= xlint -PROGNAME= lint -SRCS= xlint.c mem.c -MAN= lint.1 - -CFLAGS+=-I${.CURDIR}/../lint1 -CFLAGS+= -DPREFIX=\"${TOOLS_PREFIX}\" - -.include "${.CURDIR}/../../Makefile.inc" -.include Index: usr.bin/xlint/xlint/Makefile.depend =================================================================== --- usr.bin/xlint/xlint/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Index: usr.bin/xlint/xlint/lint.1 =================================================================== --- usr.bin/xlint/xlint/lint.1 +++ /dev/null @@ -1,627 +0,0 @@ -.\" $NetBSD: lint.1,v 1.29 2004/01/26 21:59:42 wiz Exp $ -.\" -.\" Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. -.\" Copyright (c) 1994, 1995 Jochen Pohl -.\" All Rights Reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by Jochen Pohl for -.\" The NetBSD Project. -.\" 4. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd Mar 23, 2015 -.Dt LINT 1 -.Os -.Sh NAME -.Nm lint -.Nd a C program verifier -.Sh SYNOPSIS -.Bk -words -.Nm -.Op Fl abceghprvwxzHFV -.Op Fl s | t -.Op Fl i | nu -.Op Fl D Ar name Ns Op = Ns Ar def -.Op Fl U Ar name -.Op Fl I Ar directory -.Op Fl d Ar directory -.Op Fl L Ar directory -.Op Fl MD -.Op Fl l Ar library -.Op Fl o Ar outputfile -.Op Fl B Ar directory -.Op Fl X Ar id Ns Op , Ns Ar id ... -.Ar -.Nm -.Op Fl abceghprvwzHFV -.Op Fl s | t -.Fl C Ar library -.Op Fl D Ar name Ns Op = Ns Ar def -.Op Fl U Ar name -.Op Fl I Ar directory -.Op Fl d Ar directory -.Op Fl B Ar directory -.Op Fl X Ar id Ns Op , Ns Ar id ... -.Ar -.Ek -.Sh DESCRIPTION -The -.Nm -utility attempts to detect features of the named C program files -that are likely to be bugs, to be non-portable, or to be -wasteful. -It also performs stricter type checking than does -the C compiler. -The -.Nm -utility runs the C preprocessor as its first phase, with the -preprocessor symbol -.Dq Dv lint -defined to allow certain questionable code to be altered -or skipped by -.Nm . -Therefore, this symbol should be thought of as a reserved -word for all code that is to be checked by -.Nm . -.Pp -Among the possible problems that are currently noted are -unreachable statements, loops not entered at the top, -variables declared and not used, and logical expressions -with constant values. -Function calls are checked for -inconsistencies, such as calls to functions that return -values in some places and not in others, functions called -with varying numbers of arguments, function calls that -pass arguments of a type other than the type the function -expects to receive, functions whose values are not used, -and calls to functions not returning values that use -the non-existent return value of the function. -.Pp -Filename arguments ending with -.Pa .c -are taken to be C source files. -Filename arguments with -names ending with -.Pa .ln -are taken to be the result of an earlier invocation of -.Nm , -with either the -.Fl i , o , -or -.Fl C -option in effect. -The -.Pa .ln -files are analogous to the -.Pa .o -(object) files produced by -.Xr cc 1 -from -.Pa .c -files. -The -.Nm -utility also accepts special libraries specified with the -.Fl l -option, which contain definitions of library routines and -variables. -.Pp -The -.Nm -utility takes all the -.Pa .c , .ln , -and -.Pa llib-l Ns Ar library Ns Pa .ln -(lint library) files and processes them in command-line order. -By default, -.Nm -appends the standard C lint library -.Pq Pa llib-lc.ln -to the end of the list of files. -When the -.Fl i -option is used, the -.Pa .ln -files are ignored. -Also, when the -.Fl o -or -.Fl i -options are used, the -.Pa llib-l Ns Ar library Ns Pa .ln -files are ignored. -When the -.Fl i -option is -.Em omitted -the second pass of -.Nm -checks this list of files for mutual compatibility. -At this point, -if a complaint stems not from a given source file, but from one of -its included files, the source filename will be printed followed by -a question mark. -.Pp -The special input file name -.Dq Pa - -causes -.Nm -to take input from standard input (until end of file) and process -it as if it were a -.Pa .c -file. -If the -.Fl i -flag is given and -.Dq Pa - -is named as one of the input files, the -.Fl o -flag must also be specified to provide an output file name. -The options are as follows: -.Bl -tag -width indent -.It Fl a -Report assignments of -.Vt long -values to variables that are not -.Vt long . -.It Fl aa -Additional to -.Fl a , -report -.Em all -assignments of integer values to other integer values which -cause implicit narrowing conversion. -.It Fl b -Report -.Ic break -statements that cannot be reached. -This is not the default -because, unfortunately, most -.Xr lex 1 -and many -.Xr yacc 1 -outputs produce many such complaints. -.It Fl c -Complain about casts which have questionable portability. -.It Fl e -Complain about unusual operations on -.Vt enum Ns -Types -and combinations of -.Vt enum Ns - -and -.Sy integer Ns -Types . -.It Fl g -Do not print warnings for some extensions of -.Xr gcc 1 -to the C language. -Currently these are nonconstant initializers in -automatic aggregate initializations, arithmetic on pointer to void, -trailing commas in -.Vt enum -declarations, C++ -style -.Dq Li // -comments, -zero sized structures, subscripting of non-lvalue arrays, prototypes -overriding old style function declarations and long long -integer types. -The -.Fl g -flag also turns on the keywords -.Ic asm -and -.Ic inline -(alternative keywords with leading underscores for both -.Ic asm -and -.Ic inline -are always available). -.It Fl h -Apply a number of heuristic tests to attempt to intuit -bugs, improve style, and reduce waste. -.It Fl i -Produce a -.Pa .ln -file for every -.Pa .c -file on the command line. -These -.Pa .ln -files are the product of -.Nm Ns 's -first pass only, and are not checked for compatibility -between functions. -.It Fl n -Do not check compatibility against the standard library. -.It Fl p -Attempt to check portability of code to other dialects of C. -.It Fl r -In case of redeclarations report the position of the -previous declaration. -.It Fl s -Strict ANSI C mode. -Issue warnings and errors required by ANSI C. -Also do not produce warnings for constructs which behave -differently in traditional C and ANSI C. -With the -.Fl s -flag, -.Dv __STRICT_ANSI__ -is a predefined preprocessor macro. -.It Fl S -C9X mode. Currently not fully implemented. -.It Fl t -Traditional C mode. -.Dv __STDC__ -is not predefined in this mode. -Warnings are printed for constructs -not allowed in traditional C. -Warnings for constructs which behave -differently in traditional C and ANSI C are suppressed. -Preprocessor -macros describing the machine type (e.g., -.Dv sun3 ) -and machine architecture (e.g., -.Dv m68k ) -are defined without leading and trailing underscores. -The keywords -.Ic const , volatile -and -.Ic signed -are not available in traditional C mode (although the alternative -keywords with leading underscores still are). -.It Fl u -Do not complain about functions and external variables used -and not defined, or defined and not used (this is suitable -for running -.Nm -on a subset of files comprising part of a larger program). -.It Fl v -Suppress complaints about unused arguments in functions. -.It Fl x -Report variables referred to by -.Ic extern -declarations, but never used. -.It Fl z -Do not complain about structures that are never defined -(for example, using a structure pointer without knowing -its contents). -.It Fl B Ar path -Path to use when looking for the -.Pa lint1 -and -.Pa lint2 -binaries. -Defaults to -.Pa /usr/libexec . -.It Fl C Ar library -Create a -.Nm -library with the name -.Pa llib-l Ns Ar library Ns Pa .ln . -This library is built from all -.Pa .c -and -.Pa .ln -input files. -After all global definitions of functions and -variables in these files are written to the newly created library, -.Nm -checks all input files, including libraries specified with the -.Fl l -option, for mutual compatibility. -.It Fl D Ar name Ns Op = Ns Ar def -Define -.Ar name -for -.Xr cpp 1 , -as if by a -.Ic #define -directive. -If no definition is given, -.Ar name -is defined as 1. -.It Fl I Ar directory -Add -.Ar directory -to the list of directories in which to search for include files. -.It Fl d Ar directory -Use -.Ar directory -instead of -.Pa /usr/include -as the default place to find include files. -.It Fl l Ar library -Include the lint library -.Pa llib-l Ns Ar library Ns Pa .ln . -.It Fl L Ar directory -Search for lint libraries in -.Ar directory -and -.Ar directory Ns Pa /lint -before searching the standard place. -.It Fl F -Print pathnames of files. -The -.Nm -utility normally prints the filename without the path. -.It Fl H -If a complaint stems from an included file -.Nm -prints the name of the included file instead of the source file name -followed by a question mark. -.It Fl MD -Pass -.Fl MD -to -.Xr cpp 1 -causing cpp to create files containing dependency information for -each source file. -.It Fl o Ar outputfile -Name the output file -.Ar outputfile . -The output file produced is the input that is given to -.Nm Ns 's -second pass. -The -.Fl o -option simply saves this file in the named output file. -If the -.Fl i -option is also used the files are not checked for compatibility. -To produce a -.Pa llib-l Ns Ar library Ns Pa .ln -without extraneous messages, use of the -.Fl u -option is suggested. -The -.Fl v -option is useful if the source file(s) for the lint library -are just external interfaces. -.It Fl U Ar name -Remove any initial definition of -.Ar name -for the preprocessor. -.It Fl V -Print the command lines constructed by the controller program to -run the C preprocessor and -.Nm Ns 's -first and second pass. -.It Fl w -Treat warnings as errors. -.It Fl X Ar id Ns Op , Ns Ar id ... -Suppress error messages identified by the list of ids. -A list of messages -and ids can be found in -.Xr lint 7 . -.El -.Ss Input Grammar -.Nm Ns 's -first pass reads standard C source files. -The -.Nm -utility recognizes the following C comments as commands. -.Bl -tag -width indent -.It Li /* ARGSUSED Ns Ar n Li */ -Makes -.Nm -check only the first -.Ar n -arguments for usage; a missing -.Ar n -is taken to be 0 (this option acts like the -.Fl v -option for the next function). -.It Li /* BITFIELDTYPE */ -Suppress error messages about illegal bitfield types if the type -is an integer type, and suppress non-portable bitfield type warnings. -.It Xo -.Li /* CONSTCOND */ -or -.Li /* CONSTANTCOND */ -or -.Li /* CONSTANTCONDITION */ -.Xc -suppress complaints about constant operands for the next expression. -.It Xo -.Li /* FALLTHRU */ -or -.Li /* FALLTHROUGH */ -.Xc -suppress complaints about fall through to a -.Ic case -or -.Ic default -labelled statement. -This directive should be placed immediately -preceding the label. -.It Li /* LINTLIBRARY */ -At the beginning of a file, mark all functions and variables defined -in this file as -.Em used . -Also shut off complaints about unused function arguments. -.It Xo -.Li /* LINTED Oo Ar comment Oc Li */ -or -.Li /* NOSTRICT Oo Ar comment Oc Li */ -.Xc -Suppresses any intra-file warning except those dealing with -unused variables or functions. -This directive should be placed -on the line immediately preceding where the -.Nm -warning occurred. -.It Li /* LONGLONG */ -Suppress complaints about use of long long integer types. -.It Li /* NOTREACHED */ -At appropriate points, inhibit complaints about unreachable code. -(This comment is typically placed just after calls to functions -like -.Xr exit 3 ) . -.It Li /* PRINTFLIKE Ns Ar n Li */ -makes -.Nm -check the first -.Pq Ar n Ns -1 -arguments as usual. -The -.Ar n Ns -th -argument is interpreted as a -.Xr printf 3 -format string that is used to check the remaining arguments. -.It Li /* PROTOLIB Ns Ar n Li */ -causes -.Nm -to treat function declaration prototypes as function definitions -if -.Ar n -is non-zero. -This directive can only be used in conjunction with -the -.Li /* LINTLIBRARY */ -directive. -If -.Ar n -is zero, function prototypes will be treated normally. -.It Li /* SCANFLIKE Ns Ar n Li */ -makes -.Nm -check the first -.Pq Ar n Ns -1 -arguments as usual. -The -.Ar n Ns -th -argument is interpreted as a -.Xr scanf 3 -format string that is used to check the remaining arguments. -.It Li /* VARARGS Ns Ar n Li */ -Suppress the usual checking for variable numbers of arguments in -the following function declaration. -The data types of the first -.Ar n -arguments are checked; a missing -.Ar n -is taken to be 0. -.El -.Pp -The behavior of the -.Fl i -and the -.Fl o -options allows for incremental use of -.Nm -on a set of C source files. -Generally, one invokes -.Nm -once for each source file with the -.Fl i -option. -Each of these invocations produces a -.Pa .ln -file that corresponds to the -.Pa .c -file, and prints all messages that are about just that -source file. -After all the source files have been separately -run through -.Nm , -it is invoked once more (without the -.Fl i -option), listing all the -.Pa .ln -files with the needed -.Fl l Ar library -options. -This will print all the inter-file inconsistencies. -This -scheme works well with -.Xr make 1 ; -it allows -.Xr make 1 -to be used to -.Nm -only the source files that have been modified since the last -time the set of source files were -.Nm Ns ed . -.Sh ENVIRONMENT -.Bl -tag -width LIBDIR -.It Ev LIBDIR -the directory where the lint libraries specified by the -.Bk -words -.Fl l Ar library -.Ek -option must exist. -If this environment variable is undefined, -then the default path -.Pa /usr/libdata/lint -will be used to search for the libraries. -.It Ev TMPDIR -usually the path for temporary files can be redefined by setting -this environment variable. -.It Ev CC -Location of the C compiler program. -Defaults to -.Pa /usr/bin/cc . -.El -.Sh FILES -.Bl -tag -width /usr/libdata/lint/llib-lc.ln -compact -.It Pa /usr/libexec/lint Ns Bq Pa 12 -programs -.It Pa /usr/libdata/lint/llib-l*.ln -various prebuilt lint libraries -.It Pa /tmp/lint* -temporaries -.El -.Sh SEE ALSO -.Xr cc 1 , -.Xr cpp 1 , -.Xr make 1 -.Sh AUTHORS -.An Jochen Pohl -.Sh BUGS -.Bl -item -.It -The routines -.Xr exit 3 , -.Xr longjmp 3 -and other functions that do not return are not understood; this -causes various incorrect diagnostics. -.It -Static functions which are used only before their first -extern declaration are reported as unused. -.It -Libraries created by the -.Fl o -option will, when used in later -.Nm -runs, cause certain errors that were reported when the libraries -were created to be reported again, and cause line numbers and file -names from the original source used to create those libraries -to be reported in error messages. -For these reasons, it is recommended -to use the -.Fl C -option to create lint libraries. -.El Index: usr.bin/xlint/xlint/pathnames.h =================================================================== --- usr.bin/xlint/xlint/pathnames.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $NetBSD: pathnames.h,v 1.3 1999/04/22 04:40:58 mrg Exp $ */ - -/* - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* directory where lint1 and lint2 reside */ -#ifndef PATH_LIBEXEC -#define PATH_LIBEXEC PREFIX"/usr/libexec" -#endif - -/* directory where cc(1) resides */ -#define PATH_USRBIN PREFIX"/usr/bin" - -/* default library search path */ -#define PATH_LINTLIB PREFIX"/usr/libdata/lint" Index: usr.bin/xlint/xlint/xlint.c =================================================================== --- usr.bin/xlint/xlint/xlint.c +++ /dev/null @@ -1,883 +0,0 @@ -/* $NetBSD: xlint.c,v 1.36 2005/02/09 21:24:48 dsl Exp $ */ - -/* - * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. - * Copyright (c) 1994, 1995 Jochen Pohl - * All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Jochen Pohl for - * The NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#if defined(__RCSID) && !defined(lint) -__RCSID("$NetBSD: xlint.c,v 1.36 2005/02/09 21:24:48 dsl Exp $"); -#endif -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "lint.h" -#include "pathnames.h" - -#define DEFAULT_PATH _PATH_DEFPATH - -int main(int, char *[]); - -/* directory for temporary files */ -static const char *tmpdir; - -/* path name for cpp output */ -static char *cppout; - -/* file descriptor for cpp output */ -static int cppoutfd = -1; - -/* files created by 1st pass */ -static char **p1out; - -/* input files for 2nd pass (without libraries) */ -static char **p2in; - -/* library which will be created by 2nd pass */ -static char *p2out; - -/* flags always passed to cc(1) */ -static char **cflags; - -/* flags for cc(1), controlled by sflag/tflag */ -static char **lcflags; - -/* flags for lint1 */ -static char **l1flags; - -/* flags for lint2 */ -static char **l2flags; - -/* libraries for lint2 */ -static char **l2libs; - -/* default libraries */ -static char **deflibs; - -/* additional libraries */ -static char **libs; - -/* search path for libraries */ -static char **libsrchpath; - -static char *libexec_path; - -/* flags */ -static int iflag, oflag, Cflag, sflag, tflag, Fflag, dflag, Bflag, Sflag; - -/* print the commands executed to run the stages of compilation */ -static int Vflag; - -/* filename for oflag */ -static char *outputfn; - -/* reset after first .c source has been processed */ -static int first = 1; - -/* - * name of a file which is currently written by a child and should - * be removed after abnormal termination of the child - */ -static const char *currfn; - -#if !defined(TARGET_PREFIX) -#define TARGET_PREFIX "" -#endif -static const char target_prefix[] = TARGET_PREFIX; - -static void appstrg(char ***, char *); -static void appcstrg(char ***, const char *); -static void applst(char ***, char *const *); -static void freelst(char ***); -static char *concat2(const char *, const char *); -static char *concat3(const char *, const char *, const char *); -static void terminate(int) __attribute__((__noreturn__)); -static const char *lbasename(const char *, int); -static void appdef(char ***, const char *); -static void usage(void) __dead2; -static void fname(const char *); -static void runchild(const char *, char *const *, const char *, int); -static void findlibs(char *const *); -static int rdok(const char *); -static void lint2(void); -static void cat(char *const *, const char *); - -/* - * Some functions to deal with lists of strings. - * Take care that we get no surprises in case of asynchronous signals. - */ -static void -appstrg(char ***lstp, char *s) -{ - char **lst, **olst; - int i; - - olst = *lstp; - for (i = 0; olst[i] != NULL; i++) - continue; - lst = xrealloc(olst, (i + 2) * sizeof (char *)); - lst[i] = s; - lst[i + 1] = NULL; - *lstp = lst; -} - -static void -appcstrg(char ***lstp, const char *s) -{ - - appstrg(lstp, xstrdup(s)); -} - -static void -applst(char ***destp, char *const *src) -{ - int i, k; - char **dest, **odest; - - odest = *destp; - for (i = 0; odest[i] != NULL; i++) - continue; - for (k = 0; src[k] != NULL; k++) - continue; - dest = xrealloc(odest, (i + k + 1) * sizeof (char *)); - for (k = 0; src[k] != NULL; k++) - dest[i + k] = xstrdup(src[k]); - dest[i + k] = NULL; - *destp = dest; -} - -static void -freelst(char ***lstp) -{ - char *s; - int i; - - for (i = 0; (*lstp)[i] != NULL; i++) - continue; - while (i-- > 0) { - s = (*lstp)[i]; - (*lstp)[i] = NULL; - free(s); - } -} - -static char * -concat2(const char *s1, const char *s2) -{ - char *s; - - s = xmalloc(strlen(s1) + strlen(s2) + 1); - (void)strcpy(s, s1); - (void)strcat(s, s2); - - return (s); -} - -static char * -concat3(const char *s1, const char *s2, const char *s3) -{ - char *s; - - s = xmalloc(strlen(s1) + strlen(s2) + strlen(s3) + 1); - (void)strcpy(s, s1); - (void)strcat(s, s2); - (void)strcat(s, s3); - - return (s); -} - -/* - * Clean up after a signal. - */ -static void -terminate(int signo) -{ - int i; - - if (cppoutfd != -1) - (void)close(cppoutfd); - if (cppout != NULL) - (void)remove(cppout); - - if (p1out != NULL) { - for (i = 0; p1out[i] != NULL; i++) - (void)remove(p1out[i]); - } - - if (p2out != NULL) - (void)remove(p2out); - - if (currfn != NULL) - (void)remove(currfn); - - exit(signo != 0 ? 1 : 0); -} - -/* - * Returns a pointer to the last component of strg after delim. - * Returns strg if the string does not contain delim. - */ -static const char * -lbasename(const char *strg, int delim) -{ - const char *cp, *cp1, *cp2; - - cp = cp1 = cp2 = strg; - while (*cp != '\0') { - if (*cp++ == delim) { - cp2 = cp1; - cp1 = cp; - } - } - return (*cp1 == '\0' ? cp2 : cp1); -} - -static void -appdef(char ***lstp, const char *def) -{ - - appstrg(lstp, concat2("-D__", def)); - appstrg(lstp, concat3("-D__", def, "__")); -} - -static void -usage(void) -{ - - (void)fprintf(stderr, - "usage: lint [-abceghprvwxzHFS] [-s|-t] [-i|-nu] [-Dname[=def]]" - " [-Uname] [-X [,]...\n"); - (void)fprintf(stderr, - "\t[-Idirectory] [-Ldirectory] [-llibrary] [-ooutputfile]" - " file...\n"); - (void)fprintf(stderr, - " lint [-abceghprvwzHFS] [-s|-t] -Clibrary [-Dname[=def]]\n" - " [-X [,]...\n"); - (void)fprintf(stderr, "\t[-Idirectory] [-Uname] [-Bpath] file" - " ...\n"); - terminate(-1); -} - - -int -main(int argc, char *argv[]) -{ - int c; - char flgbuf[3], *s; - const char *tmp; - size_t len; - - if ((tmp = getenv("TMPDIR")) == NULL || (len = strlen(tmp)) == 0) { - tmpdir = _PATH_TMP; - } else { - s = xmalloc(len + 2); - (void)sprintf(s, "%s%s", tmp, tmp[len - 1] == '/' ? "" : "/"); - tmpdir = s; - } - - cppout = xmalloc(strlen(tmpdir) + sizeof ("lint0.XXXXXX")); - (void)sprintf(cppout, "%slint0.XXXXXX", tmpdir); - cppoutfd = mkstemp(cppout); - if (cppoutfd == -1) { - warn("can't make temp"); - terminate(-1); - } - - p1out = xcalloc(1, sizeof (char *)); - p2in = xcalloc(1, sizeof (char *)); - cflags = xcalloc(1, sizeof (char *)); - lcflags = xcalloc(1, sizeof (char *)); - l1flags = xcalloc(1, sizeof (char *)); - l2flags = xcalloc(1, sizeof (char *)); - l2libs = xcalloc(1, sizeof (char *)); - deflibs = xcalloc(1, sizeof (char *)); - libs = xcalloc(1, sizeof (char *)); - libsrchpath = xcalloc(1, sizeof (char *)); - - appcstrg(&cflags, "-E"); - appcstrg(&cflags, "-x"); - appcstrg(&cflags, "c"); -#if 0 - appcstrg(&cflags, "-D__attribute__(x)="); - appcstrg(&cflags, "-D__extension__(x)=/*NOSTRICT*/0"); -#else - appcstrg(&cflags, "-U__GNUC__"); - appcstrg(&cflags, "-undef"); -#endif -#if 0 - appcstrg(&cflags, "-Wp,-$"); -#endif - appcstrg(&cflags, "-Wp,-C"); - appcstrg(&cflags, "-Wcomment"); - appcstrg(&cflags, "-D__LINT__"); - appcstrg(&cflags, "-Dlint"); /* XXX don't def. with -s */ - - appdef(&cflags, "lint"); - - appcstrg(&deflibs, "c"); - - if (signal(SIGHUP, terminate) == SIG_IGN) - (void)signal(SIGHUP, SIG_IGN); - (void)signal(SIGINT, terminate); - (void)signal(SIGQUIT, terminate); - (void)signal(SIGTERM, terminate); - while ((c = getopt(argc, argv, "abcd:eghil:no:prstuvwxzB:C:D:FHI:L:M:SU:VX:")) != -1) { - switch (c) { - - case 'a': - case 'b': - case 'c': - case 'e': - case 'g': - case 'r': - case 'v': - case 'w': - case 'z': - (void)sprintf(flgbuf, "-%c", c); - appcstrg(&l1flags, flgbuf); - break; - - case 'F': - Fflag = 1; - /* FALLTHROUGH */ - case 'u': - case 'h': - (void)sprintf(flgbuf, "-%c", c); - appcstrg(&l1flags, flgbuf); - appcstrg(&l2flags, flgbuf); - break; - - case 'X': - (void)sprintf(flgbuf, "-%c", c); - appcstrg(&l1flags, flgbuf); - appcstrg(&l1flags, optarg); - break; - - case 'i': - if (Cflag) - usage(); - iflag = 1; - break; - - case 'n': - freelst(&deflibs); - break; - - case 'p': - appcstrg(&lcflags, "-Wtraditional"); - appcstrg(&lcflags, "-Wno-system-headers"); - appcstrg(&l1flags, "-p"); - appcstrg(&l2flags, "-p"); - if (*deflibs != NULL) { - freelst(&deflibs); - appcstrg(&deflibs, "c"); - } - break; - - case 's': - if (tflag) - usage(); - freelst(&lcflags); - appcstrg(&lcflags, "-trigraphs"); - appcstrg(&lcflags, "-Wtrigraphs"); - appcstrg(&lcflags, "-pedantic"); - appcstrg(&lcflags, "-D__STRICT_ANSI__"); - appcstrg(&l1flags, "-s"); - appcstrg(&l2flags, "-s"); - sflag = 1; - break; - - case 'S': - if (tflag) - usage(); - appcstrg(&l1flags, "-S"); - Sflag = 1; - break; - -#if !HAVE_CONFIG_H - case 't': - if (sflag) - usage(); - freelst(&lcflags); - appcstrg(&lcflags, "-traditional"); - appstrg(&lcflags, concat2("-D", MACHINE)); - appstrg(&lcflags, concat2("-D", MACHINE_ARCH)); - appcstrg(&l1flags, "-t"); - appcstrg(&l2flags, "-t"); - tflag = 1; - break; -#endif - - case 'x': - appcstrg(&l2flags, "-x"); - break; - - case 'C': - if (Cflag || oflag || iflag) - usage(); - Cflag = 1; - appstrg(&l2flags, concat2("-C", optarg)); - p2out = xmalloc(sizeof ("llib-l.ln") + strlen(optarg)); - (void)sprintf(p2out, "llib-l%s.ln", optarg); - freelst(&deflibs); - break; - - case 'd': - if (dflag) - usage(); - dflag = 1; - appcstrg(&cflags, "-nostdinc"); - appcstrg(&cflags, "-idirafter"); - appcstrg(&cflags, optarg); - break; - - case 'D': - case 'I': - case 'M': - case 'U': - (void)sprintf(flgbuf, "-%c", c); - appstrg(&cflags, concat2(flgbuf, optarg)); - break; - - case 'l': - appcstrg(&libs, optarg); - break; - - case 'o': - if (Cflag || oflag) - usage(); - oflag = 1; - outputfn = xstrdup(optarg); - break; - - case 'L': - appcstrg(&libsrchpath, optarg); - break; - - case 'H': - appcstrg(&l2flags, "-H"); - break; - - case 'B': - Bflag = 1; - libexec_path = xstrdup(optarg); - break; - - case 'V': - Vflag = 1; - break; - - default: - usage(); - /* NOTREACHED */ - } - } - argc -= optind; - argv += optind; - - /* - * To avoid modifying getopt(3)'s state engine midstream, we - * explicitly accept just a few options after the first source file. - * - * In particular, only -l and -L (and these with a space - * after -l or -L) are allowed. - */ - while (argc > 0) { - const char *arg = argv[0]; - - if (arg[0] == '-') { - char ***list; - - /* option */ - switch (arg[1]) { - case 'l': - list = &libs; - break; - - case 'L': - list = &libsrchpath; - break; - - default: - usage(); - /* NOTREACHED */ - } - if (arg[2]) - appcstrg(list, arg + 2); - else if (argc > 1) { - argc--; - appcstrg(list, *++argv); - } else - usage(); - } else { - /* filename */ - fname(arg); - first = 0; - } - argc--; - argv++; - } - - if (first) - usage(); - - if (iflag) - terminate(0); - - if (!oflag) { - if ((tmp = getenv("LIBDIR")) == NULL || strlen(tmp) == 0) - tmp = PATH_LINTLIB; - appcstrg(&libsrchpath, tmp); - findlibs(libs); - findlibs(deflibs); - } - - (void)printf("Lint pass2:\n"); - lint2(); - - if (oflag) - cat(p2in, outputfn); - - if (Cflag) - p2out = NULL; - - terminate(0); - /* NOTREACHED */ -} - -/* - * Read a file name from the command line - * and pass it through lint1 if it is a C source. - */ -static void -fname(const char *name) -{ - const char *bn, *suff; - char **args, *ofn, *p, *pathname; - size_t len; - int is_stdin; - int fd; - - is_stdin = (strcmp(name, "-") == 0); - bn = lbasename(name, '/'); - suff = lbasename(bn, '.'); - - if (strcmp(suff, "ln") == 0) { - /* only for lint2 */ - if (!iflag) - appcstrg(&p2in, name); - return; - } - - if (!is_stdin && strcmp(suff, "c") != 0 && - (strncmp(bn, "llib-l", 6) != 0 || bn != suff)) { - warnx("unknown file type: %s\n", name); - return; - } - - if (!iflag || !first) - (void)printf("%s:\n", - is_stdin ? "{standard input}" : Fflag ? name : bn); - - /* build the name of the output file of lint1 */ - if (oflag) { - ofn = outputfn; - outputfn = NULL; - oflag = 0; - } else if (iflag) { - if (is_stdin) { - warnx("-i not supported without -o for standard input"); - return; - } - ofn = xmalloc(strlen(bn) + (bn == suff ? 4 : 2)); - len = bn == suff ? strlen(bn) : (size_t)((suff - 1) - bn); - (void)sprintf(ofn, "%.*s", (int)len, bn); - (void)strcat(ofn, ".ln"); - } else { - ofn = xmalloc(strlen(tmpdir) + sizeof ("lint1.XXXXXX")); - (void)sprintf(ofn, "%slint1.XXXXXX", tmpdir); - fd = mkstemp(ofn); - if (fd == -1) { - warn("can't make temp"); - terminate(-1); - } - close(fd); - } - if (!iflag) - appcstrg(&p1out, ofn); - - args = xcalloc(1, sizeof (char *)); - - /* run cc */ - - if (getenv("CC") == NULL) { - pathname = xmalloc(strlen(PATH_USRBIN) + sizeof ("/cc")); - (void)sprintf(pathname, "%s/cc", PATH_USRBIN); - appcstrg(&args, pathname); - } else { - pathname = strdup(getenv("CC")); - for (p = strtok(pathname, " \t"); p; p = strtok(NULL, " \t")) - appcstrg(&args, p); - } - - applst(&args, cflags); - applst(&args, lcflags); - appcstrg(&args, name); - - /* we reuse the same tmp file for cpp output, so rewind and truncate */ - if (lseek(cppoutfd, (off_t)0, SEEK_SET) != 0) { - warn("lseek"); - terminate(-1); - } - if (ftruncate(cppoutfd, (off_t)0) != 0) { - warn("ftruncate"); - terminate(-1); - } - - runchild(pathname, args, cppout, cppoutfd); - free(pathname); - freelst(&args); - - /* run lint1 */ - - if (!Bflag) { - pathname = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint1") + - strlen(target_prefix)); - (void)sprintf(pathname, "%s/%slint1", PATH_LIBEXEC, - target_prefix); - } else { - /* - * XXX Unclear whether we should be using target_prefix - * XXX here. --thorpej@wasabisystems.com - */ - pathname = xmalloc(strlen(libexec_path) + sizeof ("/lint1")); - (void)sprintf(pathname, "%s/lint1", libexec_path); - } - - appcstrg(&args, pathname); - applst(&args, l1flags); - appcstrg(&args, cppout); - appcstrg(&args, ofn); - - runchild(pathname, args, ofn, -1); - free(pathname); - freelst(&args); - - appcstrg(&p2in, ofn); - free(ofn); - - free(args); -} - -static void -runchild(const char *path, char *const *args, const char *crfn, int fdout) -{ - int status, rv, signo, i; - - if (Vflag) { - for (i = 0; args[i] != NULL; i++) - (void)printf("%s ", args[i]); - (void)printf("\n"); - } - - currfn = crfn; - - (void)fflush(stdout); - - switch (vfork()) { - case -1: - warn("cannot fork"); - terminate(-1); - /* NOTREACHED */ - default: - /* parent */ - break; - case 0: - /* child */ - - /* setup the standard output if necessary */ - if (fdout != -1) { - dup2(fdout, STDOUT_FILENO); - close(fdout); - } - (void)execvp(path, args); - warn("cannot exec %s", path); - _exit(1); - /* NOTREACHED */ - } - - while ((rv = wait(&status)) == -1 && errno == EINTR) ; - if (rv == -1) { - warn("wait"); - terminate(-1); - } - if (WIFSIGNALED(status)) { - signo = WTERMSIG(status); -#if HAVE_DECL_SYS_SIGNAME - warnx("%s got SIG%s", path, sys_signame[signo]); -#else - warnx("%s got signal %d", path, signo); -#endif - terminate(-1); - } - if (WEXITSTATUS(status) != 0) - terminate(-1); - currfn = NULL; -} - -static void -findlibs(char *const *liblst) -{ - int i, k; - const char *lib, *path; - char *lfn; - size_t len; - - lfn = NULL; - - for (i = 0; (lib = liblst[i]) != NULL; i++) { - for (k = 0; (path = libsrchpath[k]) != NULL; k++) { - len = strlen(path) + strlen(lib); - lfn = xrealloc(lfn, len + sizeof ("/llib-l.ln")); - (void)sprintf(lfn, "%s/llib-l%s.ln", path, lib); - if (rdok(lfn)) - break; - lfn = xrealloc(lfn, len + sizeof ("/lint/llib-l.ln")); - (void)sprintf(lfn, "%s/lint/llib-l%s.ln", path, lib); - if (rdok(lfn)) - break; - } - if (path != NULL) { - appstrg(&l2libs, concat2("-l", lfn)); - } else { - warnx("cannot find llib-l%s.ln", lib); - } - } - - free(lfn); -} - -static int -rdok(const char *path) -{ - struct stat sbuf; - - if (stat(path, &sbuf) == -1) - return (0); - if (!S_ISREG(sbuf.st_mode)) - return (0); - if (access(path, R_OK) == -1) - return (0); - return (1); -} - -static void -lint2(void) -{ - char *path, **args; - - args = xcalloc(1, sizeof (char *)); - - if (!Bflag) { - path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint2") + - strlen(target_prefix)); - (void)sprintf(path, "%s/%slint2", PATH_LIBEXEC, - target_prefix); - } else { - /* - * XXX Unclear whether we should be using target_prefix - * XXX here. --thorpej@wasabisystems.com - */ - path = xmalloc(strlen(libexec_path) + sizeof ("/lint2")); - (void)sprintf(path, "%s/lint2", libexec_path); - } - - appcstrg(&args, path); - applst(&args, l2flags); - applst(&args, l2libs); - applst(&args, p2in); - - runchild(path, args, p2out, -1); - free(path); - freelst(&args); - free(args); -} - -static void -cat(char *const *srcs, const char *dest) -{ - int ifd, ofd, i; - char *src, *buf; - ssize_t rlen; - - if ((ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) { - warn("cannot open %s", dest); - terminate(-1); - } - - buf = xmalloc(MBLKSIZ); - - for (i = 0; (src = srcs[i]) != NULL; i++) { - if ((ifd = open(src, O_RDONLY)) == -1) { - free(buf); - warn("cannot open %s", src); - terminate(-1); - } - do { - if ((rlen = read(ifd, buf, MBLKSIZ)) == -1) { - free(buf); - warn("read error on %s", src); - terminate(-1); - } - if (write(ofd, buf, (size_t)rlen) == -1) { - free(buf); - warn("write error on %s", dest); - terminate(-1); - } - } while (rlen == MBLKSIZ); - (void)close(ifd); - } - (void)close(ofd); - free(buf); -}