--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -2049,17 +2049,17 @@ protected:
// because WebGLContext objects only go away during GC, which shouldn't happen too frequently.
// If in the future GC becomes much more frequent, we may have to revisit then (maybe use a timer).
ForceDiscreteGPUHelperCGL mForceDiscreteGPUHelper;
#endif
public:
// console logging helpers
void GenerateWarning(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
- void GenerateWarning(const char* fmt, va_list ap);
+ void GenerateWarning(const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
void GeneratePerfWarning(const char* fmt, ...) const MOZ_FORMAT_PRINTF(2, 3);
public:
UniquePtr<webgl::FormatUsageAuthority> mFormatUsage;
virtual UniquePtr<webgl::FormatUsageAuthority>
CreateFormatUsage(gl::GLContext* gl) const = 0;
--- a/js/src/jit/JitSpewer.h
+++ b/js/src/jit/JitSpewer.h
@@ -178,19 +178,19 @@ class JitSpewIndent
};
void JitSpew(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
void JitSpewStart(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
void JitSpewCont(JitSpewChannel channel, const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
void JitSpewFin(JitSpewChannel channel);
void JitSpewHeader(JitSpewChannel channel);
bool JitSpewEnabled(JitSpewChannel channel);
-void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap);
-void JitSpewStartVA(JitSpewChannel channel, const char* fmt, va_list ap);
-void JitSpewContVA(JitSpewChannel channel, const char* fmt, va_list ap);
+void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
+void JitSpewStartVA(JitSpewChannel channel, const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
+void JitSpewContVA(JitSpewChannel channel, const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def);
void EnableChannel(JitSpewChannel channel);
void DisableChannel(JitSpewChannel channel);
void EnableIonDebugSyncLogging();
void EnableIonDebugAsyncLogging();
#else
@@ -248,17 +248,18 @@ static inline void JitSpewCheckArguments
static inline void JitSpewFin(JitSpewChannel channel)
{ }
static inline void JitSpewHeader(JitSpewChannel channel)
{ }
static inline bool JitSpewEnabled(JitSpewChannel channel)
{ return false; }
-static inline void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap)
+static inline MOZ_FORMAT_PRINTF(2, 0)
+void JitSpewVA(JitSpewChannel channel, const char* fmt, va_list ap)
{ }
static inline void JitSpewDef(JitSpewChannel channel, const char* str, MDefinition* def)
{ }
static inline void EnableChannel(JitSpewChannel)
{ }
static inline void DisableChannel(JitSpewChannel)
{ }
--- a/js/src/jit/MIRGenerator.h
+++ b/js/src/jit/MIRGenerator.h
@@ -72,17 +72,17 @@ class MIRGenerator
// Set an error state and prints a message. Returns false so errors can be
// propagated up.
mozilla::GenericErrorResult<AbortReason> abort(AbortReason r);
mozilla::GenericErrorResult<AbortReason>
abort(AbortReason r, const char* message, ...) MOZ_FORMAT_PRINTF(3, 4);
mozilla::GenericErrorResult<AbortReason>
- abortFmt(AbortReason r, const char* message, va_list ap);
+ abortFmt(AbortReason r, const char* message, va_list ap) MOZ_FORMAT_PRINTF(3, 0);
// Collect the evaluation result of phases after IonBuilder, such that
// off-thread compilation can report what error got encountered.
void setOffThreadStatus(AbortReasonOr<Ok> result) {
MOZ_ASSERT(offThreadStatus_.isOk());
offThreadStatus_ = result;
}
AbortReasonOr<Ok> getOffThreadStatus() const {
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1312,17 +1312,17 @@ class Assembler : public AssemblerShared
uint32_t spewNext_;
Sprinter* printer_;
bool spewDisabled();
uint32_t spewResolve(Label* l);
uint32_t spewProbe(Label* l);
uint32_t spewDefine(Label* l);
void spew(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
- void spew(const char* fmt, va_list args);
+ void spew(const char* fmt, va_list args) MOZ_FORMAT_PRINTF(2, 0);
#endif
public:
// For the alignment fill use NOP: 0x0320f000 or (Always | InstNOP::NopInst).
// For the nopFill use a branch to the next instruction: 0xeaffffff.
Assembler()
: m_buffer(1, 1, 8, GetPoolMaxOffset(), 8, 0xe320f000, 0xeaffffff, GetNopFill()),
#ifdef JS_DISASM_ARM
--- a/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h
+++ b/js/src/jit/x86-shared/AssemblerBuffer-x86-shared.h
@@ -218,16 +218,16 @@ namespace jit {
va_start(va, fmt);
spew(fmt, va);
va_end(va);
}
#endif
}
#ifdef JS_JITSPEW
- MOZ_COLD void spew(const char* fmt, va_list va);
+ MOZ_COLD void spew(const char* fmt, va_list va) MOZ_FORMAT_PRINTF(2, 0);
#endif
};
} // namespace jit
} // namespace js
#endif /* jit_x86_shared_AssemblerBuffer_x86_shared_h */
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1019,17 +1019,17 @@ enum ErrorArgumentsType {
* Defined in SelfHosting.cpp.
*/
JSFunction*
SelfHostedFunction(JSContext* cx, HandlePropertyName propName);
#ifdef va_start
extern bool
ReportErrorVA(JSContext* cx, unsigned flags, const char* format,
- ErrorArgumentsType argumentsType, va_list ap);
+ ErrorArgumentsType argumentsType, va_list ap) MOZ_FORMAT_PRINTF(3, 0);
extern bool
ReportErrorNumberVA(JSContext* cx, unsigned flags, JSErrorCallback callback,
void* userRef, const unsigned errorNumber,
ErrorArgumentsType argumentsType, va_list ap);
extern bool
ReportErrorNumberUCArray(JSContext* cx, unsigned flags, JSErrorCallback callback,
--- a/js/src/jsprf.h
+++ b/js/src/jsprf.h
@@ -21,13 +21,15 @@ extern JS_PUBLIC_API(JS::UniqueChars) JS
MOZ_FORMAT_PRINTF(1, 2);
extern JS_PUBLIC_API(void) JS_smprintf_free(char* mem);
extern JS_PUBLIC_API(JS::UniqueChars) JS_sprintf_append(JS::UniqueChars&& last,
const char* fmt, ...)
MOZ_FORMAT_PRINTF(2, 3);
-extern JS_PUBLIC_API(JS::UniqueChars) JS_vsmprintf(const char* fmt, va_list ap);
+extern JS_PUBLIC_API(JS::UniqueChars) JS_vsmprintf(const char* fmt, va_list ap)
+ MOZ_FORMAT_PRINTF(1, 0);
extern JS_PUBLIC_API(JS::UniqueChars) JS_vsprintf_append(JS::UniqueChars&& last,
- const char* fmt, va_list ap);
+ const char* fmt, va_list ap)
+ MOZ_FORMAT_PRINTF(2, 0);
#endif /* jsprf_h */
--- a/js/src/vm/Printer.h
+++ b/js/src/vm/Printer.h
@@ -40,17 +40,17 @@ class GenericPrinter
virtual bool put(const char* s, size_t len) = 0;
inline bool put(const char* s) {
return put(s, strlen(s));
}
// Prints a formatted string into the buffer.
bool printf(const char* fmt, ...) MOZ_FORMAT_PRINTF(2, 3);
- bool vprintf(const char* fmt, va_list ap);
+ bool vprintf(const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(2, 0);
// Report that a string operation failed to get the memory it requested. The
// first call to this function calls JS_ReportOutOfMemory, and sets this
// Sprinter's outOfMemory flag; subsequent calls do nothing.
virtual void reportOutOfMemory();
// Return true if this Sprinter ran out of memory.
virtual bool hadOutOfMemory() const;
--- a/js/src/wasm/AsmJS.cpp
+++ b/js/src/wasm/AsmJS.cpp
@@ -2263,17 +2263,17 @@ class MOZ_STACK_CLASS ModuleValidator
bool failCurrentOffset(const char* str) {
return failOffset(tokenStream().currentToken().pos.begin, str);
}
bool fail(ParseNode* pn, const char* str) {
return failOffset(pn->pn_pos.begin, str);
}
- bool failfVAOffset(uint32_t offset, const char* fmt, va_list ap) {
+ bool failfVAOffset(uint32_t offset, const char* fmt, va_list ap) MOZ_FORMAT_PRINTF(3, 0) {
MOZ_ASSERT(!hasAlreadyFailed());
MOZ_ASSERT(errorOffset_ == UINT32_MAX);
MOZ_ASSERT(fmt);
errorOffset_ = offset;
errorString_ = JS_vsmprintf(fmt, ap);
return false;
}
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -622,16 +622,19 @@
* So, for a simple case like:
* void print_something (int whatever, const char *fmt, ...);
* The corresponding annotation would be
* MOZ_FORMAT_PRINTF(2, 3)
* However, if "print_something" were a non-static member function,
* then the annotation would be:
* MOZ_FORMAT_PRINTF(3, 4)
*
+ * The second argument should be 0 for vprintf-like functions; that
+ * is, those taking a va_list argument.
+ *
* Note that the checking is limited to standards-conforming
* printf-likes, and in particular this should not be used for
* PR_snprintf and friends, which are "printf-like" but which assign
* different meanings to the various formats.
*
* MinGW requires special handling due to different format specifiers
* on different platforms. The macro __MINGW_PRINTF_FORMAT maps to
* either gnu_printf or ms_printf depending on where we are compiling
--- a/mfbt/Sprintf.h
+++ b/mfbt/Sprintf.h
@@ -13,16 +13,17 @@
#include <stdarg.h>
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#ifdef __cplusplus
template <size_t N>
+MOZ_FORMAT_PRINTF(2, 0)
int VsprintfLiteral(char (&buffer)[N], const char* format, va_list args)
{
MOZ_ASSERT(format != buffer);
int result = vsnprintf(buffer, N, format, args);
buffer[N - 1] = '\0';
return result;
}
--- a/mozglue/misc/Printf.h
+++ b/mozglue/misc/Printf.h
@@ -68,17 +68,17 @@ namespace mozilla {
*/
class PrintfTarget
{
public:
/* The Printf-like interface. */
bool MFBT_API print(const char* format, ...) MOZ_FORMAT_PRINTF(2, 3);
/* The Vprintf-like interface. */
- bool MFBT_API vprint(const char* format, va_list);
+ bool MFBT_API vprint(const char* format, va_list) MOZ_FORMAT_PRINTF(2, 0);
protected:
MFBT_API PrintfTarget();
virtual ~PrintfTarget() { }
/* Subclasses override this. It is called when more output is
available. It may be called with len==0. This should return
true on success, or false on failure. */
@@ -135,17 +135,17 @@ class MOZ_STACK_CLASS SprintfState final
, mCur(base ? base + mMaxlen : 0)
{
}
~SprintfState() {
this->free_(mBase);
}
- bool vprint(const char* format, va_list ap_list) {
+ bool vprint(const char* format, va_list ap_list) MOZ_FORMAT_PRINTF(2, 0) {
// The "" here has a single \0 character, which is what we're
// trying to append.
return mozilla::PrintfTarget::vprint(format, ap_list) && append("", 1);
}
SmprintfPolicyPointer<AllocPolicy> release() {
SmprintfPolicyPointer<AllocPolicy> result(mBase);
mBase = nullptr;
@@ -229,25 +229,27 @@ SmprintfPolicyPointer<AllocPolicy> Smpri
}
return ss.release();
}
/*
** va_list forms of the above.
*/
template<typename AllocPolicy = mozilla::MallocAllocPolicy>
+MOZ_FORMAT_PRINTF(1, 0)
SmprintfPolicyPointer<AllocPolicy> Vsmprintf(const char* fmt, va_list ap)
{
SprintfState<AllocPolicy> ss(nullptr);
if (!ss.vprint(fmt, ap))
return nullptr;
return ss.release();
}
template<typename AllocPolicy = mozilla::MallocAllocPolicy>
+MOZ_FORMAT_PRINTF(2, 0)
SmprintfPolicyPointer<AllocPolicy> VsmprintfAppend(SmprintfPolicyPointer<AllocPolicy>&& last,
const char* fmt, va_list ap)
{
SprintfState<AllocPolicy> ss(last.release());
if (!ss.vprint(fmt, ap))
return nullptr;
return ss.release();
}
--- a/xpcom/base/Logging.cpp
+++ b/xpcom/base/Logging.cpp
@@ -341,16 +341,17 @@ public:
module = new LogModule(aName, LogLevel::Disabled);
mModules.Put(aName, module);
}
return module;
}
void Print(const char* aName, LogLevel aLevel, const char* aFmt, va_list aArgs)
+ MOZ_FORMAT_PRINTF(4, 0)
{
const size_t kBuffSize = 1024;
char buff[kBuffSize];
char* buffToWrite = buff;
SmprintfPointer allocatedBuff;
va_list argsCopy;
--- a/xpcom/base/Logging.h
+++ b/xpcom/base/Logging.h
@@ -114,17 +114,17 @@ public:
/**
* Sets the log module's level.
*/
void SetLevel(LogLevel level) { mLevel = level; }
/**
* Print a log message for this module.
*/
- void Printv(LogLevel aLevel, const char* aFmt, va_list aArgs) const;
+ void Printv(LogLevel aLevel, const char* aFmt, va_list aArgs) const MOZ_FORMAT_PRINTF(3, 0);
/**
* Retrieves the module name.
*/
const char* Name() const { return mName; }
private:
friend class LogModuleManager;
--- a/xpcom/base/nsDebug.h
+++ b/xpcom/base/nsDebug.h
@@ -388,17 +388,17 @@ extern "C" {
* - on Windows, if a debugger is present, it calls OutputDebugString
* in *addition* to writing to stderr
*/
void printf_stderr(const char* aFmt, ...) MOZ_FORMAT_PRINTF(1, 2);
/**
* Same as printf_stderr, but taking va_list instead of varargs
*/
-void vprintf_stderr(const char* aFmt, va_list aArgs);
+void vprintf_stderr(const char* aFmt, va_list aArgs) MOZ_FORMAT_PRINTF(1, 0);
/**
* fprintf_stderr is like fprintf, except that if its file argument
* is stderr, it invokes printf_stderr instead.
*
* This is useful for general debugging code that logs information to a
* file, but that you would like to be useful on Android and Firefox OS.
* If you use fprintf_stderr instead of fprintf in such debugging code,
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -687,17 +687,17 @@ public:
/**
* Append a formatted string to the current string. Uses the
* standard printf format codes. This uses NSPR formatting, which will be
* locale-aware for floating-point values. You probably don't want to use
* this with floating-point values as a result.
*/
void AppendPrintf(const char* aFormat, ...) MOZ_FORMAT_PRINTF(2, 3);
- void AppendPrintf(const char* aFormat, va_list aAp);
+ void AppendPrintf(const char* aFormat, va_list aAp) MOZ_FORMAT_PRINTF(2, 0);
void AppendInt(int32_t aInteger)
{
AppendPrintf("%" PRId32, aInteger);
}
void AppendInt(int32_t aInteger, int aRadix)
{
if (aRadix == 10) {
AppendPrintf("%" PRId32, aInteger);