X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/b072092f32623dab70e6ffe1613740542ea66748..b2a40ced6227156a72f33e0fd47452e10309bc8b:/src/cppexp.c diff --git a/src/cppexp.c b/src/cppexp.c index d14d8ea..8182205 100644 --- a/src/cppexp.c +++ b/src/cppexp.c @@ -1,6 +1,6 @@ /* -** LCLint - annotation-assisted static program checker -** Copyright (C) 1994-2001 University of Virginia, +** Splint - annotation-assisted static program checker +** Copyright (C) 1994-2003 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -17,9 +17,9 @@ ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, ** MA 02111-1307, USA. ** -** For information on lclint: lclint-request@cs.virginia.edu -** To report a bug: lclint-bug@cs.virginia.edu -** For more information: http://lclint.cs.virginia.edu +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org +** For more information: http://www.splint.org */ /* ** cppexp.c @@ -54,10 +54,9 @@ Written by Per Bothner 1994. */ /*@+ignorequals@*/ /*@+ignoresigns@*/ /*@+matchanyintegral@*/ -/*@-shiftsigned@*/ # include -# include "lclintMacros.nf" +# include "splintMacros.nf" # include "llbasic.h" # include "cpplib.h" # include "cpphash.h" @@ -74,7 +73,7 @@ Written by Per Bothner 1994. */ /* these are guesses! */ -/*@constant int BITS_PER_UNIT@*/ +/*@constant int BITS_PER_UNIT = 8@*/ # define BITS_PER_UNIT 8 /*@constant size_t BITS_PER_CHAR@*/ @@ -86,7 +85,7 @@ Written by Per Bothner 1994. */ /*@constant size_t HOST_BITS_PER_INT@*/ # define HOST_BITS_PER_INT 32 -/*@constant size_t HOST_BITS_PER_LONG@*/ +/*@constant size_t HOST_BITS_PER_LONG = 32@*/ # define HOST_BITS_PER_LONG 32 /*@constant char TARGET_BELL@*/ @@ -152,9 +151,9 @@ Written by Per Bothner 1994. */ #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE #endif -static struct operation cppReader_lex (cppReader *); +static struct operation cppexp_lex (cppReader *); static void integer_overflow (cppReader *); -static long left_shift (cppReader *, long, bool p_unsignedp, size_t); +static long left_shift (cppReader *, long, bool p_unsignedp, unsigned long); static long right_shift (long, bool p_unsignedp, unsigned long); /*@constant short CPPREADER_ERRORTOK@*/ @@ -239,7 +238,7 @@ struct operation { /* maybe needs to actually deal with floating point numbers */ struct operation -cppReader_parseNumber (cppReader *pfile, char *start, int olen) +cppReader_parseNumber (cppReader *pfile, char *start, int olen) /*@requires maxRead(start) >= (olen - 1) @*/ { struct operation op; char *p = start; @@ -257,7 +256,7 @@ cppReader_parseNumber (cppReader *pfile, char *start, int olen) for (i = 0; i < len; i++) { - if (p[i] == '.') { + if (p[i] == '.') { /* It's a float since it contains a point. */ cppReader_errorLit (pfile, @@ -331,7 +330,7 @@ cppReader_parseNumber (cppReader *pfile, char *start, int olen) /*@innerbreak@*/ break; } - c = *p++; + c = *p++; } /* Don't look for any more digits after the suffixes. */ break; @@ -388,6 +387,7 @@ cppReader_parseNumber (cppReader *pfile, char *start, int olen) op.value = n; op.op = CPPEXP_INT; + DPRINTF (("Parse number: %d", op.value)); return op; } @@ -412,7 +412,7 @@ static struct token tokentab2[] = { /* Read one token. */ -struct operation cppReader_lex (cppReader *pfile) +struct operation cppexp_lex (cppReader *pfile) { int ic; char c; @@ -423,27 +423,39 @@ struct operation cppReader_lex (cppReader *pfile) int old_written; retry: - - old_written = size_toInt (cppReader_getWritten (pfile)); + + old_written = size_toInt (cpplib_getWritten (pfile)); cppSkipHspace (pfile); - ic = cppBufPeek (cppReader_getBufferSafe (pfile)); + ic = cpplib_bufPeek (cppReader_getBufferSafe (pfile)); c = (char) ic; - llassert (c != '#'); - + + if (c == '#') + { + /* was: llassert (c != '#'); - Solaris uses this, attempt to continue anyway... */ + cppReader_pedwarn (pfile, + message ("non-standard pre-processor directive: %c", c)); + } + + DPRINTF (("Read: %c", c)); + if (c == '\n') { op.op = 0; return op; } - token = cppGetToken (pfile); + token = cpplib_getTokenForceExpand (pfile); + tok_start = pfile->token_buffer + old_written; - tok_end = cppReader_getPWritten (pfile); + tok_end = cpplib_getPWritten (pfile); + + DPRINTF (("Token: %s < %s", tok_start, tok_end)); + pfile->limit = tok_start; switch (token) - { + { case CPP_EOF: /* Should not happen ... */ case CPP_VSPACE: op.op = 0; @@ -462,7 +474,7 @@ struct operation cppReader_lex (cppReader *pfile) return cppReader_parseNumber (pfile, tok_start, tok_end - tok_start); case CPP_STRING: cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("string constants not allowed in #if expressions")); + cstring_makeLiteralTemp ("string constants not allowed in #if expressions")); op.op = CPPREADER_ERRORTOK; return op; case CPP_CHAR: @@ -481,7 +493,7 @@ struct operation cppReader_lex (cppReader *pfile) #else char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1]; #endif - + if (*ptr == 'L') { ptr++; @@ -497,9 +509,9 @@ struct operation cppReader_lex (cppReader *pfile) { max_chars = size_toInt (MAX_LONG_TYPE_SIZE / width); } - + ++ptr; - while (ptr < tok_end && ((c = *ptr++) != '\'')) + while (ptr < tok_end && ((c = *ptr++) != '\'')) { if (c == '\\') { @@ -530,24 +542,24 @@ struct operation cppReader_lex (cppReader *pfile) } } - token_buffer[num_chars] = 0; + token_buffer[num_chars] = 0; if (c != '\'') cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("malformatted character constant")); + cstring_makeLiteralTemp ("malformatted character constant")); else if (num_chars == 0) cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("empty character constant")); + cstring_makeLiteralTemp ("empty character constant")); else if (num_chars > max_chars) { num_chars = max_chars; cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("character constant too long")); + cstring_makeLiteralTemp ("character constant too long")); } else if (num_chars != 1 && ! cppReader_isTraditional (pfile)) { cppReader_warningLit (pfile, - cstring_makeLiteralTemp ("multi-character character constant")); + cstring_makeLiteralTemp ("multi-character character constant")); } else { @@ -559,17 +571,19 @@ struct operation cppReader_lex (cppReader *pfile) { int num_bits = num_chars * width; - if ((cppReader_lookup ("__CHAR_UNSIGNED__", + if ((cpphash_lookup ("__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__") - 1, -1) != NULL) - || (((unsigned) result >> (num_bits - 1)) & 1) == 0) + || (((unsigned) result >> (int_toNonNegative (num_bits - 1))) & 1) == 0) { op.value - = result & ((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits)); + = result & ((unsigned long) ~0 + >> int_toNonNegative ((HOST_BITS_PER_LONG - num_bits))); } else { op.value - = result | ~((unsigned long) ~0 >> (HOST_BITS_PER_LONG - num_bits)); + = result | ~((unsigned long) ~0 + >> int_toNonNegative ((HOST_BITS_PER_LONG - num_bits))); } } else @@ -601,6 +615,7 @@ struct operation cppReader_lex (cppReader *pfile) return op; case CPP_NAME: + DPRINTF (("Name!")); return cppReader_parseNumber (pfile, "0", 0); case CPP_OTHER: @@ -609,8 +624,8 @@ struct operation cppReader_lex (cppReader *pfile) { for (toktab = tokentab2; toktab->operator != NULL; toktab++) { - if (tok_start[0] == toktab->operator[0] - && tok_start[1] == toktab->operator[1]) + if (tok_start[0] == toktab->operator[0] && + tok_start[1] == toktab->operator[1]) { /*@loopbreak@*/ break; } @@ -618,7 +633,9 @@ struct operation cppReader_lex (cppReader *pfile) if (toktab->token == CPPREADER_ERRORTOK) { - cppReader_error (pfile, message ("`%s' not allowed in operand of `#if'", cstring_fromChars (tok_start))); + cppReader_error (pfile, + message ("`%s' not allowed in operand of `#if'", + cstring_fromChars (tok_start))); } op.op = toktab->token; @@ -652,7 +669,7 @@ struct operation cppReader_lex (cppReader *pfile) int cppReader_parseEscape (cppReader *pfile, char **string_ptr) { - char c = *(*string_ptr)++; + char c = *(*string_ptr)++; switch (c) { @@ -665,7 +682,7 @@ cppReader_parseEscape (cppReader *pfile, char **string_ptr) if (cppReader_isPedantic (pfile)) { cppReader_pedwarn (pfile, - message ("non-ANSI-standard escape sequence, `\\%c'", c)); + message ("non-standard escape sequence, `\\%c'", c)); } return (char) 033; case 'f': @@ -706,7 +723,7 @@ cppReader_parseEscape (cppReader *pfile, char **string_ptr) else { - (*string_ptr)--; + (*string_ptr)--; /*@loopbreak@*/ break; } } @@ -753,7 +770,7 @@ cppReader_parseEscape (cppReader *pfile, char **string_ptr) cstring_makeLiteralTemp ("\\x used with no following hex digits")); } - if ((overflow | (i & ~((1 << BITS_PER_UNIT) - 1))) != 0) + if ((overflow | (i & ~((1 << int_toNonNegative (BITS_PER_UNIT)) - 1))) != 0) { i &= (1 << BITS_PER_UNIT) - 1; cppReader_pedwarnLit (pfile, @@ -776,7 +793,7 @@ integer_overflow (cppReader *pfile) } static long -left_shift (cppReader *pfile, long a, bool unsignedp, size_t b) +left_shift (cppReader *pfile, long a, bool unsignedp, unsigned long b) { if (b >= HOST_BITS_PER_LONG) { @@ -793,9 +810,13 @@ left_shift (cppReader *pfile, long a, bool unsignedp, size_t b) } else { - long l = a << b; - - if (l >> b != a) + long l = int_toNonNegative (a) << b; + +# ifdef WIN32 +# pragma warning( disable : 4018 ) +# endif + + if (int_toNonNegative (l) >> b != a) { integer_overflow (pfile); } @@ -808,11 +829,11 @@ static long right_shift (long a, bool unsignedp, unsigned long b) { if (b >= HOST_BITS_PER_LONG) - return (unsignedp ? 0 : a >> (HOST_BITS_PER_LONG - 1)); + return (unsignedp ? 0 : int_toNonNegative (a) >> (HOST_BITS_PER_LONG - 1)); else if (unsignedp) return (unsigned long) a >> b; else - return a >> b; + return int_toNonNegative (a) >> b; } /* These priorities are all even, so we can handle associatively. */ @@ -904,7 +925,7 @@ cppReader_parseExpression (cppReader *pfile) int flags = 0; /* Read a token */ - op = cppReader_lex (pfile); + op = cppexp_lex (pfile); /* See if the token is an operand, in which case go to set_value. If the token is an operator, figure out its left and right @@ -973,7 +994,7 @@ cppReader_parseExpression (cppReader *pfile) if ((top->flags & HAVE_VALUE) != 0) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("syntax error in #if")); + cstring_makeLiteralTemp ("syntax error in #if")); goto syntax_error; } top->flags |= HAVE_VALUE; @@ -984,7 +1005,8 @@ cppReader_parseExpression (cppReader *pfile) while (top->rprio > lprio) { /*@-usedef@*/ - long v1 = top[-1].value, v2 = top[0].value; + HOST_WIDE_INT v1 = top[-1].value; + HOST_WIDE_INT v2 = top[0].value; bool unsigned1 = top[-1].unsignedp; bool unsigned2 = top[0].unsignedp; @@ -994,14 +1016,14 @@ cppReader_parseExpression (cppReader *pfile) && ((top[0].flags & HAVE_VALUE) == 0)) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("syntax error - missing left operand")); + cstring_makeLiteralTemp ("syntax error - missing left operand")); goto syntax_error; } if (((top[1].flags & RIGHT_OPERAND_REQUIRED) != 0) && ((top[1].flags & HAVE_VALUE) == 0)) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("syntax error - missing right operand")); + cstring_makeLiteralTemp ("syntax error - missing right operand")); goto syntax_error; } /* top[0].value = (top[1].op)(v1, v2);*/ @@ -1073,7 +1095,7 @@ cppReader_parseExpression (cppReader *pfile) if (v2 == 0) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("Division by zero in #if")); + cstring_makeLiteralTemp ("Division by zero in #if")); v2 = 1; } top->unsignedp = unsigned1 || unsigned2; @@ -1092,7 +1114,7 @@ cppReader_parseExpression (cppReader *pfile) if (v2 == 0) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("Division by zero in #if")); + cstring_makeLiteralTemp ("Division by zero in #if")); v2 = 1; } top->unsignedp = unsigned1 || unsigned2; @@ -1117,7 +1139,7 @@ cppReader_parseExpression (cppReader *pfile) if ((top->flags & HAVE_VALUE) != 0) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("syntax error")); + cstring_makeLiteralTemp ("syntax error")); goto syntax_error; } top->value = ~ v2; @@ -1194,13 +1216,13 @@ cppReader_parseExpression (cppReader *pfile) /*@switchbreak@*/ break; case '(': case '?': cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("syntax error in #if")); + cstring_makeLiteralTemp ("syntax error in #if")); goto syntax_error; case ':': if (top[0].op != '?') { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("syntax error ':' without preceding '?'")); + cstring_makeLiteralTemp ("syntax error ':' without preceding '?'")); goto syntax_error; } else if (((top[1].flags & HAVE_VALUE) == 0) @@ -1208,7 +1230,7 @@ cppReader_parseExpression (cppReader *pfile) || ((top[0].flags & HAVE_VALUE) == 0)) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("bad syntax for ?: operator")); + cstring_makeLiteralTemp ("bad syntax for ?: operator")); goto syntax_error; } else @@ -1230,7 +1252,7 @@ cppReader_parseExpression (cppReader *pfile) || ((top[-1].flags & HAVE_VALUE) != 0)) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("mismatched parentheses in #if")); + cstring_makeLiteralTemp ("mismatched parentheses in #if")); goto syntax_error; } else @@ -1258,7 +1280,7 @@ cppReader_parseExpression (cppReader *pfile) if (top != stack) { cppReader_errorLit (pfile, - cstring_makeLiteralTemp ("internal error in #if expression")); + cstring_makeLiteralTemp ("internal error in #if expression")); } val = top->value; @@ -1277,8 +1299,8 @@ cppReader_parseExpression (cppReader *pfile) if (top == limit) { struct operation *new_stack; - int old_size = (char *) limit - (char *) stack; - size_t new_size = size_fromInt (2 * old_size); + size_t old_size = size_fromInt ((char *) limit - (char *) stack); + size_t new_size = (size_t) (2 * old_size); if (stack != init_stack) {