MFH @ r323558.

This commit is contained in:
np 2017-09-13 19:12:28 +00:00
commit 7daed4fc05
959 changed files with 273278 additions and 209751 deletions

View File

@ -557,7 +557,7 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
# cross-tools stage
XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
MK_GDB=no MK_TESTS=no
MK_GDB=no MK_LLD_IS_LD=${MK_LLD_BOOTSTRAP} MK_TESTS=no
# kernel-tools stage
KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
@ -1786,7 +1786,8 @@ update: .PHONY
# ELF Tool Chain libraries are needed for ELF tools and dtrace tools.
# r296685 fix cross-endian objcopy
.if ${BOOTSTRAPPING} < 1100102
# r310724 fixed PR 215350, a crash in libdwarf with objects built by GCC 6.2.
.if ${BOOTSTRAPPING} < 1200020
_elftoolchain_libs= lib/libelf lib/libdwarf
.endif
@ -1984,8 +1985,12 @@ _gcc_tools= gnu/usr.bin/cc/cc_tools
_rescue=rescue/rescue
.endif
.if ${MK_TCSH} != "no"
_tcsh=bin/csh
.endif
.for _tool in \
bin/csh \
${_tcsh} \
bin/sh \
${LOCAL_TOOL_DIRS} \
lib/ncurses/ncurses \
@ -2143,7 +2148,7 @@ native-xtools: .PHONY
bin/cat \
bin/chmod \
bin/cp \
bin/csh \
${_tcsh} \
bin/echo \
bin/expr \
bin/hostname \

View File

@ -38,6 +38,13 @@
# xargs -n1 | sort | uniq -d;
# done
# 20170913: remove unneeded catman utility
OLD_FILES+=etc/periodic/weekly/330.catman
OLD_FILES+=usr/bin/catman
OLD_FILES+=usr/libexec/catman.local
OLD_FILES+=usr/share/man/man1/catman.1.gz
OLD_FILES+=usr/share/man/man8/catman.local.8.gz
# 20170802: ksyms(4) ioctl interface was removed
OLD_FILES+=usr/include/sys/ksyms.h

View File

@ -51,6 +51,29 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
****************************** SPECIAL WARNING: ******************************
20170912:
The default serial number format for CTL LUNs has changed. This will
affect users who use /dev/diskid/* device nodes, or whose FibreChannel
or iSCSI clients care about their LUNs' serial numbers. Users who
require serial number stability should hardcode serial numbers in
/etc/ctl.conf .
20170912:
For 32-bit arm compiled for hard-float support, soft-floating point
binaries now always get their shared libraries from
LD_SOFT_LIBRARY_PATH (in the past, this was only used if
/usr/libsoft also existed). Only users with a hard-float ld.so, but
soft-float everything else should be affected.
20170826:
During boot the geli passphrase will be hidden. To restore previous
behavior see geli(8) configuration options.
20170825:
Move PMTUD blackhole counters to TCPSTATS and remove them from bare
sysctl values. Minor nit, but requires a rebuild of both world/kernel
to complete.
20170814:
"make check" behavior (made in ^/head@r295380) has been changed to
execute from a limited sandbox, as opposed to executing from

View File

@ -4,4 +4,7 @@
PACKAGE=runtime
PROG= chflags
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

View File

@ -0,0 +1,5 @@
# $FreeBSD$
ATF_TESTS_SH+= chflags_test
.include <bsd.test.mk>

View File

@ -0,0 +1,63 @@
#
# Copyright 2017 Shivansh Rai
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
#
usage_output='usage: chflags'
atf_test_case invalid_usage
invalid_usage_head()
{
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
}
invalid_usage_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" chflags -f
atf_check -s not-exit:0 -e match:"$usage_output" chflags -H
atf_check -s not-exit:0 -e match:"$usage_output" chflags -h
atf_check -s not-exit:0 -e match:"$usage_output" chflags -L
atf_check -s not-exit:0 -e match:"$usage_output" chflags -P
atf_check -s not-exit:0 -e match:"$usage_output" chflags -R
atf_check -s not-exit:0 -e match:"$usage_output" chflags -v
}
atf_test_case no_arguments
no_arguments_head()
{
atf_set "descr" "Verify that chflags(1) fails and generates a valid usage message when no arguments are supplied"
}
no_arguments_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" chflags
}
atf_init_test_cases()
{
atf_add_test_case invalid_usage
atf_add_test_case no_arguments
}

View File

@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <inttypes.h>
@ -184,7 +185,7 @@ f_bs(char *arg)
res = get_num(arg);
if (res < 1 || res > SSIZE_MAX)
errx(1, "bs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
errx(1, "bs must be between 1 and %zd", (ssize_t)SSIZE_MAX);
in.dbsz = out.dbsz = (size_t)res;
}
@ -195,22 +196,22 @@ f_cbs(char *arg)
res = get_num(arg);
if (res < 1 || res > SSIZE_MAX)
errx(1, "cbs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
errx(1, "cbs must be between 1 and %zd", (ssize_t)SSIZE_MAX);
cbsz = (size_t)res;
}
static void
f_count(char *arg)
{
intmax_t res;
uintmax_t res;
res = (intmax_t)get_num(arg);
if (res < 0)
errx(1, "count cannot be negative");
res = get_num(arg);
if (res == UINTMAX_MAX)
errc(1, ERANGE, "%s", oper);
if (res == 0)
cpy_cnt = (uintmax_t)-1;
cpy_cnt = UINTMAX_MAX;
else
cpy_cnt = (uintmax_t)res;
cpy_cnt = res;
}
static void
@ -219,7 +220,7 @@ f_files(char *arg)
files_cnt = get_num(arg);
if (files_cnt < 1)
errx(1, "files must be between 1 and %jd", (uintmax_t)-1);
errx(1, "files must be between 1 and %zu", SIZE_MAX);
}
static void
@ -240,8 +241,8 @@ f_ibs(char *arg)
if (!(ddflags & C_BS)) {
res = get_num(arg);
if (res < 1 || res > SSIZE_MAX)
errx(1, "ibs must be between 1 and %jd",
(intmax_t)SSIZE_MAX);
errx(1, "ibs must be between 1 and %zd",
(ssize_t)SSIZE_MAX);
in.dbsz = (size_t)res;
}
}
@ -261,8 +262,8 @@ f_obs(char *arg)
if (!(ddflags & C_BS)) {
res = get_num(arg);
if (res < 1 || res > SSIZE_MAX)
errx(1, "obs must be between 1 and %jd",
(intmax_t)SSIZE_MAX);
errx(1, "obs must be between 1 and %zd",
(ssize_t)SSIZE_MAX);
out.dbsz = (size_t)res;
}
}

View File

@ -133,7 +133,7 @@ block(void)
*/
ch = 0;
for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
maxlen = MIN(cbsz, in.dbcnt);
maxlen = MIN(cbsz, (size_t)in.dbcnt);
if ((t = ctab) != NULL)
for (cnt = 0; cnt < maxlen && (ch = *inp++) != '\n';
++cnt)
@ -146,7 +146,7 @@ block(void)
* Check for short record without a newline. Reassemble the
* input block.
*/
if (ch != '\n' && in.dbcnt < cbsz) {
if (ch != '\n' && (size_t)in.dbcnt < cbsz) {
(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
break;
}
@ -228,7 +228,7 @@ unblock(void)
* translation has to already be done or we might not recognize the
* spaces.
*/
for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
for (inp = in.db; (size_t)in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t)
;
if (t >= inp) {

View File

@ -204,10 +204,10 @@ setup(void)
* record oriented I/O, only need a single buffer.
*/
if (!(ddflags & (C_BLOCK | C_UNBLOCK))) {
if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL)
if ((in.db = malloc((size_t)out.dbsz + in.dbsz - 1)) == NULL)
err(1, "input buffer");
out.db = in.db;
} else if ((in.db = malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL ||
} else if ((in.db = malloc(MAX((size_t)in.dbsz, cbsz) + cbsz)) == NULL ||
(out.db = malloc(out.dbsz + cbsz)) == NULL)
err(1, "output buffer");
@ -405,7 +405,7 @@ dd_in(void)
++st.in_full;
/* Handle full input blocks. */
} else if ((size_t)n == in.dbsz) {
} else if ((size_t)n == (size_t)in.dbsz) {
in.dbcnt += in.dbrcnt = n;
++st.in_full;
@ -562,7 +562,7 @@ dd_out(int force)
outp += nw;
st.bytes += nw;
if ((size_t)nw == n && n == out.dbsz)
if ((size_t)nw == n && n == (size_t)out.dbsz)
++st.out_full;
else
++st.out_part;

View File

@ -38,10 +38,9 @@
typedef struct {
u_char *db; /* buffer address */
u_char *dbp; /* current buffer I/O address */
/* XXX ssize_t? */
size_t dbcnt; /* current buffer byte count */
size_t dbrcnt; /* last read byte count */
size_t dbsz; /* block size */
ssize_t dbcnt; /* current buffer byte count */
ssize_t dbrcnt; /* last read byte count */
ssize_t dbsz; /* block size */
#define ISCHR 0x01 /* character device (warn on short) */
#define ISPIPE 0x02 /* pipe-like (see position.c) */

View File

@ -207,7 +207,7 @@ pos_out(void)
n = write(out.fd, out.db, out.dbsz);
if (n == -1)
err(1, "%s", out.name);
if ((size_t)n != out.dbsz)
if (n != out.dbsz)
errx(1, "%s: write failure", out.name);
}
break;

View File

@ -4,4 +4,7 @@
PACKAGE=runtime
PROG= mkdir
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

5
bin/mkdir/tests/Makefile Normal file
View File

@ -0,0 +1,5 @@
# $FreeBSD$
ATF_TESTS_SH+= mkdir_test
.include <bsd.test.mk>

View File

@ -0,0 +1,61 @@
#
# Copyright 2017 Shivansh Rai
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
#
usage_output='usage: mkdir'
atf_test_case invalid_usage
invalid_usage_head()
{
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
}
invalid_usage_body()
{
atf_check -s not-exit:0 -e inline:"mkdir: option requires an argument -- m
usage: mkdir [-pv] [-m mode] directory_name ...
" mkdir -m
atf_check -s not-exit:0 -e match:"$usage_output" mkdir -p
atf_check -s not-exit:0 -e match:"$usage_output" mkdir -v
}
atf_test_case no_arguments
no_arguments_head()
{
atf_set "descr" "Verify that mkdir(1) fails and generates a valid usage message when no arguments are supplied"
}
no_arguments_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" mkdir
}
atf_init_test_cases()
{
atf_add_test_case invalid_usage
atf_add_test_case no_arguments
}

View File

@ -568,7 +568,7 @@ main(int argc, char **argv)
continue;
rv |= (*action)(kp);
}
if (rv && pgrep)
if (rv && pgrep && !quiet)
putchar('\n');
if (!did_action && !pgrep && longfmt)
fprintf(stderr,

View File

@ -262,9 +262,9 @@ state(KINFO *k, VARENT *ve __unused)
cp++;
if (!(flag & P_INMEM))
*cp++ = 'W';
if (k->ki_p->ki_nice < NZERO)
if (k->ki_p->ki_nice < NZERO || k->ki_p->ki_pri.pri_class == PRI_REALTIME)
*cp++ = '<';
else if (k->ki_p->ki_nice > NZERO)
else if (k->ki_p->ki_nice > NZERO || k->ki_p->ki_pri.pri_class == PRI_IDLE)
*cp++ = 'N';
if (flag & P_TRACED)
*cp++ = 'X';
@ -274,6 +274,8 @@ state(KINFO *k, VARENT *ve __unused)
*cp++ = 'V';
if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0)
*cp++ = 'L';
if ((k->ki_p->ki_cr_flags & CRED_FLAG_CAPMODE) != 0)
*cp++ = 'C';
if (k->ki_p->ki_kiflag & KI_SLEADER)
*cp++ = 's';
if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid)

View File

@ -29,7 +29,7 @@
.\" @(#)ps.1 8.3 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
.Dd July 25, 2017
.Dd September 7, 2017
.Dt PS 1
.Os
.Sh NAME
@ -436,6 +436,10 @@ information:
The process is in the foreground process group of its control terminal.
.It Li <
The process has raised CPU scheduling priority.
.It Li C
The process is in
.Xr capsicum 4
capability mode.
.It Li E
The process is trying to exit.
.It Li J
@ -541,7 +545,7 @@ short-term CPU usage factor (for scheduling)
.It Cm dsiz
data size (in Kbytes)
.It Cm emul
system-call emulation environment
system-call emulation environment (ABI)
.It Cm etime
elapsed running time, format
.Op days- Ns

View File

@ -11,4 +11,7 @@ PACKAGE=rcmds
BINOWN= root
BINMODE=4555
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

5
bin/rcp/tests/Makefile Normal file
View File

@ -0,0 +1,5 @@
# $FreeBSD$
ATF_TESTS_SH+= rcp_test
.include <bsd.test.mk>

60
bin/rcp/tests/rcp_test.sh Normal file
View File

@ -0,0 +1,60 @@
#
# Copyright 2017 Shivansh Rai
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
#
usage_output='usage: rcp'
atf_test_case invalid_usage
invalid_usage_head()
{
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
}
invalid_usage_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" rcp -4
atf_check -s not-exit:0 -e match:"$usage_output" rcp -6
atf_check -s not-exit:0 -e match:"$usage_output" rcp -p
atf_check -s not-exit:0 -e match:"$usage_output" rcp -r
}
atf_test_case no_arguments
no_arguments_head()
{
atf_set "descr" "Verify that rcp(1) fails and generates a valid usage message when no arguments are supplied"
}
no_arguments_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" rcp
}
atf_init_test_cases()
{
atf_add_test_case invalid_usage
atf_add_test_case no_arguments
}

View File

@ -4,4 +4,7 @@
PACKAGE=runtime
PROG= rmdir
HAS_TESTS=
SUBDIR.${MK_TESTS}+= tests
.include <bsd.prog.mk>

5
bin/rmdir/tests/Makefile Normal file
View File

@ -0,0 +1,5 @@
# $FreeBSD$
ATF_TESTS_SH+= rmdir_test
.include <bsd.test.mk>

View File

@ -0,0 +1,58 @@
#
# Copyright 2017 Shivansh Rai
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
#
usage_output='usage: rmdir'
atf_test_case invalid_usage
invalid_usage_head()
{
atf_set "descr" "Verify that an invalid usage with a supported option produces a valid error message"
}
invalid_usage_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" rmdir -p
atf_check -s not-exit:0 -e match:"$usage_output" rmdir -v
}
atf_test_case no_arguments
no_arguments_head()
{
atf_set "descr" "Verify that rmdir(1) fails and generates a valid usage message when no arguments are supplied"
}
no_arguments_body()
{
atf_check -s not-exit:0 -e match:"$usage_output" rmdir
}
atf_init_test_cases()
{
atf_add_test_case invalid_usage
atf_add_test_case no_arguments
}

View File

