Merge "Fix stack use-after-scope in async_safe_log."
diff --git a/libc/include/getopt.h b/libc/include/getopt.h
index 014226a..c1c0442 100644
--- a/libc/include/getopt.h
+++ b/libc/include/getopt.h
@@ -49,8 +49,11 @@
#define optional_argument 2
struct option {
- /** Name of long option. */
- const char *name;
+ /**
+ * Name of long option. Options must have a non-NULL name.
+ * A NULL name signals the end of the options array.
+ */
+ const char * _Nullable name;
/**
* One of `no_argument`, `required_argument`, or `optional_argument`.
@@ -58,7 +61,7 @@
int has_arg;
/** If not NULL, set `*flag` to val when option found. */
- int* flag;
+ int* _Nullable flag;
/** If `flag` not NULL, the value to assign to `*flag`; otherwise the return value. */
int val;
@@ -69,12 +72,12 @@
/**
* [getopt_long(3)](http://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
*/
-int getopt_long(int __argc, char* const* __argv, const char* __options, const struct option* __long_options, int* __long_index);
+int getopt_long(int __argc, char* _Nonnull const* _Nonnull __argv, const char* _Nonnull __options, const struct option* _Nonnull __long_options, int* _Nullable __long_index);
/**
* [getopt_long_only(3)](http://man7.org/linux/man-pages/man3/getopt.3.html) parses command-line options.
*/
-int getopt_long_only(int __argc, char* const* __argv, const char* __options, const struct option* __long_options, int* __long_index);
+int getopt_long_only(int __argc, char* _Nonnull const* _Nonnull __argv, const char* _Nonnull __options, const struct option* _Nonnull __long_options, int* _Nullable __long_index);
#ifndef _OPTRESET_DECLARED
#define _OPTRESET_DECLARED
diff --git a/libc/include/mntent.h b/libc/include/mntent.h
index d5987dc..43cab1f 100644
--- a/libc/include/mntent.h
+++ b/libc/include/mntent.h
@@ -47,21 +47,21 @@
#define MNTOPT_SUID "suid"
struct mntent {
- char* mnt_fsname;
- char* mnt_dir;
- char* mnt_type;
- char* mnt_opts;
+ char* _Nullable mnt_fsname;
+ char* _Nullable mnt_dir;
+ char* _Nullable mnt_type;
+ char* _Nullable mnt_opts;
int mnt_freq;
int mnt_passno;
};
__BEGIN_DECLS
-int endmntent(FILE* __fp) __INTRODUCED_IN(21);
-struct mntent* getmntent(FILE* __fp);
-struct mntent* getmntent_r(FILE* __fp, struct mntent* __entry, char* __buf, int __size) __INTRODUCED_IN(21);
-FILE* setmntent(const char* __filename, const char* __type) __INTRODUCED_IN(21);
-char* hasmntopt(const struct mntent* __entry, const char* __option) __INTRODUCED_IN(26);
+int endmntent(FILE* _Nullable __fp) __INTRODUCED_IN(21);
+struct mntent* _Nullable getmntent(FILE* _Nonnull __fp);
+struct mntent* _Nullable getmntent_r(FILE* _Nonnull __fp, struct mntent* _Nonnull __entry, char* _Nonnull __buf, int __size) __INTRODUCED_IN(21);
+FILE* _Nullable setmntent(const char* _Nonnull __filename, const char* _Nonnull __type) __INTRODUCED_IN(21);
+char* _Nullable hasmntopt(const struct mntent* _Nonnull __entry, const char* _Nonnull __option) __INTRODUCED_IN(26);
__END_DECLS
diff --git a/libc/include/resolv.h b/libc/include/resolv.h
index 6318d00..f25484a 100644
--- a/libc/include/resolv.h
+++ b/libc/include/resolv.h
@@ -40,24 +40,24 @@
__BEGIN_DECLS
#define b64_ntop __b64_ntop
-int b64_ntop(u_char const* __src, size_t __src_size, char* __dst, size_t __dst_size);
+int b64_ntop(u_char const* _Nonnull __src, size_t __src_size, char* _Nonnull __dst, size_t __dst_size);
#define b64_pton __b64_pton
-int b64_pton(char const* __src, u_char* __dst, size_t __dst_size);
+int b64_pton(char const* _Nonnull __src, u_char* _Nonnull __dst, size_t __dst_size);
#define dn_comp __dn_comp
-int dn_comp(const char* __src, u_char* __dst, int __dst_size, u_char** __dn_ptrs , u_char** __last_dn_ptr);
+int dn_comp(const char* _Nonnull __src, u_char* _Nonnull __dst, int __dst_size, u_char* _Nullable * _Nullable __dn_ptrs , u_char* _Nullable * _Nullable __last_dn_ptr);
-int dn_expand(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, int __dst_size);
+int dn_expand(const u_char* _Nonnull __msg, const u_char* _Nonnull __eom, const u_char* _Nonnull __src, char* _Nonnull __dst, int __dst_size);
#define p_class __p_class
-const char* p_class(int __class);
+const char* _Nonnull p_class(int __class);
#define p_type __p_type
-const char* p_type(int __type);
+const char* _Nonnull p_type(int __type);
int res_init(void);
-int res_mkquery(int __opcode, const char* __domain_name, int __class, int __type, const u_char* __data, int __data_size, const u_char* __new_rr_in, u_char* __buf, int __buf_size);
-int res_query(const char* __name, int __class, int __type, u_char* __answer, int __answer_size);
-int res_search(const char* __name, int __class, int __type, u_char* __answer, int __answer_size);
+int res_mkquery(int __opcode, const char* _Nonnull __domain_name, int __class, int __type, const u_char* _Nullable __data, int __data_size, const u_char* _Nullable __new_rr_in, u_char* _Nonnull __buf, int __buf_size);
+int res_query(const char* _Nonnull __name, int __class, int __type, u_char* _Nonnull __answer, int __answer_size);
+int res_search(const char* _Nonnull __name, int __class, int __type, u_char* _Nonnull __answer, int __answer_size);
#define res_randomid __res_randomid
u_int __res_randomid(void) __INTRODUCED_IN(29);
diff --git a/libc/include/sys/signalfd.h b/libc/include/sys/signalfd.h
index bd911f7..f669cc8 100644
--- a/libc/include/sys/signalfd.h
+++ b/libc/include/sys/signalfd.h
@@ -48,11 +48,11 @@
*
* Available since API level 18.
*/
-int signalfd(int __fd, const sigset_t* __mask, int __flags) __INTRODUCED_IN(18);
+int signalfd(int __fd, const sigset_t* _Nonnull __mask, int __flags) __INTRODUCED_IN(18);
/**
* Like signalfd() but allows setting a signal mask with RT signals even from a 32-bit process.
*/
-int signalfd64(int __fd, const sigset64_t* __mask, int __flags) __INTRODUCED_IN(28);
+int signalfd64(int __fd, const sigset64_t* _Nonnull __mask, int __flags) __INTRODUCED_IN(28);
__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/tests/stack_protector_test_helper.cpp b/tests/stack_protector_test_helper.cpp
index eddd940..69b3c5d 100644
--- a/tests/stack_protector_test_helper.cpp
+++ b/tests/stack_protector_test_helper.cpp
@@ -15,12 +15,11 @@
*/
// Deliberately overwrite the stack canary.
-__attribute__((noinline)) void modify_stack_protector_test() {
+__attribute__((noinline, optnone)) void modify_stack_protector_test() {
// We can't use memset here because it's fortified, and we want to test
// the line of defense *after* that.
- // Without volatile, the generic x86/x86-64 targets don't write to the stack.
// We can't make a constant change, since the existing byte might already have
// had that value.
- volatile char* p = reinterpret_cast<volatile char*>(&p + 1);
+ char* p = reinterpret_cast<char*>(&p + 1);
*p = ~*p;
}