# include "lclintMacros.nf"
# include "basic.h"
-# ifdef SANITIZER
-# include "sgrammar.h"
-# include "sgrammar_tokens.h"
-# else
# include "cgrammar.h"
# include "cgrammar_tokens.h"
-# endif
# include "fileIdList.h"
# include "portab.h"
/* yes, this is exported! */
bool g_expectingTypeName = TRUE; /* beginning of file can be type name! */
+static bool expectingMetaStateName = FALSE;
+
static int returnInt (ctype, long);
static int returnFloat (ctype, double);
static int returnChar (char);
}
# include "flex.head"
+
+/*@-unrecog@*/ /*@i5343@*/
+
%}
%%
{
if (lastWasString)
{
- ;
+ /* was nothing! */ /*@i32@*/
+ RETURN_STRING (cstring_makeLiteral ("\"\""));
}
else
{
"static" { setTokLength (6); RETURN_TOK (QSTATIC); }
\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }
+L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); }
"out" { return (processSpec (QOUT)); }
"in" { return (processSpec (QIN)); }
"partial" { return (processSpec (QPARTIAL)); }
"yield" { return (processSpec (QYIELD)); }
"undef" { return (processSpec (QUNDEF)); }
"killed" { return (processSpec (QKILLED)); }
+"nullterminated" { return (processSpec (QNULLTERMINATED));}
+"MaxSet" { return (processSpec (QMAXSET));}
+"MaxRead" { return (processSpec (QMAXREAD));}
+"maxSet" { return (processSpec (QMAXSET));}
+"maxRead" { return (processSpec (QMAXREAD));}
+
{Letter}({Letter}|{Digit})* { int tok;
context_saveLocation ();
setTokLength (longUnsigned_toInt (mstring_length (yytext)));
"|" { setTokLength (1); RETURN_TOK (TBAR); }
"?" { setTokLength (1); RETURN_TOK (TQUEST); }
+
+"/\\" { setTokLength (1); RETURN_TOK (TCAND); }
+
+
[ \t\v\f] { incColumn (); }
\n { context_incLineno ();
if (continueLine)
}
}
"@.CT" { setTokLength (4); lldiagmsg (ctype_unparseTable ()); }
+"@.FA" { setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); }
"@.F" { setTokLength (3);
lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc)));
}
int tok;
incColumn (); incColumn ();
tok = handleLlSpecial ();
+
if (tok != BADTOK)
{
- RETURN_TOK (tok);
+ if (tok == CANNOTATION) {
+ return (tok);
+ } else {
+ /* Beware - this bashes yylval! */
+ RETURN_TOK (tok);
+ }
}
}
"%}" { /* AFTER_COMMENT_MARKER */
RETURN_TOK (QENDMACRO); }
"\\" { incColumn (); continueLine = TRUE; }
. { incColumn ();
- voptgenerror
- (FLG_SYNTAX,
- message ("Invalid character (ascii: %d), skipping character",
- (int)(*yytext)),
- g_currentloc);
+ if ((int) *yytext == 13 ) {
+ ;
+ } else {
+ voptgenerror
+ (FLG_SYNTAX,
+ message ("Invalid character (ascii: %d), skipping character",
+ (int)(*yytext)),
+ g_currentloc);
+ }
}
%%
{ "modifies", QMODIFIES } ,
{ "globals", QGLOBALS } ,
{ "alt", QALT } ,
+ { "warn", QWARN } ,
{ "constant", QCONSTANT } ,
{ "function", QFUNCTION } ,
{ "iter", QITER } ,
{ "releases", QRELEASES } ,
{ "pre", QPRECLAUSE } ,
{ "post", QPOSTCLAUSE } ,
+ { "setBufferSize", QSETBUFFERSIZE},
+ { "setStringLength", QSETSTRINGLENGTH},
+ { "testinRange", QTESTINRANGE},
+ { "requires", QPRECLAUSE } ,
+ { "ensures", QPOSTCLAUSE } ,
{ NULL, BADTOK }
} ;
{ "killref", QKILLREF } ,
{ "null", QNULL } ,
{ "relnull", QRELNULL } ,
+ { "nullterminated", QNULLTERMINATED },
+ { "setBufferSize", QSETBUFFERSIZE },
+ { "testInRange", QTESTINRANGE},
+ { "MaxSet", QMAXSET},
+ { "MaxRead", QMAXREAD},
{ "reldef", QRELDEF } ,
{ "observer", QOBSERVER } ,
{ "exits", QEXITS } ,
{
return (cstring_equalLit (s, "modifies")
|| cstring_equalLit (s, "globals")
+ || cstring_equalLit (s, "warn")
|| cstring_equalLit (s, "alt"));
}
}
else
{
- checkUngetc (i, yyin);
+ reader_checkUngetc (i, yyin);
return;
}
}
if (i != EOF)
{
- checkUngetc (i, yyin);
+ reader_checkUngetc (i, yyin);
}
}
while (s_parsetable[i].name != NULL)
{
+ DPRINTF (("Try :%s:%s:", s, s_parsetable[i].name));
+
if (cstring_equalLit (s, s_parsetable[i].name))
{
return s_parsetable[i].token;
"This is interpreted by "
"LCLint in the same way as most Unix lints, but it is "
"preferable to replace it with the /*@fallthrough@*/ "
- "stylized comment"),
+ "semantic comment"),
g_currentloc);
return QFALLTHROUGH;
}
"This is interpreted by "
"LCLint in the same way as most Unix lints, but it is "
"preferable to replace it with the /*@fallthrough@*/ "
- "stylized comment"),
+ "semantic comment"),
g_currentloc);
return QFALLTHROUGH;
}
"This is interpreted by "
"LCLint in the same way as most Unix lints, but it is "
"preferable to replace it with the /*@notreached@*/ "
- "stylized comment."),
+ "semantic comment."),
g_currentloc);
return QNOTREACHED;
}
else if (s_keytable[i].token == QPRINTFLIKE)
{
- setSpecialFunction (QU_PRINTFLIKE);
+ setSpecialFunction (qual_createPrintfLike ());
return SKIPTOK;
}
else if (s_keytable[i].token == QLINTPRINTFLIKE)
"/*@scanflike@*/ or /*@messagelike@*/."),
g_currentloc);
- setSpecialFunction (QU_PRINTFLIKE);
+ setSpecialFunction (qual_createPrintfLike ());
return SKIPTOK;
}
else if (s_keytable[i].token == QSCANFLIKE)
{
- setSpecialFunction (QU_SCANFLIKE);
+ setSpecialFunction (qual_createScanfLike ());
return SKIPTOK;
}
else if (s_keytable[i].token == QMESSAGELIKE)
{
- setSpecialFunction (QU_MESSAGELIKE);
+ setSpecialFunction (qual_createMessageLike ());
return SKIPTOK;
}
else if (s_keytable[i].token == QARGSUSED)
}
else /* if (c == '@') */
{
+ llassert (FALSE); /*@i23@*/
if (handleLlSpecial () != BADTOK)
{
llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax");
}
/*
-** keeps stylized comments
+** keeps semantic comments
*/
static char macro_nextCharC ()
if (macrocode == BADTOK && !isArtificial (mac))
{
- DPRINTF (("Add macro: %s", mac));
context_addMacroCache (mac);
}
else
e2 = usymtab_lookupExpose (fname);
ct = uentry_getType (e2);
-
if (uentry_isCodeDefined (e2)
&& fileloc_isUser (uentry_whereDefined (e2)))
{
uentry_showWhereSpecified (e2);
uentry_setType (e2, ctype_unknown);
- uentry_makeVarFunction (e2);
+ uentry_makeConstantFunction (e2);
uentry_setDefined (e2, g_currentloc);
uentry_setFunctionDefined (e2, g_currentloc);
context_enterUnknownMacro (e2);
&& !uentry_isElipsisMarker (uentryList_getN
(specparams, paramno)))
{
+ fileloc sloc = context_getSaveLocation ();
uentry decl = uentryList_getN (specparams, paramno);
sRef sr;
uentry_setParam (param);
- sr = sRef_makeParam (paramno, uentry_getType (param));
+ sr = sRef_makeParam (paramno, uentry_getType (param), stateInfo_makeLoc (sloc));
if (sRef_getNullState (sr) == NS_ABSNULL)
{
}
else
{
- sRef_setNullState (sr, NS_UNKNOWN, g_currentloc);
+ sRef_setNullState (sr, NS_UNKNOWN, sloc);
}
}
uentry_setSref (param, sr);
- uentry_setDeclaredForceOnly (param, context_getSaveLocation ());
+ uentry_setDeclaredForceOnly (param, sloc);
skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno));
}
fileloc sloc = context_getSaveLocation ();
param = uentry_makeVariableSrefParam
- (paramname, ctype_unknown, sRef_makeParam (paramno, ctype_unknown));
+ (paramname, ctype_unknown, fileloc_copy (sloc),
+ sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (sloc)));
cstring_free (paramname);
sRef_setPosNull (uentry_getSref (param), sloc);
-
uentry_setDeclaredForce (param, sloc);
skipparam = FALSE;
|| (sscanf (ol, " %d \"", &lineno) == 1))
{
char *tmp = ol;
- char *fname;
+ cstring fname;
fileId fid;
+ /*@access cstring@*/
while (*tmp != '\"' && *tmp != '\0')
{
tmp++;
llassert (*tmp == '\"');
tmp++;
+
fname = tmp;
while (*tmp != '\"' && *tmp != '\0')
*tmp = '\0';
- DPRINTF (("fname: %s", fname));
-
# if defined(OS2) || defined(MSDOS) || defined(WIN32)
/*
** Skip past the drive marker.
*/
- DPRINTF (("stmp: %s / %s", stmp, fname));
-
if (strchr (stmp, ':') != NULL)
{
stmp = strchr (stmp, ':') + 1;
}
- DPRINTF (("stmp: %s / %s", stmp, fname));
-
while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL )
{
if (*(stmp+1) == CONNECTCHAR)
}
stmp++;
- DPRINTF (("stmp: %s / %s", stmp, fname));
}
- DPRINTF (("Now: base = %s", fname));
-
- fid = fileTable_lookupBase (context_fileTable (),
- cstring_fromChars (fname));
+ fid = fileTable_lookupBase (context_fileTable (), fname);
if (!(fileId_isValid (fid)))
{
fname = removePreDirs (fname);
- fid = fileTable_lookupBase (context_fileTable (),
- cstring_fromChars (fname));
+ fid = fileTable_lookupBase (context_fileTable (), fname);
}
}
# else /* !defined(OS2) && !defined(MSDOS) */
fname = removePreDirs (fname);
- fid = fileTable_lookupBase (context_fileTable (),
- cstring_fromChars (fname));
+ fid = fileTable_lookupBase (context_fileTable (), fname);
# endif /* !defined(OS2) && !defined(MSDOS) */
if (!(fileId_isValid (fid)))
{
- if (isHeaderFile (cstring_fromChars (fname)))
+ if (context_inXHFile ())
{
- fid = fileTable_addHeaderFile (context_fileTable (),
- cstring_fromChars (fname));
+ fid = fileTable_addXHFile (context_fileTable (), fname);
+ }
+ else if (isHeaderFile (fname))
+ {
+ fid = fileTable_addHeaderFile (context_fileTable (), fname);
}
else
{
- fid = fileTable_addFile (context_fileTable (),
- cstring_fromChars (fname));
+ fid = fileTable_addFile (context_fileTable (), fname);
}
}
setFileLine (fid, lineno);
+ /*@noaccess cstring@*/
}
else if ((sscanf (ol, "line %d", &lineno) == 1)
|| (sscanf (ol, " %d", &lineno) == 1))
char *os;
int tok;
int charsread = 0;
+ fileloc loc;
+
+ loc = fileloc_copy (g_currentloc);
+ DPRINTF (("Handle special: %s", fileloc_unparse (loc)));
while (((ic = ninput ()) != 0) && isalpha (ic))
{
charsread++;
}
+ DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));
os = s;
if (charsread == 0 && ic == (int) AFTER_COMMENT_MARKER[0])
ic = ninput ();
llassert (ic == AFTER_COMMENT_MARKER[1]);
-
- if (isProcessingGlobMods () && (*s == '\0'))
+ if (*s == '\0')
{
sfree (os);
+ fileloc_free (loc);
return QNOMODS; /* special token no modifications token */
}
- else
- {
- ;
- }
}
+ DPRINTF (("Coment marker: %s", os));
tok = commentMarkerToken (cstring_fromChars (os));
if (tok != BADTOK)
tokLength = charsread;
sfree (os);
inSpecPart = TRUE;
+ fileloc_free (loc);
return tok;
}
-
+
+ DPRINTF (("Not a comment marker..."));
/* Add rest of the comment */
if (ic != 0 && ic != EOF)
{
c = (char) ic;
-
s = mstring_append (s, c);
charsread++;
}
}
+ DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc)));
+
if (ic == AFTER_COMMENT_MARKER[0])
{
int nc = ninput ();
charsread++;
}
-
os = s;
while (*s == ' ' || *s == '\t' || *s == '\n')
{
cstring flagname = thisflag;
flagcode fflag = identifyFlag (flagname);
-
+
if (flagcode_isSkip (fflag))
{
;
llerror
(FLG_BADFLAG,
message
- ("Stylized comment attempts to restore flag %s. "
+ ("Semantic comment attempts to restore flag %s. "
"A mode flag cannot be restored.",
flagname));
}
}
else
{
- llerror
- (FLG_BADFLAG,
- message ("Unrecognized option in stylized comment: %s",
- flagname));
+ voptgenerror
+ (FLG_UNRECOGFLAGCOMMENTS,
+ message ("Unrecognized option in semantic comment: %s",
+ flagname),
+ g_currentloc);
}
}
else if (flagcode_isGlobalFlag (fflag))
{
- llerror
+ voptgenerror
(FLG_BADFLAG,
message
- ("Stylized comment attempts to set global flag %s. "
+ ("Semantic comment attempts to set global flag %s. "
"A global flag cannot be set locally.",
- flagname));
+ flagname),
+ g_currentloc);
}
else
{
context_fileSetFlag (fflag, set);
-
+
if (flagcode_hasArgument (fflag))
{
if (ynm_isMaybe (set))
{
- llerror
+ voptgenerror
(FLG_BADFLAG,
message
- ("Stylized comment attempts to restore flag %s. "
+ ("Semantic comment attempts to restore flag %s. "
"A flag for setting a value cannot be restored.",
- flagname));
+ flagname),
+ g_currentloc);
}
else
{ /* cut-and-pastied from llmain...blecch */
}
sfree (orest);
-
+
if (cstring_isUndefined (extra))
{
llerror
(FLG_BADFLAG,
message
- ("Flag %s (in stylized comment) must be followed by an argument",
+ ("Flag %s (in semantic comment) must be followed by an argument",
flagcode_unparse (fflag)));
}
else
}
else
{
- }
+ ;
+ }
*s = c;
while ((c == ' ') || (c == '\t') || (c == '\n'))
if (context_inHeader () && !isArtificial (cstring_fromChars (os)))
{
- context_addComment (cstring_fromCharsNew (os));
+ DPRINTF (("Here adding comment: %s", os));
+ context_addComment (cstring_fromCharsNew (os));
}
else
{
char *t = s;
int macrocode;
char tchar = '\0';
+ annotationInfo ainfo;
while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n')
{
if (macrocode != BADTOK)
{
tokLength = mstring_length (t);
-
sfree (t);
sfree (os);
+ fileloc_free (loc);
if (macrocode == SKIPTOK)
{
return macrocode;
}
+ ainfo = context_lookupAnnotation (cstring_fromChars (os));
+
+ if (annotationInfo_isDefined (ainfo)) {
+ DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));
+ /*@i324@*/ yylval.annotation = ainfo;
+ tokLength = 0;
+ sfree (os);
+ sfree (t);
+ fileloc_free (loc);
+ return CANNOTATION;
+ }
+
if (context_inHeader ())
{
if (tchar != '\0')
&& macrocode != SKIPTOK
&& !isArtificial (cstring_fromChars (os)))
{
+ DPRINTF (("Add comment: %s", os));
context_addComment (cstring_fromCharsNew (os));
}
else
*s = '\0';
-
+ DPRINTF (("Access %s", tname));
+
if (!context_getFlag (FLG_NOCOMMENTS)
&& !context_getFlag (FLG_NOACCESS))
{
if (usymtab_existsType (tname))
{
- usymId uid = usymtab_getTypeId (tname);
+ typeId uid = usymtab_getTypeId (tname);
+ uentry ue = usymtab_getTypeEntry (uid);
- context_addFileAccessType (uid);
+ if (uentry_isAbstractDatatype (ue))
+ {
+ context_addFileAccessType (uid);
+ DPRINTF (("Adding access to: %s / %d", tname, uid));
+ }
+ else
+ {
+ voptgenerror
+ (FLG_COMMENTERROR,
+ message
+ ("Non-abstract type %s used in access comment",
+ tname),
+ g_currentloc);
+ }
}
else
{
if (!(context_inSuppressRegion ()
|| context_inSuppressZone (g_currentloc)))
{
- llmsg
- (message
- ("%q: Unrecognized type %s used in access comment",
- fileloc_unparse (g_currentloc), tname));
+ voptgenerror
+ (FLG_COMMENTERROR,
+ message
+ ("Unrecognized type %s used in access comment",
+ tname),
+ g_currentloc);
}
}
}
if (context_couldHaveAccess (tuid))
{
+ DPRINTF (("Removing access: %s", tname));
context_removeFileAccessType (tuid);
}
else
if (uentry_isAbstractDatatype (ue))
{
- llmsg
- (message
- ("%q: Non-accessible abstract type %s used in noaccess comment",
- fileloc_unparse (g_currentloc), tname));
+ voptgenerror
+ (FLG_COMMENTERROR,
+ message
+ ("Non-accessible abstract type %s used in noaccess comment",
+ tname),
+ g_currentloc);
}
else
{
- llmsg
- (message
- ("%q: Non-abstract type %s used in noaccess comment",
- fileloc_unparse (g_currentloc), tname));
+ voptgenerror
+ (FLG_COMMENTERROR,
+ message
+ ("Non-abstract type %s used in noaccess comment",
+ tname),
+ g_currentloc);
}
}
}
if (!(context_inSuppressRegion ()
|| context_inSuppressZone (g_currentloc)))
{
- llmsg
- (message
- ("%q: Unrecognized type %s used in noaccess comment",
- fileloc_unparse (g_currentloc), tname));
+ voptgenerror
+ (FLG_COMMENTERROR,
+ message
+ ("Unrecognized type %s used in noaccess comment",
+ tname),
+ g_currentloc);
}
}
}
}
else
{
- setTokLength (- (2 + charsread));
-
voptgenerror (FLG_UNRECOGCOMMENTS,
- message ("Stylized comment unrecognized: %s",
- cstring_fromChars (os)),
- g_currentloc);
+ message ("Semantic comment unrecognized: %s",
+ cstring_fromChars (os)), loc);
}
sfree (t);
}
- sfree (os);
+ sfree (os);
+ fileloc_free (loc);
return BADTOK;
}
{
uentry le;
- DPRINTF (("Process identifier: %s", id));
+ if (context_getFlag (FLG_GRAMMAR))
+ {
+ lldiagmsg (message ("Process identifier: %s", id));
+ }
context_clearJustPopped ();
lastidprocessed = id;
- if (context_inFunctionDecl ())
+ if (context_inFunctionHeader ())
{
int tok = commentMarkerToken (id);
+ DPRINTF (("in function decl..."));
if (tok != BADTOK)
{
{
return tok;
}
+ else
+ {
+ annotationInfo ainfo;
+
+ if (expectingMetaStateName)
+ {
+ metaStateInfo msinfo = context_lookupMetaStateInfo (id);
+
+ if (metaStateInfo_isDefined (msinfo))
+ {
+ yylval.msinfo = msinfo;
+ return METASTATE_NAME;
+ }
+ else
+ {
+ DPRINTF (("Not meta state name: %s", cstring_toCharsSafe (id)));
+ }
+ }
+
+ ainfo = context_lookupAnnotation (id);
+
+ if (annotationInfo_isDefined (ainfo))
+ {
+ DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo)));
+ /*@i324@*/ yylval.annotation = ainfo;
+ return CANNOTATION;
+ }
+ else
+ {
+ DPRINTF (("Not annotation: %s", id));
+ }
+ }
}
}
if (uentry_isIter (le))
{
- yylval.entry = le;
+ /*@i32@*/ yylval.entry = le;
return (ITER_NAME);
}
else if (uentry_isEndIter (le))
{
- yylval.entry = le;
+ /*@i32@*/ yylval.entry = le;
return (ITER_ENDNAME);
}
else if (uentry_isUndefined (le))
}
else
{
- yylval.entry = le;
+ /*@i32@*/ yylval.entry = le;
return (IDENTIFIER);
}
}
}
else
{
- yylval.entry = le;
+ /*@i32@*/ yylval.entry = le;
return (IDENTIFIER);
}
tval = (int) c - (int) 'A' + 10;
} else if (c >= 'a' && c <= 'f') {
tval = (int) c - (int) 'a' + 10;
+ } else if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
+ index++;
+ while (yytext[index] != '\0') {
+ if (c == 'U' || c == 'L' || c == 'u' || c == 'l') {
+ ;
+ } else {
+ voptgenerror
+ (FLG_SYNTAX,
+ message ("Invalid character (%c) following specifier in hex constant: %s",
+ c, cstring_fromChars (yytext)),
+ g_currentloc);
+ }
+ index++;
+ }
+
+ break;
} else {
voptgenerror
(FLG_SYNTAX,
return (processIdentifier (makeIdentifier (yytext)));
}
}
+
+void cscanner_expectingMetaStateName ()
+{
+ llassert (!expectingMetaStateName);
+ llassert (context_inFunctionHeader ());
+ expectingMetaStateName = TRUE;
+}
+
+void cscanner_clearExpectingMetaStateName ()
+{
+ llassert (expectingMetaStateName);
+ expectingMetaStateName = FALSE;
+}