Merge "Nullability check for resolv module"
diff --git a/libc/Android.bp b/libc/Android.bp
index 1e65fea..c101f45 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -672,7 +672,6 @@
},
riscv64: {
srcs: [
- "arch-riscv64/string/memset_chk.c",
"upstream-freebsd/lib/libc/string/memcmp.c",
"upstream-freebsd/lib/libc/string/memcpy.c",
"upstream-freebsd/lib/libc/string/memmove.c",
@@ -825,6 +824,11 @@
"arch-arm64/string/__memset_chk.S",
],
},
+ riscv64: {
+ srcs: [
+ "arch-riscv64/string/__memset_chk.S",
+ ],
+ },
},
}
@@ -1088,7 +1092,6 @@
"bionic/ffs.cpp",
"bionic/fgetxattr.cpp",
"bionic/flistxattr.cpp",
- "bionic/flockfile.cpp",
"bionic/fpclassify.cpp",
"bionic/fsetxattr.cpp",
"bionic/ftruncate.cpp",
diff --git a/libc/arch-common/bionic/crtend.S b/libc/arch-common/bionic/crtend.S
index 9676db8..49c729f 100644
--- a/libc/arch-common/bionic/crtend.S
+++ b/libc/arch-common/bionic/crtend.S
@@ -46,11 +46,10 @@
ASM_ALIGN_TO_PTR_SIZE
ASM_PTR_SIZE(0)
-#if defined(__linux__) && defined(__ELF__)
- .section .note.GNU-stack,"",%progbits
-#endif
+ .section .note.GNU-stack, "", %progbits
+
#if !defined(__arm__)
- .section .eh_frame,"a",@progbits
+ .section .eh_frame, "a", @progbits
.balign 4
.type __FRAME_END__, @object
.size __FRAME_END__, 4
diff --git a/libc/arch-common/bionic/crtend_so.S b/libc/arch-common/bionic/crtend_so.S
index 5875acb..bc4bfb6 100644
--- a/libc/arch-common/bionic/crtend_so.S
+++ b/libc/arch-common/bionic/crtend_so.S
@@ -32,11 +32,10 @@
__bionic_asm_custom_note_gnu_section()
#endif
-#if defined(__linux__) && defined(__ELF__)
- .section .note.GNU-stack,"",%progbits
-#endif
+ .section .note.GNU-stack, "", %progbits
+
#if !defined(__arm__)
- .section .eh_frame,"a",@progbits
+ .section .eh_frame, "a", @progbits
.balign 4
.type __FRAME_END__, @object
.size __FRAME_END__, 4
diff --git a/libc/arch-riscv64/bionic/__bionic_clone.S b/libc/arch-riscv64/bionic/__bionic_clone.S
index d535095..2827857 100644
--- a/libc/arch-riscv64/bionic/__bionic_clone.S
+++ b/libc/arch-riscv64/bionic/__bionic_clone.S
@@ -51,7 +51,7 @@
.L_bc_failure:
# Set errno if something went wrong.
neg a0, a0
- j __set_errno_internal
+ tail __set_errno_internal
.L_bc_child:
# We're in the child now. Set the end of the frame record chain.
@@ -62,5 +62,5 @@
ld a0, 0(sp)
ld a1, 8(sp)
addi sp, sp, 16
- j __start_thread
+ tail __start_thread
END(__bionic_clone)
diff --git a/libc/arch-riscv64/bionic/syscall.S b/libc/arch-riscv64/bionic/syscall.S
index 7b9d3ca..1a6e60a 100644
--- a/libc/arch-riscv64/bionic/syscall.S
+++ b/libc/arch-riscv64/bionic/syscall.S
@@ -49,5 +49,5 @@
ret
1:
neg a0, a0
- j __set_errno_internal
+ tail __set_errno_internal
END(syscall)
diff --git a/libc/arch-riscv64/bionic/vfork.S b/libc/arch-riscv64/bionic/vfork.S
index 0eff9e9..29ab405 100644
--- a/libc/arch-riscv64/bionic/vfork.S
+++ b/libc/arch-riscv64/bionic/vfork.S
@@ -62,5 +62,5 @@
.L_failure:
neg a0, a0
- j __set_errno_internal
+ tail __set_errno_internal
END(vfork)
diff --git a/libc/arch-riscv64/string/__memset_chk.S b/libc/arch-riscv64/string/__memset_chk.S
new file mode 100644
index 0000000..a5562cb
--- /dev/null
+++ b/libc/arch-riscv64/string/__memset_chk.S
@@ -0,0 +1,10 @@
+#include <private/bionic_asm.h>
+
+ENTRY(__memset_chk)
+ bleu a2, a3, 1f
+ call __memset_chk_fail
+
+1:
+ tail memset
+END(__memset_chk)
+
diff --git a/libc/arch-riscv64/string/memset_chk.c b/libc/arch-riscv64/string/memset_chk.c
deleted file mode 100644
index bdd15a5..0000000
--- a/libc/arch-riscv64/string/memset_chk.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <stdint.h>
-
-extern void* memset(void*, int, size_t);
-extern void* __memset_chk_fail(void*, int, size_t, size_t);
-
-void* __memset_chk(void* dst, int c, size_t n, size_t dst_len) {
- if (dst_len < n) __memset_chk_fail(dst, c, n, dst_len);
- return memset(dst, c, n);
-}
diff --git a/libc/bionic/flockfile.cpp b/libc/bionic/flockfile.cpp
deleted file mode 100644
index db53828..0000000
--- a/libc/bionic/flockfile.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * 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 COPYRIGHT HOLDERS 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
- * COPYRIGHT OWNER 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.
- */
-
-#include <errno.h>
-#include <stdio.h>
-
-#include "local.h"
-
-// We can't use the OpenBSD implementation which uses kernel-specific
-// APIs not available on Linux. Instead we use a pthread_mutex_t within
-// struct __sfileext (see fileext.h).
-
-void flockfile(FILE* fp) {
- if (fp != nullptr) {
- pthread_mutex_lock(&_FLOCK(fp));
- }
-}
-
-int ftrylockfile(FILE* fp) {
- // The specification for ftrylockfile() says it returns 0 on success,
- // or non-zero on error. So return an errno code directly on error.
- if (fp == nullptr) {
- return EINVAL;
- }
-
- return pthread_mutex_trylock(&_FLOCK(fp));
-}
-
-void funlockfile(FILE* fp) {
- if (fp != nullptr) {
- pthread_mutex_unlock(&_FLOCK(fp));
- }
-}
diff --git a/libc/include/assert.h b/libc/include/assert.h
index 79e7b86..8db970b 100644
--- a/libc/include/assert.h
+++ b/libc/include/assert.h
@@ -75,12 +75,12 @@
* __assert() is called by assert() on failure. Most users want assert()
* instead, but this can be useful for reporting other failures.
*/
-void __assert(const char* __file, int __line, const char* __msg) __noreturn;
+void __assert(const char* _Nonnull __file, int __line, const char* _Nonnull __msg) __noreturn;
/**
* __assert2() is called by assert() on failure. Most users want assert()
* instead, but this can be useful for reporting other failures.
*/
-void __assert2(const char* __file, int __line, const char* __function, const char* __msg) __noreturn;
+void __assert2(const char* _Nonnull __file, int __line, const char* _Nonnull __function, const char* _Nonnull __msg) __noreturn;
__END_DECLS
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index 68d8bc9..a8066a9 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -36,21 +36,23 @@
typedef struct {
/* Pathname of shared object that contains address. */
- const char* dli_fname;
+ const char* _Nullable dli_fname;
/* Address at which shared object is loaded. */
- void* dli_fbase;
+ void* _Nullable dli_fbase;
/* Name of nearest symbol with address lower than addr. */
- const char* dli_sname;
+ const char* _Nullable dli_sname;
/* Exact address of symbol named in dli_sname. */
- void* dli_saddr;
+ void* _Nullable dli_saddr;
} Dl_info;
-void* dlopen(const char* __filename, int __flag);
-int dlclose(void* __handle);
-char* dlerror(void);
-void* dlsym(void* __handle, const char* __symbol);
-void* dlvsym(void* __handle, const char* __symbol, const char* __version) __INTRODUCED_IN(24);
-int dladdr(const void* __addr, Dl_info* __info);
+void* _Nullable dlopen(const char* _Nullable __filename, int __flag);
+int dlclose(void* _Nonnull __handle);
+char* _Nullable dlerror(void);
+/* (RTLD_DEFAULT is null for LP64, but -1 for LP32) */
+void* _Nullable dlsym(void* __BIONIC_COMPLICATED_NULLNESS __handle, const char* _Nullable __symbol);
+/* (RTLD_DEFAULT is null for LP64, but -1 for LP32) */
+void* _Nullable dlvsym(void* __BIONIC_COMPLICATED_NULLNESS __handle, const char* _Nullable __symbol, const char* _Nullable __version) __INTRODUCED_IN(24);
+int dladdr(const void* _Nonnull __addr, Dl_info* _Nonnull __info);
#define RTLD_LOCAL 0
#define RTLD_LAZY 0x00001
diff --git a/libc/include/grp.h b/libc/include/grp.h
index 9d67adf..2451db5 100644
--- a/libc/include/grp.h
+++ b/libc/include/grp.h
@@ -39,26 +39,26 @@
#include <sys/types.h>
struct group {
- char* gr_name; /* group name */
- char* gr_passwd; /* group password */
+ char* _Nullable gr_name; /* group name */
+ char* _Nullable gr_passwd; /* group password */
gid_t gr_gid; /* group id */
- char** gr_mem; /* group members */
+ char* _Nullable * _Nullable gr_mem; /* group members */
};
__BEGIN_DECLS
-struct group* getgrgid(gid_t __gid);
-struct group* getgrnam(const char* __name);
+struct group* _Nullable getgrgid(gid_t __gid);
+struct group* _Nullable getgrnam(const char* _Nonnull __name);
/* Note: Android has thousands and thousands of ids to iterate through. */
-struct group* getgrent(void) __INTRODUCED_IN(26);
+struct group* _Nullable getgrent(void) __INTRODUCED_IN(26);
void setgrent(void) __INTRODUCED_IN(26);
void endgrent(void) __INTRODUCED_IN(26);
-int getgrgid_r(gid_t __gid, struct group* __group, char* __buf, size_t __n, struct group** __result) __INTRODUCED_IN(24);
-int getgrnam_r(const char* __name, struct group* __group, char* __buf, size_t __n, struct group** __result) __INTRODUCED_IN(24);
-int getgrouplist(const char* __user, gid_t __group, gid_t* __groups, int* __group_count);
-int initgroups(const char* __user, gid_t __group);
+int getgrgid_r(gid_t __gid, struct group* __BIONIC_COMPLICATED_NULLNESS __group, char* _Nonnull __buf, size_t __n, struct group* _Nullable * _Nonnull __result) __INTRODUCED_IN(24);
+int getgrnam_r(const char* _Nonnull __name, struct group* __BIONIC_COMPLICATED_NULLNESS __group, char* _Nonnull __buf, size_t __n, struct group* _Nullable *_Nonnull __result) __INTRODUCED_IN(24);
+int getgrouplist(const char* _Nonnull __user, gid_t __group, gid_t* __BIONIC_COMPLICATED_NULLNESS __groups, int* _Nonnull __group_count);
+int initgroups(const char* _Nonnull __user, gid_t __group);
__END_DECLS
diff --git a/libc/include/ifaddrs.h b/libc/include/ifaddrs.h
index 9eaabbd..7c0dcbf 100644
--- a/libc/include/ifaddrs.h
+++ b/libc/include/ifaddrs.h
@@ -44,26 +44,26 @@
*/
struct ifaddrs {
/** Pointer to the next element in the linked list. */
- struct ifaddrs* ifa_next;
+ struct ifaddrs* _Nullable ifa_next;
/** Interface name. */
- char* ifa_name;
+ char* _Nullable ifa_name;
/** Interface flags (like `SIOCGIFFLAGS`). */
unsigned int ifa_flags;
/** Interface address. */
- struct sockaddr* ifa_addr;
+ struct sockaddr* _Nullable ifa_addr;
/** Interface netmask. */
- struct sockaddr* ifa_netmask;
+ struct sockaddr* _Nullable ifa_netmask;
union {
/** Interface broadcast address (if IFF_BROADCAST is set). */
- struct sockaddr* ifu_broadaddr;
+ struct sockaddr* _Nullable ifu_broadaddr;
/** Interface destination address (if IFF_POINTOPOINT is set). */
- struct sockaddr* ifu_dstaddr;
+ struct sockaddr* _Nullable ifu_dstaddr;
} ifa_ifu;
/** Unused. */
- void* ifa_data;
+ void* _Nullable ifa_data;
};
/** Synonym for `ifa_ifu.ifu_broadaddr` in `struct ifaddrs`. */
@@ -80,7 +80,7 @@
*
* Available since API level 24.
*/
-int getifaddrs(struct ifaddrs** __list_ptr) __INTRODUCED_IN(24);
+int getifaddrs(struct ifaddrs* _Nullable * _Nonnull __list_ptr) __INTRODUCED_IN(24);
/**
* [freeifaddrs(3)](http://man7.org/linux/man-pages/man3/freeifaddrs.3.html) frees a linked list
@@ -88,6 +88,6 @@
*
* Available since API level 24.
*/
-void freeifaddrs(struct ifaddrs* __ptr) __INTRODUCED_IN(24);
+void freeifaddrs(struct ifaddrs* _Nullable __ptr) __INTRODUCED_IN(24);
__END_DECLS
diff --git a/libc/include/inttypes.h b/libc/include/inttypes.h
index f8b7f7d..76aee38 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -85,6 +85,42 @@
#define PRIiPTR __PRI_PTR_prefix"i" /* intptr_t */
/* fprintf macros for unsigned integers */
+#define PRIb8 "b" /* int8_t */
+#define PRIb16 "b" /* int16_t */
+#define PRIb32 "b" /* int32_t */
+#define PRIb64 __PRI_64_prefix"b" /* int64_t */
+
+#define PRIbLEAST8 "b" /* int_least8_t */
+#define PRIbLEAST16 "b" /* int_least16_t */
+#define PRIbLEAST32 "b" /* int_least32_t */
+#define PRIbLEAST64 __PRI_64_prefix"b" /* int_least64_t */
+
+#define PRIbFAST8 "b" /* int_fast8_t */
+#define PRIbFAST16 __PRI_FAST_prefix"b" /* int_fast16_t */
+#define PRIbFAST32 __PRI_FAST_prefix"b" /* int_fast32_t */
+#define PRIbFAST64 __PRI_64_prefix"b" /* int_fast64_t */
+
+#define PRIbMAX "jb" /* intmax_t */
+#define PRIbPTR __PRI_PTR_prefix"b" /* intptr_t */
+
+#define PRIB8 "B" /* int8_t */
+#define PRIB16 "B" /* int16_t */
+#define PRIB32 "B" /* int32_t */
+#define PRIB64 __PRI_64_prefix"B" /* int64_t */
+
+#define PRIBLEAST8 "B" /* int_least8_t */
+#define PRIBLEAST16 "B" /* int_least16_t */
+#define PRIBLEAST32 "B" /* int_least32_t */
+#define PRIBLEAST64 __PRI_64_prefix"B" /* int_least64_t */
+
+#define PRIBFAST8 "B" /* int_fast8_t */
+#define PRIBFAST16 __PRI_FAST_prefix"B" /* int_fast16_t */
+#define PRIBFAST32 __PRI_FAST_prefix"B" /* int_fast32_t */
+#define PRIBFAST64 __PRI_64_prefix"B" /* int_fast64_t */
+
+#define PRIBMAX "jB" /* intmax_t */
+#define PRIBPTR __PRI_PTR_prefix"B" /* intptr_t */
+
#define PRIo8 "o" /* int8_t */
#define PRIo16 "o" /* int16_t */
#define PRIo32 "o" /* int32_t */
@@ -195,6 +231,42 @@
#define SCNiPTR __PRI_PTR_prefix"i" /* intptr_t */
/* fscanf macros for unsigned integers */
+#define SCNb8 "hhb" /* uint8_t */
+#define SCNb16 "hb" /* uint16_t */
+#define SCNb32 "b" /* uint32_t */
+#define SCNb64 __PRI_64_prefix"b" /* uint64_t */
+
+#define SCNbLEAST8 "hhb" /* uint_least8_t */
+#define SCNbLEAST16 "hb" /* uint_least16_t */
+#define SCNbLEAST32 "b" /* uint_least32_t */
+#define SCNbLEAST64 __PRI_64_prefix"b" /* uint_least64_t */
+
+#define SCNbFAST8 "hhb" /* uint_fast8_t */
+#define SCNbFAST16 __PRI_FAST_prefix"b" /* uint_fast16_t */
+#define SCNbFAST32 __PRI_FAST_prefix"b" /* uint_fast32_t */
+#define SCNbFAST64 __PRI_64_prefix"b" /* uint_fast64_t */
+
+#define SCNbMAX "jb" /* uintmax_t */
+#define SCNbPTR __PRI_PTR_prefix"b" /* uintptr_t */
+
+#define SCNB8 "hhB" /* uint8_t */
+#define SCNB16 "hB" /* uint16_t */
+#define SCNB32 "B" /* uint32_t */
+#define SCNB64 __PRI_64_prefix"B" /* uint64_t */
+
+#define SCNBLEAST8 "hhB" /* uint_least8_t */
+#define SCNBLEAST16 "hB" /* uint_least16_t */
+#define SCNBLEAST32 "B" /* uint_least32_t */
+#define SCNBLEAST64 __PRI_64_prefix"B" /* uint_least64_t */
+
+#define SCNBFAST8 "hhB" /* uint_fast8_t */
+#define SCNBFAST16 __PRI_FAST_prefix"B" /* uint_fast16_t */
+#define SCNBFAST32 __PRI_FAST_prefix"B" /* uint_fast32_t */
+#define SCNBFAST64 __PRI_64_prefix"B" /* uint_fast64_t */
+
+#define SCNBMAX "jB" /* uintmax_t */
+#define SCNBPTR __PRI_PTR_prefix"B" /* uintptr_t */
+
#define SCNo8 "hho" /* uint8_t */
#define SCNo16 "ho" /* uint16_t */
#define SCNo32 "o" /* uint32_t */
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index f4b2911..e748faa 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -59,9 +59,9 @@
typedef struct __sFILE FILE;
#if __ANDROID_API__ >= 23
-extern FILE* stdin __INTRODUCED_IN(23);
-extern FILE* stdout __INTRODUCED_IN(23);
-extern FILE* stderr __INTRODUCED_IN(23);
+extern FILE* _Nonnull stdin __INTRODUCED_IN(23);
+extern FILE* _Nonnull stdout __INTRODUCED_IN(23);
+extern FILE* _Nonnull stderr __INTRODUCED_IN(23);
/* C99 and earlier plus current C++ standards say these must be macros. */
#define stdin stdin
@@ -103,54 +103,54 @@
#define L_tmpnam 4096
#define TMP_MAX 308915776
-void clearerr(FILE* __fp);
-int fclose(FILE* __fp);
-int feof(FILE* __fp);
-int ferror(FILE* __fp);
-int fflush(FILE* __fp);
-int fgetc(FILE* __fp);
-char* fgets(char* __buf, int __size, FILE* __fp);
-int fprintf(FILE* __fp , const char* __fmt, ...) __printflike(2, 3);
-int fputc(int __ch, FILE* __fp);
-int fputs(const char* __s, FILE* __fp);
-size_t fread(void* __buf, size_t __size, size_t __count, FILE* __fp);
-int fscanf(FILE* __fp, const char* __fmt, ...) __scanflike(2, 3);
-size_t fwrite(const void* __buf, size_t __size, size_t __count, FILE* __fp);
-int getc(FILE* __fp);
+void clearerr(FILE* _Nonnull __fp);
+int fclose(FILE* _Nonnull __fp);
+int feof(FILE* _Nonnull __fp);
+int ferror(FILE* _Nonnull __fp);
+int fflush(FILE* _Nullable __fp);
+int fgetc(FILE* _Nonnull __fp);
+char* _Nullable fgets(char* _Nonnull __buf, int __size, FILE* _Nonnull __fp);
+int fprintf(FILE* _Nonnull __fp , const char* _Nonnull __fmt, ...) __printflike(2, 3);
+int fputc(int __ch, FILE* _Nonnull __fp);
+int fputs(const char* _Nonnull __s, FILE* _Nonnull __fp);
+size_t fread(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
+int fscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, ...) __scanflike(2, 3);
+size_t fwrite(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp);
+int getc(FILE* _Nonnull __fp);
int getchar(void);
-ssize_t getdelim(char** __line_ptr, size_t* __line_length_ptr, int __delimiter, FILE* __fp) __INTRODUCED_IN(18);
-ssize_t getline(char** __line_ptr, size_t* __line_length_ptr, FILE* __fp) __INTRODUCED_IN(18);
+ssize_t getdelim(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, int __delimiter, FILE* _Nonnull __fp) __INTRODUCED_IN(18);
+ssize_t getline(char* _Nullable * _Nonnull __line_ptr, size_t* _Nonnull __line_length_ptr, FILE* _Nonnull __fp) __INTRODUCED_IN(18);
-void perror(const char* __msg);
-int printf(const char* __fmt, ...) __printflike(1, 2);
-int putc(int __ch, FILE* __fp);
+void perror(const char* _Nullable __msg);
+int printf(const char* _Nonnull __fmt, ...) __printflike(1, 2);
+int putc(int __ch, FILE* _Nonnull __fp);
int putchar(int __ch);
-int puts(const char* __s);
-int remove(const char* __path);
-void rewind(FILE* __fp);
-int scanf(const char* __fmt, ...) __scanflike(1, 2);
-void setbuf(FILE* __fp, char* __buf);
-int setvbuf(FILE* __fp, char* __buf, int __mode, size_t __size);
-int sscanf(const char* __s, const char* __fmt, ...) __scanflike(2, 3);
-int ungetc(int __ch, FILE* __fp);
-int vfprintf(FILE* __fp, const char* __fmt, va_list __args) __printflike(2, 0);
-int vprintf(const char* __fp, va_list __args) __printflike(1, 0);
+int puts(const char* _Nonnull __s);
+int remove(const char* _Nonnull __path);
+void rewind(FILE* _Nonnull __fp);
+int scanf(const char* _Nonnull __fmt, ...) __scanflike(1, 2);
+void setbuf(FILE* _Nonnull __fp, char* _Nullable __buf);
+int setvbuf(FILE* _Nonnull __fp, char* _Nullable __buf, int __mode, size_t __size);
+int sscanf(const char* _Nonnull __s, const char* _Nonnull __fmt, ...) __scanflike(2, 3);
+int ungetc(int __ch, FILE* _Nonnull __fp);
+int vfprintf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0);
+int vprintf(const char* _Nonnull __fp, va_list __args) __printflike(1, 0);
-int dprintf(int __fd, const char* __fmt, ...) __printflike(2, 3) __INTRODUCED_IN(21);
-int vdprintf(int __fd, const char* __fmt, va_list __args) __printflike(2, 0) __INTRODUCED_IN(21);
+int dprintf(int __fd, const char* _Nonnull __fmt, ...) __printflike(2, 3) __INTRODUCED_IN(21);
+int vdprintf(int __fd, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0) __INTRODUCED_IN(21);
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ < 201112L) || \
(defined(__cplusplus) && __cplusplus <= 201103L)
-char* gets(char* __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
+char* _Nullable gets(char* _Nonnull __buf) __attribute__((deprecated("gets is unsafe, use fgets instead")));
#endif
-int sprintf(char* __s, const char* __fmt, ...)
+int sprintf(char* _Nonnull __s, const char* _Nonnull __fmt, ...)
__printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf");
-int vsprintf(char* __s, const char* __fmt, va_list __args)
+int vsprintf(char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args)
__printflike(2, 0) __warnattr_strict("vsprintf is often misused; please use vsnprintf");
-char* tmpnam(char* __s)
+char* _Nullable tmpnam(char* _Nullable __s)
__warnattr("tmpnam is unsafe, use mkstemp or tmpfile instead");
#define P_tmpdir "/tmp/" /* deprecated */
-char* tempnam(const char* __dir, const char* __prefix)
+char* _Nullable tempnam(const char* _Nullable __dir, const char* _Nullable __prefix)
__warnattr("tempnam is unsafe, use mkstemp or tmpfile instead");
/**
@@ -159,7 +159,7 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int rename(const char* __old_path, const char* __new_path);
+int rename(const char* _Nonnull __old_path, const char* _Nonnull __new_path);
/**
* [renameat(2)](http://man7.org/linux/man-pages/man2/renameat.2.html) changes
@@ -167,7 +167,7 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int renameat(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path);
+int renameat(int __old_dir_fd, const char* _Nonnull __old_path, int __new_dir_fd, const char* _Nonnull __new_path);
#if defined(__USE_GNU)
@@ -196,108 +196,111 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int renameat2(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path, unsigned __flags) __INTRODUCED_IN(30);
+int renameat2(int __old_dir_fd, const char* _Nonnull __old_path, int __new_dir_fd, const char* _Nonnull __new_path, unsigned __flags) __INTRODUCED_IN(30);
#endif
-int fseek(FILE* __fp, long __offset, int __whence);
-long ftell(FILE* __fp);
+int fseek(FILE* _Nonnull __fp, long __offset, int __whence);
+long ftell(FILE* _Nonnull __fp);
/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
#if defined(__USE_FILE_OFFSET64)
-int fgetpos(FILE* __fp, fpos_t* __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
-int fsetpos(FILE* __fp, const fpos_t* __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
-int fseeko(FILE* __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24);
-off_t ftello(FILE* __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
+int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos) __RENAME(fgetpos64) __INTRODUCED_IN(24);
+int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos) __RENAME(fsetpos64) __INTRODUCED_IN(24);
+int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence) __RENAME(fseeko64) __INTRODUCED_IN(24);
+off_t ftello(FILE* _Nonnull __fp) __RENAME(ftello64) __INTRODUCED_IN(24);
# if defined(__USE_BSD)
-FILE* funopen(const void* __cookie,
- int (*__read_fn)(void*, char*, int),
- int (*__write_fn)(void*, const char*, int),
- fpos_t (*__seek_fn)(void*, fpos_t, int),
- int (*__close_fn)(void*)) __RENAME(funopen64) __INTRODUCED_IN(24);
+/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
+FILE* _Nullable funopen(const void* _Nullable __cookie,
+ int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
+ int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
+ fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
+ int (* _Nullable __close_fn)(void* _Nonnull)) __RENAME(funopen64) __INTRODUCED_IN(24);
# endif
#else
-int fgetpos(FILE* __fp, fpos_t* __pos);
-int fsetpos(FILE* __fp, const fpos_t* __pos);
-int fseeko(FILE* __fp, off_t __offset, int __whence);
-off_t ftello(FILE* __fp);
+int fgetpos(FILE* _Nonnull __fp, fpos_t* _Nonnull __pos);
+int fsetpos(FILE* _Nonnull __fp, const fpos_t* _Nonnull __pos);
+int fseeko(FILE* _Nonnull __fp, off_t __offset, int __whence);
+off_t ftello(FILE* _Nonnull __fp);
# if defined(__USE_BSD)
-FILE* funopen(const void* __cookie,
- int (*__read_fn)(void*, char*, int),
- int (*__write_fn)(void*, const char*, int),
- fpos_t (*__seek_fn)(void*, fpos_t, int),
- int (*__close_fn)(void*));
+/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
+FILE* _Nullable funopen(const void* _Nullable __cookie,
+ int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
+ int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
+ fpos_t (* _Nullable __seek_fn)(void* _Nonnull, fpos_t, int),
+ int (* _Nullable __close_fn)(void* _Nonnull));
# endif
#endif
-int fgetpos64(FILE* __fp, fpos64_t* __pos) __INTRODUCED_IN(24);
-int fsetpos64(FILE* __fp, const fpos64_t* __pos) __INTRODUCED_IN(24);
-int fseeko64(FILE* __fp, off64_t __offset, int __whence) __INTRODUCED_IN(24);
-off64_t ftello64(FILE* __fp) __INTRODUCED_IN(24);
+int fgetpos64(FILE* _Nonnull __fp, fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
+int fsetpos64(FILE* _Nonnull __fp, const fpos64_t* _Nonnull __pos) __INTRODUCED_IN(24);
+int fseeko64(FILE* _Nonnull __fp, off64_t __offset, int __whence) __INTRODUCED_IN(24);
+off64_t ftello64(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
#if defined(__USE_BSD)
-FILE* funopen64(const void* __cookie,
- int (*__read_fn)(void*, char*, int),
- int (*__write_fn)(void*, const char*, int),
- fpos64_t (*__seek_fn)(void*, fpos64_t, int),
- int (*__close_fn)(void*)) __INTRODUCED_IN(24);
+/* If __read_fn and __write_fn are both nullptr, it will cause EINVAL */
+FILE* _Nullable funopen64(const void* _Nullable __cookie,
+ int (* __BIONIC_COMPLICATED_NULLNESS __read_fn)(void* _Nonnull, char* _Nonnull, int),
+ int (* __BIONIC_COMPLICATED_NULLNESS __write_fn)(void* _Nonnull, const char* _Nonnull, int),
+ fpos64_t (* _Nullable __seek_fn)(void* _Nonnull, fpos64_t, int),
+ int (* _Nullable __close_fn)(void* _Nonnull)) __INTRODUCED_IN(24);
#endif
-FILE* fopen(const char* __path, const char* __mode);
-FILE* fopen64(const char* __path, const char* __mode) __INTRODUCED_IN(24);
-FILE* freopen(const char* __path, const char* __mode, FILE* __fp);
-FILE* freopen64(const char* __path, const char* __mode, FILE* __fp) __INTRODUCED_IN(24);
-FILE* tmpfile(void);
-FILE* tmpfile64(void) __INTRODUCED_IN(24);
+FILE* _Nullable fopen(const char* _Nonnull __path, const char* _Nonnull __mode);
+FILE* _Nullable fopen64(const char* _Nonnull __path, const char* _Nonnull __mode) __INTRODUCED_IN(24);
+FILE* _Nullable freopen(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp);
+FILE* _Nullable freopen64(const char* _Nullable __path, const char* _Nonnull __mode, FILE* _Nonnull __fp) __INTRODUCED_IN(24);
+FILE* _Nullable tmpfile(void);
+FILE* _Nullable tmpfile64(void) __INTRODUCED_IN(24);
-int snprintf(char* __buf, size_t __size, const char* __fmt, ...) __printflike(3, 4);
-int vfscanf(FILE* __fp, const char* __fmt, va_list __args) __scanflike(2, 0);
-int vscanf(const char* __fmt , va_list __args) __scanflike(1, 0);
-int vsnprintf(char* __buf, size_t __size, const char* __fmt, va_list __args) __printflike(3, 0);
-int vsscanf(const char* __s, const char* __fmt, va_list __args) __scanflike(2, 0);
+int snprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, ...) __printflike(3, 4);
+int vfscanf(FILE* _Nonnull __fp, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
+int vscanf(const char* _Nonnull __fmt , va_list __args) __scanflike(1, 0);
+int vsnprintf(char* _Nullable __buf, size_t __size, const char* _Nonnull __fmt, va_list __args) __printflike(3, 0);
+int vsscanf(const char* _Nonnull __s, const char* _Nonnull __fmt, va_list __args) __scanflike(2, 0);
#define L_ctermid 1024 /* size for ctermid() */
-char* ctermid(char* __buf) __INTRODUCED_IN(26);
+char* _Nonnull ctermid(char* _Nullable __buf) __INTRODUCED_IN(26);
-FILE* fdopen(int __fd, const char* __mode);
-int fileno(FILE* __fp);
-int pclose(FILE* __fp);
-FILE* popen(const char* __command, const char* __mode);
-void flockfile(FILE* __fp);
-int ftrylockfile(FILE* __fp);
-void funlockfile(FILE* __fp);
-int getc_unlocked(FILE* __fp);
+FILE* _Nullable fdopen(int __fd, const char* _Nonnull __mode);
+int fileno(FILE* _Nonnull __fp);
+int pclose(FILE* _Nonnull __fp);
+FILE* _Nullable popen(const char* _Nonnull __command, const char* _Nonnull __mode);
+void flockfile(FILE* _Nonnull __fp);
+int ftrylockfile(FILE* _Nonnull __fp);
+void funlockfile(FILE* _Nonnull __fp);
+int getc_unlocked(FILE* _Nonnull __fp);
int getchar_unlocked(void);
-int putc_unlocked(int __ch, FILE* __fp);
+int putc_unlocked(int __ch, FILE* _Nonnull __fp);
int putchar_unlocked(int __ch);
-FILE* fmemopen(void* __buf, size_t __size, const char* __mode) __INTRODUCED_IN(23);
-FILE* open_memstream(char** __ptr, size_t* __size_ptr) __INTRODUCED_IN(23);
+FILE* _Nullable fmemopen(void* _Nullable __buf, size_t __size, const char* _Nonnull __mode) __INTRODUCED_IN(23);
+FILE* _Nullable open_memstream(char* _Nonnull * _Nonnull __ptr, size_t* _Nonnull __size_ptr) __INTRODUCED_IN(23);
#if defined(__USE_BSD) || defined(__BIONIC__) /* Historically bionic exposed these. */
-int asprintf(char** __s_ptr, const char* __fmt, ...) __printflike(2, 3);
-char* fgetln(FILE* __fp, size_t* __length_ptr);
-int fpurge(FILE* __fp);
-void setbuffer(FILE* __fp, char* __buf, int __size);
-int setlinebuf(FILE* __fp);
-int vasprintf(char** __s_ptr, const char* __fmt, va_list __args) __printflike(2, 0);
-void clearerr_unlocked(FILE* __fp) __INTRODUCED_IN(23);
-int feof_unlocked(FILE* __fp) __INTRODUCED_IN(23);
-int ferror_unlocked(FILE* __fp) __INTRODUCED_IN(23);
-int fileno_unlocked(FILE* __fp) __INTRODUCED_IN(24);
+int asprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, ...) __printflike(2, 3);
+char* _Nullable fgetln(FILE* _Nonnull __fp, size_t* _Nonnull __length_ptr);
+int fpurge(FILE* _Nonnull __fp);
+void setbuffer(FILE* _Nonnull __fp, char* _Nullable __buf, int __size);
+int setlinebuf(FILE* _Nonnull __fp);
+int vasprintf(char* _Nullable * _Nonnull __s_ptr, const char* _Nonnull __fmt, va_list __args) __printflike(2, 0);
+void clearerr_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+int feof_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+int ferror_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(23);
+int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
#define fropen(cookie, fn) funopen(cookie, fn, 0, 0, 0)
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#endif
#if defined(__USE_BSD)
-int fflush_unlocked(FILE* __fp) __INTRODUCED_IN(28);
-int fgetc_unlocked(FILE* __fp) __INTRODUCED_IN(28);
-int fputc_unlocked(int __ch, FILE* __fp) __INTRODUCED_IN(28);
-size_t fread_unlocked(void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN(28);
-size_t fwrite_unlocked(const void* __buf, size_t __size, size_t __count, FILE* __fp) __INTRODUCED_IN(28);
+int fflush_unlocked(FILE* _Nullable __fp) __INTRODUCED_IN(28);
+int fgetc_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+int fputc_unlocked(int __ch, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+size_t fread_unlocked(void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+size_t fwrite_unlocked(const void* _Nonnull __buf, size_t __size, size_t __count, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
#endif
#if defined(__USE_GNU)
-int fputs_unlocked(const char* __s, FILE* __fp) __INTRODUCED_IN(28);
-char* fgets_unlocked(char* __buf, int __size, FILE* __fp) __INTRODUCED_IN(28);
+int fputs_unlocked(const char* _Nonnull __s, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
+char* _Nullable fgets_unlocked(char* _Nonnull __buf, int __size, FILE* _Nonnull __fp) __INTRODUCED_IN(28);
#endif
#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
diff --git a/libc/include/sys/pidfd.h b/libc/include/sys/pidfd.h
index 6d0e809..30455bb 100644
--- a/libc/include/sys/pidfd.h
+++ b/libc/include/sys/pidfd.h
@@ -71,6 +71,6 @@
*
* Available since API level 31.
*/
-int pidfd_send_signal(int __pidfd, int __sig, siginfo_t *__info, unsigned int __flags) __INTRODUCED_IN(31);
+int pidfd_send_signal(int __pidfd, int __sig, siginfo_t * _Nullable __info, unsigned int __flags) __INTRODUCED_IN(31);
__END_DECLS
diff --git a/libc/include/sys/ucontext.h b/libc/include/sys/ucontext.h
index 8e5873d..cefe177 100644
--- a/libc/include/sys/ucontext.h
+++ b/libc/include/sys/ucontext.h
@@ -316,6 +316,8 @@
#define NGREG 32
+#if defined(__USE_GNU)
+
#define REG_PC 0
#define REG_RA 1
#define REG_SP 2
@@ -323,6 +325,8 @@
#define REG_S0 8
#define REG_A0 10
+#endif // defined(__USE_GNU)
+
typedef unsigned long __riscv_mc_gp_state[NGREG];
typedef unsigned long greg_t;
diff --git a/libc/include/sys/utsname.h b/libc/include/sys/utsname.h
index 1fa3187..aa8c1a0 100644
--- a/libc/include/sys/utsname.h
+++ b/libc/include/sys/utsname.h
@@ -62,6 +62,6 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int uname(struct utsname* __buf);
+int uname(struct utsname* _Nonnull __buf);
__END_DECLS
diff --git a/libc/include/threads.h b/libc/include/threads.h
index 1b00b8f..b1008de 100644
--- a/libc/include/threads.h
+++ b/libc/include/threads.h
@@ -51,9 +51,9 @@
typedef pthread_mutex_t mtx_t;
/** The type for a thread-specific storage destructor. */
-typedef void (*tss_dtor_t)(void*);
+typedef void (*tss_dtor_t)(void* _Nullable);
/** The type of the function passed to thrd_create() to create a new thread. */
-typedef int (*thrd_start_t)(void*);
+typedef int (*thrd_start_t)(void* _Nullable);
/** The type used by call_once(). */
typedef pthread_once_t once_flag;
@@ -82,72 +82,72 @@
// This file is implemented as static inlines before API level 30.
/** Uses `__flag` to ensure that `__function` is called exactly once. */
-void call_once(once_flag* __flag, void (*__function)(void)) __INTRODUCED_IN(30);
+void call_once(once_flag* _Nonnull __flag, void (* _Nonnull __function)(void)) __INTRODUCED_IN(30);
/**
* Unblocks all threads blocked on `__cond`.
*/
-int cnd_broadcast(cnd_t* __cond) __INTRODUCED_IN(30);
+int cnd_broadcast(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
/**
* Destroys a condition variable.
*/
-void cnd_destroy(cnd_t* __cond) __INTRODUCED_IN(30);
+void cnd_destroy(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
/**
* Creates a condition variable.
*/
-int cnd_init(cnd_t* __cond) __INTRODUCED_IN(30);
+int cnd_init(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
/**
* Unblocks one thread blocked on `__cond`.
*/
-int cnd_signal(cnd_t* __cond) __INTRODUCED_IN(30);
+int cnd_signal(cnd_t* _Nonnull __cond) __INTRODUCED_IN(30);
/**
* Unlocks `__mutex` and blocks until `__cond` is signaled or `__timeout` occurs.
*/
-int cnd_timedwait(cnd_t* __cond, mtx_t* __mutex, const struct timespec* __timeout)
+int cnd_timedwait(cnd_t* _Nonnull __cond, mtx_t* _Nonnull __mutex, const struct timespec* _Nonnull __timeout)
__INTRODUCED_IN(30);
/**
* Unlocks `__mutex` and blocks until `__cond` is signaled.
*/
-int cnd_wait(cnd_t* __cond, mtx_t* __mutex) __INTRODUCED_IN(30);
+int cnd_wait(cnd_t* _Nonnull __cond, mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
/**
* Destroys a mutex.
*/
-void mtx_destroy(mtx_t* __mutex) __INTRODUCED_IN(30);
+void mtx_destroy(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
/**
* Creates a mutex.
*/
-int mtx_init(mtx_t* __mutex, int __type) __INTRODUCED_IN(30);
+int mtx_init(mtx_t* _Nonnull __mutex, int __type) __INTRODUCED_IN(30);
/**
* Blocks until `__mutex` is acquired.
*/
-int mtx_lock(mtx_t* __mutex) __INTRODUCED_IN(30);
+int mtx_lock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
/**
* Blocks until `__mutex` is acquired or `__timeout` expires.
*/
-int mtx_timedlock(mtx_t* __mutex, const struct timespec* __timeout) __INTRODUCED_IN(30);
+int mtx_timedlock(mtx_t* _Nonnull __mutex, const struct timespec* _Nonnull __timeout) __INTRODUCED_IN(30);
/**
* Acquires `__mutex` or returns `thrd_busy`.
*/
-int mtx_trylock(mtx_t* __mutex) __INTRODUCED_IN(30);
+int mtx_trylock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
/**
* Unlocks `__mutex`.
*/
-int mtx_unlock(mtx_t* __mutex) __INTRODUCED_IN(30);
+int mtx_unlock(mtx_t* _Nonnull __mutex) __INTRODUCED_IN(30);
@@ -155,7 +155,7 @@
* Creates a new thread running `__function(__arg)`, and sets `*__thrd` to
* the new thread.
*/
-int thrd_create(thrd_t* __thrd, thrd_start_t __function, void* __arg) __INTRODUCED_IN(30);
+int thrd_create(thrd_t* _Nonnull __thrd, thrd_start_t _Nonnull __function, void* _Nullable __arg) __INTRODUCED_IN(30);
/**
* Returns the `thrd_t` corresponding to the caller.
@@ -181,7 +181,7 @@
* Blocks until `__thrd` terminates. If `__result` is not null, `*__result`
* is set to the exiting thread's result.
*/
-int thrd_join(thrd_t __thrd, int* __result) __INTRODUCED_IN(30);
+int thrd_join(thrd_t __thrd, int* _Nullable __result) __INTRODUCED_IN(30);
/**
* Blocks the caller for at least `__duration` unless a signal is delivered.
@@ -190,7 +190,7 @@
*
* Returns 0 on success, or -1 if a signal was delivered.
*/
-int thrd_sleep(const struct timespec* __duration, struct timespec* __remaining) __INTRODUCED_IN(30);
+int thrd_sleep(const struct timespec* _Nonnull __duration, struct timespec* _Nullable __remaining) __INTRODUCED_IN(30);
/**
* Request that other threads should be scheduled.
@@ -203,7 +203,7 @@
* Creates a thread-specific storage key with the associated destructor (which
* may be null).
*/
-int tss_create(tss_t* __key, tss_dtor_t __dtor) __INTRODUCED_IN(30);
+int tss_create(tss_t* _Nonnull __key, tss_dtor_t _Nullable __dtor) __INTRODUCED_IN(30);
/**
* Destroys a thread-specific storage key.
@@ -214,13 +214,13 @@
* Returns the value for the current thread held in the thread-specific storage
* identified by `__key`.
*/
-void* tss_get(tss_t __key) __INTRODUCED_IN(30);
+void* _Nullable tss_get(tss_t __key) __INTRODUCED_IN(30);
/**
* Sets the current thread's value for the thread-specific storage identified
* by `__key` to `__value`.
*/
-int tss_set(tss_t __key, void* __value) __INTRODUCED_IN(30);
+int tss_set(tss_t __key, void* _Nonnull __value) __INTRODUCED_IN(30);
#endif
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 6ffda49..2fc12a0 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -170,7 +170,6 @@
#define _EXT(fp) __BIONIC_CAST(reinterpret_cast, struct __sfileext*, (fp)->_ext._base)
#define _UB(fp) _EXT(fp)->_ub
-#define _FLOCK(fp) _EXT(fp)->_lock
#define _FILEEXT_SETUP(fp, fext) \
do { \
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 27813a6..645aefa 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -197,7 +197,7 @@
fp->_lb._size = 0;
memset(_EXT(fp), 0, sizeof(struct __sfileext));
- _FLOCK(fp) = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+ _EXT(fp)->_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
_EXT(fp)->_caller_handles_locking = false;
// Caller sets cookie, _read/_write etc.
@@ -884,7 +884,7 @@
void perror(const char* msg) {
if (msg == nullptr) msg = "";
- fprintf(stderr, "%s%s%s\n", msg, (*msg == '\0') ? "" : ": ", strerror(errno));
+ fprintf(stderr, "%s%s%m\n", msg, (*msg == '\0') ? "" : ": ");
}
int printf(const char* fmt, ...) {
@@ -1239,6 +1239,23 @@
return __FILE_close(fp);
}
+void flockfile(FILE* fp) {
+ CHECK_FP(fp);
+ pthread_mutex_lock(&_EXT(fp)->_lock);
+}
+
+int ftrylockfile(FILE* fp) {
+ CHECK_FP(fp);
+ // The specification for ftrylockfile() says it returns 0 on success,
+ // or non-zero on error. We don't bother canonicalizing to 0/-1...
+ return pthread_mutex_trylock(&_EXT(fp)->_lock);
+}
+
+void funlockfile(FILE* fp) {
+ CHECK_FP(fp);
+ pthread_mutex_unlock(&_EXT(fp)->_lock);
+}
+
namespace {
namespace phony {
diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py
index a525a98..558b004 100755
--- a/libc/tools/gensyscalls.py
+++ b/libc/tools/gensyscalls.py
@@ -93,7 +93,7 @@
ret
1:
neg a0, a0
- j __set_errno_internal
+ tail __set_errno_internal
END(%(func)s)
"""
diff --git a/libc/tzcode/strptime.c b/libc/tzcode/strptime.c
index fe9e10f..d31a501 100644
--- a/libc/tzcode/strptime.c
+++ b/libc/tzcode/strptime.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: strptime.c,v 1.30 2019/05/12 12:49:52 schwarze Exp $ */
+/* $OpenBSD: strptime.c,v 1.31 2023/03/02 16:21:51 millert Exp $ */
/* $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ */
/*-
* Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc.
@@ -29,8 +29,10 @@
*/
#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
#include <locale.h>
-#include <stdint.h>
+#include <stdlib.h>
#include <string.h>
#include <time.h>
@@ -43,6 +45,8 @@
// Android: this code is not pointer-sign clean.
#pragma clang diagnostic ignored "-Wpointer-sign"
#pragma clang diagnostic ignored "-Wunused-function"
+// Android: clang thinks people don't know && has higher precedence than ||.
+#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
#define _ctloc(x) (_CurrentTimeLocale->x)
@@ -78,8 +82,8 @@
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
-static int _conv_num64(const unsigned char **, int64_t *, int64_t, int64_t);
static int _conv_num(const unsigned char **, int *, int, int);
+static int epoch_to_tm(const unsigned char **, struct tm *);
static int leaps_thru_end_of(const int y);
static char *_strptime(const char *, const char *, struct tm *, int);
static const u_char *_find_string(const u_char *, int *, const char * const *,
@@ -351,27 +355,10 @@
if (!(_conv_num(&bp, &tm->tm_sec, 0, 60)))
return (NULL);
break;
- case 's': /* Seconds since epoch */
- {
- // Android change based on FreeBSD's implementation.
- int saved_errno = errno;
- errno = 0;
- const unsigned char* old_bp = bp;
- long n = strtol((const char*) bp, (char**) &bp, 10);
- errno = saved_errno;
- time_t t = n;
- if (bp == old_bp || errno == ERANGE ||
- ((long) t) != n) return NULL;
-
- if (localtime_r(&t, tm) == NULL) return NULL;
-
- //int64_t i64;
- //if (!(_conv_num64(&bp, &i64, 0, INT64_MAX)))
- // return (NULL);
- //if (!gmtime_r(&i64, tm))
- // return (NULL);
- fields = 0xffff; /* everything */
- }
+ case 's': /* Seconds since epoch. */
+ if (!(epoch_to_tm(&bp, tm)))
+ return (NULL);
+ fields = 0xffff; /* everything */
break;
case 'U': /* The week of year, beginning on sunday. */
case 'W': /* The week of year, beginning on monday. */
@@ -635,26 +622,27 @@
}
static int
-_conv_num64(const unsigned char **buf, int64_t *dest, int64_t llim, int64_t ulim)
+epoch_to_tm(const unsigned char **buf, struct tm *tm)
{
- int result = 0;
- int64_t rulim = ulim;
+ int saved_errno = errno;
+ int ret = 0;
+ time_t secs;
+ char *ep;
- if (**buf < '0' || **buf > '9')
- return (0);
-
- /* we use rulim to break out of the loop when we run out of digits */
- do {
- result *= 10;
- result += *(*buf)++ - '0';
- rulim /= 10;
- } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
-
- if (result < llim || result > ulim)
- return (0);
-
- *dest = result;
- return (1);
+ errno = 0;
+ secs = strtoll(*buf, &ep, 10);
+ if (*buf == (unsigned char *)ep)
+ goto done;
+ if (secs < 0 ||
+ secs == LLONG_MAX && errno == ERANGE)
+ goto done;
+ if (localtime_r(&secs, tm) == NULL)
+ goto done;
+ ret = 1;
+done:
+ *buf = ep;
+ errno = saved_errno;
+ return (ret);
}
static const u_char *
diff --git a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
index 823f2a9..f853045 100644
--- a/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
+++ b/libc/upstream-openbsd/lib/libc/gdtoa/gdtoaimp.h
@@ -26,7 +26,7 @@
****************************************************************/
-/* This is a variation on dtoa.c that converts arbitary binary
+/* This is a variation on dtoa.c that converts arbitrary binary
floating-point formats to and from decimal notation. It uses
double-precision arithmetic internally, so there are still
various #ifdefs that adapt the calculations to the native
diff --git a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
index 9a08d13..74a1695 100644
--- a/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setvbuf.c,v 1.14 2016/09/21 04:38:56 guenther Exp $ */
+/* $OpenBSD: setvbuf.c,v 1.15 2022/09/28 16:44:14 gnezdo Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@@ -31,6 +31,7 @@
* SUCH DAMAGE.
*/
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
@@ -52,7 +53,7 @@
* when setting _IONBF.
*/
if (mode != _IONBF)
- if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
+ if ((mode != _IOFBF && mode != _IOLBF) || size > INT_MAX)
return (EOF);
/*
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/div.c b/libc/upstream-openbsd/lib/libc/stdlib/div.c
index beaa428..5e6164f 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/div.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/div.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: div.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */
+/* $OpenBSD: div.c,v 1.7 2022/12/27 17:10:06 jmc Exp $ */
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
@@ -46,7 +46,7 @@
* words, we should always truncate the quotient towards
* 0, never -infinity.
*
- * Machine division and remainer may work either way when
+ * Machine division and remainder may work either way when
* one or both of n or d is negative. If only one is
* negative and r.quot has been truncated towards -inf,
* r.rem will have the same sign as denom and the opposite
diff --git a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
index 15c550b..fc8e5b6 100644
--- a/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setenv.c,v 1.19 2016/09/21 04:38:56 guenther Exp $ */
+/* $OpenBSD: setenv.c,v 1.20 2022/08/08 22:40:03 millert Exp $ */
/*
* Copyright (c) 1987 Regents of the University of California.
* All rights reserved.
@@ -48,9 +48,10 @@
for (cp = str; *cp && *cp != '='; ++cp)
;
- if (*cp != '=') {
+ if (cp == str || *cp != '=') {
+ /* '=' is the first character of string or is missing. */
errno = EINVAL;
- return (-1); /* missing `=' in string */
+ return (-1);
}
if (__findenv(str, (int)(cp - str), &offset) != NULL) {
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 939c092..3f70279 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -889,11 +889,14 @@
void* sym;
#if defined(__BIONIC__) && !defined(__LP64__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
// RTLD_DEFAULT in lp32 bionic is not (void*)0
// so it can be distinguished from the NULL handle.
sym = dlsym(nullptr, "test");
ASSERT_TRUE(sym == nullptr);
ASSERT_STREQ("dlsym failed: library handle is null", dlerror());
+#pragma clang diagnostic pop
#endif
// Symbol that doesn't exist.
@@ -1008,9 +1011,12 @@
dlerror(); // Clear any pending errors.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
// No symbol corresponding to NULL.
ASSERT_EQ(dladdr(nullptr, &info), 0); // Zero on error, non-zero on success.
ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
+#pragma clang diagnostic pop
// No symbol corresponding to a stack address.
ASSERT_EQ(dladdr(&info, &info), 0); // Zero on error, non-zero on success.
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
index 82ccf82..56736e7 100644
--- a/tests/elftls_dl_test.cpp
+++ b/tests/elftls_dl_test.cpp
@@ -30,6 +30,7 @@
#include <link.h>
#include <android-base/file.h>
+#include <android-base/test_utils.h>
#include <gtest/gtest.h>
#include <thread>
@@ -153,6 +154,7 @@
}
TEST(elftls_dl, dtv_resize) {
+ SKIP_WITH_HWASAN; // TODO(b/271243811): Fix for new toolchain
#if defined(__BIONIC__)
#define LOAD_LIB(soname) ({ \
auto lib = dlopen(soname, RTLD_LOCAL | RTLD_NOW); \
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
index 38661c7..8b12bec 100644
--- a/tests/gwp_asan_test.cpp
+++ b/tests/gwp_asan_test.cpp
@@ -58,13 +58,10 @@
// the torture mode is is generally 40,000, so that svelte devices don't
// explode, as this uses ~163MiB RAM (4KiB per live allocation).
TEST(gwp_asan_integration, malloc_tests_under_torture) {
- if (running_with_hwasan()) {
- // Skip the malloc.zeroed tests since they fail in this particular config.
- // TODO(b/267386540): Need to fix this problem.
- RunGwpAsanTest("malloc.*:-malloc.mallinfo*:malloc.zeroed*");
- } else {
- RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
- }
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
+ RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
}
class SyspropRestorer {
@@ -153,6 +150,9 @@
}
TEST(gwp_asan_integration, sysprops_program_specific) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
std::string path = testing::internal::GetArgvs()[0];
@@ -167,6 +167,9 @@
}
TEST(gwp_asan_integration, sysprops_persist_program_specific) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
std::string path = testing::internal::GetArgvs()[0];
@@ -182,6 +185,9 @@
}
TEST(gwp_asan_integration, sysprops_system) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
__system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
@@ -192,6 +198,9 @@
}
TEST(gwp_asan_integration, sysprops_persist_system) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
__system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "1");
@@ -202,6 +211,9 @@
}
TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
__system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
@@ -216,6 +228,9 @@
}
TEST(gwp_asan_integration, sysprops_program_specific_overrides_default) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
std::string path = testing::internal::GetArgvs()[0];
@@ -235,6 +250,9 @@
}
TEST(gwp_asan_integration, sysprops_can_disable) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
__system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
@@ -245,6 +263,9 @@
}
TEST(gwp_asan_integration, env_overrides_sysprop) {
+ // Do not override HWASan with GWP ASan.
+ SKIP_WITH_HWASAN;
+
SyspropRestorer restorer;
__system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 907a35c..06a0f3d 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -41,6 +41,7 @@
#include <android-base/scopeguard.h>
#include <android-base/silent_death_test.h>
#include <android-base/strings.h>
+#include <android-base/test_utils.h>
#include "private/bionic_constants.h"
#include "SignalUtils.h"
@@ -184,6 +185,30 @@
ASSERT_EQ(0, pthread_key_delete(key));
}
+static void* FnWithStackFrame(void*) {
+ int x;
+ *const_cast<volatile int*>(&x) = 1;
+ return nullptr;
+}
+
+TEST(pthread, pthread_heap_allocated_stack) {
+ SKIP_WITH_HWASAN; // TODO(b/148982147): Re-enable when fixed.
+
+ size_t stack_size = 640 * 1024;
+ std::vector<char> stack_vec(stack_size, '\xff');
+ void* stack = stack_vec.data();
+
+ pthread_attr_t attr;
+ ASSERT_EQ(0, pthread_attr_init(&attr));
+ ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size));
+
+ pthread_t t;
+ ASSERT_EQ(0, pthread_create(&t, &attr, FnWithStackFrame, nullptr));
+
+ void* result;
+ ASSERT_EQ(0, pthread_join(t, &result));
+}
+
TEST(pthread, static_pthread_key_used_before_creation) {
#if defined(__BIONIC__)
// See http://b/19625804. The bug is about a static/global pthread key being used before creation.
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index acc7ccd..fb6bce9 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -190,6 +190,8 @@
}
TEST(STDIO_TEST, getdelim_invalid) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
FILE* fp = tmpfile();
ASSERT_TRUE(fp != nullptr);
@@ -206,6 +208,7 @@
ASSERT_EQ(getdelim(&buffer, nullptr, ' ', fp), -1);
ASSERT_EQ(EINVAL, errno);
fclose(fp);
+#pragma clang diagnostic pop
}
TEST(STDIO_TEST, getdelim_directory) {
@@ -260,6 +263,8 @@
}
TEST(STDIO_TEST, getline_invalid) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
FILE* fp = tmpfile();
ASSERT_TRUE(fp != nullptr);
@@ -276,6 +281,7 @@
ASSERT_EQ(getline(&buffer, nullptr, fp), -1);
ASSERT_EQ(EINVAL, errno);
fclose(fp);
+#pragma clang diagnostic pop
}
TEST(STDIO_TEST, printf_ssize_t) {
@@ -1944,6 +1950,8 @@
TEST(STDIO_TEST, open_memstream_EINVAL) {
#if defined(__BIONIC__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
char* p;
size_t size;
@@ -1956,6 +1964,7 @@
errno = 0;
ASSERT_EQ(nullptr, open_memstream(&p, nullptr));
ASSERT_EQ(EINVAL, errno);
+#pragma clang diagnostic pop
#else
GTEST_SKIP() << "glibc is broken";
#endif
@@ -2975,9 +2984,6 @@
}
TEST(STDIO_TEST, snprintf_b) {
- // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
char buf[BUFSIZ];
EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%b>", 5));
EXPECT_STREQ("<101>", buf);
@@ -2989,13 +2995,9 @@
EXPECT_STREQ("<0b10101010101010101010101010101010>", buf);
EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#b>", 0));
EXPECT_STREQ("<0>", buf);
-#pragma clang diagnostic pop
}
TEST(STDIO_TEST, snprintf_B) {
- // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
char buf[BUFSIZ];
EXPECT_EQ(5, snprintf(buf, sizeof(buf), "<%B>", 5));
EXPECT_STREQ("<101>", buf);
@@ -3007,13 +3009,9 @@
EXPECT_STREQ("<0B10101010101010101010101010101010>", buf);
EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%#B>", 0));
EXPECT_STREQ("<0>", buf);
-#pragma clang diagnostic pop
}
TEST(STDIO_TEST, swprintf_b) {
- // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
wchar_t buf[BUFSIZ];
EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%b>", 5));
EXPECT_EQ(std::wstring(L"<101>"), buf);
@@ -3025,13 +3023,9 @@
EXPECT_EQ(std::wstring(L"<0b10101010101010101010101010101010>"), buf);
EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#b>", 0));
EXPECT_EQ(std::wstring(L"<0>"), buf);
-#pragma clang diagnostic pop
}
TEST(STDIO_TEST, swprintf_B) {
- // Our clang doesn't know about %b/%B yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
wchar_t buf[BUFSIZ];
EXPECT_EQ(5, swprintf(buf, sizeof(buf), L"<%B>", 5));
EXPECT_EQ(std::wstring(L"<101>"), buf);
@@ -3043,7 +3037,6 @@
EXPECT_EQ(std::wstring(L"<0B10101010101010101010101010101010>"), buf);
EXPECT_EQ(3, swprintf(buf, sizeof(buf), L"<%#B>", 0));
EXPECT_EQ(std::wstring(L"<0>"), buf);
-#pragma clang diagnostic pop
}
TEST(STDIO_TEST, scanf_i_decimal) {
@@ -3143,10 +3136,6 @@
}
TEST(STDIO_TEST, scanf_b) {
- // Our clang doesn't know about %b yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat"
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
int i;
char ch;
EXPECT_EQ(2, sscanf("<1012>", "<%b%c>", &i, &ch));
@@ -3159,14 +3148,9 @@
EXPECT_EQ(2, sscanf("-0b", "%i%c", &i, &ch));
EXPECT_EQ(0, i);
EXPECT_EQ('b', ch);
-#pragma clang diagnostic pop
}
TEST(STDIO_TEST, swscanf_b) {
- // Our clang doesn't know about %b yet.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wformat"
-#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
int i;
char ch;
EXPECT_EQ(2, swscanf(L"<1012>", L"<%b%c>", &i, &ch));
@@ -3179,5 +3163,4 @@
EXPECT_EQ(2, swscanf(L"-0b", L"%i%c", &i, &ch));
EXPECT_EQ(0, i);
EXPECT_EQ('b', ch);
-#pragma clang diagnostic pop
}