/*
-** 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
** 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
/*@+ignorequals@*/
/*@+ignoresigns@*/
/*@+matchanyintegral@*/
-/*@-shiftsigned@*/
# include <string.h>
-# include "lclintMacros.nf"
-# include "llbasic.h"
-# include "cpp.h"
+# include "splintMacros.nf"
+# include "basic.h"
# include "cpplib.h"
# include "cpphash.h"
# include "cppexp.h"
/* 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@*/
/*@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@*/
#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@*/
/* 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;
for (i = 0; i < len; i++)
{
- if (p[i] == '.') {
+ if (p[i] == '.') {
/* It's a float since it contains a point. */
cppReader_errorLit
(pfile,
/*@innerbreak@*/ break;
}
- c = *p++;
+ c = *p++;
}
/* Don't look for any more digits after the suffixes. */
break;
if (overflow)
{
- /*@i23 add flags for all these...*/
cppReader_pedwarnLit
(pfile,
cstring_makeLiteralTemp ("Integer constant out of range"));
op.value = n;
op.op = CPPEXP_INT;
+ DPRINTF (("Parse number: %d", op.value));
return op;
}
/* Read one token. */
-struct operation cppReader_lex (cppReader *pfile)
+struct operation cppexp_lex (cppReader *pfile)
{
int ic;
char c;
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;
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:
#else
char token_buffer[MAX_LONG_TYPE_SIZE/MAX_CHAR_TYPE_SIZE + 1];
#endif
-
+
if (*ptr == 'L')
{
ptr++;
{
max_chars = size_toInt (MAX_LONG_TYPE_SIZE / width);
}
-
+
++ptr;
- while (ptr < tok_end && ((c = *ptr++) != '\''))
+ while (ptr < tok_end && ((c = *ptr++) != '\''))
{
if (c == '\\')
{
}
}
- 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
{
{
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
return op;
case CPP_NAME:
+ DPRINTF (("Name!"));
return cppReader_parseNumber (pfile, "0", 0);
case CPP_OTHER:
{
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;
}
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;
int
cppReader_parseEscape (cppReader *pfile, char **string_ptr)
{
- char c = *(*string_ptr)++;
+ char c = *(*string_ptr)++;
switch (c)
{
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':
else
{
- (*string_ptr)--;
+ (*string_ptr)--;
/*@loopbreak@*/ break;
}
}
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,
}
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)
{
}
else
{
- long l = a << b;
-
- if (l >> b != a)
+ /*@-shiftimplementation@*/
+ long l = a << b; /* int_toNonNegative removed (allow shifts of negative values) */
+
+# ifdef WIN32
+# pragma warning( disable : 4018 )
+# endif
+
+ if (l >> b != a) /* int_toNonNegative removed (allow shifts of negative values) */
{
integer_overflow (pfile);
}
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 a >> b; /* int_toNonNegative removed (allow shifts of negative values) */
+ /*@=shiftimplementation@*/
}
/* These priorities are all even, so we can handle associatively. */
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
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;
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;
&& ((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);*/
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;
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;
if ((top->flags & HAVE_VALUE) != 0)
{
cppReader_errorLit (pfile,
- cstring_makeLiteralTemp ("syntax error"));
+ cstring_makeLiteralTemp ("syntax error"));
goto syntax_error;
}
top->value = ~ v2;
/*@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)
|| ((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
|| ((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
if (top != stack)
{
cppReader_errorLit (pfile,
- cstring_makeLiteralTemp ("internal error in #if expression"));
+ cstring_makeLiteralTemp ("internal error in #if expression"));
}
val = top->value;
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)
{