@ -74,7 +74,7 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
char *dataptr, int datalen, char *optptr, int optlen)
{
struct iovec *iov;
char *optstr, *os, *p;
char *optstr, *os, *p, *tofree;
int iovlen, rv;
assert(spec != NULL);
@ -87,7 +87,7 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
assert(optptr != NULL);
assert(optlen > 0);
optstr = strdup(optptr);
tofree = optstr = strdup(optptr);
assert(optstr != NULL);
iov = NULL;
@ -98,11 +98,9 @@ zmount(const char *spec, const char *dir, int mflag, char *fstype,
build_iovec(&iov, &iovlen, "fspath", __DECONST(char *, dir),
(size_t)-1);
build_iovec(&iov, &iovlen, "from", __DECONST(char *, spec), (size_t)-1);
for (p = optstr; p != NULL; strsep(&p, ",/ ")) {
if (*p != '\0')
build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
}
while ((p = strsep(&optstr, ",/")) != NULL)
build_iovec(&iov, &iovlen, p, NULL, (size_t)-1);
rv = nmount(iov, iovlen, 0);
free(optstr);
free(tofree);
return (rv);
}

View File

@ -28,9 +28,6 @@
#pragma D option quiet
inline int AF_INET = 2;
inline int AF_INET6 = 28;
in_addr_t *ip4a;
in_addr_t *ip4b;
in_addr_t *ip4c;

View File

@ -0,0 +1,25 @@
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright 2017 Mark Johnston <markj@FreeBSD.org>
*/
/*
* A regression test for FreeBSD r322773. 100^9 fits in 64 bits, but
* llquantize() will create buckets up to 100^{10}, which does not fit.
*/
BEGIN
{
@ = llquantize(0, 100, 0, 9, 100);
exit(0);
}

View File

@ -19,14 +19,15 @@
.\" information: Portions Copyright [yyyy] [name of copyright owner]
.\"
.\" Copyright (c) 2010, Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 2011, Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2011, Justin T. Gibbs <gibbs@FreeBSD.org>
.\" Copyright (c) 2013 by Delphix. All Rights Reserved.
.\" Copyright (c) 2012, Glen Barber <gjb@FreeBSD.org>
.\" Copyright (c) 2013 by Delphix. All Rights Reserved.
.\" Copyright 2017 Nexenta Systems, Inc.
.\" Copyright (c) 2017 Datto Inc.
.\"
.\" $FreeBSD$
.\"
.Dd July 26, 2014
.Dd September 08, 2017
.Dt ZPOOL 8
.Os
.Sh NAME
@ -153,7 +154,7 @@
.Op Ar new_device
.Nm
.Cm scrub
.Op Fl s
.Op Fl s | Fl p
.Ar pool ...
.Nm
.Cm set
@ -1543,43 +1544,54 @@ manner.
.It Xo
.Nm
.Cm scrub
.Op Fl s
.Op Fl s | Fl p
.Ar pool ...
.Xc
.Pp
Begins a scrub. The scrub examines all data in the specified pools to verify
that it checksums correctly. For replicated (mirror or
.No raidz )
devices,
.Tn ZFS
automatically repairs any damage discovered during the scrub. The
.Qq Nm Cm status
Begins a scrub or resumes a paused scrub.
The scrub examines all data in the specified pools to verify that it checksums
correctly.
For replicated
.Pq mirror or raidz
devices, ZFS automatically repairs any damage discovered during the scrub.
The
.Nm zpool Cm status
command reports the progress of the scrub and summarizes the results of the
scrub upon completion.
.Pp
Scrubbing and resilvering are very similar operations. The difference is that
resilvering only examines data that
.Tn ZFS
knows to be out of date (for example, when attaching a new device to a mirror
or replacing an existing device), whereas scrubbing examines all data to
discover silent errors due to hardware faults or disk failure.
Scrubbing and resilvering are very similar operations.
The difference is that resilvering only examines data that ZFS knows to be out
of date
.Po
for example, when attaching a new device to a mirror or replacing an existing
device
.Pc ,
whereas scrubbing examines all data to discover silent errors due to hardware
faults or disk failure.
.Pp
Because scrubbing and resilvering are
.Tn I/O Ns -intensive
operations,
.Tn ZFS
only allows one at a time. If a scrub is already in progress, the
.Qq Nm Cm scrub
command returns an error. To start a new scrub, you have to stop the old scrub
with the
.Qq Nm Cm scrub Fl s
command first. If a resilver is in progress,
.Tn ZFS
does not allow a scrub to be started until the resilver completes.
.Bl -tag -width indent
Because scrubbing and resilvering are I/O-intensive operations, ZFS only allows
one at a time.
If a scrub is paused, the
.Nm zpool Cm scrub
resumes it.
If a resilver is in progress, ZFS does not allow a scrub to be started until the
resilver completes.
.Bl -tag -width Ds
.It Fl s
Stop scrubbing.
.El
.Bl -tag -width Ds
.It Fl p
Pause scrubbing.
Scrub pause state and progress are periodically synced to disk.
If the system is restarted or pool is exported during a paused scrub,
even after import, scrub will remain paused until it is resumed.
Once resumed the scrub will pick up from the place where it was last
checkpointed to disk.
To resume a paused scrub issue
.Nm zpool Cm scrub
again.
.El
.It Xo
.Nm
.Cm set

View File

@ -27,6 +27,7 @@
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
* Copyright 2016 Nexenta Systems, Inc.
* Copyright (c) 2017 Datto Inc.
*/
#include <solaris.h>
@ -252,7 +253,7 @@ get_usage(zpool_help_t idx)
case HELP_REOPEN:
return (gettext("\treopen <pool>\n"));
case HELP_SCRUB:
return (gettext("\tscrub [-s] <pool> ...\n"));
return (gettext("\tscrub [-s | -p] <pool> ...\n"));
case HELP_STATUS:
return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
"[count]]\n"));
@ -3825,6 +3826,7 @@ typedef struct scrub_cbdata {
int cb_type;
int cb_argc;
char **cb_argv;
pool_scrub_cmd_t cb_scrub_cmd;
} scrub_cbdata_t;
int
@ -3842,15 +3844,16 @@ scrub_callback(zpool_handle_t *zhp, void *data)
return (1);
}
err = zpool_scan(zhp, cb->cb_type);
err = zpool_scan(zhp, cb->cb_type, cb->cb_scrub_cmd);
return (err != 0);
}
/*
* zpool scrub [-s] <pool> ...
* zpool scrub [-s | -p] <pool> ...
*
* -s Stop. Stops any in-progress scrub.
* -p Pause. Pause in-progress scrub.
*/
int
zpool_do_scrub(int argc, char **argv)
@ -3859,13 +3862,17 @@ zpool_do_scrub(int argc, char **argv)
scrub_cbdata_t cb;
cb.cb_type = POOL_SCAN_SCRUB;
cb.cb_scrub_cmd = POOL_SCRUB_NORMAL;
/* check options */
while ((c = getopt(argc, argv, "s")) != -1) {
while ((c = getopt(argc, argv, "sp")) != -1) {
switch (c) {
case 's':
cb.cb_type = POOL_SCAN_NONE;
break;
case 'p':
cb.cb_scrub_cmd = POOL_SCRUB_PAUSE;
break;
case '?':
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
optopt);
@ -3873,6 +3880,13 @@ zpool_do_scrub(int argc, char **argv)
}
}
if (cb.cb_type == POOL_SCAN_NONE &&
cb.cb_scrub_cmd == POOL_SCRUB_PAUSE) {
(void) fprintf(stderr, gettext("invalid option combination: "
"-s and -p are mutually exclusive\n"));
usage(B_FALSE);
}
cb.cb_argc = argc;
cb.cb_argv = argv;
argc -= optind;
@ -3901,7 +3915,7 @@ typedef struct status_cbdata {
void
print_scan_status(pool_scan_stat_t *ps)
{
time_t start, end;
time_t start, end, pause;
uint64_t elapsed, mins_left, hours_left;
uint64_t pass_exam, examined, total;
uint_t rate;
@ -3919,6 +3933,7 @@ print_scan_status(pool_scan_stat_t *ps)
start = ps->pss_start_time;
end = ps->pss_end_time;
pause = ps->pss_pass_scrub_pause;
zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
assert(ps->pss_func == POOL_SCAN_SCRUB ||
@ -3961,8 +3976,17 @@ print_scan_status(pool_scan_stat_t *ps)
* Scan is in progress.
*/
if (ps->pss_func == POOL_SCAN_SCRUB) {
(void) printf(gettext("scrub in progress since %s"),
ctime(&start));
if (pause == 0) {
(void) printf(gettext("scrub in progress since %s"),
ctime(&start));
} else {
char buf[32];
struct tm *p = localtime(&pause);
(void) strftime(buf, sizeof (buf), "%a %b %e %T %Y", p);
(void) printf(gettext("scrub paused since %s\n"), buf);
(void) printf(gettext("\tscrub started on %s"),
ctime(&start));
}
} else if (ps->pss_func == POOL_SCAN_RESILVER) {
(void) printf(gettext("resilver in progress since %s"),
ctime(&start));
@ -3974,6 +3998,7 @@ print_scan_status(pool_scan_stat_t *ps)
/* elapsed time for this pass */
elapsed = time(NULL) - ps->pss_pass_start;
elapsed -= ps->pss_pass_scrub_spent_paused;
elapsed = elapsed ? elapsed : 1;
pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
rate = pass_exam / elapsed;
@ -3983,19 +4008,25 @@ print_scan_status(pool_scan_stat_t *ps)
zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
zfs_nicenum(total, total_buf, sizeof (total_buf));
zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
/*
* do not print estimated time if hours_left is more than 30 days
* or we have a paused scrub
*/
(void) printf(gettext(" %s scanned out of %s at %s/s"),
examined_buf, total_buf, rate_buf);
if (hours_left < (30 * 24)) {
(void) printf(gettext(", %lluh%um to go\n"),
(u_longlong_t)hours_left, (uint_t)(mins_left % 60));
if (pause == 0) {
zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
(void) printf(gettext("\t%s scanned out of %s at %s/s"),
examined_buf, total_buf, rate_buf);
if (hours_left < (30 * 24)) {
(void) printf(gettext(", %lluh%um to go\n"),
(u_longlong_t)hours_left, (uint_t)(mins_left % 60));
} else {
(void) printf(gettext(
", (scan is slow, no estimated time)\n"));
}
} else {
(void) printf(gettext(
", (scan is slow, no estimated time)\n"));
(void) printf(gettext("\t%s scanned out of %s\n"),
examined_buf, total_buf);
}
if (ps->pss_func == POOL_SCAN_RESILVER) {

View File

@ -1503,7 +1503,7 @@ dt_compile_agg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
"divide a power of the factor\n");
}
for (i = 0, order = 1; i < args[2].value; i++) {
for (i = 0, order = 1; i <= args[2].value + 1; i++) {
if (order * args[0].value > order) {
order *= args[0].value;
continue;
@ -1511,7 +1511,7 @@ dt_compile_agg(dtrace_hdl_t *dtp, dt_node_t *dnp, dtrace_stmtdesc_t *sdp)
dnerror(dnp, D_LLQUANT_MAGTOOBIG, "llquantize( ) "
"factor (%d) raised to power of high magnitude "
"(%d) overflows 64-bits\n", args[0].value,
"(%d) plus 1 overflows 64-bits\n", args[0].value,
args[2].value);
}

View File

@ -963,7 +963,7 @@ dt_provmod_open(dt_provmod_t **provmod, dt_fdlist_t *dfp)
(void) snprintf(path, sizeof (path), "/dev/dtrace/%s", p1);
if ((fd = open(path, O_RDONLY)) == -1)
if ((fd = open(path, O_RDONLY | O_CLOEXEC)) == -1)
continue; /* failed to open driver; just skip it */
if (((prov = malloc(sizeof (dt_provmod_t))) == NULL) ||
@ -1100,7 +1100,7 @@ dt_vopen(int version, int flags, int *errp,
*/
dt_provmod_open(&provmod, &df);
dtfd = open("/dev/dtrace/dtrace", O_RDWR);
dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
err = errno; /* save errno from opening dtfd */
#if defined(__FreeBSD__)
/*
@ -1109,14 +1109,14 @@ dt_vopen(int version, int flags, int *errp,
*/
if (err == ENOENT && modfind("dtraceall") < 0) {
kldload("dtraceall"); /* ignore the error */
dtfd = open("/dev/dtrace/dtrace", O_RDWR);
dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
err = errno;
}
#endif
#ifdef illumos
ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
#else
ftfd = open("/dev/dtrace/fasttrap", O_RDWR);
ftfd = open("/dev/dtrace/fasttrap", O_RDWR | O_CLOEXEC);
#endif
fterr = ftfd == -1 ? errno : 0; /* save errno from open ftfd */
@ -1146,9 +1146,6 @@ dt_vopen(int version, int flags, int *errp,
return (set_open_errno(dtp, errp, err));
}
(void) fcntl(dtfd, F_SETFD, FD_CLOEXEC);
(void) fcntl(ftfd, F_SETFD, FD_CLOEXEC);
alloc:
if ((dtp = malloc(sizeof (dtrace_hdl_t))) == NULL) {
dt_provmod_destroy(&provmod);

View File

@ -28,6 +28,7 @@
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright 2016 Nexenta Systems, Inc.
* Copyright (c) 2017 Datto Inc.
*/
#ifndef _LIBZFS_H
@ -129,6 +130,7 @@ typedef enum zfs_error {
EZFS_DIFF, /* general failure of zfs diff */
EZFS_DIFFDATA, /* bad zfs diff data */
EZFS_POOLREADONLY, /* pool is in read-only mode */
EZFS_SCRUB_PAUSED, /* scrub currently paused */
EZFS_UNKNOWN
} zfs_error_t;
@ -241,7 +243,7 @@ typedef struct splitflags {
/*
* Functions to manipulate pool and vdev state
*/
extern int zpool_scan(zpool_handle_t *, pool_scan_func_t);
extern int zpool_scan(zpool_handle_t *, pool_scan_func_t, pool_scrub_cmd_t);
extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
extern int zpool_reguid(zpool_handle_t *);
extern int zpool_reopen(zpool_handle_t *);
@ -772,6 +774,7 @@ extern int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **,
* Label manipulation.
*/
extern int zpool_read_label(int, nvlist_t **);
extern int zpool_read_all_labels(int, nvlist_t **);
extern int zpool_clear_label(int);
/* is this zvol valid for use as a dump device? */

View File

@ -914,6 +914,65 @@ zpool_read_label(int fd, nvlist_t **config)
return (0);
}
/*
* Given a file descriptor, read the label information and return an nvlist
* describing the configuration, if there is one.
* returns the number of valid labels found
*/
int
zpool_read_all_labels(int fd, nvlist_t **config)
{
struct stat64 statbuf;
int l;
vdev_label_t *label;
uint64_t state, txg, size;
int nlabels = 0;
*config = NULL;
if (fstat64(fd, &statbuf) == -1)
return (0);
size = P2ALIGN_TYPED(statbuf.st_size, sizeof (vdev_label_t), uint64_t);
if ((label = malloc(sizeof (vdev_label_t))) == NULL)
return (0);
for (l = 0; l < VDEV_LABELS; l++) {
nvlist_t *temp = NULL;
/* TODO: use aio_read so we can read al 4 labels in parallel */
if (pread64(fd, label, sizeof (vdev_label_t),
label_offset(size, l)) != sizeof (vdev_label_t))
continue;
if (nvlist_unpack(label->vl_vdev_phys.vp_nvlist,
sizeof (label->vl_vdev_phys.vp_nvlist), &temp, 0) != 0)
continue;
if (nvlist_lookup_uint64(temp, ZPOOL_CONFIG_POOL_STATE,
&state) != 0 || state > POOL_STATE_L2CACHE) {
nvlist_free(temp);
temp = NULL;
continue;
}
if (state != POOL_STATE_SPARE && state != POOL_STATE_L2CACHE &&
(nvlist_lookup_uint64(temp, ZPOOL_CONFIG_POOL_TXG,
&txg) != 0 || txg == 0)) {
nvlist_free(temp);
temp = NULL;
continue;
}
if (temp)
*config = temp;
nlabels++;
}
free(label);
return (nlabels);
}
typedef struct rdsk_node {
char *rn_name;
int rn_dfd;

View File

@ -20,9 +20,11 @@
*/
/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014 by Delphix. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright 2017 RackTop Systems.
*/
/*
@ -87,7 +89,7 @@ zfs_share_type_t zfs_is_shared_proto(zfs_handle_t *, char **,
zfs_share_proto_t);
/*
* The share protocols table must be in the same order as the zfs_share_prot_t
* The share protocols table must be in the same order as the zfs_share_proto_t
* enum in libzfs_impl.h
*/
typedef struct {
@ -872,7 +874,7 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
/* make sure libshare initialized */
if ((err = zfs_init_libshare(hdl, SA_INIT_SHARE_API)) != SA_OK) {
free(mntpt); /* don't need the copy anymore */
return (zfs_error_fmt(hdl, EZFS_SHARENFSFAILED,
return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
name, _sa_errorstr(err)));
}
@ -883,12 +885,13 @@ unshare_one(libzfs_handle_t *hdl, const char *name, const char *mountpoint,
if (share != NULL) {
err = zfs_sa_disable_share(share, proto_table[proto].p_name);
if (err != SA_OK) {
return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
return (zfs_error_fmt(hdl,
proto_table[proto].p_unshare_err,
dgettext(TEXT_DOMAIN, "cannot unshare '%s': %s"),
name, _sa_errorstr(err)));
}
} else {
return (zfs_error_fmt(hdl, EZFS_UNSHARENFSFAILED,
return (zfs_error_fmt(hdl, proto_table[proto].p_unshare_err,
dgettext(TEXT_DOMAIN, "cannot unshare '%s': not found"),
name));
}

View File

@ -25,6 +25,7 @@
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright 2016 Nexenta Systems, Inc.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright (c) 2017 Datto Inc.
*/
#include <sys/types.h>
@ -1841,22 +1842,39 @@ zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
* Scan the pool.
*/
int
zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func, pool_scrub_cmd_t cmd)
{
zfs_cmd_t zc = { 0 };
char msg[1024];
int err;
libzfs_handle_t *hdl = zhp->zpool_hdl;
(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
zc.zc_cookie = func;
zc.zc_flags = cmd;
if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0 ||
(errno == ENOENT && func != POOL_SCAN_NONE))
if (zfs_ioctl(hdl, ZFS_IOC_POOL_SCAN, &zc) == 0)
return (0);
err = errno;
/* ECANCELED on a scrub means we resumed a paused scrub */
if (err == ECANCELED && func == POOL_SCAN_SCRUB &&
cmd == POOL_SCRUB_NORMAL)
return (0);
if (err == ENOENT && func != POOL_SCAN_NONE && cmd == POOL_SCRUB_NORMAL)
return (0);
if (func == POOL_SCAN_SCRUB) {
(void) snprintf(msg, sizeof (msg),
dgettext(TEXT_DOMAIN, "cannot scrub %s"), zc.zc_name);
if (cmd == POOL_SCRUB_PAUSE) {
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
"cannot pause scrubbing %s"), zc.zc_name);
} else {
assert(cmd == POOL_SCRUB_NORMAL);
(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
"cannot scrub %s"), zc.zc_name);
}
} else if (func == POOL_SCAN_NONE) {
(void) snprintf(msg, sizeof (msg),
dgettext(TEXT_DOMAIN, "cannot cancel scrubbing %s"),
@ -1865,7 +1883,7 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
assert(!"unexpected result");
}
if (errno == EBUSY) {
if (err == EBUSY) {
nvlist_t *nvroot;
pool_scan_stat_t *ps = NULL;
uint_t psc;
@ -1874,14 +1892,18 @@ zpool_scan(zpool_handle_t *zhp, pool_scan_func_t func)
ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
(void) nvlist_lookup_uint64_array(nvroot,
ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &psc);
if (ps && ps->pss_func == POOL_SCAN_SCRUB)
return (zfs_error(hdl, EZFS_SCRUBBING, msg));
else
if (ps && ps->pss_func == POOL_SCAN_SCRUB) {
if (cmd == POOL_SCRUB_PAUSE)
return (zfs_error(hdl, EZFS_SCRUB_PAUSED, msg));
else
return (zfs_error(hdl, EZFS_SCRUBBING, msg));
} else {
return (zfs_error(hdl, EZFS_RESILVERING, msg));
} else if (errno == ENOENT) {
}
} else if (err == ENOENT) {
return (zfs_error(hdl, EZFS_NO_SCRUB, msg));
} else {
return (zpool_standard_error(hdl, errno, msg));
return (zpool_standard_error(hdl, err, msg));
}
}

View File

@ -24,6 +24,7 @@
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
* Copyright (c) 2017 Datto Inc.
*/
/*
@ -224,6 +225,9 @@ libzfs_error_description(libzfs_handle_t *hdl)
case EZFS_POSTSPLIT_ONLINE:
return (dgettext(TEXT_DOMAIN, "disk was split from this pool "
"into a new one"));
case EZFS_SCRUB_PAUSED:
return (dgettext(TEXT_DOMAIN, "scrub is paused; "
"use 'zpool scrub' to resume"));
case EZFS_SCRUBBING:
return (dgettext(TEXT_DOMAIN, "currently scrubbing; "
"use 'zpool scrub -s' to cancel current scrub"));

View File

@ -735,11 +735,9 @@ static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
void
vpanic(const char *fmt, va_list adx)
{
(void) fprintf(stderr, "error: ");
(void) vfprintf(stderr, fmt, adx);
(void) fprintf(stderr, "\n");
abort(); /* think of it as a "user-level crash dump" */
char buf[512];
(void) vsnprintf(buf, 512, fmt, adx);
assfail(buf, NULL, 0);
}
void

View File

@ -54,6 +54,7 @@ DSRCS= errno.d \
siftr.d \
signal.d \
tcp.d \
socket.d \
udp.d \
unistd.d

301
cddl/lib/libdtrace/socket.d Normal file
View File

@ -0,0 +1,301 @@
/*
* Copyright (c) 2017 George V. Neville-Neil
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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$
*
* Translators and flags for the socket structure. FreeBSD specific code.
*/
#pragma D depends_on module kernel
/*
* Option flags per-socket.
*/
#pragma D binding "1.13" SO_DEBUG
inline int SO_DEBUG = 0x0001; /* turn on debugging info recording */
#pragma D binding "1.13" SO_ACCEPTCONN
inline int SO_ACCEPTCONN = 0x0002; /* socket has had listen() */
#pragma D binding "1.13" SO_REUSEADDR
inline int SO_REUSEADDR = 0x0004; /* allow local address reuse */
#pragma D binding "1.13" SO_KEEPALIVE
inline int SO_KEEPALIVE = 0x0008; /* keep connections alive */
#pragma D binding "1.13" SO_DONTROUTE
inline int SO_DONTROUTE = 0x0010; /* just use interface addresses */
#pragma D binding "1.13" SO_BROADCAST
inline int SO_BROADCAST = 0x0020; /* permit sending of broadcast msgs */
#pragma D binding "1.13" SO_USELOOPBACK
inline int SO_USELOOPBACK = 0x0040; /* bypass hardware when possible */
#pragma D binding "1.13" SO_LINGER
inline int SO_LINGER = 0x0080; /* linger on close if data present */
#pragma D binding "1.13" SO_OOBINLINE
inline int SO_OOBINLINE = 0x0100; /* leave received OOB data in line */
#pragma D binding "1.13" SO_REUSEPORT
inline int SO_REUSEPORT = 0x0200; /* allow local address & port reuse */
#pragma D binding "1.13" SO_TIMESTAMP
inline int SO_TIMESTAMP = 0x0400; /* timestamp received dgram traffic */
#pragma D binding "1.13" SO_NOSIGPIPE
inline int SO_NOSIGPIPE = 0x0800; /* no SIGPIPE from EPIPE */
#pragma D binding "1.13" SO_ACCEPTFILTER
inline int SO_ACCEPTFILTER = 0x1000; /* there is an accept filter */
#pragma D binding "1.13" SO_BINTIME
inline int SO_BINTIME = 0x2000; /* timestamp received dgram traffic */
#pragma D binding "1.13" SO_NO_OFFLOAD
inline int SO_NO_OFFLOAD = 0x4000; /* socket cannot be offloaded */
#pragma D binding "1.13" SO_NO_DDP
inline int SO_NO_DDP = 0x8000; /* disable direct data placement */
/*
* Additional options, not kept in so_options.
*/
#pragma D binding "1.13" SO_SNDBUF
inline int SO_SNDBUF = 0x1001; /* send buffer size */
#pragma D binding "1.13" SO_RCVBUF
inline int SO_RCVBUF = 0x1002; /* receive buffer size */
#pragma D binding "1.13" SO_SNDLOWAT
inline int SO_SNDLOWAT = 0x1003; /* send low-water mark */
#pragma D binding "1.13" SO_RCVLOWAT
inline int SO_RCVLOWAT = 0x1004; /* receive low-water mark */
#pragma D binding "1.13" SO_SNDTIMEO
inline int SO_SNDTIMEO = 0x1005; /* send timeout */
#pragma D binding "1.13" SO_RCVTIMEO
inline int SO_RCVTIMEO = 0x1006; /* receive timeout */
#pragma D binding "1.13" SO_ERROR
inline int SO_ERROR = 0x1007; /* get error status and clear */
#pragma D binding "1.13" SO_TYPE
inline int SO_TYPE = 0x1008; /* get socket type */
#pragma D binding "1.13" SO_LABEL
inline int SO_LABEL = 0x1009; /* socket's MAC label */
#pragma D binding "1.13" SO_PEERLABEL
inline int SO_PEERLABEL = 0x1010; /* socket's peer's MAC label */
#pragma D binding "1.13" SO_LISTENQLIMIT
inline int SO_LISTENQLIMIT = 0x1011; /* socket's backlog limit */
#pragma D binding "1.13" SO_LISTENQLEN
inline int SO_LISTENQLEN = 0x1012; /* socket's complete queue length */
#pragma D binding "1.13" SO_LISTENINCQLEN
inline int SO_LISTENINCQLEN = 0x1013; /* socket's incomplete queue length */
#pragma D binding "1.13" SO_SETFIB
inline int SO_SETFIB = 0x1014; /* use this FIB to route */
#pragma D binding "1.13" SO_USER_COOKIE
inline int SO_USER_COOKIE = 0x1015; /* user cookie (dummynet etc.) */
#pragma D binding "1.13" SO_PROTOCOL
inline int SO_PROTOCOL = 0x1016; /* get socket protocol (Linux name) */
#pragma D binding "1.13" SO_PROTOTYPE
inline int SO_PROTOTYPE = SO_PROTOCOL; /* alias for SO_PROTOCOL (SunOS name) */
#pragma D binding "1.13" SO_TS_CLOCK
inline int SO_TS_CLOCK = 0x1017; /* clock type used for SO_TIMESTAMP */
#pragma D binding "1.13" SO_MAX_PACING_RATE
inline int SO_MAX_PACING_RATE = 0x1018; /* socket's max TX pacing rate (Linux name) */
#pragma D binding "1.13" SO_TS_REALTIME_MICRO
inline int SO_TS_REALTIME_MICRO = 0; /* microsecond resolution, realtime */
#pragma D binding "1.13" SO_TS_BINTIME
inline int SO_TS_BINTIME = 1; /* sub-nanosecond resolution, realtime */
#pragma D binding "1.13" SO_TS_REALTIME
inline int SO_TS_REALTIME = 2; /* nanosecond resolution, realtime */
#pragma D binding "1.13" SO_TS_MONOTONIC
inline int SO_TS_MONOTONIC = 3; /* nanosecond resolution, monotonic */
#pragma D binding "1.13" SO_TS_DEFAULT
inline int SO_TS_DEFAULT = SO_TS_REALTIME_MICRO;
#pragma D binding "1.13" SO_TS_CLOCK_MAX
inline int SO_TS_CLOCK_MAX = SO_TS_MONOTONIC;
#pragma D binding "1.13" AF_UNSPEC
inline int AF_UNSPEC = 0; /* unspecified */
#pragma D binding "1.13" AF_UNIX
inline int AF_UNIX = 1; /* standardized name for AF_LOCAL */
#pragma D binding "1.13" AF_LOCAL
inline int AF_LOCAL = AF_UNIX; /* local to host (pipes, portals) */
#pragma D binding "1.13" AF_INET
inline int AF_INET = 2; /* internetwork: UDP, TCP, etc. */
#pragma D binding "1.13" AF_IMPLINK
inline int AF_IMPLINK = 3; /* arpanet imp addresses */
#pragma D binding "1.13" AF_PUP
inline int AF_PUP = 4; /* pup protocols: e.g. BSP */
#pragma D binding "1.13" AF_CHAOS
inline int AF_CHAOS = 5; /* mit CHAOS protocols */
#pragma D binding "1.13" AF_NETBIOS
inline int AF_NETBIOS = 6; /* SMB protocols */
#pragma D binding "1.13" AF_ISO
inline int AF_ISO = 7; /* ISO protocols */
#pragma D binding "1.13" AF_OSI
inline int AF_OSI = AF_ISO;
#pragma D binding "1.13" AF_ECMA
inline int AF_ECMA = 8; /* European computer manufacturers */
#pragma D binding "1.13" AF_DATAKIT
inline int AF_DATAKIT = 9; /* datakit protocols */
#pragma D binding "1.13" AF_CCITT
inline int AF_CCITT = 10; /* CCITT protocols, X.25 etc */
#pragma D binding "1.13" AF_SNA
inline int AF_SNA = 11; /* IBM SNA */
#pragma D binding "1.13" AF_DECnet
inline int AF_DECnet = 12; /* DECnet */
#pragma D binding "1.13" AF_DLI
inline int AF_DLI = 13; /* DEC Direct data link interface */
#pragma D binding "1.13" AF_LAT
inline int AF_LAT = 14; /* LAT */
#pragma D binding "1.13" AF_HYLINK
inline int AF_HYLINK = 15; /* NSC Hyperchannel */
#pragma D binding "1.13" AF_APPLETALK
inline int AF_APPLETALK = 16; /* Apple Talk */
#pragma D binding "1.13" AF_ROUTE
inline int AF_ROUTE = 17; /* Internal Routing Protocol */
#pragma D binding "1.13" AF_LINK
inline int AF_LINK = 18; /* Link layer interface */
#pragma D binding "1.13" pseudo_AF_XTP
inline int pseudo_AF_XTP = 19; /* eXpress Transfer Protocol (no AF) */
#pragma D binding "1.13" AF_COIP
inline int AF_COIP = 20; /* connection-oriented IP, aka ST II */
#pragma D binding "1.13" AF_CNT
inline int AF_CNT = 21; /* Computer Network Technology */
#pragma D binding "1.13" pseudo_AF_RTIP
inline int pseudo_AF_RTIP = 22; /* Help Identify RTIP packets */
#pragma D binding "1.13" AF_IPX
inline int AF_IPX = 23; /* Novell Internet Protocol */
#pragma D binding "1.13" AF_SIP
inline int AF_SIP = 24; /* Simple Internet Protocol */
#pragma D binding "1.13" pseudo_AF_PIP
inline int pseudo_AF_PIP = 25; /* Help Identify PIP packets */
#pragma D binding "1.13" AF_ISDN
inline int AF_ISDN = 26; /* Integrated Services Digital Network*/
#pragma D binding "1.13" AF_E164
inline int AF_E164 = AF_ISDN; /* CCITT E.164 recommendation */
#pragma D binding "1.13" pseudo_AF_KEY
inline int pseudo_AF_KEY = 27; /* Internal key-management function */
#pragma D binding "1.13" AF_INET6
inline int AF_INET6 = 28; /* IPv6 */
#pragma D binding "1.13" AF_NATM
inline int AF_NATM = 29; /* native ATM access */
#pragma D binding "1.13" AF_ATM
inline int AF_ATM = 30; /* ATM */
#pragma D binding "1.13" pseudo_AF_HDRCMPLT
inline int pseudo_AF_HDRCMPLT = 31; /* Used by BPF to not rewrite headers
* in interface output routine
*/
#pragma D binding "1.13" AF_NETGRAPH
inline int AF_NETGRAPH = 32; /* Netgraph sockets */
#pragma D binding "1.13" AF_SLOW
inline int AF_SLOW = 33; /* 802.3ad slow protocol */
#pragma D binding "1.13" AF_SCLUSTER
inline int AF_SCLUSTER = 34; /* Sitara cluster protocol */
#pragma D binding "1.13" AF_ARP
inline int AF_ARP = 35; /* Address Resolution Protocol */
#pragma D binding "1.13" AF_BLUETOOTH
inline int AF_BLUETOOTH = 36; /* Bluetooth sockets */
#pragma D binding "1.13" AF_IEEE80211
inline int AF_IEEE80211 = 37; /* IEEE 802.11 protocol */
#pragma D binding "1.13" AF_INET_SDP
inline int AF_INET_SDP = 40; /* OFED Socket Direct Protocol ipv4 */
#pragma D binding "1.13" AF_INET6_SDP
inline int AF_INET6_SDP = 42; /* OFED Socket Direct Protocol ipv6 */
#pragma D binding "1.13" AF_MAX
inline int AF_MAX = 42;
/*
* Protocol families, same as address families for now.
*/
#pragma D binding "1.13" PF_UNSPEC
inline int PF_UNSPEC = AF_UNSPEC;
#pragma D binding "1.13" PF_LOCAL
inline int PF_LOCAL = AF_LOCAL;
#pragma D binding "1.13" PF_UNIX
inline int PF_UNIX = PF_LOCAL; /* backward compatibility */
#pragma D binding "1.13" PF_INET
inline int PF_INET = AF_INET;
#pragma D binding "1.13" PF_IMPLINK
inline int PF_IMPLINK = AF_IMPLINK;
#pragma D binding "1.13" PF_PUP
inline int PF_PUP = AF_PUP;
#pragma D binding "1.13" PF_CHAOS
inline int PF_CHAOS = AF_CHAOS;
#pragma D binding "1.13" PF_NETBIOS
inline int PF_NETBIOS = AF_NETBIOS;
#pragma D binding "1.13" PF_ISO
inline int PF_ISO = AF_ISO;
#pragma D binding "1.13" PF_OSI
inline int PF_OSI = AF_ISO;
#pragma D binding "1.13" PF_ECMA
inline int PF_ECMA = AF_ECMA;
#pragma D binding "1.13" PF_DATAKIT
inline int PF_DATAKIT = AF_DATAKIT;
#pragma D binding "1.13" PF_CCITT
inline int PF_CCITT = AF_CCITT;
#pragma D binding "1.13" PF_SNA
inline int PF_SNA = AF_SNA;
#pragma D binding "1.13" PF_DECnet
inline int PF_DECnet = AF_DECnet;
#pragma D binding "1.13" PF_DLI
inline int PF_DLI = AF_DLI;
#pragma D binding "1.13" PF_LAT
inline int PF_LAT = AF_LAT;
#pragma D binding "1.13" PF_HYLINK
inline int PF_HYLINK = AF_HYLINK;
#pragma D binding "1.13" PF_APPLETALK
inline int PF_APPLETALK = AF_APPLETALK;
#pragma D binding "1.13" PF_ROUTE
inline int PF_ROUTE = AF_ROUTE;
#pragma D binding "1.13" PF_LINK
inline int PF_LINK = AF_LINK;
#pragma D binding "1.13" PF_XTP
inline int PF_XTP = pseudo_AF_XTP; /* really just proto family, no AF */
#pragma D binding "1.13" PF_COIP
inline int PF_COIP = AF_COIP;
#pragma D binding "1.13" PF_CNT
inline int PF_CNT = AF_CNT;
#pragma D binding "1.13" PF_SIP
inline int PF_SIP = AF_SIP;
#pragma D binding "1.13" PF_IPX
inline int PF_IPX = AF_IPX;
#pragma D binding "1.13" PF_RTIP
inline int PF_RTIP = pseudo_AF_RTIP; /* same format as AF_INET */
#pragma D binding "1.13" PF_PIP
inline int PF_PIP = pseudo_AF_PIP;
#pragma D binding "1.13" PF_ISDN
inline int PF_ISDN = AF_ISDN;
#pragma D binding "1.13" PF_KEY
inline int PF_KEY = pseudo_AF_KEY;
#pragma D binding "1.13" PF_INET6
inline int PF_INET6 = AF_INET6;
#pragma D binding "1.13" PF_NATM
inline int PF_NATM = AF_NATM;
#pragma D binding "1.13" PF_ATM
inline int PF_ATM = AF_ATM;
#pragma D binding "1.13" PF_NETGRAPH
inline int PF_NETGRAPH = AF_NETGRAPH;
#pragma D binding "1.13" PF_SLOW
inline int PF_SLOW = AF_SLOW;
#pragma D binding "1.13" PF_SCLUSTER
inline int PF_SCLUSTER = AF_SCLUSTER;
#pragma D binding "1.13" PF_ARP
inline int PF_ARP = AF_ARP;
#pragma D binding "1.13" PF_BLUETOOTH
inline int PF_BLUETOOTH = AF_BLUETOOTH;
#pragma D binding "1.13" PF_IEEE80211
inline int PF_IEEE80211 = AF_IEEE80211;
#pragma D binding "1.13" PF_INET_SDP
inline int PF_INET_SDP= AF_INET_SDP;
#pragma D binding "1.13" PF_INET6_SDP
inline int PF_INET6_SDP= AF_INET6_SDP;
#pragma D binding "1.13" PF_MAX
inline int PF_MAX = AF_MAX;

View File

@ -26,7 +26,7 @@ ATOMIC_SRCS= opensolaris_atomic.c
LIB= zpool
ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} vdev_file.c trim_map.c
ZFS_COMMON_SRCS= ${ZFS_COMMON_OBJS:C/.o$/.c/} trim_map.c
ZFS_SHARED_SRCS= ${ZFS_SHARED_OBJS:C/.o$/.c/}
KERNEL_SRCS= kernel.c taskq.c util.c
LIST_SRCS= list.c

View File

@ -22,6 +22,7 @@ ${PACKAGE}FILES= \
err.D_LLQUANT_LOWVAL.d \
err.D_LLQUANT_MAGRANGE.d \
err.D_LLQUANT_MAGTOOBIG.d \
err.D_LLQUANT_MAGTOOBIG.offbyone.d \
err.D_LLQUANT_NSTEPMATCH.d \
err.D_LLQUANT_NSTEPTYPE.d \
err.D_LLQUANT_NSTEPVAL.d \

View File

@ -36,6 +36,7 @@
#include <sys/cdefs.h>
#include <sys/time.h>
#include <sys/fs/zfs.h>
#include <sys/vdev_impl.h>
#include <syslog.h>
@ -93,6 +94,7 @@ DevfsEvent::ReadLabel(int devFd, bool &inUse, bool &degraded)
pool_state_t poolState;
char *poolName;
boolean_t b_inuse;
int nlabels;
inUse = false;
degraded = false;
@ -105,8 +107,16 @@ DevfsEvent::ReadLabel(int devFd, bool &inUse, bool &degraded)
if (poolName != NULL)
free(poolName);
if (zpool_read_label(devFd, &devLabel) != 0
|| devLabel == NULL)
nlabels = zpool_read_all_labels(devFd, &devLabel);
/*
* If we find a disk with fewer than the maximum number of
* labels, it might be the whole disk of a partitioned disk
* where ZFS resides on a partition. In that case, we should do
* nothing and wait for the partition to appear. Or, the disk
* might be damaged. In that case, zfsd should do nothing and
* wait for the sysadmin to decide.
*/
if (nlabels != VDEV_LABELS || devLabel == NULL)
return (NULL);
try {

View File

@ -1302,7 +1302,7 @@ static const unsigned char twobyte_uses_REPZ_prefix[256] = {
/* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
/* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
/* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
/* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
/* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, /* af */
/* b0 */ 0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, /* bf */
/* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
/* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
@ -1793,10 +1793,10 @@ static const struct dis386 grps[][8] = {
},
/* GRP15 */
{
{ "fxsave", { Ev } },
{ "fxrstor", { Ev } },
{ "ldmxcsr", { Ev } },
{ "stmxcsr", { Ev } },
{ "fxsave", { { OP_0fae, v_mode } } },
{ "fxrstor", { { OP_0fae, v_mode } } },
{ "ldmxcsr", { { OP_0fae, v_mode } } },
{ "stmxcsr", { { OP_0fae, v_mode } } },
{ "xsave", { Ev } },
{ "xrstor", { { OP_0fae, v_mode } } },
{ "xsaveopt", { { OP_0fae, v_mode } } },
@ -5997,19 +5997,34 @@ OP_0fae (int bytemode, int sizeflag)
{
if (modrm.mod == 3)
{
if (modrm.reg == 7)
strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
else if (modrm.reg == 6)
strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
else if (modrm.reg == 5)
strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
if (modrm.reg < 5 || modrm.rm != 0)
if (modrm.reg >= 5 && modrm.reg <= 7 && modrm.rm == 0)
{
BadOp (); /* bad sfence, mfence, or lfence */
if (modrm.reg == 7)
strcpy (obuf + strlen (obuf) - sizeof ("clflush") + 1, "sfence");
else if (modrm.reg == 6)
strcpy (obuf + strlen (obuf) - sizeof ("xsaveopt") + 1, "mfence");
else if (modrm.reg == 5)
strcpy (obuf + strlen (obuf) - sizeof ("xrstor") + 1, "lfence");
bytemode = 0;
}
else if (modrm.reg <= 3 && (prefixes & PREFIX_REPZ) != 0)
{
if (modrm.reg == 0)
strcpy (obuf + strlen (obuf) - sizeof ("fxsave") + 1, "rdfsbase");
else if (modrm.reg == 1)
strcpy (obuf + strlen (obuf) - sizeof ("fxrstor") + 1, "rdgsbase");
else if (modrm.reg == 2)
strcpy (obuf + strlen (obuf) - sizeof ("ldmxcsr") + 1, "wrfsbase");
else if (modrm.reg == 3)
strcpy (obuf + strlen (obuf) - sizeof ("stmxcsr") + 1, "wrgsbase");
used_prefixes |= PREFIX_REPZ;
bytemode = dq_mode;
}
else
{
BadOp ();
return;
}
bytemode = 0;
}
OP_E (bytemode, sizeflag);

View File

@ -81,6 +81,7 @@ typedef struct template
#define CpuPCLMUL 0x10000000 /* Carry-less Multiplication extensions */
#define CpuRdRnd 0x20000000 /* Intel Random Number Generator extensions */
#define CpuSMAP 0x40000000 /* Intel Supervisor Mode Access Prevention */
#define CpuFSGSBase 0x80000000 /* Read/write fs/gs segment base registers */
/* SSE4.1/4.2 Instructions required */
#define CpuSSE4 (CpuSSE4_1|CpuSSE4_2)
@ -89,7 +90,8 @@ typedef struct template
#define CpuUnknownFlags (Cpu186|Cpu286|Cpu386|Cpu486|Cpu586|Cpu686 \
|CpuP4|CpuSledgehammer|CpuMMX|CpuMMX2|CpuSSE|CpuSSE2|CpuSSE3|CpuVMX \
|Cpu3dnow|Cpu3dnowA|CpuK6|CpuPadLock|CpuSVME|CpuSSSE3|CpuSSE4_1 \
|CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP)
|CpuSSE4_2|CpuABM|CpuSSE4a|CpuXSAVE|CpuAES|CpuPCLMUL|CpuRdRnd|CpuSMAP \
|CpuFSGSBase)
/* the bits in opcode_modifier are used to generate the final opcode from
the base_opcode. These bits also are used to detect alternate forms of

View File

@ -1525,3 +1525,13 @@ pclmulhqhqdq, 2, 0x660f3a44, 0x11, CpuPCLMUL, Modrm|IgnoreSize|No_bSuf|No_wSuf|N
// Intel Random Number Generator extensions
rdrand, 1, 0x0fc7, 0x6, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 }
rdseed, 1, 0x0fc7, 0x7, CpuRdRnd, Modrm|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_xSuf, { Reg16|Reg32|Reg64 }
// Intel Supervisor Mode Access Prevention extensions
clac, 0, 0x0f01, 0xca, CpuSMAP, NoSuf|ImmExt, { 0 }
stac, 0, 0x0f01, 0xcb, CpuSMAP, NoSuf|ImmExt, { 0 }
// Read/write fs/gs segment base registers
rdfsbase, 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
rdgsbase, 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
wrfsbase, 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }
wrgsbase, 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64, Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf, { Reg32|Reg64 }

View File

@ -4400,6 +4400,20 @@ const template i386_optab[] =
NoSuf|ImmExt, { 0, 0, 0 } },
{"stac", 0, 0x0f01, 0xcb, CpuSMAP,
NoSuf|ImmExt, { 0, 0, 0 } },
/* Read/write fs/gs segment base registers */
{"rdfsbase", 1, 0xf30fae, 0x0, CpuFSGSBase|Cpu64,
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
{ Reg32|Reg64 } },
{"rdgsbase", 1, 0xf30fae, 0x1, CpuFSGSBase|Cpu64,
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
{ Reg32|Reg64 } },
{"wrfsbase", 1, 0xf30fae, 0x2, CpuFSGSBase|Cpu64,
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
{ Reg32|Reg64 } },
{"wrgsbase", 1, 0xf30fae, 0x3, CpuFSGSBase|Cpu64,
Modrm|No_bSuf|No_wSuf|No_sSuf|No_xSuf,
{ Reg32|Reg64 } },
{ NULL, 0, 0, 0, 0, 0, { 0 } }
};

View File

@ -18,11 +18,20 @@
// }
// }
#if defined(COMPILER_RT_ARMHF_TARGET)
# define CONVERT_DCMP_ARGS_TO_DF2_ARGS \
vmov d0, r0, r1 SEPARATOR \
vmov d1, r2, r3
#else
# define CONVERT_DCMP_ARGS_TO_DF2_ARGS
#endif
#define DEFINE_AEABI_DCMP(cond) \
.syntax unified SEPARATOR \
.p2align 2 SEPARATOR \
DEFINE_COMPILERRT_FUNCTION(__aeabi_dcmp ## cond) \
push { r4, lr } SEPARATOR \
CONVERT_DCMP_ARGS_TO_DF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## df2) SEPARATOR \
cmp r0, #0 SEPARATOR \
b ## cond 1f SEPARATOR \

View File

@ -18,11 +18,20 @@
// }
// }
#if defined(COMPILER_RT_ARMHF_TARGET)
# define CONVERT_FCMP_ARGS_TO_SF2_ARGS \
vmov s0, r0 SEPARATOR \
vmov s1, r1
#else
# define CONVERT_FCMP_ARGS_TO_SF2_ARGS
#endif
#define DEFINE_AEABI_FCMP(cond) \
.syntax unified SEPARATOR \
.p2align 2 SEPARATOR \
DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmp ## cond) \
push { r4, lr } SEPARATOR \
CONVERT_FCMP_ARGS_TO_SF2_ARGS SEPARATOR \
bl SYMBOL_NAME(__ ## cond ## sf2) SEPARATOR \
cmp r0, #0 SEPARATOR \
b ## cond 1f SEPARATOR \

View File

@ -92,12 +92,13 @@
* does not have dedicated bit counting instructions.
*/
#if defined(__FreeBSD__) && (defined(__sparc64__) || \
defined(__mips_n64) || defined(__mips_o64) || defined(__riscv))
defined(__mips_n32) || defined(__mips_n64) || defined(__mips_o64) || \
defined(__riscv))
si_int __clzsi2(si_int);
si_int __ctzsi2(si_int);
#define __builtin_clz __clzsi2
#define __builtin_ctz __ctzsi2
#endif /* FreeBSD && (sparc64 || mips_n64 || mips_o64) */
#endif /* FreeBSD && (sparc64 || mips_n32 || mips_n64 || mips_o64 || riscv) */
COMPILER_RT_ABI si_int __paritysi2(si_int a);
COMPILER_RT_ABI si_int __paritydi2(di_int a);

View File

@ -70,7 +70,7 @@ int SidelineThread::runSideline(void *Arg) {
// Set up a signal handler on an alternate stack for safety.
InternalScopedBuffer<char> StackMap(SigAltStackSize);
struct sigaltstack SigAltStack;
stack_t SigAltStack;
SigAltStack.ss_sp = StackMap.data();
SigAltStack.ss_size = SigAltStackSize;
SigAltStack.ss_flags = 0;

View File

@ -1,11 +1,11 @@
//===- InstrProfilingNameVar.c - profile name variable setup --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/*===- InstrProfilingNameVar.c - profile name variable setup -------------===*\
|*
|* The LLVM Compiler Infrastructure
|*
|* This file is distributed under the University of Illinois Open Source
|* License. See LICENSE.TXT for details.
|*
\*===----------------------------------------------------------------------===*/
#include "InstrProfiling.h"

View File

@ -77,8 +77,8 @@
#define D_h x13
#define E_l src
#define E_h count
#define F_l srcend
#define F_h dst
#define F_l dst
#define F_h srcend
#define tmp1 x9
#define L(l) .L ## l

View File

@ -509,7 +509,7 @@ do_bid_note(struct magic_set *ms, unsigned char *nbuf, uint32_t type,
size_t noff, size_t doff, int *flags)
{
if (namesz == 4 && strcmp((char *)&nbuf[noff], "GNU") == 0 &&
type == NT_GNU_BUILD_ID && (descsz >= 4 || descsz <= 20)) {
type == NT_GNU_BUILD_ID && (descsz >= 4 && descsz <= 20)) {
uint8_t desc[20];
const char *btype;
uint32_t i;

View File

@ -85,7 +85,10 @@ namespace ISD {
/// If N is a BUILD_VECTOR node whose elements are all the same constant or
/// undefined, return true and return the constant value in \p SplatValue.
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
/// This sets \p SplatValue to the smallest possible splat unless AllowShrink
/// is set to false.
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue,
bool AllowShrink = true);
/// Return true if the specified node is a BUILD_VECTOR where all of the
/// elements are ~0 or undef.
@ -798,7 +801,8 @@ public:
/// if DAG changes.
static bool hasPredecessorHelper(const SDNode *N,
SmallPtrSetImpl<const SDNode *> &Visited,
SmallVectorImpl<const SDNode *> &Worklist) {
SmallVectorImpl<const SDNode *> &Worklist,
unsigned int MaxSteps = 0) {
if (Visited.count(N))
return true;
while (!Worklist.empty()) {
@ -813,6 +817,8 @@ public:
}
if (Found)
return true;
if (MaxSteps != 0 && Visited.size() >= MaxSteps)
return false;
}
return false;
}

View File

@ -23,8 +23,6 @@ using namespace llvm;
#define DEBUG_TYPE "postdomtree"
template class llvm::DominatorTreeBase<BasicBlock, true>; // PostDomTreeBase
//===----------------------------------------------------------------------===//
// PostDominatorTree Implementation
//===----------------------------------------------------------------------===//

View File

@ -1118,22 +1118,30 @@ SDValue DAGCombiner::PromoteIntBinOp(SDValue Op) {
SDValue RV =
DAG.getNode(ISD::TRUNCATE, DL, VT, DAG.getNode(Opc, DL, PVT, NN0, NN1));
// New replace instances of N0 and N1
if (Replace0 && N0 && N0.getOpcode() != ISD::DELETED_NODE && NN0 &&
NN0.getOpcode() != ISD::DELETED_NODE) {
// We are always replacing N0/N1's use in N and only need
// additional replacements if there are additional uses.
Replace0 &= !N0->hasOneUse();
Replace1 &= (N0 != N1) && !N1->hasOneUse();
// Combine Op here so it is presreved past replacements.
CombineTo(Op.getNode(), RV);
// If operands have a use ordering, make sur we deal with
// predecessor first.
if (Replace0 && Replace1 && N0.getNode()->isPredecessorOf(N1.getNode())) {
std::swap(N0, N1);
std::swap(NN0, NN1);
}
if (Replace0) {
AddToWorklist(NN0.getNode());
ReplaceLoadWithPromotedLoad(N0.getNode(), NN0.getNode());
}
if (Replace1 && N1 && N1.getOpcode() != ISD::DELETED_NODE && NN1 &&
NN1.getOpcode() != ISD::DELETED_NODE) {
if (Replace1) {
AddToWorklist(NN1.getNode());
ReplaceLoadWithPromotedLoad(N1.getNode(), NN1.getNode());
}
// Deal with Op being deleted.
if (Op && Op.getOpcode() != ISD::DELETED_NODE)
return RV;
return Op;
}
return SDValue();
}
@ -12599,25 +12607,37 @@ void DAGCombiner::getStoreMergeCandidates(
}
}
// We need to check that merging these stores does not cause a loop
// in the DAG. Any store candidate may depend on another candidate
// We need to check that merging these stores does not cause a loop in
// the DAG. Any store candidate may depend on another candidate
// indirectly through its operand (we already consider dependencies
// through the chain). Check in parallel by searching up from
// non-chain operands of candidates.
bool DAGCombiner::checkMergeStoreCandidatesForDependencies(
SmallVectorImpl<MemOpLink> &StoreNodes, unsigned NumStores) {
// FIXME: We should be able to truncate a full search of
// predecessors by doing a BFS and keeping tabs the originating
// stores from which worklist nodes come from in a similar way to
// TokenFactor simplfication.
SmallPtrSet<const SDNode *, 16> Visited;
SmallVector<const SDNode *, 8> Worklist;
// search ops of store candidates
unsigned int Max = 8192;
// Search Ops of store candidates.
for (unsigned i = 0; i < NumStores; ++i) {
SDNode *n = StoreNodes[i].MemNode;
// Potential loops may happen only through non-chain operands
for (unsigned j = 1; j < n->getNumOperands(); ++j)
Worklist.push_back(n->getOperand(j).getNode());
}
// search through DAG. We can stop early if we find a storenode
// Search through DAG. We can stop early if we find a store node.
for (unsigned i = 0; i < NumStores; ++i) {
if (SDNode::hasPredecessorHelper(StoreNodes[i].MemNode, Visited, Worklist))
if (SDNode::hasPredecessorHelper(StoreNodes[i].MemNode, Visited, Worklist,
Max))
return false;
// Check if we ended early, failing conservatively if so.
if (Visited.size() >= Max)
return false;
}
return true;

View File

@ -627,6 +627,7 @@ private:
SDValue ScalarizeVecOp_CONCAT_VECTORS(SDNode *N);
SDValue ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N);
SDValue ScalarizeVecOp_VSELECT(SDNode *N);
SDValue ScalarizeVecOp_VSETCC(SDNode *N);
SDValue ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo);
SDValue ScalarizeVecOp_FP_ROUND(SDNode *N, unsigned OpNo);

View File

@ -484,6 +484,9 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) {
case ISD::VSELECT:
Res = ScalarizeVecOp_VSELECT(N);
break;
case ISD::SETCC:
Res = ScalarizeVecOp_VSETCC(N);
break;
case ISD::STORE:
Res = ScalarizeVecOp_STORE(cast<StoreSDNode>(N), OpNo);
break;
@ -560,6 +563,36 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_VSELECT(SDNode *N) {
N->getOperand(2));
}
/// If the operand is a vector that needs to be scalarized then the
/// result must be v1i1, so just convert to a scalar SETCC and wrap
/// with a scalar_to_vector since the res type is legal if we got here
SDValue DAGTypeLegalizer::ScalarizeVecOp_VSETCC(SDNode *N) {
assert(N->getValueType(0).isVector() &&
N->getOperand(0).getValueType().isVector() &&
"Operand types must be vectors");
assert(N->getValueType(0) == MVT::v1i1 && "Expected v1i1 type");
EVT VT = N->getValueType(0);
SDValue LHS = GetScalarizedVector(N->getOperand(0));
SDValue RHS = GetScalarizedVector(N->getOperand(1));
EVT OpVT = N->getOperand(0).getValueType();
EVT NVT = VT.getVectorElementType();
SDLoc DL(N);
// Turn it into a scalar SETCC.
SDValue Res = DAG.getNode(ISD::SETCC, DL, MVT::i1, LHS, RHS,
N->getOperand(2));
// Vectors may have a different boolean contents to scalars. Promote the
// value appropriately.
ISD::NodeType ExtendCode =
TargetLowering::getExtendForContent(TLI.getBooleanContents(OpVT));
Res = DAG.getNode(ExtendCode, DL, NVT, Res);
return DAG.getNode(ISD::SCALAR_TO_VECTOR, DL, VT, Res);
}
/// If the value to store is a vector that needs to be scalarized, it must be
/// <1 x ty>. Just store the element.
SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){

View File

@ -116,7 +116,8 @@ bool ConstantFPSDNode::isValueValidForType(EVT VT,
// ISD Namespace
//===----------------------------------------------------------------------===//
bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal,
bool AllowShrink) {
auto *BV = dyn_cast<BuildVectorSDNode>(N);
if (!BV)
return false;
@ -124,9 +125,11 @@ bool ISD::isConstantSplatVector(const SDNode *N, APInt &SplatVal) {
APInt SplatUndef;
unsigned SplatBitSize;
bool HasUndefs;
EVT EltVT = N->getValueType(0).getVectorElementType();
return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs) &&
EltVT.getSizeInBits() >= SplatBitSize;
unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits();
unsigned MinSplatBits = AllowShrink ? 0 : EltSize;
return BV->isConstantSplat(SplatVal, SplatUndef, SplatBitSize, HasUndefs,
MinSplatBits) &&
EltSize >= SplatBitSize;
}
// FIXME: AllOnes and AllZeros duplicate a lot of code. Could these be

View File

@ -2239,14 +2239,14 @@ bool llvm::UpgradeDebugInfo(Module &M) {
}
bool llvm::UpgradeModuleFlags(Module &M) {
const NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
NamedMDNode *ModFlags = M.getModuleFlagsMetadata();
if (!ModFlags)
return false;
bool HasObjCFlag = false, HasClassProperties = false;
bool HasObjCFlag = false, HasClassProperties = false, Changed = false;
for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) {
MDNode *Op = ModFlags->getOperand(I);
if (Op->getNumOperands() < 2)
if (Op->getNumOperands() != 3)
continue;
MDString *ID = dyn_cast_or_null<MDString>(Op->getOperand(1));
if (!ID)
@ -2255,7 +2255,24 @@ bool llvm::UpgradeModuleFlags(Module &M) {
HasObjCFlag = true;
if (ID->getString() == "Objective-C Class Properties")
HasClassProperties = true;
// Upgrade PIC/PIE Module Flags. The module flag behavior for these two
// field was Error and now they are Max.
if (ID->getString() == "PIC Level" || ID->getString() == "PIE Level") {
if (auto *Behavior =
mdconst::dyn_extract_or_null<ConstantInt>(Op->getOperand(0))) {
if (Behavior->getLimitedValue() == Module::Error) {
Type *Int32Ty = Type::getInt32Ty(M.getContext());
Metadata *Ops[3] = {
ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Module::Max)),
MDString::get(M.getContext(), ID->getString()),
Op->getOperand(2)};
ModFlags->setOperand(I, MDNode::get(M.getContext(), Ops));
Changed = true;
}
}
}
}
// "Objective-C Class Properties" is recently added for Objective-C. We
// upgrade ObjC bitcodes to contain a "Objective-C Class Properties" module
// flag of value 0, so we can correclty downgrade this flag when trying to
@ -2264,9 +2281,10 @@ bool llvm::UpgradeModuleFlags(Module &M) {
if (HasObjCFlag && !HasClassProperties) {
M.addModuleFlag(llvm::Module::Override, "Objective-C Class Properties",
(uint32_t)0);
return true;
Changed = true;
}
return false;
return Changed;
}
static bool isOldLoopArgument(Metadata *MD) {

View File

@ -232,7 +232,13 @@ private:
for (;;) {
read();
if (Tok.K == Identifier && Tok.Value[0] == '@') {
Tok.Value.drop_front().getAsInteger(10, E.Ordinal);
if (Tok.Value.drop_front().getAsInteger(10, E.Ordinal)) {
// Not an ordinal modifier at all, but the next export (fastcall
// decorated) - complete the current one.
unget();
Info.Exports.push_back(E);
return Error::success();
}
read();
if (Tok.K == KwNoname) {
E.Noname = true;

View File

@ -5901,7 +5901,10 @@ static bool isVUZPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
return false;
for (unsigned i = 0; i < M.size(); i += NumElts) {
WhichResult = M[i] == 0 ? 0 : 1;
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1;
for (unsigned j = 0; j < NumElts; ++j) {
if (M[i+j] >= 0 && (unsigned) M[i+j] != 2 * j + WhichResult)
return false;
@ -5932,7 +5935,10 @@ static bool isVUZP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
unsigned Half = NumElts / 2;
for (unsigned i = 0; i < M.size(); i += NumElts) {
WhichResult = M[i] == 0 ? 0 : 1;
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1;
for (unsigned j = 0; j < NumElts; j += Half) {
unsigned Idx = WhichResult;
for (unsigned k = 0; k < Half; ++k) {
@ -5972,7 +5978,10 @@ static bool isVZIPMask(ArrayRef<int> M, EVT VT, unsigned &WhichResult) {
return false;
for (unsigned i = 0; i < M.size(); i += NumElts) {
WhichResult = M[i] == 0 ? 0 : 1;
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1;
unsigned Idx = WhichResult * NumElts / 2;
for (unsigned j = 0; j < NumElts; j += 2) {
if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
@ -6005,7 +6014,10 @@ static bool isVZIP_v_undef_Mask(ArrayRef<int> M, EVT VT, unsigned &WhichResult){
return false;
for (unsigned i = 0; i < M.size(); i += NumElts) {
WhichResult = M[i] == 0 ? 0 : 1;
if (M.size() == NumElts * 2)
WhichResult = i / NumElts;
else
WhichResult = M[i] == 0 ? 0 : 1;
unsigned Idx = WhichResult * NumElts / 2;
for (unsigned j = 0; j < NumElts; j += 2) {
if ((M[i+j] >= 0 && (unsigned) M[i+j] != Idx) ||
@ -8793,6 +8805,8 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
.addReg(ARM::R4, RegState::Implicit | RegState::Kill)
.addReg(ARM::R4, RegState::Implicit | RegState::Define)
.addReg(ARM::R12,
RegState::Implicit | RegState::Define | RegState::Dead)
.addReg(ARM::CPSR,
RegState::Implicit | RegState::Define | RegState::Dead);
break;
case CodeModel::Large:
@ -8808,6 +8822,8 @@ ARMTargetLowering::EmitLowered__chkstk(MachineInstr &MI,
.addReg(ARM::R4, RegState::Implicit | RegState::Kill)
.addReg(ARM::R4, RegState::Implicit | RegState::Define)
.addReg(ARM::R12,
RegState::Implicit | RegState::Define | RegState::Dead)
.addReg(ARM::CPSR,
RegState::Implicit | RegState::Define | RegState::Dead);
break;
}

View File

@ -29540,8 +29540,9 @@ static bool detectZextAbsDiff(const SDValue &Select, SDValue &Op0,
// In SetLT case, The second operand of the comparison can be either 1 or 0.
APInt SplatVal;
if ((CC == ISD::SETLT) &&
!((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal) &&
SplatVal == 1) ||
!((ISD::isConstantSplatVector(SetCC.getOperand(1).getNode(), SplatVal,
/*AllowShrink*/false) &&
SplatVal.isOneValue()) ||
(ISD::isBuildVectorAllZeros(SetCC.getOperand(1).getNode()))))
return false;
@ -30628,6 +30629,9 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
// Byte blends are only available in AVX2
if (VT == MVT::v32i8 && !Subtarget.hasAVX2())
return SDValue();
// There are no 512-bit blend instructions that use sign bits.
if (VT.is512BitVector())
return SDValue();
assert(BitWidth >= 8 && BitWidth <= 64 && "Invalid mask size");
APInt DemandedMask(APInt::getSignMask(BitWidth));
@ -30938,11 +30942,40 @@ static bool checkBoolTestAndOrSetCCCombine(SDValue Cond, X86::CondCode &CC0,
return true;
}
// When legalizing carry, we create carries via add X, -1
// If that comes from an actual carry, via setcc, we use the
// carry directly.
static SDValue combineCarryThroughADD(SDValue EFLAGS) {
if (EFLAGS.getOpcode() == X86ISD::ADD) {
if (isAllOnesConstant(EFLAGS.getOperand(1))) {
SDValue Carry = EFLAGS.getOperand(0);
while (Carry.getOpcode() == ISD::TRUNCATE ||
Carry.getOpcode() == ISD::ZERO_EXTEND ||
Carry.getOpcode() == ISD::SIGN_EXTEND ||
Carry.getOpcode() == ISD::ANY_EXTEND ||
(Carry.getOpcode() == ISD::AND &&
isOneConstant(Carry.getOperand(1))))
Carry = Carry.getOperand(0);
if (Carry.getOpcode() == X86ISD::SETCC ||
Carry.getOpcode() == X86ISD::SETCC_CARRY) {
if (Carry.getConstantOperandVal(0) == X86::COND_B)
return Carry.getOperand(1);
}
}
}
return SDValue();
}
/// Optimize an EFLAGS definition used according to the condition code \p CC
/// into a simpler EFLAGS value, potentially returning a new \p CC and replacing
/// uses of chain values.
static SDValue combineSetCCEFLAGS(SDValue EFLAGS, X86::CondCode &CC,
SelectionDAG &DAG) {
if (CC == X86::COND_B)
if (SDValue Flags = combineCarryThroughADD(EFLAGS))
return Flags;
if (SDValue R = checkBoolTestSetCCCombine(EFLAGS, CC))
return R;
return combineSetCCAtomicArith(EFLAGS, CC, DAG);
@ -32058,7 +32091,8 @@ static SDValue combineAndMaskToShift(SDNode *N, SelectionDAG &DAG,
return SDValue();
APInt SplatVal;
if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) ||
if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal,
/*AllowShrink*/false) ||
!SplatVal.isMask())
return SDValue();
@ -32642,7 +32676,8 @@ static SDValue detectUSatPattern(SDValue In, EVT VT) {
"Unexpected types for truncate operation");
APInt C;
if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C)) {
if (ISD::isConstantSplatVector(In.getOperand(1).getNode(), C,
/*AllowShrink*/false)) {
// C should be equal to UINT32_MAX / UINT16_MAX / UINT8_MAX according
// the element size of the destination type.
return C.isMask(VT.getScalarSizeInBits()) ? In.getOperand(0) :
@ -34983,27 +35018,13 @@ static SDValue combineSIntToFP(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
// Optimize RES, EFLAGS = X86ISD::ADD LHS, RHS
static SDValue combineX86ADD(SDNode *N, SelectionDAG &DAG,
X86TargetLowering::DAGCombinerInfo &DCI) {
// When legalizing carry, we create carries via add X, -1
// If that comes from an actual carry, via setcc, we use the
// carry directly.
if (isAllOnesConstant(N->getOperand(1)) && N->hasAnyUseOfValue(1)) {
SDValue Carry = N->getOperand(0);
while (Carry.getOpcode() == ISD::TRUNCATE ||
Carry.getOpcode() == ISD::ZERO_EXTEND ||
Carry.getOpcode() == ISD::SIGN_EXTEND ||
Carry.getOpcode() == ISD::ANY_EXTEND ||
(Carry.getOpcode() == ISD::AND &&
isOneConstant(Carry.getOperand(1))))
Carry = Carry.getOperand(0);
if (Carry.getOpcode() == X86ISD::SETCC ||
Carry.getOpcode() == X86ISD::SETCC_CARRY) {
if (Carry.getConstantOperandVal(0) == X86::COND_B)
return DCI.CombineTo(N, SDValue(N, 0), Carry.getOperand(1));
}
static SDValue combineSBB(SDNode *N, SelectionDAG &DAG) {
if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
MVT VT = N->getSimpleValueType(0);
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
return DAG.getNode(X86ISD::SBB, SDLoc(N), VTs,
N->getOperand(0), N->getOperand(1),
Flags);
}
return SDValue();
@ -35032,6 +35053,14 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
return DCI.CombineTo(N, Res1, CarryOut);
}
if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
MVT VT = N->getSimpleValueType(0);
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
return DAG.getNode(X86ISD::ADC, SDLoc(N), VTs,
N->getOperand(0), N->getOperand(1),
Flags);
}
return SDValue();
}
@ -35346,7 +35375,8 @@ static SDValue combineIncDecVector(SDNode *N, SelectionDAG &DAG) {
SDNode *N1 = N->getOperand(1).getNode();
APInt SplatVal;
if (!ISD::isConstantSplatVector(N1, SplatVal) || !SplatVal.isOneValue())
if (!ISD::isConstantSplatVector(N1, SplatVal, /*AllowShrink*/false) ||
!SplatVal.isOneValue())
return SDValue();
SDValue AllOnesVec = getOnesVector(VT, DAG, SDLoc(N));
@ -35670,7 +35700,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case X86ISD::CMOV: return combineCMov(N, DAG, DCI, Subtarget);
case ISD::ADD: return combineAdd(N, DAG, Subtarget);
case ISD::SUB: return combineSub(N, DAG, Subtarget);
case X86ISD::ADD: return combineX86ADD(N, DAG, DCI);
case X86ISD::SBB: return combineSBB(N, DAG);
case X86ISD::ADC: return combineADC(N, DAG, DCI);
case ISD::MUL: return combineMul(N, DAG, DCI, Subtarget);
case ISD::SHL:

View File

@ -3619,8 +3619,8 @@ let Predicates = [HasVLX] in {
def : Pat<(alignedstore256 (v4f64 (extract_subvector
(v8f64 VR512:$src), (iPTR 0))), addr:$dst),
(VMOVAPDZ256mr addr:$dst, (v4f64 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
def : Pat<(alignedstore (v8f32 (extract_subvector
(v16f32 VR512:$src), (iPTR 0))), addr:$dst),
def : Pat<(alignedstore256 (v8f32 (extract_subvector
(v16f32 VR512:$src), (iPTR 0))), addr:$dst),
(VMOVAPSZ256mr addr:$dst, (v8f32 (EXTRACT_SUBREG VR512:$src,sub_ymm)))>;
def : Pat<(alignedstore256 (v4i64 (extract_subvector
(v8i64 VR512:$src), (iPTR 0))), addr:$dst),

File diff suppressed because it is too large Load Diff

View File

@ -161,6 +161,22 @@ int llvm::dlltoolDriverMain(llvm::ArrayRef<const char *> ArgsArr) {
if (Path.empty())
Path = getImplibPath(Def->OutputFile);
if (Machine == IMAGE_FILE_MACHINE_I386 && Args.getLastArg(OPT_k)) {
for (COFFShortExport& E : Def->Exports) {
if (E.isWeak() || (!E.Name.empty() && E.Name[0] == '?'))
continue;
E.SymbolName = E.Name;
// Trim off the trailing decoration. Symbols will always have a
// starting prefix here (either _ for cdecl/stdcall, @ for fastcall
// or ? for C++ functions). (Vectorcall functions also will end up having
// a prefix here, even if they shouldn't.)
E.Name = E.Name.substr(0, E.Name.find('@', 1));
// By making sure E.SymbolName != E.Name for decorated symbols,
// writeImportLibrary writes these symbols with the type
// IMPORT_NAME_UNDECORATE.
}
}
if (writeImportLibrary(Def->OutputFile, Path, Def->Exports, Machine, true))
return 1;
return 0;

View File

@ -12,13 +12,13 @@ def D_long : JoinedOrSeparate<["--"], "dllname">, Alias<D>;
def d: JoinedOrSeparate<["-"], "d">, HelpText<"Input .def File">;
def d_long : JoinedOrSeparate<["--"], "input-def">, Alias<d>;
def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
def k_alias: Flag<["--"], "kill-at">, Alias<k>;
//==============================================================================
// The flags below do nothing. They are defined only for dlltool compatibility.
//==============================================================================
def k: Flag<["-"], "k">, HelpText<"Kill @n Symbol from export">;
def k_alias: Flag<["--"], "kill-at">, Alias<k>;
def S: JoinedOrSeparate<["-"], "S">, HelpText<"Assembler">;
def S_alias: JoinedOrSeparate<["--"], "as">, Alias<S>;

View File

@ -155,8 +155,7 @@ public:
}
bool runOnFunction(Function &F) override {
if (skipFunction(F))
return false;
// Don't skip optnone functions; atomics still need to be lowered.
FunctionAnalysisManager DummyFAM;
auto PA = Impl.run(F, DummyFAM);
return !PA.areAllPreserved();

View File

@ -1941,6 +1941,12 @@ Instruction *ReassociatePass::canonicalizeNegConstExpr(Instruction *I) {
if (!User->isCommutative() && User->getOperand(1) != I)
return nullptr;
// Don't canonicalize x + (-Constant * y) -> x - (Constant * y), if the
// resulting subtract will be broken up later. This can get us into an
// infinite loop during reassociation.
if (UserOpcode == Instruction::FAdd && ShouldBreakUpSubtract(User))
return nullptr;
// Change the sign of the constant.
APFloat Val = CF->getValueAPF();
Val.changeSign();

View File

@ -341,8 +341,9 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
SimplifyInstruction(NewInst, BB->getModule()->getDataLayout())) {
// On the off-chance that this simplifies to an instruction in the old
// function, map it back into the new function.
if (Value *MappedV = VMap.lookup(V))
V = MappedV;
if (NewFunc != OldFunc)
if (Value *MappedV = VMap.lookup(V))
V = MappedV;
if (!NewInst->mayHaveSideEffects()) {
VMap[&*II] = V;

View File

@ -375,6 +375,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief These flags are \c true if a defaulted corresponding special
/// member can't be fully analyzed without performing overload resolution.
/// @{
unsigned NeedOverloadResolutionForCopyConstructor : 1;
unsigned NeedOverloadResolutionForMoveConstructor : 1;
unsigned NeedOverloadResolutionForMoveAssignment : 1;
unsigned NeedOverloadResolutionForDestructor : 1;
@ -383,6 +384,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief These flags are \c true if an implicit defaulted corresponding
/// special member would be defined as deleted.
/// @{
unsigned DefaultedCopyConstructorIsDeleted : 1;
unsigned DefaultedMoveConstructorIsDeleted : 1;
unsigned DefaultedMoveAssignmentIsDeleted : 1;
unsigned DefaultedDestructorIsDeleted : 1;
@ -415,6 +417,12 @@ class CXXRecordDecl : public RecordDecl {
/// constructor.
unsigned HasDefaultedDefaultConstructor : 1;
/// \brief True if this class can be passed in a non-address-preserving
/// fashion (such as in registers) according to the C++ language rules.
/// This does not imply anything about how the ABI in use will actually
/// pass an object of this class.
unsigned CanPassInRegisters : 1;
/// \brief True if a defaulted default constructor for this class would
/// be constexpr.
unsigned DefaultedDefaultConstructorIsConstexpr : 1;
@ -811,18 +819,50 @@ public:
return data().FirstFriend.isValid();
}
/// \brief \c true if a defaulted copy constructor for this class would be
/// deleted.
bool defaultedCopyConstructorIsDeleted() const {
assert((!needsOverloadResolutionForCopyConstructor() ||
(data().DeclaredSpecialMembers & SMF_CopyConstructor)) &&
"this property has not yet been computed by Sema");
return data().DefaultedCopyConstructorIsDeleted;
}
/// \brief \c true if a defaulted move constructor for this class would be
/// deleted.
bool defaultedMoveConstructorIsDeleted() const {
assert((!needsOverloadResolutionForMoveConstructor() ||
(data().DeclaredSpecialMembers & SMF_MoveConstructor)) &&
"this property has not yet been computed by Sema");
return data().DefaultedMoveConstructorIsDeleted;
}
/// \brief \c true if a defaulted destructor for this class would be deleted.
bool defaultedDestructorIsDeleted() const {
return !data().DefaultedDestructorIsDeleted;
}
/// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous copy constructor that is not deleted.
bool hasSimpleCopyConstructor() const {
return !hasUserDeclaredCopyConstructor() &&
!data().DefaultedCopyConstructorIsDeleted;
}
/// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous move constructor that is not deleted.
bool hasSimpleMoveConstructor() const {
return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
!data().DefaultedMoveConstructorIsDeleted;
}
/// \brief \c true if we know for sure that this class has a single,
/// accessible, unambiguous move assignment operator that is not deleted.
bool hasSimpleMoveAssignment() const {
return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
!data().DefaultedMoveAssignmentIsDeleted;
}
/// \brief \c true if we know for sure that this class has an accessible
/// destructor that is not deleted.
bool hasSimpleDestructor() const {
@ -878,7 +918,16 @@ public:
/// \brief Determine whether we need to eagerly declare a defaulted copy
/// constructor for this class.
bool needsOverloadResolutionForCopyConstructor() const {
return data().HasMutableFields;
// C++17 [class.copy.ctor]p6:
// If the class definition declares a move constructor or move assignment
// operator, the implicitly declared copy constructor is defined as
// deleted.
// In MSVC mode, sometimes a declared move assignment does not delete an
// implicit copy constructor, so defer this choice to Sema.
if (data().UserDeclaredSpecialMembers &
(SMF_MoveConstructor | SMF_MoveAssignment))
return true;
return data().NeedOverloadResolutionForCopyConstructor;
}
/// \brief Determine whether an implicit copy constructor for this type
@ -919,7 +968,16 @@ public:
needsImplicitMoveConstructor();
}
/// \brief Set that we attempted to declare an implicitly move
/// \brief Set that we attempted to declare an implicit copy
/// constructor, but overload resolution failed so we deleted it.
void setImplicitCopyConstructorIsDeleted() {
assert((data().DefaultedCopyConstructorIsDeleted ||
needsOverloadResolutionForCopyConstructor()) &&
"Copy constructor should not be deleted");
data().DefaultedCopyConstructorIsDeleted = true;
}
/// \brief Set that we attempted to declare an implicit move
/// constructor, but overload resolution failed so we deleted it.
void setImplicitMoveConstructorIsDeleted() {
assert((data().DefaultedMoveConstructorIsDeleted ||
@ -1316,6 +1374,18 @@ public:
return data().HasIrrelevantDestructor;
}
/// \brief Determine whether this class has at least one trivial, non-deleted
/// copy or move constructor.
bool canPassInRegisters() const {
return data().CanPassInRegisters;
}
/// \brief Set that we can pass this RecordDecl in registers.
// FIXME: This should be set as part of completeDefinition.
void setCanPassInRegisters(bool CanPass) {
data().CanPassInRegisters = CanPass;
}
/// \brief Determine whether this class has a non-literal or/ volatile type
/// non-static data member or base class.
bool hasNonLiteralTypeFieldsOrBases() const {
@ -1958,7 +2028,10 @@ public:
/// \brief Returns the type of the \c this pointer.
///
/// Should only be called for instance (i.e., non-static) methods.
/// Should only be called for instance (i.e., non-static) methods. Note
/// that for the call operator of a lambda closure type, this returns the
/// desugared 'this' type (a pointer to the closure type), not the captured
/// 'this' type.
QualType getThisType(ASTContext &C) const;
unsigned getTypeQualifiers() const {

View File

@ -694,6 +694,9 @@ def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>;
def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,
Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">;
def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Group>,
Flags<[CC1Option]>, MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
HelpText<"Attempt to match the ABI of Clang <version>">;
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">;

View File

@ -120,6 +120,10 @@ CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
///< enabled.
/// A version of Clang that we should attempt to be ABI-compatible with.
ENUM_CODEGENOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest)
VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.

View File

@ -69,6 +69,23 @@ public:
LocalExecTLSModel
};
/// Clang versions with different platform ABI conformance.
enum class ClangABI {
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
/// (SVN r257626). This causes <1 x long long> to be passed in an
/// integer register instead of an SSE register on x64_64.
Ver3_8,
/// Attempt to be ABI-compatible with code generated by Clang 4.0.x
/// (SVN r291814). This causes move operations to be ignored when
/// determining whether a class type can be passed or returned directly.
Ver4,
/// Conform to the underlying platform's C and C++ ABIs as closely
/// as we can.
Latest
};
enum StructReturnConventionKind {
SRCK_Default, // No special option was passed.
SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return).

View File

@ -1048,10 +1048,6 @@ public:
/// which implicitly adds the builtin defines etc.
void EnterMainSourceFile();
/// \brief After parser warm-up, initialize the conditional stack from
/// the preamble.
void replayPreambleConditionalStack();
/// \brief Inform the preprocessor callbacks that processing is complete.
void EndSourceFile();
@ -2025,6 +2021,10 @@ public:
}
private:
/// \brief After processing predefined file, initialize the conditional stack from
/// the preamble.
void replayPreambleConditionalStack();
// Macro handling.
void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef);
void HandleUndefDirective();

View File

@ -956,12 +956,16 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.HasUninitializedFields = FromData.HasUninitializedFields;
ToData.HasInheritedConstructor = FromData.HasInheritedConstructor;
ToData.HasInheritedAssignment = FromData.HasInheritedAssignment;
ToData.NeedOverloadResolutionForCopyConstructor
= FromData.NeedOverloadResolutionForCopyConstructor;
ToData.NeedOverloadResolutionForMoveConstructor
= FromData.NeedOverloadResolutionForMoveConstructor;
ToData.NeedOverloadResolutionForMoveAssignment
= FromData.NeedOverloadResolutionForMoveAssignment;
ToData.NeedOverloadResolutionForDestructor
= FromData.NeedOverloadResolutionForDestructor;
ToData.DefaultedCopyConstructorIsDeleted
= FromData.DefaultedCopyConstructorIsDeleted;
ToData.DefaultedMoveConstructorIsDeleted
= FromData.DefaultedMoveConstructorIsDeleted;
ToData.DefaultedMoveAssignmentIsDeleted
@ -973,6 +977,7 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
= FromData.HasConstexprNonCopyMoveConstructor;
ToData.HasDefaultedDefaultConstructor
= FromData.HasDefaultedDefaultConstructor;
ToData.CanPassInRegisters = FromData.CanPassInRegisters;
ToData.DefaultedDefaultConstructorIsConstexpr
= FromData.DefaultedDefaultConstructorIsConstexpr;
ToData.HasConstexprDefaultConstructor

View File

@ -55,15 +55,18 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
HasOnlyCMembers(true), HasInClassInitializer(false),
HasUninitializedReferenceMember(false), HasUninitializedFields(false),
HasInheritedConstructor(false), HasInheritedAssignment(false),
NeedOverloadResolutionForCopyConstructor(false),
NeedOverloadResolutionForMoveConstructor(false),
NeedOverloadResolutionForMoveAssignment(false),
NeedOverloadResolutionForDestructor(false),
DefaultedCopyConstructorIsDeleted(false),
DefaultedMoveConstructorIsDeleted(false),
DefaultedMoveAssignmentIsDeleted(false),
DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true),
HasConstexprNonCopyMoveConstructor(false),
HasDefaultedDefaultConstructor(false),
CanPassInRegisters(true),
DefaultedDefaultConstructorIsConstexpr(true),
HasConstexprDefaultConstructor(false),
HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
@ -352,8 +355,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
setHasVolatileMember(true);
// Keep track of the presence of mutable fields.
if (BaseClassDecl->hasMutableFields())
if (BaseClassDecl->hasMutableFields()) {
data().HasMutableFields = true;
data().NeedOverloadResolutionForCopyConstructor = true;
}
if (BaseClassDecl->hasUninitializedReferenceMember())
data().HasUninitializedReferenceMember = true;
@ -406,6 +411,8 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
// -- a direct or virtual base class B that cannot be copied/moved [...]
// -- a non-static data member of class type M (or array thereof)
// that cannot be copied or moved [...]
if (!Subobj->hasSimpleCopyConstructor())
data().NeedOverloadResolutionForCopyConstructor = true;
if (!Subobj->hasSimpleMoveConstructor())
data().NeedOverloadResolutionForMoveConstructor = true;
@ -426,6 +433,7 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
// -- any non-static data member has a type with a destructor
// that is deleted or inaccessible from the defaulted [ctor or dtor].
if (!Subobj->hasSimpleDestructor()) {
data().NeedOverloadResolutionForCopyConstructor = true;
data().NeedOverloadResolutionForMoveConstructor = true;
data().NeedOverloadResolutionForDestructor = true;
}
@ -711,8 +719,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
data().IsStandardLayout = false;
// Keep track of the presence of mutable fields.
if (Field->isMutable())
if (Field->isMutable()) {
data().HasMutableFields = true;
data().NeedOverloadResolutionForCopyConstructor = true;
}
// C++11 [class.union]p8, DR1460:
// If X is a union, a non-static data member of X that is not an anonymous
@ -756,6 +766,12 @@ void CXXRecordDecl::addedMember(Decl *D) {
// A standard-layout class is a class that:
// -- has no non-static data members of type [...] reference,
data().IsStandardLayout = false;
// C++1z [class.copy.ctor]p10:
// A defaulted copy constructor for a class X is defined as deleted if X has:
// -- a non-static data member of rvalue reference type
if (T->isRValueReferenceType())
data().DefaultedCopyConstructorIsDeleted = true;
}
if (!Field->hasInClassInitializer() && !Field->isMutable()) {
@ -809,6 +825,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
// We may need to perform overload resolution to determine whether a
// field can be moved if it's const or volatile qualified.
if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
// We need to care about 'const' for the copy constructor because an
// implicit copy constructor might be declared with a non-const
// parameter.
data().NeedOverloadResolutionForCopyConstructor = true;
data().NeedOverloadResolutionForMoveConstructor = true;
data().NeedOverloadResolutionForMoveAssignment = true;
}
@ -819,6 +839,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
// -- X is a union-like class that has a variant member with a
// non-trivial [corresponding special member]
if (isUnion()) {
if (FieldRec->hasNonTrivialCopyConstructor())
data().DefaultedCopyConstructorIsDeleted = true;
if (FieldRec->hasNonTrivialMoveConstructor())
data().DefaultedMoveConstructorIsDeleted = true;
if (FieldRec->hasNonTrivialMoveAssignment())
@ -830,6 +852,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
// For an anonymous union member, our overload resolution will perform
// overload resolution for its members.
if (Field->isAnonymousStructOrUnion()) {
data().NeedOverloadResolutionForCopyConstructor |=
FieldRec->data().NeedOverloadResolutionForCopyConstructor;
data().NeedOverloadResolutionForMoveConstructor |=
FieldRec->data().NeedOverloadResolutionForMoveConstructor;
data().NeedOverloadResolutionForMoveAssignment |=
@ -915,8 +939,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
}
// Keep track of the presence of mutable fields.
if (FieldRec->hasMutableFields())
if (FieldRec->hasMutableFields()) {
data().HasMutableFields = true;
data().NeedOverloadResolutionForCopyConstructor = true;
}
// C++11 [class.copy]p13:
// If the implicitly-defined constructor would satisfy the
@ -1450,7 +1476,7 @@ void CXXRecordDecl::completeDefinition() {
void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
RecordDecl::completeDefinition();
// If the class may be abstract (but hasn't been marked as such), check for
// any pure final overriders.
if (mayBeAbstract()) {

View File

@ -36,7 +36,7 @@ std::string getClangRepositoryPath() {
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/branches/release_50/lib/Basic/Version.cpp $");
StringRef SVNRepository("$URL: https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_500/final/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));

View File

@ -24,6 +24,7 @@ namespace llvm {
namespace clang {
class ASTContext;
class CodeGenOptions;
class TargetInfo;
namespace CodeGen {
@ -68,6 +69,7 @@ namespace swiftcall {
llvm::LLVMContext &getVMContext() const;
const llvm::DataLayout &getDataLayout() const;
const TargetInfo &getTarget() const;
const CodeGenOptions &getCodeGenOpts() const;
/// Return the calling convention to use for system runtime
/// functions.

View File

@ -30,38 +30,9 @@ void CGCXXABI::ErrorUnsupportedABI(CodeGenFunction &CGF, StringRef S) {
}
bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
// If RD has a non-trivial move or copy constructor, we cannot copy the
// argument.
if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialMoveConstructor())
return false;
// If RD has a non-trivial destructor, we cannot copy the argument.
if (RD->hasNonTrivialDestructor())
return false;
// We can only copy the argument if there exists at least one trivial,
// non-deleted copy or move constructor.
// FIXME: This assumes that all lazily declared copy and move constructors are
// not deleted. This assumption might not be true in some corner cases.
bool CopyDeleted = false;
bool MoveDeleted = false;
for (const CXXConstructorDecl *CD : RD->ctors()) {
if (CD->isCopyConstructor() || CD->isMoveConstructor()) {
assert(CD->isTrivial());
// We had at least one undeleted trivial copy or move ctor. Return
// directly.
if (!CD->isDeleted())
return true;
if (CD->isCopyConstructor())
CopyDeleted = true;
else
MoveDeleted = true;
}
}
// If all trivial copy and move constructors are deleted, we cannot copy the
// argument.
return !(CopyDeleted && MoveDeleted);
return RD->canPassInRegisters();
}
llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {

View File

@ -3260,7 +3260,7 @@ void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
llvm::DISubprogram *SP = nullptr;
if (FI != SPCache.end())
SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
if (!SP)
if (!SP || !SP->isDefinition())
SP = getFunctionStub(GD);
FnBeginRegionCount.push_back(LexicalBlockStack.size());
LexicalBlockStack.emplace_back(SP);

View File

@ -22,6 +22,7 @@
#include "CodeGenPGO.h"
#include "TargetInfo.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/StmtCXX.h"
@ -983,11 +984,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
}
// Check the 'this' pointer once per function, if it's available.
if (CXXThisValue) {
if (CXXABIThisValue) {
SanitizerSet SkippedChecks;
SkippedChecks.set(SanitizerKind::ObjectSize, true);
QualType ThisTy = MD->getThisType(getContext());
EmitTypeCheck(TCK_Load, Loc, CXXThisValue, ThisTy,
// If this is the call operator of a lambda with no capture-default, it
// may have a static invoker function, which may call this operator with
// a null 'this' pointer.
if (isLambdaCallOperator(MD) &&
cast<CXXRecordDecl>(MD->getParent())->getLambdaCaptureDefault() ==
LCD_None)
SkippedChecks.set(SanitizerKind::Null, true);
EmitTypeCheck(isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall
: TCK_MemberCall,
Loc, CXXABIThisValue, ThisTy,
getContext().getTypeAlignInChars(ThisTy->getPointeeType()),
SkippedChecks);
}

View File

@ -44,6 +44,10 @@ CodeGenTypes::~CodeGenTypes() {
delete &*I++;
}
const CodeGenOptions &CodeGenTypes::getCodeGenOpts() const {
return CGM.getCodeGenOpts();
}
void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
llvm::StructType *Ty,
StringRef suffix) {

View File

@ -178,6 +178,7 @@ public:
const TargetInfo &getTarget() const { return Target; }
CGCXXABI &getCXXABI() const { return TheCXXABI; }
llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }
const CodeGenOptions &getCodeGenOpts() const;
/// ConvertType - Convert type T into a llvm::Type.
llvm::Type *ConvertType(QualType T);

View File

@ -62,12 +62,20 @@ public:
bool classifyReturnType(CGFunctionInfo &FI) const override;
bool passClassIndirect(const CXXRecordDecl *RD) const {
// Clang <= 4 used the pre-C++11 rule, which ignores move operations.
// The PS4 platform ABI follows the behavior of Clang 3.2.
if (CGM.getCodeGenOpts().getClangABICompat() <=
CodeGenOptions::ClangABI::Ver4 ||
CGM.getTriple().getOS() == llvm::Triple::PS4)
return RD->hasNonTrivialDestructor() ||
RD->hasNonTrivialCopyConstructor();
return !canCopyArgument(RD);
}
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
// Structures with either a non-trivial destructor or a non-trivial
// copy constructor are always indirect.
// FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
// special members.
if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
// If C++ prohibits us from making a copy, pass by address.
if (passClassIndirect(RD))
return RAA_Indirect;
return RAA_Default;
}
@ -998,10 +1006,8 @@ bool ItaniumCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
if (!RD)
return false;
// Return indirectly if we have a non-trivial copy ctor or non-trivial dtor.
// FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
// special members.
if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) {
// If C++ prohibits us from making a copy, return by address.
if (passClassIndirect(RD)) {
auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
return true;

View File

@ -819,46 +819,44 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
return RAA_Default;
case llvm::Triple::x86_64:
// Win64 passes objects with non-trivial copy ctors indirectly.
if (RD->hasNonTrivialCopyConstructor())
return RAA_Indirect;
// If an object has a destructor, we'd really like to pass it indirectly
// If a class has a destructor, we'd really like to pass it indirectly
// because it allows us to elide copies. Unfortunately, MSVC makes that
// impossible for small types, which it will pass in a single register or
// stack slot. Most objects with dtors are large-ish, so handle that early.
// We can't call out all large objects as being indirect because there are
// multiple x64 calling conventions and the C++ ABI code shouldn't dictate
// how we pass large POD types.
//
// Note: This permits small classes with nontrivial destructors to be
// passed in registers, which is non-conforming.
if (RD->hasNonTrivialDestructor() &&
getContext().getTypeSize(RD->getTypeForDecl()) > 64)
return RAA_Indirect;
// If this is true, the implicit copy constructor that Sema would have
// created would not be deleted. FIXME: We should provide a more direct way
// for CodeGen to ask whether the constructor was deleted.
if (!RD->hasUserDeclaredCopyConstructor() &&
!RD->hasUserDeclaredMoveConstructor() &&
!RD->needsOverloadResolutionForMoveConstructor() &&
!RD->hasUserDeclaredMoveAssignment() &&
!RD->needsOverloadResolutionForMoveAssignment())
return RAA_Default;
// Otherwise, Sema should have created an implicit copy constructor if
// needed.
assert(!RD->needsImplicitCopyConstructor());
// We have to make sure the trivial copy constructor isn't deleted.
for (const CXXConstructorDecl *CD : RD->ctors()) {
if (CD->isCopyConstructor()) {
assert(CD->isTrivial());
// We had at least one undeleted trivial copy ctor. Return directly.
if (!CD->isDeleted())
return RAA_Default;
// If a class has at least one non-deleted, trivial copy constructor, it
// is passed according to the C ABI. Otherwise, it is passed indirectly.
//
// Note: This permits classes with non-trivial copy or move ctors to be
// passed in registers, so long as they *also* have a trivial copy ctor,
// which is non-conforming.
if (RD->needsImplicitCopyConstructor()) {
// If the copy ctor has not yet been declared, we can read its triviality
// off the AST.
if (!RD->defaultedCopyConstructorIsDeleted() &&
RD->hasTrivialCopyConstructor())
return RAA_Default;
} else {
// Otherwise, we need to find the copy constructor(s) and ask.
for (const CXXConstructorDecl *CD : RD->ctors()) {
if (CD->isCopyConstructor()) {
// We had at least one nondeleted trivial copy ctor. Return directly.
if (!CD->isDeleted() && CD->isTrivial())
return RAA_Default;
}
}
}
// The trivial copy constructor was deleted. Return indirectly.
// We have no trivial, non-deleted copy constructor.
return RAA_Indirect;
}

View File

@ -183,7 +183,11 @@ const TargetInfo &ABIInfo::getTarget() const {
return CGT.getTarget();
}
bool ABIInfo:: isAndroid() const { return getTarget().getTriple().isAndroid(); }
const CodeGenOptions &ABIInfo::getCodeGenOpts() const {
return CGT.getCodeGenOpts();
}
bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }
bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
return false;
@ -2095,9 +2099,14 @@ class X86_64ABIInfo : public SwiftABIInfo {
return !getTarget().getTriple().isOSDarwin();
}
/// GCC classifies <1 x long long> as SSE but compatibility with older clang
// compilers require us to classify it as INTEGER.
/// GCC classifies <1 x long long> as SSE but some platform ABIs choose to
/// classify it as INTEGER (for compatibility with older clang compilers).
bool classifyIntegerMMXAsSSE() const {
// Clang <= 3.8 did not do this.
if (getCodeGenOpts().getClangABICompat() <=
CodeGenOptions::ClangABI::Ver3_8)
return false;
const llvm::Triple &Triple = getTarget().getTriple();
if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::PS4)
return false;

View File

@ -2855,6 +2855,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
if (auto *ABICompatArg = Args.getLastArg(options::OPT_fclang_abi_compat_EQ))
ABICompatArg->render(Args, CmdArgs);
// Add runtime flag for PS4 when PGO or Coverage are enabled.
if (getToolChain().getTriple().isPS4CPU())
PS4cpu::addProfileRTArgs(getToolChain(), Args, CmdArgs);

View File

@ -1837,7 +1837,12 @@ Darwin::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
}
bool MachO::IsUnwindTablesDefault(const ArgList &Args) const {
return !UseSjLjExceptions(Args);
// Unwind tables are not emitted if -fno-exceptions is supplied (except when
// targeting x86_64).
return getArch() == llvm::Triple::x86_64 ||
(!UseSjLjExceptions(Args) &&
Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions,
true));
}
bool MachO::UseDwarfDebugFlags() const {

View File

@ -76,7 +76,7 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName,
// Check various environment variables to try and find a toolchain.
static bool findVCToolChainViaEnvironment(std::string &Path,
bool &IsVS2017OrNewer) {
MSVCToolChain::ToolsetLayout &VSLayout) {
// These variables are typically set by vcvarsall.bat
// when launching a developer command prompt.
if (llvm::Optional<std::string> VCToolsInstallDir =
@ -84,7 +84,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
// This is only set by newer Visual Studios, and it leads straight to
// the toolchain directory.
Path = std::move(*VCToolsInstallDir);
IsVS2017OrNewer = true;
VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
return true;
}
if (llvm::Optional<std::string> VCInstallDir =
@ -94,7 +94,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
// so this check has to appear second.
// In older Visual Studios, the VC directory is the toolchain.
Path = std::move(*VCInstallDir);
IsVS2017OrNewer = false;
VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
return true;
}
@ -134,9 +134,16 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
}
if (IsBin) {
llvm::StringRef ParentPath = llvm::sys::path::parent_path(TestPath);
if (llvm::sys::path::filename(ParentPath) == "VC") {
llvm::StringRef ParentFilename = llvm::sys::path::filename(ParentPath);
if (ParentFilename == "VC") {
Path = ParentPath;
IsVS2017OrNewer = false;
VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
return true;
}
if (ParentFilename == "x86ret" || ParentFilename == "x86chk"
|| ParentFilename == "amd64ret" || ParentFilename == "amd64chk") {
Path = ParentPath;
VSLayout = MSVCToolChain::ToolsetLayout::DevDivInternal;
return true;
}
@ -165,7 +172,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
ToolChainPath = llvm::sys::path::parent_path(ToolChainPath);
Path = ToolChainPath;
IsVS2017OrNewer = true;
VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
return true;
}
@ -181,7 +188,7 @@ static bool findVCToolChainViaEnvironment(std::string &Path,
// This is the preferred way to discover new Visual Studios, as they're no
// longer listed in the registry.
static bool findVCToolChainViaSetupConfig(std::string &Path,
bool &IsVS2017OrNewer) {
MSVCToolChain::ToolsetLayout &VSLayout) {
#if !defined(USE_MSVC_SETUP_API)
return false;
#else
@ -263,7 +270,7 @@ static bool findVCToolChainViaSetupConfig(std::string &Path,
return false;
Path = ToolchainPath.str();
IsVS2017OrNewer = true;
VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer;
return true;
#endif
}
@ -272,7 +279,7 @@ static bool findVCToolChainViaSetupConfig(std::string &Path,
// a toolchain path. VS2017 and newer don't get added to the registry.
// So if we find something here, we know that it's an older version.
static bool findVCToolChainViaRegistry(std::string &Path,
bool &IsVS2017OrNewer) {
MSVCToolChain::ToolsetLayout &VSLayout) {
std::string VSInstallPath;
if (getSystemRegistryString(R"(SOFTWARE\Microsoft\VisualStudio\$VERSION)",
"InstallDir", VSInstallPath, nullptr) ||
@ -284,7 +291,7 @@ static bool findVCToolChainViaRegistry(std::string &Path,
llvm::sys::path::append(VCPath, "VC");
Path = VCPath.str();
IsVS2017OrNewer = false;
VSLayout = MSVCToolChain::ToolsetLayout::OlderVS;
return true;
}
}
@ -475,6 +482,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// native target bin directory.
// e.g. when compiling for x86 on an x64 host, PATH should start with:
// /bin/HostX64/x86;/bin/HostX64/x64
// This doesn't attempt to handle ToolsetLayout::DevDivInternal.
if (TC.getIsVS2017OrNewer() &&
llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
@ -677,9 +685,9 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
// what they want to use.
// Failing that, just try to find the newest Visual Studio version we can
// and use its default VC toolchain.
findVCToolChainViaEnvironment(VCToolChainPath, IsVS2017OrNewer) ||
findVCToolChainViaSetupConfig(VCToolChainPath, IsVS2017OrNewer) ||
findVCToolChainViaRegistry(VCToolChainPath, IsVS2017OrNewer);
findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) ||
findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) ||
findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
}
Tool *MSVCToolChain::buildLinker() const {
@ -766,6 +774,21 @@ static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
}
}
// Similar to the above function, but for DevDiv internal builds.
static const char *llvmArchToDevDivInternalArch(llvm::Triple::ArchType Arch) {
using ArchType = llvm::Triple::ArchType;
switch (Arch) {
case ArchType::x86:
return "i386";
case ArchType::x86_64:
return "amd64";
case ArchType::arm:
return "arm";
default:
return "";
}
}
// Get the path to a specific subdirectory in the current toolchain for
// a given target architecture.
// VS2017 changed the VC toolchain layout, so this should be used instead
@ -773,26 +796,40 @@ static const char *llvmArchToLegacyVCArch(llvm::Triple::ArchType Arch) {
std::string
MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type,
llvm::Triple::ArchType TargetArch) const {
const char *SubdirName;
const char *IncludeName;
switch (VSLayout) {
case ToolsetLayout::OlderVS:
SubdirName = llvmArchToLegacyVCArch(TargetArch);
IncludeName = "include";
break;
case ToolsetLayout::VS2017OrNewer:
SubdirName = llvmArchToWindowsSDKArch(TargetArch);
IncludeName = "include";
break;
case ToolsetLayout::DevDivInternal:
SubdirName = llvmArchToDevDivInternalArch(TargetArch);
IncludeName = "inc";
break;
}
llvm::SmallString<256> Path(VCToolChainPath);
switch (Type) {
case SubDirectoryType::Bin:
if (IsVS2017OrNewer) {
bool HostIsX64 =
if (VSLayout == ToolsetLayout::VS2017OrNewer) {
const bool HostIsX64 =
llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit();
llvm::sys::path::append(Path, "bin", (HostIsX64 ? "HostX64" : "HostX86"),
llvmArchToWindowsSDKArch(TargetArch));
} else {
llvm::sys::path::append(Path, "bin", llvmArchToLegacyVCArch(TargetArch));
const char *const HostName = HostIsX64 ? "HostX64" : "HostX86";
llvm::sys::path::append(Path, "bin", HostName, SubdirName);
} else { // OlderVS or DevDivInternal
llvm::sys::path::append(Path, "bin", SubdirName);
}
break;
case SubDirectoryType::Include:
llvm::sys::path::append(Path, "include");
llvm::sys::path::append(Path, IncludeName);
break;
case SubDirectoryType::Lib:
llvm::sys::path::append(
Path, "lib", IsVS2017OrNewer ? llvmArchToWindowsSDKArch(TargetArch)
: llvmArchToLegacyVCArch(TargetArch));
llvm::sys::path::append(Path, "lib", SubdirName);
break;
}
return Path.str();

View File

@ -92,7 +92,12 @@ public:
return getSubDirectoryPath(Type, getArch());
}
bool getIsVS2017OrNewer() const { return IsVS2017OrNewer; }
enum class ToolsetLayout {
OlderVS,
VS2017OrNewer,
DevDivInternal,
};
bool getIsVS2017OrNewer() const { return VSLayout == ToolsetLayout::VS2017OrNewer; }
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
@ -130,7 +135,7 @@ protected:
Tool *buildAssembler() const override;
private:
std::string VCToolChainPath;
bool IsVS2017OrNewer = false;
ToolsetLayout VSLayout = ToolsetLayout::OlderVS;
CudaInstallationDetector CudaInstallation;
};

View File

@ -246,12 +246,12 @@ AlignTokenSequence(unsigned Start, unsigned End, unsigned Column, F &&Matches,
for (unsigned i = Start; i != End; ++i) {
if (ScopeStack.size() != 0 &&
Changes[i].nestingAndIndentLevel() <
Changes[ScopeStack.back()].nestingAndIndentLevel())
Changes[i].indentAndNestingLevel() <
Changes[ScopeStack.back()].indentAndNestingLevel())
ScopeStack.pop_back();
if (i != Start && Changes[i].nestingAndIndentLevel() >
Changes[i - 1].nestingAndIndentLevel())
if (i != Start && Changes[i].indentAndNestingLevel() >
Changes[i - 1].indentAndNestingLevel())
ScopeStack.push_back(i);
bool InsideNestedScope = ScopeStack.size() != 0;
@ -327,8 +327,8 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
// Measure the scope level (i.e. depth of (), [], {}) of the first token, and
// abort when we hit any token in a higher scope than the starting one.
auto NestingAndIndentLevel = StartAt < Changes.size()
? Changes[StartAt].nestingAndIndentLevel()
auto IndentAndNestingLevel = StartAt < Changes.size()
? Changes[StartAt].indentAndNestingLevel()
: std::pair<unsigned, unsigned>(0, 0);
// Keep track of the number of commas before the matching tokens, we will only
@ -359,7 +359,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
unsigned i = StartAt;
for (unsigned e = Changes.size(); i != e; ++i) {
if (Changes[i].nestingAndIndentLevel() < NestingAndIndentLevel)
if (Changes[i].indentAndNestingLevel() < IndentAndNestingLevel)
break;
if (Changes[i].NewlinesBefore != 0) {
@ -375,7 +375,7 @@ static unsigned AlignTokens(const FormatStyle &Style, F &&Matches,
if (Changes[i].Tok->is(tok::comma)) {
++CommasBeforeMatch;
} else if (Changes[i].nestingAndIndentLevel() > NestingAndIndentLevel) {
} else if (Changes[i].indentAndNestingLevel() > IndentAndNestingLevel) {
// Call AlignTokens recursively, skipping over this scope block.
unsigned StoppedAt = AlignTokens(Style, Matches, Changes, i);
i = StoppedAt - 1;
@ -472,9 +472,14 @@ void WhitespaceManager::alignTrailingComments() {
continue;
unsigned ChangeMinColumn = Changes[i].StartOfTokenColumn;
unsigned ChangeMaxColumn = Style.ColumnLimit >= Changes[i].TokenLength
? Style.ColumnLimit - Changes[i].TokenLength
: ChangeMinColumn;
unsigned ChangeMaxColumn;
if (Style.ColumnLimit == 0)
ChangeMaxColumn = UINT_MAX;
else if (Style.ColumnLimit >= Changes[i].TokenLength)
ChangeMaxColumn = Style.ColumnLimit - Changes[i].TokenLength;
else
ChangeMaxColumn = ChangeMinColumn;
// If we don't create a replacement for this change, we have to consider
// it to be immovable.

View File

@ -154,12 +154,11 @@ public:
const Change *StartOfBlockComment;
int IndentationOffset;
// A combination of nesting level and indent level, which are used in
// A combination of indent level and nesting level, which are used in
// tandem to compute lexical scope, for the purposes of deciding
// when to stop consecutive alignment runs.
std::pair<unsigned, unsigned>
nestingAndIndentLevel() const {
return std::make_pair(Tok->NestingLevel, Tok->IndentLevel);
std::pair<unsigned, unsigned> indentAndNestingLevel() const {
return std::make_pair(Tok->IndentLevel, Tok->NestingLevel);
}
};

View File

@ -573,6 +573,33 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
if (!Opts.ProfileInstrumentUsePath.empty())
setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
Opts.setClangABICompat(CodeGenOptions::ClangABI::Latest);
StringRef Ver = A->getValue();
std::pair<StringRef, StringRef> VerParts = Ver.split('.');
unsigned Major, Minor = 0;
// Check the version number is valid: either 3.x (0 <= x <= 9) or
// y or y.0 (4 <= y <= current version).
if (!VerParts.first.startswith("0") &&
!VerParts.first.getAsInteger(10, Major) &&
3 <= Major && Major <= CLANG_VERSION_MAJOR &&
(Major == 3 ? VerParts.second.size() == 1 &&
!VerParts.second.getAsInteger(10, Minor)
: VerParts.first.size() == Ver.size() ||
VerParts.second == "0")) {
// Got a valid version number.
if (Major == 3 && Minor <= 8)
Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver3_8);
else if (Major <= 4)
Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver4);
} else if (Ver != "latest") {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
}
}
Opts.CoverageMapping =
Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);

View File

@ -76,13 +76,7 @@ typedef intptr_t _sleb128_t;
typedef uintptr_t _uleb128_t;
struct _Unwind_Context;
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
struct _Unwind_Control_Block;
typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */
#else
struct _Unwind_Exception;
typedef struct _Unwind_Exception _Unwind_Exception;
#endif
typedef enum {
_URC_NO_REASON = 0,
#if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \
@ -115,42 +109,8 @@ typedef enum {
} _Unwind_Action;
typedef void (*_Unwind_Exception_Cleanup_Fn)(_Unwind_Reason_Code,
_Unwind_Exception *);
struct _Unwind_Exception *);
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
typedef struct _Unwind_Control_Block _Unwind_Control_Block;
typedef uint32_t _Unwind_EHT_Header;
struct _Unwind_Control_Block {
uint64_t exception_class;
void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *);
/* unwinder cache (private fields for the unwinder's use) */
struct {
uint32_t reserved1; /* forced unwind stop function, 0 if not forced */
uint32_t reserved2; /* personality routine */
uint32_t reserved3; /* callsite */
uint32_t reserved4; /* forced unwind stop argument */
uint32_t reserved5;
} unwinder_cache;
/* propagation barrier cache (valid after phase 1) */
struct {
uint32_t sp;
uint32_t bitpattern[5];
} barrier_cache;
/* cleanup cache (preserved over cleanup) */
struct {
uint32_t bitpattern[4];
} cleanup_cache;
/* personality cache (for personality's benefit) */
struct {
uint32_t fnstart; /* function start address */
_Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */
uint32_t additional; /* additional data */
uint32_t reserved1;
} pr_cache;
long long int : 0; /* force alignment of next item to 8-byte boundary */
};
#else
struct _Unwind_Exception {
_Unwind_Exception_Class exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup;
@ -160,24 +120,23 @@ struct _Unwind_Exception {
* aligned". GCC has interpreted this to mean "use the maximum useful
* alignment for the target"; so do we. */
} __attribute__((__aligned__));
#endif
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)(int, _Unwind_Action,
_Unwind_Exception_Class,
_Unwind_Exception *,
struct _Unwind_Exception *,
struct _Unwind_Context *,
void *);
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(int, _Unwind_Action,
_Unwind_Exception_Class,
_Unwind_Exception *,
struct _Unwind_Context *);
typedef _Unwind_Reason_Code (*_Unwind_Personality_Fn)(
int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *,
struct _Unwind_Context *);
typedef _Unwind_Personality_Fn __personality_routine;
typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *,
void *);
#if defined(__arm__) && !(defined(__USING_SJLJ_EXCEPTIONS__) || defined(__ARM_DWARF_EH___))
#if defined(__arm__) && !defined(__APPLE__)
typedef enum {
_UVRSC_CORE = 0, /* integer register */
_UVRSC_VFP = 1, /* vfp */
@ -199,12 +158,14 @@ typedef enum {
_UVRSR_FAILED = 2
} _Unwind_VRS_Result;
#if !defined(__USING_SJLJ_EXCEPTIONS__) && !defined(__ARM_DWARF_EH__)
typedef uint32_t _Unwind_State;
#define _US_VIRTUAL_UNWIND_FRAME ((_Unwind_State)0)
#define _US_UNWIND_FRAME_STARTING ((_Unwind_State)1)
#define _US_UNWIND_FRAME_RESUME ((_Unwind_State)2)
#define _US_ACTION_MASK ((_Unwind_State)3)
#define _US_FORCE_UNWIND ((_Unwind_State)8)
#endif
_Unwind_VRS_Result _Unwind_VRS_Get(struct _Unwind_Context *__context,
_Unwind_VRS_RegClass __regclass,
@ -263,12 +224,13 @@ _Unwind_Ptr _Unwind_GetRegionStart(struct _Unwind_Context *);
/* DWARF EH functions; currently not available on Darwin/ARM */
#if !defined(__APPLE__) || !defined(__arm__)
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *);
_Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Exception *, _Unwind_Stop_Fn,
void *);
void _Unwind_DeleteException(_Unwind_Exception *);
void _Unwind_Resume(_Unwind_Exception *);
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception *);
_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_ForcedUnwind(struct _Unwind_Exception *,
_Unwind_Stop_Fn, void *);
void _Unwind_DeleteException(struct _Unwind_Exception *);
void _Unwind_Resume(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *);
#endif
@ -279,11 +241,11 @@ typedef struct SjLj_Function_Context *_Unwind_FunctionContext_t;
void _Unwind_SjLj_Register(_Unwind_FunctionContext_t);
void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t);
_Unwind_Reason_Code _Unwind_SjLj_RaiseException(_Unwind_Exception *);
_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *,
_Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *,
_Unwind_Stop_Fn, void *);
void _Unwind_SjLj_Resume(_Unwind_Exception *);
_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *);
void _Unwind_SjLj_Resume(struct _Unwind_Exception *);
_Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *);
void *_Unwind_FindEnclosingFunction(void *);

View File

@ -458,10 +458,16 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
SourceMgr.setNumCreatedFIDsForFileID(CurPPLexer->getFileID(), NumFIDs);
}
bool ExitedFromPredefinesFile = false;
FileID ExitedFID;
if (Callbacks && !isEndOfMacro && CurPPLexer)
if (!isEndOfMacro && CurPPLexer) {
ExitedFID = CurPPLexer->getFileID();
assert(PredefinesFileID.isValid() &&
"HandleEndOfFile is called before PredefinesFileId is set");
ExitedFromPredefinesFile = (PredefinesFileID == ExitedFID);
}
if (LeavingSubmodule) {
// We're done with this submodule.
Module *M = LeaveSubmodule(/*ForPragma*/false);
@ -489,6 +495,11 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
PPCallbacks::ExitFile, FileType, ExitedFID);
}
// Restore conditional stack from the preamble right after exiting from the
// predefines file.
if (ExitedFromPredefinesFile)
replayPreambleConditionalStack();
// Client should lex another token unless we generated an EOM.
return LeavingSubmodule;
}

View File

@ -540,6 +540,8 @@ void Preprocessor::EnterMainSourceFile() {
void Preprocessor::replayPreambleConditionalStack() {
// Restore the conditional stack from the preamble, if there is one.
if (PreambleConditionalStack.isReplaying()) {
assert(CurPPLexer &&
"CurPPLexer is null when calling replayPreambleConditionalStack.");
CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack());
PreambleConditionalStack.doneReplaying();
}

View File

@ -516,8 +516,6 @@ void Parser::Initialize() {
// Prime the lexer look-ahead.
ConsumeToken();
PP.replayPreambleConditionalStack();
}
void Parser::LateTemplateParserCleanupCallback(void *P) {

View File

@ -5726,6 +5726,53 @@ static void DefineImplicitSpecialMember(Sema &S, CXXMethodDecl *MD,
}
}
/// Determine whether a type is permitted to be passed or returned in
/// registers, per C++ [class.temporary]p3.
static bool computeCanPassInRegisters(Sema &S, CXXRecordDecl *D) {
if (D->isDependentType() || D->isInvalidDecl())
return false;
// Per C++ [class.temporary]p3, the relevant condition is:
// each copy constructor, move constructor, and destructor of X is
// either trivial or deleted, and X has at least one non-deleted copy
// or move constructor
bool HasNonDeletedCopyOrMove = false;
if (D->needsImplicitCopyConstructor() &&
!D->defaultedCopyConstructorIsDeleted()) {
if (!D->hasTrivialCopyConstructor())
return false;
HasNonDeletedCopyOrMove = true;
}
if (S.getLangOpts().CPlusPlus11 && D->needsImplicitMoveConstructor() &&
!D->defaultedMoveConstructorIsDeleted()) {
if (!D->hasTrivialMoveConstructor())
return false;
HasNonDeletedCopyOrMove = true;
}
if (D->needsImplicitDestructor() && !D->defaultedDestructorIsDeleted() &&
!D->hasTrivialDestructor())
return false;
for (const CXXMethodDecl *MD : D->methods()) {
if (MD->isDeleted())
continue;
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
if (CD && CD->isCopyOrMoveConstructor())
HasNonDeletedCopyOrMove = true;
else if (!isa<CXXDestructorDecl>(MD))
continue;
if (!MD->isTrivial())
return false;
}
return HasNonDeletedCopyOrMove;
}
/// \brief Perform semantic checks on a class definition that has been
/// completing, introducing implicitly-declared members, checking for
/// abstract types, etc.
@ -5870,6 +5917,8 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
}
checkClassLevelDLLAttribute(Record);
Record->setCanPassInRegisters(computeCanPassInRegisters(*this, Record));
}
/// Look up the special member function that would be called by a special
@ -7496,8 +7545,7 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
FieldCollector->getCurNumFields()), LBrac, RBrac, AttrList);
CheckCompletedCXXClass(
dyn_cast_or_null<CXXRecordDecl>(TagDecl));
CheckCompletedCXXClass(dyn_cast_or_null<CXXRecordDecl>(TagDecl));
}
/// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared
@ -11929,8 +11977,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
Scope *S = getScopeForContext(ClassDecl);
CheckImplicitSpecialMemberDeclaration(S, CopyConstructor);
if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor))
if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) {
ClassDecl->setImplicitCopyConstructorIsDeleted();
SetDeclDeleted(CopyConstructor, ClassLoc);
}
if (S)
PushOnScopeChains(CopyConstructor, S, false);

View File

@ -872,7 +872,7 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
}
QualType RHSType = S.Context.getCanonicalType(Property->getType());
unsigned OriginalAttributes = Property->getPropertyAttributes();
unsigned OriginalAttributes = Property->getPropertyAttributesAsWritten();
enum MismatchKind {
IncompatibleType = 0,
HasNoExpectedAttribute,
@ -890,7 +890,7 @@ SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
SmallVector<MismatchingProperty, 4> Mismatches;
for (ObjCPropertyDecl *Prop : Properties) {
// Verify the property attributes.
unsigned Attr = Prop->getPropertyAttributes();
unsigned Attr = Prop->getPropertyAttributesAsWritten();
if (Attr != OriginalAttributes) {
auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute

View File

@ -1559,9 +1559,11 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasUninitializedFields = Record.readInt();
Data.HasInheritedConstructor = Record.readInt();
Data.HasInheritedAssignment = Record.readInt();
Data.NeedOverloadResolutionForCopyConstructor = Record.readInt();
Data.NeedOverloadResolutionForMoveConstructor = Record.readInt();
Data.NeedOverloadResolutionForMoveAssignment = Record.readInt();
Data.NeedOverloadResolutionForDestructor = Record.readInt();
Data.DefaultedCopyConstructorIsDeleted = Record.readInt();
Data.DefaultedMoveConstructorIsDeleted = Record.readInt();
Data.DefaultedMoveAssignmentIsDeleted = Record.readInt();
Data.DefaultedDestructorIsDeleted = Record.readInt();
@ -1570,6 +1572,7 @@ void ASTDeclReader::ReadCXXDefinitionData(
Data.HasIrrelevantDestructor = Record.readInt();
Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
Data.HasDefaultedDefaultConstructor = Record.readInt();
Data.CanPassInRegisters = Record.readInt();
Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
Data.HasConstexprDefaultConstructor = Record.readInt();
Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
@ -1697,9 +1700,11 @@ void ASTDeclReader::MergeDefinitionData(
MATCH_FIELD(HasUninitializedFields)
MATCH_FIELD(HasInheritedConstructor)
MATCH_FIELD(HasInheritedAssignment)
MATCH_FIELD(NeedOverloadResolutionForCopyConstructor)
MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
MATCH_FIELD(NeedOverloadResolutionForDestructor)
MATCH_FIELD(DefaultedCopyConstructorIsDeleted)
MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
MATCH_FIELD(DefaultedDestructorIsDeleted)
@ -1708,6 +1713,7 @@ void ASTDeclReader::MergeDefinitionData(
MATCH_FIELD(HasIrrelevantDestructor)
OR_FIELD(HasConstexprNonCopyMoveConstructor)
OR_FIELD(HasDefaultedDefaultConstructor)
MATCH_FIELD(CanPassInRegisters)
MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
OR_FIELD(HasConstexprDefaultConstructor)
MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)

Some files were not shown because too many files have changed in this diff Show More