Merge "linker: add experimental support for SHT_RELR sections."
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index 48800ca..e4eb48a 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -389,7 +389,7 @@
Android allows `dlclose` to unload a library even if there are still
thread-local variables with non-trivial destructors. This leads to
crashes when a thread exits and attempts to call the destructor, the
-code for which has been unloaded (as in [issue 360]).
+code for which has been unloaded (as in [issue 360], fixed in P).
[issue 360]: https://github.com/android-ndk/ndk/issues/360
@@ -397,8 +397,8 @@
set (so that calls to `dlclose` don't actually unload the library)
are possible workarounds.
-| | Pre-M | M+ |
-| ----------------- | -------------------------- | ------- |
-| No workaround | Works for static STL | Broken |
-| `-Wl,-z,nodelete` | Works for static STL | Works |
-| No `dlclose` | Works | Works |
+| | Pre-M | M+ | P+ |
+| ----------------- | -------------------------- | ------- | ----- |
+| No workaround | Works for static STL | Broken | Works |
+| `-Wl,-z,nodelete` | Works for static STL | Works | Works |
+| No `dlclose` | Works | Works | Works |
diff --git a/benchmarks/bionic_benchmarks.cpp b/benchmarks/bionic_benchmarks.cpp
index fe7a1b1..d8635cd 100644
--- a/benchmarks/bionic_benchmarks.cpp
+++ b/benchmarks/bionic_benchmarks.cpp
@@ -305,7 +305,7 @@
}
void RegisterGoogleBenchmarks(bench_opts_t primary_opts, bench_opts_t secondary_opts,
- std::string fn_name, args_vector_t* run_args) {
+ const std::string& fn_name, args_vector_t* run_args) {
if (g_str_to_func.find(fn_name) == g_str_to_func.end()) {
errx(1, "ERROR: No benchmark for function %s", fn_name.c_str());
}
@@ -320,7 +320,7 @@
}
benchmark_func_t benchmark_function = g_str_to_func.at(fn_name).first;
- for (std::vector<int> args : (*run_args)) {
+ for (const std::vector<int>& args : (*run_args)) {
auto registration = benchmark::RegisterBenchmark(fn_name.c_str(), LockAndRun,
benchmark_function,
cpu_to_use)->Args(args);
@@ -335,13 +335,13 @@
// Register any of the extra benchmarks that were specified in the options.
args_vector_t arg_vector;
args_vector_t* run_args = &arg_vector;
- for (std::string extra_fn : cmdline_opts.extra_benchmarks) {
+ for (const std::string& extra_fn : cmdline_opts.extra_benchmarks) {
android::base::Trim(extra_fn);
- size_t first_space_pos = extra_fn.find(" ");
+ size_t first_space_pos = extra_fn.find(' ');
std::string fn_name = extra_fn.substr(0, first_space_pos);
std::string cmd_args;
if (first_space_pos != std::string::npos) {
- cmd_args = extra_fn.substr(extra_fn.find(" ") + 1);
+ cmd_args = extra_fn.substr(extra_fn.find(' ') + 1);
} else {
cmd_args = "";
}
diff --git a/benchmarks/stdio_benchmark.cpp b/benchmarks/stdio_benchmark.cpp
index 965a3ae..9c81e0f 100644
--- a/benchmarks/stdio_benchmark.cpp
+++ b/benchmarks/stdio_benchmark.cpp
@@ -29,7 +29,7 @@
memset(line, 'x', sizeof(line));
line[sizeof(line) - 1] = '\0';
- FILE* fp = fopen(tf.path, "w");
+ FILE* fp = fopen(tf.path, "we");
for (size_t i = 0; i < 4096; ++i) fputs(line, fp);
fclose(fp);
}
diff --git a/benchmarks/util.h b/benchmarks/util.h
index a546764..3225bc2 100644
--- a/benchmarks/util.h
+++ b/benchmarks/util.h
@@ -29,7 +29,7 @@
extern std::map<std::string, std::pair<benchmark_func_t, std::string>> g_str_to_func;
-static int __attribute__((unused)) EmplaceBenchmark (std::string fn_name, benchmark_func_t fn_ptr, std::string arg = "") {
+static int __attribute__((unused)) EmplaceBenchmark(const std::string& fn_name, benchmark_func_t fn_ptr, const std::string& arg = "") {
g_map_lock.lock();
g_str_to_func.emplace(std::string(fn_name), std::make_pair(fn_ptr, arg));
g_map_lock.unlock();
diff --git a/libc/Android.bp b/libc/Android.bp
index 5f04e28..a8c518d 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -18,7 +18,7 @@
"stdio/refill.c",
"stdio/stdio.cpp",
"stdio/stdio_ext.cpp",
- "stdio/vfscanf.c",
+ "stdio/vfscanf.cpp",
"stdio/vfwscanf.c",
"stdlib/exit.c",
]
@@ -39,6 +39,7 @@
"-Wall",
"-Wextra",
"-Wunused",
+ "-Wno-char-subscripts",
"-Wno-deprecated-declarations",
"-Wno-gcc-compat",
"-Wframe-larger-than=2048",
@@ -1669,6 +1670,7 @@
cc_library {
defaults: ["libc_defaults"],
name: "libc",
+ static_ndk_lib: true,
product_variables: {
platform_sdk_version: {
asflags: ["-DPLATFORM_SDK_VERSION=%d"],
@@ -1781,6 +1783,7 @@
"bionic/new.cpp",
],
name: "libstdc++",
+ static_ndk_lib: true,
system_shared_libs: ["libc"],
static_libs: ["libasync_safe"],
diff --git a/libc/bionic/icu.cpp b/libc/bionic/icu.cpp
index 78e551b..c09c9ea 100644
--- a/libc/bionic/icu.cpp
+++ b/libc/bionic/icu.cpp
@@ -68,7 +68,7 @@
}
free(namelist);
- if (max_version == -1 || max_version < ICUDATA_VERSION_MIN) {
+ if (max_version < ICUDATA_VERSION_MIN) {
async_safe_write_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find an ICU .dat file");
return false;
}
diff --git a/libc/include/android/legacy_errno_inlines.h b/libc/include/android/legacy_errno_inlines.h
index 8f08074..9f116fa 100644
--- a/libc/include/android/legacy_errno_inlines.h
+++ b/libc/include/android/legacy_errno_inlines.h
@@ -29,11 +29,12 @@
#ifndef _ANDROID_LEGACY_ERRNO_INLINES_H
#define _ANDROID_LEGACY_ERRNO_INLINES_H
-#include <errno.h>
#include <sys/cdefs.h>
#if __ANDROID_API__ < __ANDROID_API_L__
+#include <errno.h>
+
__BEGIN_DECLS
static __inline int __attribute__((deprecated)) __set_errno(int n) {
diff --git a/libc/include/android/legacy_fenv_inlines_arm.h b/libc/include/android/legacy_fenv_inlines_arm.h
index de024cf..6f2c959 100644
--- a/libc/include/android/legacy_fenv_inlines_arm.h
+++ b/libc/include/android/legacy_fenv_inlines_arm.h
@@ -29,10 +29,12 @@
#ifndef ANDROID_LEGACY_FENV_INLINES_ARM_H
#define ANDROID_LEGACY_FENV_INLINES_ARM_H
-#include <fenv.h>
+#include <sys/cdefs.h>
#if __ANDROID_API__ < __ANDROID_API_L__ && defined(__arm__)
+#include <fenv.h>
+
__BEGIN_DECLS
#define FPSCR_RMODE_SHIFT 22
diff --git a/libc/include/android/legacy_fenv_inlines_mips.h b/libc/include/android/legacy_fenv_inlines_mips.h
index 10b93c0..43ad360 100644
--- a/libc/include/android/legacy_fenv_inlines_mips.h
+++ b/libc/include/android/legacy_fenv_inlines_mips.h
@@ -29,10 +29,12 @@
#ifndef ANDROID_LEGACY_FENV_INLINES_MIPS_H
#define ANDROID_LEGACY_FENV_INLINES_MIPS_H
-#include <fenv.h>
+#include <sys/cdefs.h>
#if __ANDROID_API__ < __ANDROID_API_L__ && (defined(__mips__) && !defined(__LP64__))
+#include <fenv.h>
+
__BEGIN_DECLS
#define FCSR_CAUSE_SHIFT 10
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index 4d474b0..44c2f4f 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -29,16 +29,16 @@
#ifndef _ANDROID_LEGACY_SIGNAL_INLINES_H_
#define _ANDROID_LEGACY_SIGNAL_INLINES_H_
+#include <sys/cdefs.h>
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
#include <errno.h>
#include <signal.h>
#include <string.h>
-#include <sys/cdefs.h>
-
__BEGIN_DECLS
-#if __ANDROID_API__ < __ANDROID_API_L__
-
sighandler_t bsd_signal(int __signal, sighandler_t __handler) __REMOVED_IN(21);
/* These weren't introduced until L. */
@@ -117,8 +117,8 @@
return bsd_signal(s, f);
}
-#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
-
__END_DECLS
+#endif /* __ANDROID_API__ < __ANDROID_API_L__ */
+
#endif /* _ANDROID_LEGACY_SIGNAL_INLINES_H_ */
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index a1cc590..4896d2e 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -29,9 +29,6 @@
#ifndef _ANDROID_LEGACY_STDLIB_INLINES_H_
#define _ANDROID_LEGACY_STDLIB_INLINES_H_
-#include <errno.h>
-#include <float.h>
-#include <stdlib.h>
#include <sys/cdefs.h>
#if __ANDROID_API__ < __ANDROID_API_K__
@@ -52,6 +49,10 @@
#if __ANDROID_API__ < __ANDROID_API_L__
+#include <errno.h>
+#include <float.h>
+#include <stdlib.h>
+
__BEGIN_DECLS
static __inline float strtof(const char* nptr, char** endptr) {
diff --git a/libc/include/android/legacy_strings_inlines.h b/libc/include/android/legacy_strings_inlines.h
index 6679c30..5d63c5a 100644
--- a/libc/include/android/legacy_strings_inlines.h
+++ b/libc/include/android/legacy_strings_inlines.h
@@ -29,16 +29,19 @@
#ifndef _ANDROID_LEGACY_STRINGS_INLINES_H_
#define _ANDROID_LEGACY_STRINGS_INLINES_H_
-#include <strings.h>
#include <sys/cdefs.h>
+#if defined(__i386__) && __ANDROID_API__ < __ANDROID_API_J_MR2__
+
+#include <strings.h>
+
__BEGIN_DECLS
-#if defined(__i386__) && __ANDROID_API__ < __ANDROID_API_J_MR2__
/* Everyone except x86 had ffs since the beginning. */
static __inline int ffs(int __n) { return __builtin_ffs(__n); }
-#endif
__END_DECLS
#endif
+
+#endif
diff --git a/libc/include/android/legacy_sys_mman_inlines.h b/libc/include/android/legacy_sys_mman_inlines.h
index 7eb537e..160e6fe 100644
--- a/libc/include/android/legacy_sys_mman_inlines.h
+++ b/libc/include/android/legacy_sys_mman_inlines.h
@@ -29,12 +29,13 @@
#pragma once
#include <sys/cdefs.h>
-#include <sys/mman.h>
-#include <sys/syscall.h>
-#include <unistd.h>
#if __ANDROID_API__ < __ANDROID_API_L__
+#include <errno.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
__BEGIN_DECLS
/*
diff --git a/libc/include/android/legacy_sys_stat_inlines.h b/libc/include/android/legacy_sys_stat_inlines.h
index bbf54c0..9521694 100644
--- a/libc/include/android/legacy_sys_stat_inlines.h
+++ b/libc/include/android/legacy_sys_stat_inlines.h
@@ -30,10 +30,11 @@
#define _ANDROID_LEGACY_SYS_STAT_INLINES_H_
#include <sys/cdefs.h>
-#include <sys/stat.h>
#if __ANDROID_API__ < __ANDROID_API_L__
+#include <sys/stat.h>
+
__BEGIN_DECLS
static __inline int mkfifo(const char* __path, mode_t __mode) {
diff --git a/libc/include/android/legacy_sys_wait_inlines.h b/libc/include/android/legacy_sys_wait_inlines.h
index 1124f8e..4298d76 100644
--- a/libc/include/android/legacy_sys_wait_inlines.h
+++ b/libc/include/android/legacy_sys_wait_inlines.h
@@ -30,12 +30,13 @@
#define _ANDROID_LEGACY_SYS_WAIT_INLINES_H_
#include <sys/cdefs.h>
+
+#if __ANDROID_API__ < __ANDROID_API_J_MR2__
+
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>
-#if __ANDROID_API__ < __ANDROID_API_J_MR2__
-
__BEGIN_DECLS
static __inline pid_t wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
diff --git a/libc/include/android/legacy_termios_inlines.h b/libc/include/android/legacy_termios_inlines.h
index 4ed56f0..a63dba1 100644
--- a/libc/include/android/legacy_termios_inlines.h
+++ b/libc/include/android/legacy_termios_inlines.h
@@ -30,14 +30,16 @@
#define _ANDROID_LEGACY_TERMIOS_INLINES_H_
#include <sys/cdefs.h>
+
+#if __ANDROID_API__ < __ANDROID_API_L__
+
+#include <linux/termios.h>
#include <sys/ioctl.h>
#include <sys/types.h>
-#include <linux/termios.h>
-
-#if __ANDROID_API__ < __ANDROID_API_L__
#define __BIONIC_TERMIOS_INLINE static __inline
#include <bits/termios_inlines.h>
+
#endif
#endif /* _ANDROID_LEGACY_TERMIOS_INLINES_H_ */
diff --git a/libc/malloc_debug/MapData.h b/libc/malloc_debug/MapData.h
index 0238139..895f78f 100644
--- a/libc/malloc_debug/MapData.h
+++ b/libc/malloc_debug/MapData.h
@@ -41,7 +41,7 @@
MapEntry(uintptr_t start, uintptr_t end, uintptr_t offset, const char* name, size_t name_len)
: start(start), end(end), offset(offset), name(name, name_len) {}
- MapEntry(uintptr_t pc) : start(pc), end(pc) {}
+ explicit MapEntry(uintptr_t pc) : start(pc), end(pc) {}
uintptr_t start;
uintptr_t end;
diff --git a/libc/malloc_debug/OptionData.h b/libc/malloc_debug/OptionData.h
index 80190f5..5c2d272 100644
--- a/libc/malloc_debug/OptionData.h
+++ b/libc/malloc_debug/OptionData.h
@@ -34,7 +34,7 @@
class OptionData {
public:
- OptionData(DebugData* debug) : debug_(debug) {}
+ explicit OptionData(DebugData* debug) : debug_(debug) {}
~OptionData() = default;
protected:
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index 6e19923..ccabac2 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -66,7 +66,7 @@
class AllocEntry : public RecordEntry {
public:
- AllocEntry(void* pointer);
+ explicit AllocEntry(void* pointer);
virtual ~AllocEntry() = default;
protected:
@@ -92,7 +92,7 @@
class FreeEntry : public AllocEntry {
public:
- FreeEntry(void* pointer);
+ explicit FreeEntry(void* pointer);
virtual ~FreeEntry() = default;
std::string GetString() const override;
diff --git a/libc/malloc_debug/TrackData.h b/libc/malloc_debug/TrackData.h
index f7486e9..9a649b9 100644
--- a/libc/malloc_debug/TrackData.h
+++ b/libc/malloc_debug/TrackData.h
@@ -46,7 +46,7 @@
class TrackData : public OptionData {
public:
- TrackData(DebugData* debug_data);
+ explicit TrackData(DebugData* debug_data);
virtual ~TrackData() = default;
void GetList(std::vector<const Header*>* list);
diff --git a/libc/private/CachedProperty.h b/libc/private/CachedProperty.h
index 84ead01..bd67d74 100644
--- a/libc/private/CachedProperty.h
+++ b/libc/private/CachedProperty.h
@@ -38,7 +38,7 @@
class CachedProperty {
public:
// The lifetime of `property_name` must be greater than that of this CachedProperty.
- CachedProperty(const char* property_name)
+ explicit CachedProperty(const char* property_name)
: property_name_(property_name),
prop_info_(nullptr),
cached_area_serial_(0),
diff --git a/libc/private/KernelArgumentBlock.h b/libc/private/KernelArgumentBlock.h
index 68d4999..747186c 100644
--- a/libc/private/KernelArgumentBlock.h
+++ b/libc/private/KernelArgumentBlock.h
@@ -32,7 +32,7 @@
// constituents for easy access.
class KernelArgumentBlock {
public:
- KernelArgumentBlock(void* raw_args) {
+ explicit KernelArgumentBlock(void* raw_args) {
uintptr_t* args = reinterpret_cast<uintptr_t*>(raw_args);
argc = static_cast<int>(*args);
argv = reinterpret_cast<char**>(args + 1);
diff --git a/libc/private/bionic_mbstate.h b/libc/private/bionic_mbstate.h
index 292959a..352115a 100644
--- a/libc/private/bionic_mbstate.h
+++ b/libc/private/bionic_mbstate.h
@@ -29,6 +29,7 @@
#ifndef _BIONIC_MBSTATE_H
#define _BIONIC_MBSTATE_H
+#include <errno.h>
#include <wchar.h>
__BEGIN_DECLS
diff --git a/libc/stdio/vfscanf.c b/libc/stdio/vfscanf.cpp
similarity index 71%
rename from libc/stdio/vfscanf.c
rename to libc/stdio/vfscanf.cpp
index f0ed4ae..49d6bf6 100644
--- a/libc/stdio/vfscanf.c
+++ b/libc/stdio/vfscanf.cpp
@@ -37,74 +37,68 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/param.h>
#include <wctype.h>
#include "local.h"
#include <private/bionic_ctype.h>
+#include <private/bionic_fortify.h>
+#include <private/bionic_mbstate.h>
#define BUF 513 /* Maximum length of numeric string. */
-/*
- * Flags used during conversion.
- */
-#define LONG 0x00001 /* l: long or double */
-#define LONGDBL 0x00002 /* L: long double */
-#define SHORT 0x00004 /* h: short */
-#define SHORTSHORT 0x00008 /* hh: 8 bit integer */
-#define LLONG 0x00010 /* ll: long long (+ deprecated q: quad) */
-#define POINTER 0x00020 /* p: void * (as hex) */
-#define SIZEINT 0x00040 /* z: (signed) size_t */
-#define MAXINT 0x00080 /* j: intmax_t */
-#define PTRINT 0x00100 /* t: ptrdiff_t */
-#define NOSKIP 0x00200 /* [ or c: do not skip blanks */
-#define SUPPRESS 0x00400 /* *: suppress assignment */
-#define UNSIGNED 0x00800 /* %[oupxX] conversions */
+// Flags used during conversion.
+// Size/type:
+#define LONG 0x00001 // l: long or double
+#define LONGDBL 0x00002 // L: long double
+#define SHORT 0x00004 // h: short
+#define SHORTSHORT 0x00008 // hh: 8 bit integer
+#define LLONG 0x00010 // ll: long long (+ deprecated q: quad)
+#define POINTER 0x00020 // p: void* (as hex)
+#define SIZEINT 0x00040 // z: (signed) size_t
+#define MAXINT 0x00080 // j: intmax_t
+#define PTRINT 0x00100 // t: ptrdiff_t
+#define NOSKIP 0x00200 // [ or c: do not skip blanks
+// Modifiers:
+#define SUPPRESS 0x00400 // *: suppress assignment
+#define UNSIGNED 0x00800 // %[oupxX] conversions
+#define ALLOCATE 0x01000 // m: allocate a char*
+// Internal use during integer parsing:
+#define SIGNOK 0x02000 // +/- is (still) legal
+#define HAVESIGN 0x04000 // Sign detected
+#define NDIGITS 0x08000 // No digits detected
+#define PFXOK 0x10000 // "0x" prefix is (still) legal
+#define NZDIGITS 0x20000 // No zero digits detected
-/*
- * The following are used in numeric conversions only:
- * SIGNOK, HAVESIGN, NDIGITS, DPTOK, and EXPOK are for floating point;
- * SIGNOK, HAVESIGN, NDIGITS, PFXOK, and NZDIGITS are for integral.
- */
-#define SIGNOK 0x01000 /* +/- is (still) legal */
-#define HAVESIGN 0x02000 /* sign detected */
-#define NDIGITS 0x04000 /* no digits detected */
+// Conversion types.
+#define CT_CHAR 0 // %c conversion
+#define CT_CCL 1 // %[...] conversion
+#define CT_STRING 2 // %s conversion
+#define CT_INT 3 // Integer: strtoimax/strtoumax
+#define CT_FLOAT 4 // Float: strtod
-#define DPTOK 0x08000 /* (float) decimal point is still legal */
-#define EXPOK 0x10000 /* (float) exponent (e+3, etc) still legal */
-
-#define PFXOK 0x08000 /* 0x prefix is (still) legal */
-#define NZDIGITS 0x10000 /* no zero digits detected */
-
-/*
- * Conversion types.
- */
-#define CT_CHAR 0 /* %c conversion */
-#define CT_CCL 1 /* %[...] conversion */
-#define CT_STRING 2 /* %s conversion */
-#define CT_INT 3 /* integer, i.e., strtoimax or strtoumax */
-#define CT_FLOAT 4 /* floating, i.e., strtod */
-
-static u_char* __sccl(char*, u_char*);
+static const unsigned char* __sccl(char*, const unsigned char*);
/*
* Internal, unlocked version of vfscanf
*/
-int __svfscanf(FILE* fp, const char* fmt0, __va_list ap) {
- u_char* fmt = (u_char*)fmt0;
+int __svfscanf(FILE* fp, const char* fmt0, va_list ap) {
+ const unsigned char* fmt = reinterpret_cast<const unsigned char*>(fmt0);
int c; /* character from format, or conversion */
size_t width; /* field width, or 0 */
- char* p; /* points into all kinds of strings */
- int n; /* handy integer */
+ char* p;
+ wchar_t* wcp;
+ size_t n;
int flags; /* flags as defined above */
- char* p0; /* saves original value of p when necessary */
int nassigned; /* number of fields assigned */
int nread; /* number of characters consumed from fp */
int base; /* base argument to strtoimax/strtouimax */
char ccltab[256]; /* character class table for %[...] */
char buf[BUF]; /* buffer for numeric conversions */
- wchar_t* wcp; /* handy wide character pointer */
size_t nconv; /* length of multibyte sequence converted */
mbstate_t mbs;
+ void* allocation = NULL; // Allocated but unassigned result for %mc/%ms/%m[.
+ size_t capacity = 0; // Number of char/wchar_t units allocated in `allocation`.
/* `basefix' is used to avoid `if' tests in the integer scanner */
static short basefix[17] = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
@@ -113,10 +107,9 @@
nassigned = 0;
nread = 0;
- base = 0; /* XXX just to keep gcc happy */
for (;;) {
c = *fmt++;
- if (c == 0) return (nassigned);
+ if (c == 0) return nassigned;
if (IsSpace(c)) {
while ((fp->_r > 0 || __srefill(fp) == 0) && IsSpace(*fp->_p)) nread++, fp->_r--, fp->_p++;
continue;
@@ -164,6 +157,9 @@
flags |= LONG;
}
goto again;
+ case 'm':
+ flags |= ALLOCATE;
+ goto again;
case 'q':
flags |= LLONG; /* deprecated */
goto again;
@@ -239,6 +235,8 @@
break;
case 's':
+ memset(ccltab, 1, 256);
+ ccltab['\t'] = ccltab['\n'] = ccltab['\v'] = ccltab['\f'] = ccltab['\r'] = ccltab[' '] = 0;
c = CT_STRING;
break;
@@ -262,29 +260,30 @@
case 'n':
if (flags & SUPPRESS) continue;
- if (flags & SHORTSHORT)
+ if (flags & SHORTSHORT) {
*va_arg(ap, signed char*) = nread;
- else if (flags & SHORT)
+ } else if (flags & SHORT) {
*va_arg(ap, short*) = nread;
- else if (flags & LONG)
+ } else if (flags & LONG) {
*va_arg(ap, long*) = nread;
- else if (flags & SIZEINT)
+ } else if (flags & SIZEINT) {
*va_arg(ap, ssize_t*) = nread;
- else if (flags & PTRINT)
+ } else if (flags & PTRINT) {
*va_arg(ap, ptrdiff_t*) = nread;
- else if (flags & LLONG)
+ } else if (flags & LLONG) {
*va_arg(ap, long long*) = nread;
- else if (flags & MAXINT)
+ } else if (flags & MAXINT) {
*va_arg(ap, intmax_t*) = nread;
- else
+ } else {
*va_arg(ap, int*) = nread;
+ }
continue;
/*
* Disgusting backwards compatibility hacks. XXX
*/
case '\0': /* compat */
- return (EOF);
+ return EOF;
default: /* compat */
if (IsUpper(c)) flags |= LONG;
@@ -293,6 +292,13 @@
break;
}
+ if ((flags & ALLOCATE) != 0 && c > CT_STRING) {
+ __fortify_fatal("scanf 'm' only works with %%c/%%s/%%[");
+ }
+ if ((flags & (ALLOCATE|SUPPRESS)) == (ALLOCATE|SUPPRESS)) {
+ __fortify_fatal("scanf 'm' makes no sense with '*'");
+ }
+
/*
* We have a conversion that requires input.
*/
@@ -326,42 +332,53 @@
/* scan arbitrary characters (sets NOSKIP) */
if (width == 0) width = 1;
if (flags & LONG) {
- wcp = ((flags & SUPPRESS) == 0) ? va_arg(ap, wchar_t*) : NULL;
- n = 0;
+ if (flags & ALLOCATE) {
+ allocation = wcp = reinterpret_cast<wchar_t*>(malloc(width * sizeof(wchar_t)));
+ if (allocation == NULL) goto allocation_failure;
+ } else if (flags & SUPPRESS) {
+ wcp = NULL;
+ } else {
+ wcp = va_arg(ap, wchar_t*);
+ }
+ size_t bytes = 0;
while (width != 0) {
- if (n == (int)MB_CUR_MAX) {
+ if (bytes == MB_CUR_MAX) {
fp->_flags |= __SERR;
goto input_failure;
}
- buf[n++] = *fp->_p;
+ buf[bytes++] = *fp->_p;
fp->_p++;
fp->_r--;
memset(&mbs, 0, sizeof(mbs));
- nconv = mbrtowc(wcp, buf, n, &mbs);
- if (nconv == (size_t)-1) {
+ nconv = mbrtowc(wcp, buf, bytes, &mbs);
+ if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
fp->_flags |= __SERR;
goto input_failure;
}
if (nconv == 0 && !(flags & SUPPRESS)) *wcp = L'\0';
- if (nconv != (size_t)-2) {
- nread += n;
+ if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+ nread += bytes;
width--;
if (!(flags & SUPPRESS)) wcp++;
- n = 0;
+ bytes = 0;
}
if (fp->_r <= 0 && __srefill(fp)) {
- if (n != 0) {
+ if (bytes != 0) {
fp->_flags |= __SERR;
goto input_failure;
}
break;
}
}
+ if (allocation != NULL) {
+ *va_arg(ap, wchar_t**) = reinterpret_cast<wchar_t*>(allocation);
+ allocation = NULL;
+ }
if (!(flags & SUPPRESS)) nassigned++;
} else if (flags & SUPPRESS) {
size_t sum = 0;
for (;;) {
- if ((n = fp->_r) < (int)width) {
+ if ((n = fp->_r) < width) {
sum += n;
width -= n;
fp->_p += n;
@@ -378,9 +395,18 @@
}
nread += sum;
} else {
- size_t r = fread((void*)va_arg(ap, char*), 1, width, fp);
-
+ if (flags & ALLOCATE) {
+ allocation = p = reinterpret_cast<char*>(malloc(width));
+ if (allocation == NULL) goto allocation_failure;
+ } else {
+ p = va_arg(ap, char*);
+ }
+ size_t r = fread(p, 1, width, fp);
if (r == 0) goto input_failure;
+ if (allocation != NULL) {
+ *va_arg(ap, char**) = reinterpret_cast<char*>(allocation);
+ allocation = NULL;
+ }
nread += r;
nassigned++;
}
@@ -390,58 +416,75 @@
case CT_STRING:
// CT_CCL: scan a (nonempty) character class (sets NOSKIP).
// CT_STRING: like CCL, but zero-length string OK, & no NOSKIP.
- if (width == 0) width = (size_t)~0; // 'infinity'.
+ if (width == 0) width = SIZE_MAX;
if (flags & LONG) {
- wchar_t twc;
- int nchars = 0;
-
- wcp = (flags & SUPPRESS) == 0 ? va_arg(ap, wchar_t*) : &twc;
+ // TODO: since no-one cares, replace this with a simple fgetwc loop?
n = 0;
+ if (flags & ALLOCATE) {
+ capacity = MIN(width, 32);
+ allocation = wcp = reinterpret_cast<wchar_t*>(malloc(sizeof(wchar_t) * capacity));
+ if (allocation == NULL) goto allocation_failure;
+ } else if (flags & SUPPRESS) {
+ wcp = NULL;
+ } else {
+ wcp = va_arg(ap, wchar_t*);
+ }
+ size_t bytes = 0;
while ((c == CT_CCL || !IsSpace(*fp->_p)) && width != 0) {
- if (n == (int)MB_CUR_MAX) {
+ if (bytes == MB_CUR_MAX) {
fp->_flags |= __SERR;
goto input_failure;
}
- buf[n++] = *fp->_p;
+ buf[bytes++] = *fp->_p;
fp->_p++;
fp->_r--;
+ wchar_t wc = L'\0';
memset(&mbs, 0, sizeof(mbs));
- nconv = mbrtowc(wcp, buf, n, &mbs);
- if (nconv == (size_t)-1) {
+ nconv = mbrtowc(&wc, buf, bytes, &mbs);
+ if (nconv == __MB_ERR_ILLEGAL_SEQUENCE) {
fp->_flags |= __SERR;
goto input_failure;
}
- if (nconv == 0) *wcp = L'\0';
- if (nconv != (size_t)-2) {
- if ((c == CT_CCL && wctob(*wcp) != EOF && !ccltab[wctob(*wcp)]) || (c == CT_STRING && iswspace(*wcp))) {
- while (n != 0) {
- n--;
- ungetc(buf[n], fp);
+ if (nconv != __MB_ERR_INCOMPLETE_SEQUENCE) {
+ if ((c == CT_CCL && wctob(wc) != EOF && !ccltab[wctob(wc)]) || (c == CT_STRING && iswspace(wc))) {
+ while (bytes != 0) {
+ bytes--;
+ ungetc(buf[bytes], fp);
}
break;
}
- nread += n;
+ if (wcp) wcp[n] = wc;
+ n++;
+ if (allocation != NULL && n == capacity) {
+ capacity *= 2;
+ wchar_t* new_allocation =
+ reinterpret_cast<wchar_t*>(realloc(allocation, sizeof(wchar_t) * capacity));
+ if (new_allocation == NULL) goto allocation_failure;
+ allocation = wcp = new_allocation;
+ }
+ nread += bytes;
width--;
- if (!(flags & SUPPRESS)) wcp++;
- nchars++;
- n = 0;
+ bytes = 0;
}
if (fp->_r <= 0 && __srefill(fp)) {
- if (n != 0) {
+ if (bytes != 0) {
fp->_flags |= __SERR;
goto input_failure;
}
break;
}
}
- if (c == CT_CCL && n != 0) {
+ if (c == CT_CCL && bytes != 0) {
fp->_flags |= __SERR;
goto input_failure;
}
- n = nchars;
+ if (allocation != NULL) {
+ *va_arg(ap, wchar_t**) = reinterpret_cast<wchar_t*>(allocation);
+ allocation = NULL;
+ }
} else if (flags & SUPPRESS) {
n = 0;
- while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !IsSpace(*fp->_p))) {
+ while (ccltab[*fp->_p]) {
n++, fp->_r--, fp->_p++;
if (--width == 0) break;
if (fp->_r <= 0 && __srefill(fp)) {
@@ -449,29 +492,46 @@
break;
}
}
+ nread += n;
} else {
- p0 = p = va_arg(ap, char*);
- while ((c == CT_CCL && ccltab[*fp->_p]) || (c == CT_STRING && !IsSpace(*fp->_p))) {
+ if (flags & ALLOCATE) {
+ capacity = MIN(width, 32);
+ allocation = p = reinterpret_cast<char*>(malloc(capacity));
+ if (allocation == NULL) goto allocation_failure;
+ } else {
+ p = va_arg(ap, char*);
+ }
+ n = 0;
+ while (ccltab[*fp->_p]) {
fp->_r--;
- *p++ = *fp->_p++;
+ p[n++] = *fp->_p++;
+ if (allocation != NULL && n == capacity) {
+ capacity *= 2;
+ char* new_allocation = reinterpret_cast<char*>(realloc(allocation, capacity));
+ if (new_allocation == NULL) goto allocation_failure;
+ allocation = p = new_allocation;
+ }
if (--width == 0) break;
if (fp->_r <= 0 && __srefill(fp)) {
- if (c == CT_CCL && p == p0) goto input_failure;
+ if (c == CT_CCL && n == 0) goto input_failure;
break;
}
}
- n = p - p0;
+ nread += n;
+ if (allocation != NULL) {
+ *va_arg(ap, char**) = reinterpret_cast<char*>(allocation);
+ allocation = NULL;
+ }
}
if (c == CT_CCL && n == 0) goto match_failure;
if (!(flags & SUPPRESS)) {
if (flags & LONG) {
- *wcp = L'\0';
+ wcp[n] = L'\0';
} else {
- *p = '\0';
+ p[n] = '\0';
}
++nassigned;
}
- nread += n;
break;
case CT_INT:
@@ -610,28 +670,30 @@
uintmax_t res;
*p = '\0';
- if (flags & UNSIGNED)
+ if (flags & UNSIGNED) {
res = strtoumax(buf, NULL, base);
- else
+ } else {
res = strtoimax(buf, NULL, base);
- if (flags & POINTER)
+ }
+ if (flags & POINTER) {
*va_arg(ap, void**) = (void*)(uintptr_t)res;
- else if (flags & MAXINT)
+ } else if (flags & MAXINT) {
*va_arg(ap, intmax_t*) = res;
- else if (flags & LLONG)
+ } else if (flags & LLONG) {
*va_arg(ap, long long*) = res;
- else if (flags & SIZEINT)
+ } else if (flags & SIZEINT) {
*va_arg(ap, ssize_t*) = res;
- else if (flags & PTRINT)
+ } else if (flags & PTRINT) {
*va_arg(ap, ptrdiff_t*) = res;
- else if (flags & LONG)
+ } else if (flags & LONG) {
*va_arg(ap, long*) = res;
- else if (flags & SHORT)
+ } else if (flags & SHORT) {
*va_arg(ap, short*) = res;
- else if (flags & SHORTSHORT)
+ } else if (flags & SHORTSHORT) {
*va_arg(ap, signed char*) = res;
- else
+ } else {
*va_arg(ap, int*) = res;
+ }
nassigned++;
}
nread += p - buf;
@@ -659,10 +721,12 @@
break;
}
}
+allocation_failure:
input_failure:
+ free(allocation);
if (nassigned == 0) nassigned = -1;
match_failure:
- return (nassigned);
+ return nassigned;
}
/*
@@ -671,7 +735,7 @@
* closing `]'. The table has a 1 wherever characters should be
* considered part of the scanset.
*/
-static u_char* __sccl(char* tab, u_char* fmt) {
+static const unsigned char* __sccl(char* tab, const unsigned char* fmt) {
int c, n, v;
/* first `clear' the whole table */
@@ -679,10 +743,10 @@
if (c == '^') {
v = 1; /* default => accept */
c = *fmt++; /* get new first char */
- } else
+ } else {
v = 0; /* default => reject */
- /* should probably use memset here */
- for (n = 0; n < 256; n++) tab[n] = v;
+ }
+ memset(tab, v, 256);
if (c == 0) return (fmt - 1); /* format ended before closing ] */
/*
@@ -744,7 +808,7 @@
break;
case ']': /* end of scanset */
- return (fmt);
+ return fmt;
default: /* just another character */
c = n;
diff --git a/libc/system_properties/include/system_properties/system_properties.h b/libc/system_properties/include/system_properties/system_properties.h
index c74f875..83ac00c 100644
--- a/libc/system_properties/include/system_properties/system_properties.h
+++ b/libc/system_properties/include/system_properties/system_properties.h
@@ -48,7 +48,7 @@
SystemProperties() {
}
// Special constructor for testing that also zero initializes the important members.
- SystemProperties(bool initialized) : initialized_(initialized) {
+ explicit SystemProperties(bool initialized) : initialized_(initialized) {
}
DISALLOW_COPY_AND_ASSIGN(SystemProperties);
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 3889bdb..0603d06 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -25,6 +25,7 @@
cc_library {
name: "libdl",
+ static_ndk_lib: true,
defaults: ["linux_bionic_supported"],
diff --git a/libm/Android.bp b/libm/Android.bp
index 6d6fafa..76a4699 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -6,6 +6,7 @@
cc_library {
name: "libm",
defaults: ["linux_bionic_supported"],
+ static_ndk_lib: true,
srcs: [
"upstream-freebsd/lib/msun/bsdsrc/b_exp.c",
diff --git a/linker/linker.cpp b/linker/linker.cpp
index abcff2a..05efc55 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3686,7 +3686,7 @@
std::string error_msg;
std::string ld_config_vndk = kLdConfigFilePath;
- size_t insert_pos = ld_config_vndk.find_last_of(".");
+ size_t insert_pos = ld_config_vndk.find_last_of('.');
if (insert_pos == std::string::npos) {
insert_pos = ld_config_vndk.length();
}
diff --git a/tests/TemporaryFile.h b/tests/TemporaryFile.h
index 5c2fe4f..070b71a 100644
--- a/tests/TemporaryFile.h
+++ b/tests/TemporaryFile.h
@@ -22,7 +22,7 @@
template <typename T = int (*)(char*)>
class GenericTemporaryFile {
public:
- GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn(mk_fn) {
+ explicit GenericTemporaryFile(T mk_fn = mkstemp) : mk_fn(mk_fn) {
// Since we might be running on the host or the target, and if we're
// running on the host we might be running under bionic or glibc,
// let's just try both possible temporary directories and take the
@@ -33,7 +33,7 @@
}
}
- GenericTemporaryFile(const char* dirpath, T mk_fn = mkstemp) : mk_fn(mk_fn) {
+ explicit GenericTemporaryFile(const char* dirpath, T mk_fn = mkstemp) : mk_fn(mk_fn) {
init(dirpath);
}
diff --git a/tests/dlext_test.cpp b/tests/dlext_test.cpp
index 04b83f2..64cfa08 100644
--- a/tests/dlext_test.cpp
+++ b/tests/dlext_test.cpp
@@ -425,7 +425,7 @@
}
void CreateRelroFile(const char* lib, const char* relro_file) {
- int relro_fd = open(relro_file, O_RDWR | O_TRUNC);
+ int relro_fd = open(relro_file, O_RDWR | O_TRUNC | O_CLOEXEC);
ASSERT_NOERROR(relro_fd);
pid_t pid = fork();
@@ -447,7 +447,7 @@
AssertChildExited(pid, 0);
// reopen file for reading so it can be used
- relro_fd = open(relro_file, O_RDONLY);
+ relro_fd = open(relro_file, O_RDONLY | O_CLOEXEC);
ASSERT_NOERROR(relro_fd);
extinfo_.flags |= ANDROID_DLEXT_USE_RELRO;
extinfo_.relro_fd = relro_fd;
diff --git a/tests/gtest_main.cpp b/tests/gtest_main.cpp
index 33dbfd9..6b20094 100644
--- a/tests/gtest_main.cpp
+++ b/tests/gtest_main.cpp
@@ -90,7 +90,6 @@
} // namespace testing
using testing::internal::GTestColor;
-using testing::internal::COLOR_DEFAULT;
using testing::internal::COLOR_RED;
using testing::internal::COLOR_GREEN;
using testing::internal::COLOR_YELLOW;
@@ -274,8 +273,7 @@
}
static bool EnumerateTests(int argc, char** argv, std::vector<TestCase>& testcase_list) {
- std::vector<const char*> args;
- for (int i = 0; i < argc; ++i) args.push_back(argv[i]);
+ std::vector<const char*> args(argv, argv + argc);
args.push_back("--gtest_list_tests");
args.push_back(nullptr);
@@ -543,7 +541,7 @@
const std::vector<TestCase>& testcase_list,
time_t epoch_iteration_start_time,
int64_t elapsed_time_ns) {
- FILE* fp = fopen(xml_output_filename.c_str(), "w");
+ FILE* fp = fopen(xml_output_filename.c_str(), "we");
if (fp == NULL) {
fprintf(stderr, "failed to open '%s': %s\n", xml_output_filename.c_str(), strerror(errno));
exit(1);
@@ -1185,10 +1183,7 @@
g_argc = argc;
g_argv = argv;
g_envp = envp;
- std::vector<char*> arg_list;
- for (int i = 0; i < argc; ++i) {
- arg_list.push_back(argv[i]);
- }
+ std::vector<char*> arg_list(argv, argv + argc);
IsolationTestOptions options;
if (PickOptions(arg_list, options) == false) {
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index d0d9130..c1a51a8 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -1016,6 +1016,138 @@
CheckScanf(swscanf, L"+,-/.", L"%[+--/]", 1, "+,-/");
}
+template <typename T1, typename T2>
+static void CheckScanfM(int sscanf_fn(const T1*, const T1*, ...),
+ const T1* input, const T1* fmt,
+ int expected_count, const T2* expected_string) {
+ T2* result = nullptr;
+ ASSERT_EQ(expected_count, sscanf_fn(input, fmt, &result)) << fmt;
+ if (expected_string == nullptr) {
+ ASSERT_EQ(nullptr, result);
+ } else {
+ ASSERT_STREQ(expected_string, result) << fmt;
+ }
+ free(result);
+}
+
+TEST(STDIO_TEST, sscanf_mc) {
+ char* p1 = nullptr;
+ char* p2 = nullptr;
+ ASSERT_EQ(2, sscanf("hello", "%mc%mc", &p1, &p2));
+ ASSERT_EQ('h', *p1);
+ ASSERT_EQ('e', *p2);
+ free(p1);
+ free(p2);
+
+ p1 = nullptr;
+ ASSERT_EQ(1, sscanf("hello", "%4mc", &p1));
+ ASSERT_EQ('h', p1[0]);
+ ASSERT_EQ('e', p1[1]);
+ ASSERT_EQ('l', p1[2]);
+ ASSERT_EQ('l', p1[3]);
+ free(p1);
+
+ p1 = nullptr;
+ ASSERT_EQ(1, sscanf("hello world", "%30mc", &p1));
+ ASSERT_EQ('h', p1[0]);
+ ASSERT_EQ('e', p1[1]);
+ ASSERT_EQ('l', p1[2]);
+ ASSERT_EQ('l', p1[3]);
+ ASSERT_EQ('o', p1[4]);
+ free(p1);
+}
+
+
+TEST(STDIO_TEST, sscanf_mlc) {
+ // This is so useless that clang doesn't even believe it exists...
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+
+ wchar_t* p1 = nullptr;
+ wchar_t* p2 = nullptr;
+ ASSERT_EQ(2, sscanf("hello", "%mlc%mlc", &p1, &p2));
+ ASSERT_EQ(L'h', *p1);
+ ASSERT_EQ(L'e', *p2);
+ free(p1);
+ free(p2);
+
+ p1 = nullptr;
+ ASSERT_EQ(1, sscanf("hello", "%4mlc", &p1));
+ ASSERT_EQ(L'h', p1[0]);
+ ASSERT_EQ(L'e', p1[1]);
+ ASSERT_EQ(L'l', p1[2]);
+ ASSERT_EQ(L'l', p1[3]);
+ free(p1);
+
+ p1 = nullptr;
+ ASSERT_EQ(1, sscanf("hello world", "%30mlc", &p1));
+ ASSERT_EQ(L'h', p1[0]);
+ ASSERT_EQ(L'e', p1[1]);
+ ASSERT_EQ(L'l', p1[2]);
+ ASSERT_EQ(L'l', p1[3]);
+ ASSERT_EQ(L'o', p1[4]);
+ free(p1);
+#pragma clang diagnostic pop
+}
+
+
+TEST(STDIO_TEST, sscanf_ms) {
+ CheckScanfM(sscanf, "hello", "%ms", 1, "hello");
+ CheckScanfM(sscanf, "hello", "%4ms", 1, "hell");
+ CheckScanfM(sscanf, "hello world", "%30ms", 1, "hello");
+}
+
+TEST(STDIO_TEST, sscanf_mls) {
+ CheckScanfM(sscanf, "hello", "%mls", 1, L"hello");
+ CheckScanfM(sscanf, "hello", "%4mls", 1, L"hell");
+ CheckScanfM(sscanf, "hello world", "%30mls", 1, L"hello");
+}
+
+TEST(STDIO_TEST, sscanf_m_ccl) {
+ CheckScanfM(sscanf, "hello", "%m[a-z]", 1, "hello");
+ CheckScanfM(sscanf, "hello", "%4m[a-z]", 1, "hell");
+ CheckScanfM(sscanf, "hello world", "%30m[a-z]", 1, "hello");
+}
+
+TEST(STDIO_TEST, sscanf_ml_ccl) {
+ CheckScanfM(sscanf, "hello", "%ml[a-z]", 1, L"hello");
+ CheckScanfM(sscanf, "hello", "%4ml[a-z]", 1, L"hell");
+ CheckScanfM(sscanf, "hello world", "%30ml[a-z]", 1, L"hello");
+}
+
+TEST(STDIO_TEST, sscanf_ls) {
+ wchar_t w[32] = {};
+ ASSERT_EQ(1, sscanf("hello world", "%ls", w));
+ ASSERT_EQ(L"hello", std::wstring(w));
+}
+
+TEST(STDIO_TEST, sscanf_ls_suppress) {
+ ASSERT_EQ(0, sscanf("hello world", "%*ls %*ls"));
+}
+
+TEST(STDIO_TEST, sscanf_ls_n) {
+ setlocale(LC_ALL, "C.UTF-8");
+ wchar_t w[32] = {};
+ int pos = 0;
+ ASSERT_EQ(1, sscanf("\xc4\x80", "%ls%n", w, &pos));
+ ASSERT_EQ(static_cast<wchar_t>(256), w[0]);
+ ASSERT_EQ(2, pos);
+}
+
+TEST(STDIO_TEST, sscanf_ls_realloc) {
+ // This is so useless that clang doesn't even believe it exists...
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-invalid-specifier"
+#pragma clang diagnostic ignored "-Wformat-extra-args"
+ wchar_t* p1 = nullptr;
+ wchar_t* p2 = nullptr;
+ ASSERT_EQ(2, sscanf("1234567890123456789012345678901234567890 world", "%mls %mls", &p1, &p2));
+ ASSERT_EQ(L"1234567890123456789012345678901234567890", std::wstring(p1));
+ ASSERT_EQ(L"world", std::wstring(p2));
+#pragma clang diagnostic pop
+}
+
// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202240
TEST(STDIO_TEST, scanf_wscanf_EOF) {
EXPECT_EQ(0, sscanf("b", "ab"));
diff --git a/tests/utils.h b/tests/utils.h
index a5783af..3f4218e 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -180,10 +180,10 @@
return const_cast<char**>(env_.data());
}
- void SetArgs(const std::vector<const char*> args) {
+ void SetArgs(const std::vector<const char*>& args) {
args_ = args;
}
- void SetEnv(const std::vector<const char*> env) {
+ void SetEnv(const std::vector<const char*>& env) {
env_ = env;
}
diff --git a/tools/versioner/src/DeclarationDatabase.cpp b/tools/versioner/src/DeclarationDatabase.cpp
index 19c2f0d..d9cff17 100644
--- a/tools/versioner/src/DeclarationDatabase.cpp
+++ b/tools/versioner/src/DeclarationDatabase.cpp
@@ -102,21 +102,18 @@
return true;
}
- DeclarationType declaration_type;
std::string declaration_name = getDeclName(named_decl);
bool is_extern = named_decl->getFormalLinkage() == ExternalLinkage;
bool is_definition = false;
bool no_guard = false;
if (auto function_decl = dyn_cast<FunctionDecl>(decl)) {
- declaration_type = DeclarationType::function;
is_definition = function_decl->isThisDeclarationADefinition();
} else if (auto var_decl = dyn_cast<VarDecl>(decl)) {
if (!var_decl->isFileVarDecl()) {
return true;
}
- declaration_type = DeclarationType::variable;
switch (var_decl->isThisDeclarationADefinition()) {
case VarDecl::DeclarationOnly:
is_definition = false;
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index efb39bd..af0c067 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -496,7 +496,6 @@
int main(int argc, char** argv) {
std::string cwd = getWorkingDir() + "/";
- bool default_args = true;
std::string platform_dir;
std::set<Arch> selected_architectures;
std::set<int> selected_levels;
@@ -507,7 +506,6 @@
int c;
while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) {
- default_args = false;
switch (c) {
case 'a': {
char* end;