# HG changeset patch # User Frits van Bommel # Date 1242512125 -7200 # Node ID 229e02867307c58dd0871bb9d3f3dc92956ba9fc # Parent 967d28b7febeffbed388d6abce5622af4682fb69 Fix format-string bugs by adding __attribute__((__format__)) in all applicable places and fixing all warnings my gcc produced. Among other things, this should fix several segfaults (including one I just ran into). diff -r 967d28b7febe -r 229e02867307 dmd/attrib.c --- a/dmd/attrib.c Sat May 16 23:44:27 2009 +0200 +++ b/dmd/attrib.c Sun May 17 00:15:25 2009 +0200 @@ -983,7 +983,7 @@ } else { - error("command '%s' invalid"); + error("command '%s' invalid", expr->toChars()); fatal(); } } diff -r 967d28b7febe -r 229e02867307 dmd/dsymbol.h --- a/dmd/dsymbol.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/dsymbol.h Sun May 17 00:15:25 2009 +0200 @@ -122,8 +122,8 @@ char *locToChars(); int equals(Object *o); int isAnonymous(); - void error(Loc loc, const char *format, ...); - void error(const char *format, ...); + void error(Loc loc, const char *format, ...) IS_PRINTF(3); + void error(const char *format, ...) IS_PRINTF(2); void checkDeprecated(Loc loc, Scope *sc); Module *getModule(); // module where declared Module *getCompilationModule(); // possibly different for templates diff -r 967d28b7febe -r 229e02867307 dmd/expression.c --- a/dmd/expression.c Sat May 16 23:44:27 2009 +0200 +++ b/dmd/expression.c Sun May 17 00:15:25 2009 +0200 @@ -1466,7 +1466,7 @@ case Tdchar: // BUG: need to cast(dchar) if ((uinteger_t)v > 0xFF) { - buf->printf("'\\U%08x'", v); + buf->printf("'\\U%08x'", (unsigned)v); break; } case Tchar: @@ -2934,7 +2934,7 @@ void ArrayLiteralExp::toMangleBuffer(OutBuffer *buf) { size_t dim = elements ? elements->dim : 0; - buf->printf("A%u", dim); + buf->printf("A%zu", dim); for (size_t i = 0; i < dim; i++) { Expression *e = (Expression *)elements->data[i]; e->toMangleBuffer(buf); @@ -3068,7 +3068,7 @@ void AssocArrayLiteralExp::toMangleBuffer(OutBuffer *buf) { size_t dim = keys->dim; - buf->printf("A%u", dim); + buf->printf("A%zu", dim); for (size_t i = 0; i < dim; i++) { Expression *key = (Expression *)keys->data[i]; Expression *value = (Expression *)values->data[i]; @@ -3284,7 +3284,7 @@ void StructLiteralExp::toMangleBuffer(OutBuffer *buf) { size_t dim = elements ? elements->dim : 0; - buf->printf("S%u", dim); + buf->printf("S%zu", dim); for (size_t i = 0; i < dim; i++) { Expression *e = (Expression *)elements->data[i]; if (e) diff -r 967d28b7febe -r 229e02867307 dmd/expression.h --- a/dmd/expression.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/expression.h Sun May 17 00:15:25 2009 +0200 @@ -98,8 +98,8 @@ void print(); char *toChars(); virtual void dump(int indent); - void error(const char *format, ...); - void warning(const char *format, ...); + void error(const char *format, ...) IS_PRINTF(2); + void warning(const char *format, ...) IS_PRINTF(2); virtual void rvalue(); static Expression *combine(Expression *e1, Expression *e2); diff -r 967d28b7febe -r 229e02867307 dmd/html.h --- a/dmd/html.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/html.h Sun May 17 00:15:25 2009 +0200 @@ -27,7 +27,7 @@ Html(const char *sourcename, unsigned char *base, unsigned length); - void error(const char *format, ...); + void error(const char *format, ...) IS_PRINTF(2); void extractCode(OutBuffer *buf); void skipTag(); void skipString(); diff -r 967d28b7febe -r 229e02867307 dmd/lexer.h --- a/dmd/lexer.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/lexer.h Sun May 17 00:15:25 2009 +0200 @@ -292,8 +292,8 @@ unsigned wchar(unsigned u); TOK number(Token *t); TOK inreal(Token *t); - void error(const char *format, ...); - void error(Loc loc, const char *format, ...); + void error(const char *format, ...) IS_PRINTF(2); + void error(Loc loc, const char *format, ...) IS_PRINTF(3); void pragma(); unsigned decodeUTF(); void getDocComment(Token *t, unsigned lineComment); diff -r 967d28b7febe -r 229e02867307 dmd/mars.h --- a/dmd/mars.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/mars.h Sun May 17 00:15:25 2009 +0200 @@ -76,6 +76,14 @@ #endif #endif +#ifndef IS_PRINTF +# ifdef __GNUC__ +# define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) )) +# else +# define IS_PRINTF(FMTARG) +# endif +#endif + #ifdef IN_GCC /* Changes for the GDC compiler by David Friedman */ #endif @@ -395,9 +403,9 @@ MATCHexact // exact match }; -void warning(Loc loc, const char *format, ...); +void warning(Loc loc, const char *format, ...) IS_PRINTF(2); void vwarning(Loc loc, const char *format, va_list); -void error(Loc loc, const char *format, ...); +void error(Loc loc, const char *format, ...) IS_PRINTF(2); void verror(Loc loc, const char *format, va_list); void fatal(); void err_nomem(); diff -r 967d28b7febe -r 229e02867307 dmd/mtype.h --- a/dmd/mtype.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/mtype.h Sun May 17 00:15:25 2009 +0200 @@ -267,8 +267,8 @@ Type *next; Type *nextOf() { return next; } - static void error(Loc loc, const char *format, ...); - static void warning(Loc loc, const char *format, ...); + static void error(Loc loc, const char *format, ...) IS_PRINTF(2); + static void warning(Loc loc, const char *format, ...) IS_PRINTF(2); #if IN_DMD // For backend diff -r 967d28b7febe -r 229e02867307 dmd/root/root.h --- a/dmd/root/root.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/root/root.h Sun May 17 00:15:25 2009 +0200 @@ -18,6 +18,14 @@ #pragma once #endif +#ifndef IS_PRINTF +# ifdef __GNUC__ +# define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) )) +# else +# define IS_PRINTF(FMTARG) +# endif +#endif + typedef size_t hash_t; #include "dchar.h" @@ -29,9 +37,9 @@ int bstrcmp(unsigned char *s1, unsigned char *s2); char *bstr2str(unsigned char *b); -void error(const char *format, ...); +void error(const char *format, ...) IS_PRINTF(1); void error(const wchar_t *format, ...); -void warning(const char *format, ...); +void warning(const char *format, ...) IS_PRINTF(1); #ifndef TYPEDEFS #define TYPEDEFS @@ -291,7 +299,7 @@ void fill0(unsigned nbytes); void align(unsigned size); void vprintf(const char *format, va_list args); - void printf(const char *format, ...); + void printf(const char *format, ...) IS_PRINTF(2); #if M_UNICODE void vprintf(const unsigned short *format, va_list args); void printf(const unsigned short *format, ...); diff -r 967d28b7febe -r 229e02867307 dmd/statement.h --- a/dmd/statement.h Sat May 16 23:44:27 2009 +0200 +++ b/dmd/statement.h Sun May 17 00:15:25 2009 +0200 @@ -104,8 +104,8 @@ void print(); char *toChars(); - void error(const char *format, ...); - void warning(const char *format, ...); + void error(const char *format, ...) IS_PRINTF(2); + void warning(const char *format, ...) IS_PRINTF(2); virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs); virtual TryCatchStatement *isTryCatchStatement() { return NULL; } virtual GotoStatement *isGotoStatement() { return NULL; } diff -r 967d28b7febe -r 229e02867307 gen/arrays.cpp --- a/gen/arrays.cpp Sat May 16 23:44:27 2009 +0200 +++ b/gen/arrays.cpp Sun May 17 00:15:25 2009 +0200 @@ -240,7 +240,7 @@ // make sure the number of initializers is sane if (arrinit->index.dim > arrlen || arrinit->dim > arrlen) { - error(arrinit->loc, "too many initializers, %d, for array[%d]", arrinit->index.dim, arrlen); + error(arrinit->loc, "too many initializers, %u, for array[%zu]", arrinit->index.dim, arrlen); fatal(); } @@ -273,7 +273,7 @@ // error check from dmd if (initvals[j] != NULL) { - error(arrinit->loc, "duplicate initialization for index %d", j); + error(arrinit->loc, "duplicate initialization for index %zu", j); } LLConstant* c = DtoConstInitializer(val->loc, elemty, val); diff -r 967d28b7febe -r 229e02867307 gen/logger.h --- a/gen/logger.h Sat May 16 23:44:27 2009 +0200 +++ b/gen/logger.h Sun May 17 00:15:25 2009 +0200 @@ -3,6 +3,14 @@ #include "llvm/Support/Streams.h" +#ifndef IS_PRINTF +# ifdef __GNUC__ +# define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) )) +# else +# define IS_PRINTF(FMTARG) +# endif +#endif + struct Loc; namespace Logger @@ -10,13 +18,13 @@ void indent(); void undent(); llvm::OStream cout(); - void println(const char* fmt, ...); - void print(const char* fmt, ...); + void println(const char* fmt, ...) IS_PRINTF(1); + void print(const char* fmt, ...) IS_PRINTF(1); void enable(); void disable(); bool enabled(); - void attention(Loc loc, const char* fmt, ...); + void attention(Loc loc, const char* fmt, ...) IS_PRINTF(2); struct LoggerScope { diff -r 967d28b7febe -r 229e02867307 gen/main.cpp --- a/gen/main.cpp Sat May 16 23:44:27 2009 +0200 +++ b/gen/main.cpp Sun May 17 00:15:25 2009 +0200 @@ -876,7 +876,7 @@ delete stripMD; if(linker.LinkInModule(llvmModules[i], &errormsg)) - error(errormsg.c_str()); + error("%s", errormsg.c_str()); delete llvmModules[i]; } diff -r 967d28b7febe -r 229e02867307 gen/toir.cpp --- a/gen/toir.cpp Sat May 16 23:44:27 2009 +0200 +++ b/gen/toir.cpp Sun May 17 00:15:25 2009 +0200 @@ -313,7 +313,8 @@ LLConstant* RealExp::toConstElem(IRState* p) { - Logger::print("RealExp::toConstElem: %s @ %s | %LX\n", toChars(), type->toChars(), value); + Logger::print("RealExp::toConstElem: %s @ %s | %LX\n", toChars(), type->toChars(), + 0xFFFFFFFFFFUL & *(long long unsigned*)&value); LOG_SCOPE; Type* t = type->toBasetype(); return DtoConstFP(t, value); @@ -2473,7 +2474,7 @@ IF_LOG Logger::println("expr: %p", expr); if (expr) { - IF_LOG Logger::println("expr = %s", it.index, expr->toChars()); + IF_LOG Logger::println("expr %zu = %s", it.index, expr->toChars()); LLValue* v = DtoExprValue(vd->type, expr); initvalues.push_back(v); } @@ -2606,7 +2607,7 @@ Expression* ekey = (Expression*)keys->data[i]; Expression* eval = (Expression*)values->data[i]; - Logger::println("(%u) aa[%s] = %s", i, ekey->toChars(), eval->toChars()); + Logger::println("(%zu) aa[%s] = %s", i, ekey->toChars(), eval->toChars()); // index DValue* key = ekey->toElem(p); diff -r 967d28b7febe -r 229e02867307 ir/irdsymbol.cpp --- a/ir/irdsymbol.cpp Sat May 16 23:44:27 2009 +0200 +++ b/ir/irdsymbol.cpp Sun May 17 00:15:25 2009 +0200 @@ -9,7 +9,7 @@ void IrDsymbol::resetAll() { - Logger::println("resetting %u Dsymbols", list.size()); + Logger::println("resetting %zu Dsymbols", list.size()); std::set::iterator it; for(it = list.begin(); it != list.end(); ++it) (*it)->reset();