From 16c024b587f5ddc115928d5cca7095508aa208d9 Mon Sep 17 00:00:00 2001 From: evans1629 Date: Wed, 18 Dec 2002 01:05:57 +0000 Subject: [PATCH] Improved tracking of state change locations. Added +showdeephistory flag to display all available information about state changes. Added +locindentspaces to control indentation of sub-messages (to allow emacs error jumping). Separated cscanner.l code into cscannerHelp.c to distinguish it from flex-generated code. --- src/.splintrc | 2 + src/Headers/cgrammar.h | 6 - src/Headers/constants.h | 8 + src/Headers/context.h | 3 + src/Headers/cscanner.h | 13 +- src/Headers/cscannerHelp.h | 90 + src/Headers/flag_codes.h | 2 +- src/Headers/flags.h | 4 +- src/Headers/lltok.h | 13 +- src/Headers/sRef.h | 4 + src/Headers/stateInfo.h | 77 +- src/Makefile.am | 4 +- src/Makefile.in | 4 +- src/cgrammar.c.der | 167 +- src/cgrammar.y | 25 +- src/clabstract.c | 12 +- src/constraintExpr.c | 4 +- src/constraintGeneration.c | 22 +- src/constraintTerm.c | 2 +- src/context.c | 6 + src/cscanner.l | 3353 +++--------------------------------- src/cscannerHelp.c | 2832 ++++++++++++++++++++++++++++++ src/ctbase.i | 3 + src/exprNode.c | 53 +- src/flags.c | 13 +- src/flags.def | 23 + src/llerror.c | 7 +- src/llmain.c | 2 +- src/lltok.c | 17 +- src/loopHeuristics.c | 4 +- src/nameChecks.c | 15 +- src/sRef.c | 303 ++-- src/stateInfo.c | 366 +++- src/stateValue.c | 5 +- src/uentry.c | 59 +- src/usymtab.c | 25 +- test/Makefile.am | 6 +- test/Makefile.in | 7 +- test/alias.expect | 2 +- test/arraylit.expect | 2 + test/cases.expect | 12 +- test/chararraylit.expect | 1 + test/clauses.expect | 20 +- test/compdestroy.expect | 4 +- test/db1.expect | 27 +- test/db1/Makefile | 4 +- test/db2.expect | 28 +- test/deadparam.expect | 4 +- test/fields.expect | 4 +- test/keep.expect | 3 + test/linked.expect | 2 +- test/list.expect | 3 + test/manual.expect | 13 +- test/mystrncat.expect | 1 + test/null.expect | 18 +- test/numabstract.c | 31 +- test/numabstract.expect | 23 +- test/observer.expect | 12 +- test/outglob.expect | 6 +- test/outparam.expect | 2 +- test/refcounts.expect | 2 +- test/repexpose.expect | 6 +- test/sharing.expect | 14 +- test/stack.expect | 4 +- test/strchr.expect | 7 +- test/strchr/.splintrc | 2 - test/strchr/strchr.c | 1 - test/strings.expect | 2 + test/structassign.expect | 6 +- test/tests2.5.expect | 2 +- test/union.expect | 6 +- 71 files changed, 4248 insertions(+), 3587 deletions(-) create mode 100644 src/Headers/cscannerHelp.h create mode 100644 src/cscannerHelp.c diff --git a/src/.splintrc b/src/.splintrc index 61e8dd7..e7af515 100644 --- a/src/.splintrc +++ b/src/.splintrc @@ -7,6 +7,8 @@ +checks # checks mode (moderately strict checking) ### Display Flags +-locindentspaces 0 ++showdeephistory +showscan +showsummary +stats diff --git a/src/Headers/cgrammar.h b/src/Headers/cgrammar.h index 6130229..ebf7a20 100644 --- a/src/Headers/cgrammar.h +++ b/src/Headers/cgrammar.h @@ -7,12 +7,6 @@ ** cgrammar.h */ -/*@-declundef@*/ /* In case cgrammar.y isn't processed... */ -extern bool g_expectingTypeName ; -extern /*@dependent@*/ /*@observer@*/ uentry coerceId (cstring p_cn); -extern /*@observer@*/ uentry coerceIterId (cstring p_cn); -/*@=declundef@*/ - /* #ifndef NCGRAM2 ** # include "cgrammar_tokens.h" ** #endif diff --git a/src/Headers/constants.h b/src/Headers/constants.h index 261b39e..2a9add2 100644 --- a/src/Headers/constants.h +++ b/src/Headers/constants.h @@ -111,6 +111,14 @@ /*@constant int DEFAULT_INDENTSPACES=3; @*/ # define DEFAULT_INDENTSPACES 3 +/* +** Setting this to 0 means emacs compile mode will +** jump to the locations in message hints. +*/ + +/*@constant int DEFAULT_LOCINDENTSPACES=3; @*/ +# define DEFAULT_LOCINDENTSPACES 3 + /* ** These constants are based on implementation limits in ANSI standard, ** Section 3.1. diff --git a/src/Headers/context.h b/src/Headers/context.h index 2493d31..a272f29 100644 --- a/src/Headers/context.h +++ b/src/Headers/context.h @@ -154,6 +154,9 @@ extern int context_getLineLen (void) /*@*/ ; extern int context_getIndentSpaces (void) /*@*/ ; # define context_getIndentSpaces() ((int)context_getValue(FLG_INDENTSPACES)) +extern int context_getLocIndentSpaces (void) /*@*/ ; +# define context_getLocIndentSpaces() ((int)context_getValue(FLG_LOCINDENTSPACES)) + extern int context_getValue (flagcode p_flag) /*@*/ ; extern void context_setValueAndFlag (flagcode p_flag, int p_val) /*@modifies internalState@*/ ; diff --git a/src/Headers/cscanner.h b/src/Headers/cscanner.h index ef0106e..0a95fff 100644 --- a/src/Headers/cscanner.h +++ b/src/Headers/cscanner.h @@ -8,17 +8,19 @@ */ /*@-declundef@*/ /* Don't always check cscanner.c */ -extern /*@observer@*/ cstring cscanner_observeLastIdentifier (void) ; -extern void cscanner_expectingMetaStateName (void) /*@modifies internalState@*/ ; -extern void cscanner_clearExpectingMetaStateName (void) /*@modifies internalState@*/ ; extern void cscanner_swallowMacro (void) /*@modifies internalState, fileSystem@*/ ; +extern int cscanner_input (void) /*@modifies internalState, fileSystem@*/ ; +extern void cscanner_unput (int) /*@modifies internalState, fileSystem@*/ ; + +extern int cscanner_returnFloat (ctype p_ct, double p_f) /*@modifies internalState@*/ ; +extern int cscanner_returnInt (ctype p_ct, long p_i) /*@modifies internalState@*/ ; +extern int cscanner_returnChar (char p_c) /*@modifies internalState@*/ ; + /* ** These are all exported by bison, but not declared: */ -# ifdef S_SPLINT_S - /*@-namechecks@*/ typedef struct yy_buffer_state *YY_BUFFER_STATE; @@ -40,4 +42,3 @@ extern /*@unused@*/ int yynerrs; /*@=namechecks@*/ /*@=declundef@*/ -# endif diff --git a/src/Headers/cscannerHelp.h b/src/Headers/cscannerHelp.h new file mode 100644 index 0000000..bec0793 --- /dev/null +++ b/src/Headers/cscannerHelp.h @@ -0,0 +1,90 @@ +/* +** Copyright (C) University of Virginia, Massachusetts Institue of Technology 1994-2001. +** See ../LICENSE for license information. +** +*/ +/* +** cscannerHelp.h +*/ + +# ifndef CSCANNERHELP_H +# define CSCANNERHELP_H + +extern void cscannerHelp_swallowMacro (void) ; +extern bool cscannerHelp_processMacro (void) ; +extern void cscannerHelp_handleMacro (void) ; + +extern void cscannerHelp_exitSpecPart (void) /*@modifies internalState@*/ ; + +extern void cscannerHelp_setContinueLine (void) /*@modifies internalState@*/ ; + +extern int cscannerHelp_returnToken (int p_t) + /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_returnTokenLength (int p_t, int p_length) + /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_returnString (/*@only@*/ cstring p_s) + /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_returnInt (ctype p_ct, long p_val) + /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_returnFloat (ctype p_ct, double p_f) + /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_returnChar (char p_c) + /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_returnType (int p_tok, ctype p_ct) + /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_returnExpr (/*@only@*/ exprNode p_e) + /*@modifies g_currentloc, internalState@*/ ; + +extern void cscannerHelp_setTokLength (int) /*@modifies g_currentloc, internalState@*/ ; +extern void cscannerHelp_setTokLengthT (size_t) /*@modifies g_currentloc, internalState@*/ ; +extern void cscannerHelp_advanceLine (void) /*@modifies g_currentloc, internalState@*/ ; + +extern /*@observer@*/ cstring cscannerHelp_observeLastIdentifier (void) ; +extern int cscannerHelp_handleLlSpecial (void) /*@modifies g_currentloc, internalState@*/ ; +extern bool cscannerHelp_handleSpecial (char *) /*@modifies g_currentloc, internalState@*/ ; +extern /*@only@*/ cstring cscannerHelp_makeIdentifier (char *); + +extern bool cscannerHelp_isConstraintToken (int p_tok) /*@*/ ; + +extern int cscannerHelp_handleNewLine (void) /*@modifies g_currentloc, internalState@*/ ; + +extern int cscannerHelp_processTextIdentifier (char *) /*@modifies internalState@*/ ; +extern int cscannerHelp_processIdentifier (/*@only@*/ cstring) /*@modifies internalState@*/ ; +extern bool cscannerHelp_processHashIdentifier (/*@only@*/ cstring) /*@modifies internalState@*/ ; + +extern int cscannerHelp_processSpec (int p_tok) /*@modifies internalState@*/ ; +extern char cscannerHelp_processChar (void) /*@modifies internalState@*/ ; +extern double cscannerHelp_processFloat (void) /*@modifies internalState@*/ ; +extern /*@only@*/ exprNode cscannerHelp_processString (void) /*@modifies internalState@*/ ; +extern /*@only@*/ exprNode cscannerHelp_processWideString (void) /*@modifies internalState@*/ ; +extern long cscannerHelp_processDec (void) /*@modifies internalState@*/ ; +extern long cscannerHelp_processHex (void) /*@modifies internalState@*/ ; +extern long cscannerHelp_processOctal (void) /*@modifies internalState@*/ ; + +extern void cscannerHelp_expectingMetaStateName (void) + /*@modifies internalState@*/ ; + +extern void cscannerHelp_clearExpectingMetaStateName (void) + /*@modifies internalState@*/ ; + +extern /*@observer@*/ uentry cscannerHelp_coerceId (cstring p_cn); +extern /*@observer@*/ uentry cscannerHelp_coerceIterId (cstring p_cn); + +extern void cscannerHelp_setExpectingTypeName (void) /*@modifies internalState@*/ ; +extern void cscannerHelp_clearExpectingTypeName (void) /*@modifies internalState@*/ ; +extern bool cscannerHelp_isExpectingTypeName (void) /*@globals internalState@*/ ; + +extern int cscannerHelp_ninput (void) /*@modifies internalState, g_currentloc@*/; + +# else +# error "Multiple include." +# endif + + diff --git a/src/Headers/flag_codes.h b/src/Headers/flag_codes.h index 5f403b4..f4e4b6d 100644 --- a/src/Headers/flag_codes.h +++ b/src/Headers/flag_codes.h @@ -27,7 +27,7 @@ typedef enum # define NUMFLAGS (LAST_FLAG) /*@constant int NUMVALUEFLAGS; @*/ -# define NUMVALUEFLAGS 14 +# define NUMVALUEFLAGS 15 /*@constant int NUMSTRINGFLAGS; @*/ # define NUMSTRINGFLAGS 28 diff --git a/src/Headers/flags.h b/src/Headers/flags.h index e441ade..2efdfe3 100644 --- a/src/Headers/flags.h +++ b/src/Headers/flags.h @@ -42,8 +42,8 @@ extern /*@only@*/ cstring describeFlag (cstring p_flagname); extern flagcode flags_identifyFlag (cstring p_s) /*@modifies g_warningstream@*/ ; extern flagcode flags_identifyFlagQuiet (cstring p_s) /*@modifies nothing@*/ ; -extern void setValueFlag (flagcode p_opt, cstring p_arg); -extern void setStringFlag (flagcode p_opt, /*@only@*/ cstring p_arg); +extern void flags_setValueFlag (flagcode p_opt, /*@only@*/ cstring p_arg); +extern void flags_setStringFlag (flagcode p_opt, /*@only@*/ cstring p_arg); extern /*@observer@*/ cstring flagcode_unparse (flagcode p_code) /*@*/ ; extern int flagcode_valueIndex (flagcode p_f) /*@*/ ; diff --git a/src/Headers/lltok.h b/src/Headers/lltok.h index 4188f67..a7d5deb 100644 --- a/src/Headers/lltok.h +++ b/src/Headers/lltok.h @@ -31,17 +31,18 @@ extern int lltok_getTok (lltok p_t) /*@*/ ; extern bool lltok_isSemi (lltok p_tok); /* DRL added 10/23/2000 for boolean stuff */ -extern bool lltok_isEq_Op (lltok p_tok); +extern bool lltok_isEqOp (lltok p_tok); +extern bool lltok_isNotEqOp (lltok p_tok); extern bool lltok_isMult (lltok p_tok); -extern bool lltok_isInc_Op (lltok p_tok); +extern bool lltok_isIncOp (lltok p_tok); -extern bool lltok_isAnd_Op (lltok p_tok); +extern bool lltok_isAndOp (lltok p_tok); -extern bool lltok_isOr_Op (lltok p_tok); +extern bool lltok_isOrOp (lltok p_tok); -extern bool lltok_isNot_Op (lltok p_tok); +extern bool lltok_isNotOp (lltok p_tok); /*drl7x added this function 11/20/00 */ @@ -63,7 +64,7 @@ bool lltok_isMinus_Op (lltok p_tok); /*drl added 1/14/2001 */ -bool lltok_isDec_Op (lltok p_tok); +bool lltok_isDecOp (lltok p_tok); bool lltok_isAmpersand_Op (lltok p_tok); extern bool lltok_isExcl_Op (lltok p_tok); diff --git a/src/Headers/sRef.h b/src/Headers/sRef.h index 53249e0..688890a 100644 --- a/src/Headers/sRef.h +++ b/src/Headers/sRef.h @@ -640,6 +640,10 @@ extern int sRef_getLen(sRef p_s); #define sRef_getLen(p_s) \ ((p_s)->bufinfo.len) +extern /*@falsewhennull@*/ bool sRef_hasExpInfoLoc (sRef) /*@*/ ; +extern /*@falsewhennull@*/ bool sRef_hasStateInfoLoc (sRef) /*@*/ ; +extern /*@falsewhennull@*/ bool sRef_hasAliasInfoLoc (sRef) /*@*/ ; + extern bool sRef_hasBufStateInfo(sRef p_s); # define sRef_hasBufStateInfo(p_s) \ (sRef_isValid(p_s)) diff --git a/src/Headers/stateInfo.h b/src/Headers/stateInfo.h index 8ff6f27..d37f1cc 100644 --- a/src/Headers/stateInfo.h +++ b/src/Headers/stateInfo.h @@ -11,10 +11,61 @@ typedef /*@null@*/ struct s_stateInfo *stateInfo ; +typedef enum { + SA_UNKNOWN, + + /* Any type of action */ + SA_CREATED, + SA_DECLARED, + SA_CHANGED, + + /* Definition actions */ + SA_UNDEFINED, + SA_MUNDEFINED, + SA_PDEFINED, + SA_DEFINED, + SA_RELEASED, + SA_ALLOCATED, + SA_KILLED, + SA_PKILLED, + SA_MERGED, + + /* sharing actions */ + SA_SHARED, + SA_ONLY, + SA_IMPONLY, + SA_OWNED, + SA_DEPENDENT, + SA_IMPDEPENDENT, + SA_KEPT, + SA_KEEP, + SA_FRESH, + SA_XSTACK, /* SA_STACK is defined in some Linux headers (but ISO does not reserve this namespace) */ + SA_TEMP, + SA_IMPTEMP, + SA_STATIC, + SA_LOCAL, + + SA_REFCOUNTED, + SA_REFS, + SA_NEWREF, + SA_KILLREF, + + /* exposure */ + SA_EXPOSED, + SA_OBSERVER, + + /* nullity actions */ + SA_BECOMESNULL, + SA_BECOMESNONNULL, + SA_BECOMESPOSSIBLYNULL, + +} stateAction; /*@null@*/ struct s_stateInfo { - /*@only@*/ fileloc loc; + /*@only@*/ fileloc loc; + stateAction action; /*@observer@*/ sRef ref; /*@null@*/ stateInfo previous; } ; @@ -29,21 +80,35 @@ extern void stateInfo_free (/*@only@*/ stateInfo p_a); extern /*@only@*/ stateInfo stateInfo_update (/*@only@*/ stateInfo p_old, stateInfo p_newinfo); -extern /*@only@*/ stateInfo stateInfo_updateLoc (/*@only@*/ stateInfo p_old, fileloc p_loc) ; +extern /*@only@*/ stateInfo stateInfo_updateLoc (/*@only@*/ stateInfo p_old, + stateAction p_action, + fileloc p_loc) ; extern /*@only@*/ stateInfo - stateInfo_updateRefLoc (/*@only@*/ stateInfo p_old, /*@exposed@*/ sRef p_ref, fileloc p_loc) ; + stateInfo_updateRefLoc (/*@only@*/ stateInfo p_old, /*@exposed@*/ sRef p_ref, + stateAction p_action, + fileloc p_loc) ; extern /*@only@*/ stateInfo stateInfo_copy (stateInfo p_a); extern /*@only@*/ /*@notnull@*/ stateInfo stateInfo_currentLoc (void) ; -extern /*@only@*/ /*@notnull@*/ stateInfo stateInfo_makeLoc (fileloc p_loc) ; -extern /*@only@*/ /*@notnull@*/ stateInfo stateInfo_makeRefLoc (/*@exposed@*/ sRef p_ref, fileloc p_loc) ; + +extern /*@only@*/ /*@notnull@*/ stateInfo +stateInfo_makeLoc (fileloc p_loc, stateAction p_action) /*@*/ ; + +extern /*@only@*/ /*@notnull@*/ stateInfo +stateInfo_makeRefLoc (/*@exposed@*/ sRef p_ref, fileloc p_loc, stateAction p_action) /*@*/ ; extern /*@observer@*/ fileloc stateInfo_getLoc (stateInfo p_info) ; extern /*@only@*/ cstring stateInfo_unparse (stateInfo p_s) /*@*/ ; -extern void stateInfo_display (stateInfo p_s, /*@only@*/ cstring p_sname) /*@modifies g_errorstream@*/ ; +extern stateAction stateAction_fromSState (sstate p_ss) /*@*/ ; +extern stateAction stateAction_fromNState (nstate p_ns) /*@*/ ; +extern stateAction stateAction_fromExkind (exkind p_ex) /*@*/ ; +extern stateAction stateAction_fromAlkind (alkind p_ak) /*@*/ ; + +extern void stateInfo_display (stateInfo p_s, /*@only@*/ cstring p_sname) + /*@modifies g_errorstream@*/ ; # else # error "Multiple include" diff --git a/src/Makefile.am b/src/Makefile.am index 39c5f1c..0dadfc1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -41,7 +41,7 @@ CSRC = context.c uentry.c cprim.c macrocache.c qual.c qtype.c stateClause.c \ globalsClause.c modifiesClause.c warnClause.c functionClause.c \ functionClauseList.c metaStateConstraint.c metaStateConstraintList.c \ metaStateExpression.c metaStateSpecifier.c functionConstraint.c \ - pointers.c + pointers.c cscannerHelp.c SPLINTSRC = exprNode.c exprChecks.c llmain.c help.c rcfiles.c CHECKSRC = structNames.c transferChecks.c varKinds.c nameChecks.c @@ -302,7 +302,7 @@ Headers/cgrammar_tokens.h cgrammar.c: cgrammar.c.der cgrammar.y bison.head bison $(CP) cgrammar.c.der cgrammar.c; \ else \ echo '* Making cgrammar.c'; \ - echo '* Expect 154 shift/reduce conflicts and 116 reduce/reduce conflicts.'; \ + echo '* Expect 157 shift/reduce conflicts and 117 reduce/reduce conflicts.'; \ echo '* (see cgrammar.y for explanation)'; \ $(BISON) $(YFLAGS) cgrammar.y; \ $(CAT) bison.head cgrammar.tab.c bison.reset | $(SED) 's/YYSTYPE/cgrammar_YYSTYPE/g' | $(SED) 's/lsllex/cgrammar_lsllex/g' > cgrammar.c; \ diff --git a/src/Makefile.in b/src/Makefile.in index 7531187..e889b90 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -132,7 +132,7 @@ CSRC = context.c uentry.c cprim.c macrocache.c qual.c qtype.c stateClause.c \ globalsClause.c modifiesClause.c warnClause.c functionClause.c \ functionClauseList.c metaStateConstraint.c metaStateConstraintList.c \ metaStateExpression.c metaStateSpecifier.c functionConstraint.c \ - pointers.c + pointers.c cscannerHelp.c SPLINTSRC = exprNode.c exprChecks.c llmain.c help.c rcfiles.c @@ -1106,7 +1106,7 @@ etags: lintnew: splintme splintme: - ./splint $(DEFAULT_INCLUDES) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) +singleinclude $(LINTSRC) $(OVERFLOWCHSRC) $(LCLSRC) -dump lclint +forcehints -misplacedsharequal +showsourceloc -unrecogcomments -supcounts -fcnuse -incondefs -exportlocal -constuse -mts file -mts filerw + ./splint $(DEFAULT_INCLUDES) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) +singleinclude cscannerHelp.c $(LINTSRC) $(OVERFLOWCHSRC) $(LCLSRC) -dump lclint +forcehints -misplacedsharequal +showsourceloc -unrecogcomments -supcounts -fcnuse -incondefs -exportlocal -constuse -mts file -mts filerw valsplint: valgrind -v --leak-resolution=high --num-callers=20 --show-reachable=no --leak-check=yes ./splint $(DEFAULT_INCLUDES) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) +singleinclude $(LINTSRC) $(OVERFLOWCHSRC) $(LCLSRC) -dump lclint +forcehints -misplacedsharequal +showsourceloc -unrecogcomments -supcounts -fcnuse -incondefs -exportlocal -constuse -mts file -mts filerw diff --git a/src/cgrammar.c.der b/src/cgrammar.c.der index 9e4421e..8c3a3e2 100644 --- a/src/cgrammar.c.der +++ b/src/cgrammar.c.der @@ -284,6 +284,7 @@ extern void yyerror (char *); # include "splintMacros.nf" # include "basic.h" # include "cscanner.h" +# include "cscannerHelp.h" # include "cgrammar.h" # include "exprChecks.h" @@ -728,77 +729,77 @@ static const short yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const short yyrline[] = { - 0, 324, 325, 329, 330, 334, 335, 336, 337, 338, - 339, 340, 341, 345, 347, 352, 352, 361, 367, 372, - 373, 378, 379, 381, 383, 400, 400, 418, 418, 433, - 434, 436, 440, 457, 457, 469, 469, 483, 483, 483, - 492, 493, 494, 495, 499, 503, 508, 508, 513, 513, - 521, 522, 526, 532, 533, 537, 538, 542, 548, 549, - 553, 554, 555, 559, 560, 561, 567, 568, 572, 574, - 576, 578, 587, 589, 591, 593, 610, 614, 615, 622, - 623, 632, 634, 639, 640, 641, 642, 643, 644, 648, - 649, 650, 651, 652, 653, 657, 661, 661, 670, 674, - 678, 678, 693, 695, 700, 704, 705, 709, 713, 719, - 724, 725, 729, 733, 734, 738, 739, 740, 744, 745, - 746, 747, 748, 752, 753, 754, 755, 756, 760, 761, - 765, 772, 777, 777, 783, 783, 783, 794, 805, 806, - 810, 811, 812, 813, 814, 815, 816, 817, 818, 822, - 823, 828, 829, 833, 835, 837, 838, 839, 840, 841, - 843, 848, 849, 853, 857, 870, 871, 872, 873, 874, - 875, 876, 876, 882, 883, 884, 885, 886, 887, 888, - 889, 890, 891, 896, 897, 901, 902, 903, 904, 905, - 906, 907, 908, 909, 910, 911, 915, 916, 918, 922, - 928, 928, 933, 934, 935, 936, 940, 941, 946, 947, - 948, 949, 953, 954, 955, 959, 960, 961, 965, 966, - 967, 968, 969, 973, 974, 975, 979, 980, 984, 985, - 989, 990, 994, 995, 995, 1007, 1008, 1008, 1021, 1022, - 1022, 1022, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, - 1036, 1037, 1038, 1039, 1043, 1044, 1048, 1049, 1053, 1059, - 1060, 1061, 1065, 1079, 1079, 1090, 1090, 1099, 1100, 1104, - 1109, 1109, 1114, 1114, 1117, 1118, 1122, 1126, 1130, 1134, - 1135, 1139, 1143, 1144, 1148, 1149, 1153, 1154, 1155, 1156, - 1164, 1165, 1170, 1171, 1175, 1176, 1180, 1182, 1192, 1193, - 1194, 1195, 1196, 1200, 1204, 1204, 1220, 1224, 1228, 1228, - 1242, 1242, 1274, 1275, 1279, 1280, 1281, 1282, 1283, 1287, - 1288, 1289, 1290, 1294, 1295, 1296, 1297, 1298, 1299, 1300, - 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, - 1314, 1315, 1319, 1320, 1324, 1325, 1329, 1330, 1331, 1332, - 1333, 1337, 1338, 1339, 1340, 1341, 1342, 1346, 1347, 1348, - 1349, 1353, 1354, 1355, 1356, 1360, 1361, 1362, 1363, 1364, - 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1379, 1380, 1381, - 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, - 1392, 1396, 1401, 1402, 1407, 1408, 1413, 1414, 1415, 1419, - 1420, 1424, 1431, 1431, 1431, 1437, 1437, 1437, 1442, 1444, - 1446, 1446, 1446, 1451, 1451, 1451, 1456, 1458, 1460, 1461, - 1465, 1469, 1470, 1471, 1475, 1477, 1482, 1484, 1489, 1490, - 1491, 1496, 1498, 1498, 1500, 1504, 1506, 1508, 1512, 1517, - 1525, 1526, 1527, 1533, 1538, 1539, 1544, 1545, 1549, 1550, - 1551, 1555, 1556, 1560, 1561, 1562, 1563, 1567, 1568, 1572, - 1573, 1577, 1578, 1579, 1583, 1583, 1584, 1584, 1589, 1601, - 1618, 1619, 1623, 1624, 1625, 1629, 1630, 1634, 1636, 1637, - 1639, 1640, 1642, 1644, 1646, 1648, 1655, 1656, 1657, 1658, - 1659, 1660, 1661, 1662, 1663, 1668, 1672, 1676, 1677, 1682, - 1684, 1686, 1688, 1693, 1693, 1693, 1701, 1701, 1705, 1709, - 1710, 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, - 1720, 1721, 1725, 1725, 1732, 1736, 1740, 1741, 1745, 1746, - 1747, 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1759, - 1760, 1768, 1769, 1776, 1776, 1778, 1778, 1783, 1783, 1785, - 1785, 1790, 1791, 1796, 1800, 1804, 1808, 1812, 1816, 1820, - 1821, 1822, 1823, 1825, 1826, 1828, 1830, 1837, 1842, 1844, - 1846, 1848, 1853, 1854, 1858, 1859, 1863, 1864, 1868, 1869, - 1873, 1874, 1878, 1879, 1883, 1884, 1885, 1889, 1903, 1908, - 1908, 1913, 1913, 1918, 1924, 1928, 1928, 1928, 1939, 1940, - 1940, 1945, 1946, 1947, 1958, 1966, 1967, 1971, 1972, 1976, - 1977, 1978, 1979, 1980, 1982, 1983, 1984, 1985, 1989, 1990, - 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002, 2003, - 2007, 2008, 2009, 2010, 2014, 2015, 2016, 2020, 2021, 2022, - 2026, 2027, 2028, 2029, 2030, 2034, 2035, 2036, 2040, 2041, - 2045, 2046, 2050, 2051, 2055, 2056, 2060, 2061, 2065, 2066, - 2066, 2066, 2072, 2073, 2074, 2075, 2076, 2077, 2078, 2079, - 2080, 2081, 2082, 2083, 2087, 2088, 2092, 2096, 2098, 2100, - 2105, 2106, 2108, 2110, 2114, 2115, 2116, 2118, 2119, 2120, - 2121, 2122, 2123, 2124, 2128, 2129, 2133, 2134, 2138, 2142, - 2143, 2144, 2145, 2146, 2150, 2151, 2152, 2153 + 0, 325, 326, 330, 331, 335, 336, 337, 338, 339, + 340, 341, 342, 346, 348, 353, 353, 362, 368, 373, + 374, 379, 380, 382, 384, 401, 401, 419, 419, 434, + 435, 437, 441, 458, 458, 470, 470, 484, 484, 484, + 493, 494, 495, 496, 500, 504, 509, 509, 514, 514, + 522, 523, 527, 533, 534, 538, 539, 543, 549, 550, + 554, 555, 556, 560, 561, 562, 568, 569, 573, 575, + 577, 579, 588, 590, 592, 594, 611, 615, 616, 623, + 624, 633, 635, 640, 641, 642, 643, 644, 645, 649, + 650, 651, 652, 653, 654, 658, 662, 662, 671, 675, + 679, 679, 694, 696, 701, 705, 706, 710, 714, 720, + 725, 726, 730, 734, 735, 739, 740, 741, 745, 746, + 747, 748, 749, 753, 754, 755, 756, 757, 761, 762, + 766, 773, 778, 778, 784, 784, 784, 795, 806, 807, + 811, 812, 813, 814, 815, 816, 817, 818, 819, 823, + 824, 829, 830, 834, 836, 838, 839, 840, 841, 842, + 844, 849, 850, 854, 858, 871, 872, 873, 874, 875, + 876, 877, 877, 883, 884, 885, 886, 887, 888, 889, + 890, 891, 892, 897, 898, 902, 903, 904, 905, 906, + 907, 908, 909, 910, 911, 912, 916, 917, 919, 923, + 929, 929, 934, 935, 936, 937, 941, 942, 947, 948, + 949, 950, 954, 955, 956, 960, 961, 962, 966, 967, + 968, 969, 970, 974, 975, 976, 980, 981, 985, 986, + 990, 991, 995, 996, 996, 1008, 1009, 1009, 1022, 1023, + 1023, 1023, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, + 1037, 1038, 1039, 1040, 1044, 1045, 1049, 1050, 1054, 1060, + 1061, 1062, 1066, 1080, 1080, 1091, 1091, 1100, 1101, 1105, + 1110, 1110, 1115, 1115, 1118, 1119, 1123, 1127, 1131, 1135, + 1136, 1140, 1144, 1145, 1149, 1150, 1154, 1155, 1156, 1157, + 1165, 1166, 1171, 1172, 1176, 1177, 1181, 1183, 1193, 1194, + 1195, 1196, 1197, 1201, 1205, 1205, 1221, 1225, 1229, 1229, + 1243, 1243, 1275, 1276, 1280, 1281, 1282, 1283, 1284, 1288, + 1289, 1290, 1291, 1295, 1296, 1297, 1298, 1299, 1300, 1301, + 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, + 1315, 1316, 1320, 1321, 1325, 1326, 1330, 1331, 1332, 1333, + 1334, 1338, 1339, 1340, 1341, 1342, 1343, 1347, 1348, 1349, + 1350, 1354, 1355, 1356, 1357, 1361, 1362, 1363, 1364, 1365, + 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1380, 1381, 1382, + 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, + 1393, 1397, 1402, 1403, 1408, 1409, 1414, 1415, 1416, 1420, + 1421, 1425, 1432, 1432, 1432, 1438, 1438, 1438, 1443, 1445, + 1447, 1447, 1447, 1452, 1452, 1452, 1457, 1459, 1461, 1462, + 1466, 1470, 1471, 1472, 1476, 1478, 1483, 1485, 1490, 1491, + 1492, 1497, 1499, 1499, 1501, 1505, 1507, 1509, 1513, 1518, + 1526, 1527, 1528, 1534, 1539, 1540, 1545, 1546, 1550, 1551, + 1552, 1556, 1557, 1561, 1562, 1563, 1564, 1568, 1569, 1573, + 1574, 1578, 1579, 1580, 1584, 1584, 1585, 1585, 1590, 1602, + 1619, 1620, 1624, 1625, 1626, 1630, 1631, 1635, 1637, 1638, + 1640, 1641, 1643, 1645, 1647, 1649, 1656, 1657, 1658, 1659, + 1660, 1661, 1662, 1663, 1664, 1669, 1673, 1677, 1678, 1683, + 1685, 1687, 1689, 1694, 1694, 1694, 1702, 1702, 1706, 1710, + 1711, 1712, 1713, 1714, 1715, 1716, 1717, 1718, 1719, 1720, + 1721, 1722, 1726, 1726, 1733, 1737, 1741, 1742, 1746, 1747, + 1748, 1749, 1750, 1751, 1752, 1753, 1754, 1755, 1756, 1760, + 1761, 1769, 1770, 1777, 1777, 1779, 1779, 1784, 1784, 1786, + 1786, 1791, 1792, 1797, 1801, 1805, 1809, 1813, 1817, 1821, + 1822, 1823, 1824, 1826, 1827, 1829, 1831, 1838, 1843, 1845, + 1847, 1849, 1854, 1855, 1859, 1860, 1864, 1865, 1869, 1870, + 1874, 1875, 1879, 1880, 1884, 1885, 1886, 1890, 1904, 1909, + 1909, 1914, 1914, 1919, 1925, 1929, 1929, 1929, 1940, 1941, + 1941, 1946, 1947, 1948, 1959, 1967, 1968, 1972, 1973, 1977, + 1978, 1979, 1980, 1981, 1983, 1984, 1985, 1986, 1990, 1991, + 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2004, + 2008, 2009, 2010, 2011, 2015, 2016, 2017, 2021, 2022, 2023, + 2027, 2028, 2029, 2030, 2031, 2035, 2036, 2037, 2041, 2042, + 2046, 2047, 2051, 2052, 2056, 2057, 2061, 2062, 2066, 2067, + 2067, 2067, 2073, 2074, 2075, 2076, 2077, 2078, 2079, 2080, + 2081, 2082, 2083, 2084, 2088, 2089, 2093, 2097, 2099, 2101, + 2106, 2107, 2109, 2111, 2115, 2116, 2117, 2119, 2120, 2121, + 2122, 2123, 2124, 2125, 2129, 2130, 2134, 2135, 2139, 2143, + 2144, 2145, 2146, 2147, 2151, 2152, 2153, 2154 }; #endif @@ -3698,19 +3699,19 @@ case 45: { yyval.msconstraint = metaStateConstraint_create (yyvsp[-2].msspec, yyvsp[0].msexpr); lltok_free (yyvsp[-1].tok); ; break;} case 46: -{ cscanner_expectingMetaStateName (); ; +{ cscannerHelp_expectingMetaStateName (); ; break;} case 47: -{ cscanner_clearExpectingMetaStateName (); +{ cscannerHelp_clearExpectingMetaStateName (); yyval.msspec = metaStateSpecifier_create (yyvsp[-3].sr, yyvsp[0].msinfo); lltok_free (yyvsp[-1].tok); ; break;} case 48: -{ cscanner_expectingMetaStateName (); ; +{ cscannerHelp_expectingMetaStateName (); ; break;} case 49: -{ cscanner_clearExpectingMetaStateName (); +{ cscannerHelp_clearExpectingMetaStateName (); yyval.msspec = metaStateSpecifier_createElipsis (yyvsp[0].msinfo); lltok_free2 (yyvsp[-3].tok, yyvsp[-1].tok); ; @@ -4060,7 +4061,7 @@ case 168: { yyval.expr = exprNode_addParens (yyvsp[-2].tok, yyvsp[-1].expr); ; break;} case 169: -{ yyval.expr = exprNode_fromIdentifier (coerceId (yyvsp[0].cname)); ; +{ yyval.expr = exprNode_fromIdentifier (cscannerHelp_coerceId (yyvsp[0].cname)); ; break;} case 170: { yyval.expr = exprNode_makeError (); ; @@ -4351,10 +4352,10 @@ case 275: { /* in the ANSI grammar, semantics unclear */ ; break;} case 276: -{ g_expectingTypeName = TRUE; ; +{ cscannerHelp_setExpectingTypeName (); ; break;} case 277: -{ g_expectingTypeName = TRUE; context_pushLoc (); ; +{ cscannerHelp_setExpectingTypeName (); context_pushLoc (); ; break;} case 278: { yyval.exprlist = yyvsp[-1].exprlist; ; @@ -4795,7 +4796,7 @@ case 419: { yyval.ctyp = handleUnion (yyvsp[-1].cname); ; break;} case 420: -{ g_expectingTypeName = FALSE; ; +{ cscannerHelp_clearExpectingTypeName (); ; break;} case 422: { yyval.flist = uentryList_undefined; /* bogus! */ ; @@ -4861,7 +4862,7 @@ case 442: { qtype qt = qtype_unknown (); qtype_adjustPointers (yyvsp[-1].pointers, qt); - yyval.ntyp = idDecl_create (cstring_copy (cscanner_observeLastIdentifier ()), qt); + yyval.ntyp = idDecl_create (cstring_copy (cscannerHelp_observeLastIdentifier ()), qt); ; break;} case 443: @@ -5268,7 +5269,7 @@ case 602: { yyval.expr = exprNode_iterId (yyvsp[0].entry); ; break;} case 603: -{ uentry ue = coerceIterId (yyvsp[0].cname); +{ uentry ue = cscannerHelp_coerceIterId (yyvsp[0].cname); if (uentry_isValid (ue)) { @@ -5276,7 +5277,7 @@ case 603: } else { - yyval.expr = exprNode_iterNewId (cstring_copy (cscanner_observeLastIdentifier ())); + yyval.expr = exprNode_iterNewId (cstring_copy (cscannerHelp_observeLastIdentifier ())); } ; break;} @@ -5796,7 +5797,7 @@ void yyerror (/*@unused@*/ char *s) } } - cscanner_swallowMacro (); + cscannerHelp_swallowMacro (); context_exitAllClausesQuiet (); } else diff --git a/src/cgrammar.y b/src/cgrammar.y index 897af93..3134c11 100644 --- a/src/cgrammar.y +++ b/src/cgrammar.y @@ -52,6 +52,7 @@ extern void yyerror (char *); # include "splintMacros.nf" # include "basic.h" # include "cscanner.h" +# include "cscannerHelp.h" # include "cgrammar.h" # include "exprChecks.h" @@ -505,13 +506,13 @@ metaStateConstraint ; metaStateSpecifier - : BufConstraintSrefExpr { cscanner_expectingMetaStateName (); } TCOLON metaStateName - { cscanner_clearExpectingMetaStateName (); + : BufConstraintSrefExpr { cscannerHelp_expectingMetaStateName (); } TCOLON metaStateName + { cscannerHelp_clearExpectingMetaStateName (); $$ = metaStateSpecifier_create ($1, $4); lltok_free ($3); } - | CTOK_ELIPSIS { cscanner_expectingMetaStateName (); } TCOLON metaStateName - { cscanner_clearExpectingMetaStateName (); + | CTOK_ELIPSIS { cscannerHelp_expectingMetaStateName (); } TCOLON metaStateName + { cscannerHelp_clearExpectingMetaStateName (); $$ = metaStateSpecifier_createElipsis ($4); lltok_free2 ($1, $3); } @@ -871,7 +872,7 @@ primaryExpr | NEW_IDENTIFIER { $$ = exprNode_fromUIO ($1); } | cconstantExpr | TLPAREN expr TRPAREN { $$ = exprNode_addParens ($1, $2); } - | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (coerceId ($1)); } + | TYPE_NAME_OR_ID { $$ = exprNode_fromIdentifier (cscannerHelp_coerceId ($1)); } | QEXTENSION { $$ = exprNode_makeError (); } | TLPAREN { exprChecks_inCompoundStatementExpression (); } compoundStmt TRPAREN @@ -1119,11 +1120,11 @@ typeDecl ; IsType - : { g_expectingTypeName = TRUE; } + : { cscannerHelp_setExpectingTypeName (); } ; PushType - : { g_expectingTypeName = TRUE; context_pushLoc (); } + : { cscannerHelp_setExpectingTypeName (); context_pushLoc (); } ; namedInitializerList @@ -1462,7 +1463,7 @@ suSpc ; NotType - : { g_expectingTypeName = FALSE; } +: { cscannerHelp_clearExpectingTypeName (); } ; structDeclList @@ -1528,7 +1529,7 @@ optNamedDecl { qtype qt = qtype_unknown (); qtype_adjustPointers ($1, qt); - $$ = idDecl_create (cstring_copy (cscanner_observeLastIdentifier ()), qt); + $$ = idDecl_create (cstring_copy (cscannerHelp_observeLastIdentifier ()), qt); } | pointers optNamedDecl { $$ = $2; qtype_adjustPointers ($1, idDecl_getTyp ($$)); } @@ -1944,7 +1945,7 @@ iterArgList iterArgExpr : assignIterExpr { $$ = exprNode_iterExpr ($1); } | id { $$ = exprNode_iterId ($1); } - | TYPE_NAME_OR_ID { uentry ue = coerceIterId ($1); + | TYPE_NAME_OR_ID { uentry ue = cscannerHelp_coerceIterId ($1); if (uentry_isValid (ue)) { @@ -1952,7 +1953,7 @@ iterArgExpr } else { - $$ = exprNode_iterNewId (cstring_copy (cscanner_observeLastIdentifier ())); + $$ = exprNode_iterNewId (cstring_copy (cscannerHelp_observeLastIdentifier ())); } } | NEW_IDENTIFIER { $$ = exprNode_iterNewId ($1); } @@ -2191,7 +2192,7 @@ void yyerror (/*@unused@*/ char *s) } } - cscanner_swallowMacro (); + cscannerHelp_swallowMacro (); context_exitAllClausesQuiet (); } else diff --git a/src/clabstract.c b/src/clabstract.c index a47ca84..304d0ed 100644 --- a/src/clabstract.c +++ b/src/clabstract.c @@ -1863,12 +1863,14 @@ void setNewStyle () { flipNewStyle = TRUE; } uentryList_elements (params, current) { uentry_setParam (current); - uentry_setSref (current, sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (uentry_whereLast (current)))); + uentry_setSref (current, sRef_makeParam + (paramno, ctype_unknown, + stateInfo_makeLoc (uentry_whereLast (current), SA_DECLARED))); paramno++; } end_uentryList_elements; setGenericParamList (params); - g_expectingTypeName = TRUE; + cscannerHelp_setExpectingTypeName (); return params; } @@ -1885,7 +1887,7 @@ void setNewStyle () { flipNewStyle = TRUE; } setGenericParamList (params); flipOldStyle = FALSE; - g_expectingTypeName = TRUE; + cscannerHelp_setExpectingTypeName (); } return (params); @@ -1905,7 +1907,9 @@ doVaDcl () if (i >= 0) { fileloc loc = context_getSaveLocation (); - e = uentry_makeVariableSrefParam (id, c, loc, sRef_makeParam (i, c, stateInfo_makeLoc (loc))); + e = uentry_makeVariableSrefParam + (id, c, loc, + sRef_makeParam (i, c, stateInfo_makeLoc (loc, SA_DECLARED))); } else { diff --git a/src/constraintExpr.c b/src/constraintExpr.c index aee3bd9..3dcd666 100644 --- a/src/constraintExpr.c +++ b/src/constraintExpr.c @@ -517,13 +517,13 @@ constraintExpr constraintExpr_makeExprNode (exprNode e) case XPR_PREOP: t = exprData_getUopNode (data); tok = exprData_getUopTok (data); - if (lltok_isInc_Op (tok) ) + if (lltok_isIncOp (tok)) { constraintExpr temp; temp = constraintExpr_makeExprNode(t); ret = constraintExpr_makeIncConstraintExpr(temp); } - else if (lltok_isDec_Op (tok) ) + else if (lltok_isDecOp (tok)) { constraintExpr temp; temp = constraintExpr_makeExprNode(t); diff --git a/src/constraintGeneration.c b/src/constraintGeneration.c index 0cc3fb3..d919f01 100644 --- a/src/constraintGeneration.c +++ b/src/constraintGeneration.c @@ -1021,17 +1021,17 @@ static bool lltok_isBoolean_Op (lltok tok) I don't want to violate the abstraction maybe this should go in lltok.c */ - if (lltok_isEq_Op (tok)) + if (lltok_isEqOp (tok)) { return TRUE; } - if (lltok_isAnd_Op (tok)) + if (lltok_isAndOp (tok)) { return TRUE; } - if (lltok_isOr_Op (tok)) + if (lltok_isOrOp (tok)) { return TRUE; } @@ -1077,7 +1077,7 @@ static void exprNode_booleanTraverse (/*@dependent@*/ exprNode e, /*@unused@*/ b /* arithmetic tests */ - if (lltok_isEq_Op (tok)) + if (lltok_isEqOp (tok)) { cons = constraint_makeEnsureEqual (t1, t2, sequencePoint); e->trueEnsuresConstraints = constraintList_add(e->trueEnsuresConstraints, cons); @@ -1120,7 +1120,7 @@ static void exprNode_booleanTraverse (/*@dependent@*/ exprNode e, /*@unused@*/ b /* Logical operations */ - if (lltok_isAnd_Op (tok)) + if (lltok_isAndOp (tok)) { /* true ensures */ tempList = constraintList_copy (t1->trueEnsuresConstraints); @@ -1137,7 +1137,7 @@ static void exprNode_booleanTraverse (/*@dependent@*/ exprNode e, /*@unused@*/ b /* evans - was constraintList_addList - memory leak detected by splint */ e->falseEnsuresConstraints = constraintList_addListFree (e->falseEnsuresConstraints, tempList); } - else if (lltok_isOr_Op (tok)) + else if (lltok_isOrOp (tok)) { /* false ensures */ tempList = constraintList_copy (t1->falseEnsuresConstraints); @@ -1369,14 +1369,14 @@ void exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, /*@ob tok = (exprData_getUopTok (data)); exprNode_exprTraverse (t1, definatelv, definaterv, sequencePoint); /*handle * pointer access */ - if (lltok_isInc_Op (tok)) + if (lltok_isIncOp (tok)) { DPRINTF(("doing ++(var)")); t1 = exprData_getUopNode (data); cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint); e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons); } - else if (lltok_isDec_Op (tok)) + else if (lltok_isDecOp (tok)) { DPRINTF(("doing --(var)")); t1 = exprData_getUopNode (data); @@ -1395,7 +1395,7 @@ void exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, /*@ob } e->requiresConstraints = constraintList_add(e->requiresConstraints, cons); } - else if (lltok_isNot_Op (tok)) + else if (lltok_isNotOp (tok)) /* ! expr */ { constraintList_free(e->trueEnsuresConstraints); @@ -1432,14 +1432,14 @@ void exprNode_exprTraverse (exprNode e, bool definatelv, bool definaterv, /*@ob exprNode_exprTraverse (exprData_getUopNode (data), TRUE, definaterv, sequencePoint); - if (lltok_isInc_Op (exprData_getUopTok (data))) + if (lltok_isIncOp (exprData_getUopTok (data))) { DPRINTF(("doing ++")); t1 = exprData_getUopNode (data); cons = constraint_makeMaxSetSideEffectPostIncrement (t1, sequencePoint); e->ensuresConstraints = constraintList_add (e->ensuresConstraints, cons); } - if (lltok_isDec_Op (exprData_getUopTok (data))) + if (lltok_isDecOp (exprData_getUopTok (data))) { DPRINTF(("doing --")); t1 = exprData_getUopNode (data); diff --git a/src/constraintTerm.c b/src/constraintTerm.c index 28f2de5..e49f75d 100644 --- a/src/constraintTerm.c +++ b/src/constraintTerm.c @@ -651,7 +651,7 @@ void constraintTerm_dump (/*@observer@*/ constraintTerm t, FILE *f) ostr2 = str2; t = ctype_undump(&str2) ; - s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc)); + s = sRef_makeParam (param, t, stateInfo_makeLoc (g_currentloc, SA_CREATED)); free (ostr2); } else if (strcmp (term, "sRef_dump" ) == 0 ) diff --git a/src/context.c b/src/context.c index eed3a05..053a86e 100644 --- a/src/context.c +++ b/src/context.c @@ -726,6 +726,8 @@ context_resetAllFlags (void) val = DEFAULT_LINELEN; break; case FLG_INDENTSPACES: val = DEFAULT_INDENTSPACES; break; + case FLG_LOCINDENTSPACES: + val = DEFAULT_LOCINDENTSPACES; break; case FLG_EXTERNALNAMELEN: val = ISO99_EXTERNALNAMELEN; break; case FLG_INTERNALNAMELEN: @@ -885,6 +887,7 @@ context_resetAllFlags (void) gc.flags[FLG_WARNUNIXLIB] = TRUE; gc.flags[FLG_WARNPOSIX] = TRUE; gc.flags[FLG_SHOWCOL] = TRUE; + gc.flags[FLG_SHOWDEEPHISTORY] = FALSE; /* TRUE; */ gc.flags[FLG_SHOWFUNC] = TRUE; gc.flags[FLG_SUPCOUNTS] = TRUE; gc.flags[FLG_HINTS] = TRUE; @@ -1039,6 +1042,7 @@ context_setModeAux (cstring s, bool warn) FLG_UNSIGNEDCOMPARE, FLG_PARAMUNUSED, FLG_VARUNUSED, FLG_FUNCUNUSED, FLG_TYPEUNUSED, + FLG_ABSTRACTCOMPARE, FLG_CONSTUNUSED, FLG_ENUMMEMUNUSED, FLG_FIELDUNUSED, FLG_PTRNUMCOMPARE, FLG_BOOLCOMPARE, FLG_UNSIGNEDCOMPARE, FLG_MUTREP, FLG_NOEFFECT, FLG_IMPTYPE, @@ -1143,6 +1147,7 @@ context_setModeAux (cstring s, bool warn) { FLG_EXPORTLOCAL, FLG_IMPTYPE, FLG_NUMABSTRACTCAST, + FLG_ABSTRACTCOMPARE, FLG_STATETRANSFER, FLG_STATEMERGE, FLG_CHECKSTRICTGLOBALIAS, FLG_CHECKEDGLOBALIAS, @@ -1238,6 +1243,7 @@ context_setModeAux (cstring s, bool warn) { flagcode modeflags[] = { + FLG_ABSTRACTCOMPARE, FLG_CHECKSTRICTGLOBALIAS, FLG_NUMABSTRACTCAST, FLG_CHECKEDGLOBALIAS, diff --git a/src/cscanner.l b/src/cscanner.l index e4fbf2d..592560e 100644 --- a/src/cscanner.l +++ b/src/cscanner.l @@ -82,430 +82,289 @@ ULSuffix ({U}{L}|{L}{U}) # include "basic.h" +# include "cscannerHelp.h" # include "cgrammar.h" # include "cgrammar_tokens.h" # include "portab.h" -static bool lastWasString = FALSE; -static char savechar = '\0'; - /*@notfunction@*/ # define yyinput() (incColumn (), getc (yyin)) -static /*@owned@*/ cstring s_lastidprocessed = cstring_undefined; -static int lminput (void); -static int tokLength = 0; -static bool s_inSpecPart = FALSE; -static int s_whichSpecPart; -static bool continueLine = FALSE; - -static int ninput (void); -static char processChar (void); -static double processFloat (void); -static /*@only@*/ exprNode processString (void) ; -static /*@only@*/ exprNode processWideString (void) ; -static long processDec (void); -static long processHex (void); -static long processOctal (void); -static int processIdentifier (/*@only@*/ cstring) - /*@globals s_lastidprocessed@*/ ; -static bool processHashIdentifier (/*@only@*/ cstring) - /*@globals s_lastidprocessed@*/ ; - -static int processSpec (int); -static bool handleSpecial (char *); -static int handleLlSpecial (void); -static void handleMacro (void); -static bool processMacro (void); -static /*@only@*/ cstring makeIdentifier (char *); - -/* 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); -static void setTokLength (int) /*@modifies g_currentloc@*/ ; -static void setTokLengthT (size_t) /*@modifies g_currentloc@*/ ; - -static void advanceLine (void) -{ - tokLength = 0; - beginLine (); -} - -/*@-allmacros@*/ -# define RETURN_INT(c,i) \ - do { lastWasString = FALSE; \ - return (returnInt (c, i)); } while (FALSE) - -# define RETURN_FLOAT(c,f) \ - do { lastWasString = FALSE; \ - return (returnFloat (c, f)); \ - } while (FALSE) - -# define RETURN_CHAR(c) \ - do { lastWasString = FALSE; \ - return (returnChar (c)); \ - } while (FALSE) - -# define RETURN_TOK(t) \ - do { yylval.tok = lltok_create (t, fileloc_decColumn (g_currentloc, tokLength)); \ - tokLength = 0; \ - lastWasString = FALSE; \ - return (t); } while (FALSE) - -# define RETURN_TYPE(t, ct) \ - do { yylval.ctyp = ct; tokLength = 0; return (t); } while (FALSE) - -/* don't fileloc_decColumn (g_currentloc, tokLength)); - the string could have \n's in it! -*/ - -# define RETURN_STRING(c) \ - do { yylval.expr = exprNode_stringLiteral (c, fileloc_decColumn (g_currentloc, tokLength)); \ - tokLength = 0; \ - lastWasString = TRUE; \ - return (CCONSTANT); } while (FALSE) - -# define RETURN_EXPR(e) \ - do { yylval.expr = e; \ - tokLength = 0; \ - lastWasString = TRUE; \ - return (CCONSTANT); } while (FALSE) - -/*@=allmacros@*/ - -static void setTokLength (int len) -{ - addColumn (len); - tokLength = len; - DPRINTF (("Set tok length: %d", len)); -} - -static void setTokLengthT (size_t len) -{ - setTokLength (size_toInt (len)); -} - # include "flex.head" -/*@-unrecog@*/ /*@i5343@*/ - %} %% "/*" { llfatalerror (cstring_makeLiteral ("Comment in pre-processor output")); } -"#"{Letter}({Letter}|{Digit})* { +"#"{Letter}({Letter}|{Digit})* { context_saveLocation (); - setTokLength (longUnsigned_toInt (mstring_length (yytext))); + cscannerHelp_setTokLength (longUnsigned_toInt (mstring_length (yytext))); - if (processHashIdentifier (makeIdentifier (yytext + 1))) + if (cscannerHelp_processHashIdentifier + (cscannerHelp_makeIdentifier (yytext + 1))) { - if (lastWasString) - { - /* was nothing! */ /*@i32@*/ - RETURN_STRING (cstring_makeLiteral ("\"\"")); - } - else - { - RETURN_STRING (cstring_makeLiteral ("\"\"")); - } + return cscannerHelp_returnString (cstring_makeLiteral ("\"\"")); } else { - if (handleSpecial (yytext)) + if (cscannerHelp_handleSpecial (yytext)) { - setTokLength (1); - RETURN_TOK (0); + cscannerHelp_setTokLength (1); + return cscannerHelp_returnToken (0); } } } -"#" { if (handleSpecial (yytext)) +"#" { if (cscannerHelp_handleSpecial (yytext)) { - setTokLength (1); RETURN_TOK (0); + cscannerHelp_setTokLength (1); return cscannerHelp_returnToken (0); } } -"..." { setTokLength (3); RETURN_TOK (CTOK_ELIPSIS); } -"break" { setTokLength (5); RETURN_TOK (BREAK); } -"case" { setTokLength (4); RETURN_TOK (CASE); } -"continue" { setTokLength (8); RETURN_TOK (CONTINUE); } -"default" { setTokLength (7); RETURN_TOK (DEFAULT); } -"do" { setTokLength (2); RETURN_TOK (DO); } -"else" { setTokLength (4); RETURN_TOK (CELSE); } -"for" { setTokLength (3); RETURN_TOK (CFOR); } -"goto" { setTokLength (4); RETURN_TOK (GOTO); } -"if" { setTokLength (2); RETURN_TOK (CIF); } -"return" { setTokLength (6); RETURN_TOK (RETURN); } -"sizeof" { setTokLength (6); RETURN_TOK (CSIZEOF); } -"offsetof" { setTokLength (8); RETURN_TOK (COFFSETOF); } -"switch" { setTokLength (6); RETURN_TOK (SWITCH); } -"while" { setTokLength (5); RETURN_TOK (WHILE); } -"va_arg" { setTokLength (6); RETURN_TOK (VA_ARG); } -"va_dcl" { setTokLength (6); RETURN_TOK (VA_DCL); } +"..." { cscannerHelp_setTokLength (3); return cscannerHelp_returnToken (CTOK_ELIPSIS); } +"break" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (BREAK); } +"case" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (CASE); } +"continue" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (CONTINUE); } +"default" { cscannerHelp_setTokLength (7); return cscannerHelp_returnToken (DEFAULT); } +"do" { cscannerHelp_setTokLength (2); return cscannerHelp_returnToken (DO); } +"else" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (CELSE); } +"for" { cscannerHelp_setTokLength (3); return cscannerHelp_returnToken (CFOR); } +"goto" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (GOTO); } +"if" { cscannerHelp_setTokLength (2); return cscannerHelp_returnToken (CIF); } +"return" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (RETURN); } +"sizeof" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (CSIZEOF); } +"offsetof" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (COFFSETOF); } +"switch" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (SWITCH); } +"while" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (WHILE); } +"va_arg" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (VA_ARG); } +"va_dcl" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (VA_DCL); } "inline" { /* gcc extension...this might not be appropriate */ - setTokLength (6); RETURN_TOK (QINLINE); } + cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QINLINE); } -"struct" { setTokLength (6); RETURN_TOK (CSTRUCT); } -"typedef" { setTokLength (7); RETURN_TOK (CTYPEDEF); } +"struct" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (CSTRUCT); } +"typedef" { cscannerHelp_setTokLength (7); return cscannerHelp_returnToken (CTYPEDEF); } -"union" { setTokLength (5); RETURN_TOK (CUNION); } -"enum" { setTokLength (4); RETURN_TOK (CENUM); } +"union" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (CUNION); } +"enum" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (CENUM); } -"void" { setTokLength (4); RETURN_TYPE (CVOID, ctype_void); } -"int" { setTokLength (3); RETURN_TYPE (CINT, ctype_int); } -"double" { setTokLength (6); RETURN_TYPE (CDOUBLE, ctype_double); } -"char" { setTokLength (4); RETURN_TYPE (CGCHAR, ctype_char); } -"float" { setTokLength (5); RETURN_TYPE (CGFLOAT, ctype_float); } +"void" { cscannerHelp_setTokLength (4); return cscannerHelp_returnType (CVOID, ctype_void); } +"int" { cscannerHelp_setTokLength (3); return cscannerHelp_returnType (CINT, ctype_int); } +"double" { cscannerHelp_setTokLength (6); return cscannerHelp_returnType (CDOUBLE, ctype_double); } +"char" { cscannerHelp_setTokLength (4); return cscannerHelp_returnType (CGCHAR, ctype_char); } +"float" { cscannerHelp_setTokLength (5); return cscannerHelp_returnType (CGFLOAT, ctype_float); } -"long" { setTokLength (4); RETURN_TOK (QLONG); } -"short" { setTokLength (5); RETURN_TOK (QSHORT); } -"unsigned" { setTokLength (8); RETURN_TOK (QUNSIGNED); } -"signed" { setTokLength (6); RETURN_TOK (QSIGNED); } +"long" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (QLONG); } +"short" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (QSHORT); } +"unsigned" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QUNSIGNED); } +"signed" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QSIGNED); } -"volatile" { setTokLength (8); RETURN_TOK (QVOLATILE); } -"const" { setTokLength (5); RETURN_TOK (QCONST); } -"restrict" { setTokLength (8); RETURN_TOK (QRESTRICT); } +"volatile" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QVOLATILE); } +"const" { cscannerHelp_setTokLength (5); return cscannerHelp_returnToken (QCONST); } +"restrict" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QRESTRICT); } /* some systems expect this! [gack!] */ -"__const" { setTokLength (7); RETURN_TOK (QCONST); } - -"extern" { setTokLength (6); RETURN_TOK (QEXTERN); } -"auto" { setTokLength (4); RETURN_TOK (QAUTO); } -"register" { setTokLength (8); RETURN_TOK (QREGISTER); } -"static" { setTokLength (6); RETURN_TOK (QSTATIC); } - -\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processString ()); } -L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { RETURN_EXPR (processWideString ()); } -"out" { return (processSpec (QOUT)); } -"in" { return (processSpec (QIN)); } -"partial" { return (processSpec (QPARTIAL)); } -"special" { return (processSpec (QSPECIAL)); } -"anytype" { return (processSpec (QANYTYPE)); } -"integraltype" { return (processSpec (QINTEGRALTYPE)); } -"unsignedintegraltype" { return (processSpec (QUNSIGNEDINTEGRALTYPE)); } -"signedintegraltype" { return (processSpec (QSIGNEDINTEGRALTYPE)); } -"keep" { return (processSpec (QKEEP)); } -"null" { return (processSpec (QNULL)); } -"notnull" { return (processSpec (QNOTNULL)); } -"isnull" { return (processSpec (QISNULL)); } -"truenull" { return (processSpec (QTRUENULL)); } -"falsenull" { return (processSpec (QFALSENULL)); } -"nullwhentrue" { return (processSpec (QTRUENULL)); } -"nullwhenfalse" { return (processSpec (QFALSENULL)); } -"relnull" { return (processSpec (QRELNULL)); } -"reldef" { return (processSpec (QRELDEF)); } -"exposed" { return (processSpec (QEXPOSED)); } -"newref" { return (processSpec (QNEWREF)); } -"tempref" { return (processSpec (QTEMPREF)); } -"killref" { return (processSpec (QKILLREF)); } -"refcounted" { return (processSpec (QREFCOUNTED)); } -"checked" { return (processSpec (QCHECKED)); } -"checkmod" { return (processSpec (QCHECKMOD)); } -"checkedstrict" { return (processSpec (QCHECKEDSTRICT)); } -"unchecked" { return (processSpec (QUNCHECKED)); } -"only" { return (processSpec (QONLY)); } -"owned" { return (processSpec (QOWNED)); } -"observer" { return (processSpec (QOBSERVER)); } -"dependent" { return (processSpec (QDEPENDENT)); } -"unused" { return (processSpec (QUNUSED)); } -"external" { return (processSpec (QEXTERNAL)); } -"sef" { return (processSpec (QSEF)); } -"shared" { return (processSpec (QSHARED)); } -"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))); - tok = processIdentifier (makeIdentifier (yytext)); - if (tok != BADTOK) +"__const" { cscannerHelp_setTokLength (7); return cscannerHelp_returnToken (QCONST); } + +"extern" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QEXTERN); } +"auto" { cscannerHelp_setTokLength (4); return cscannerHelp_returnToken (QAUTO); } +"register" { cscannerHelp_setTokLength (8); return cscannerHelp_returnToken (QREGISTER); } +"static" { cscannerHelp_setTokLength (6); return cscannerHelp_returnToken (QSTATIC); } + +\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { return cscannerHelp_returnExpr (cscannerHelp_processString ()); } +L\"(\\.|[^\\"])*\"([ \t\n]*\"(\\.|[^\\"])*\")* { return cscannerHelp_returnExpr (cscannerHelp_processWideString ()); } +"out" { return (cscannerHelp_processSpec (QOUT)); } +"in" { return (cscannerHelp_processSpec (QIN)); } +"partial" { return (cscannerHelp_processSpec (QPARTIAL)); } +"special" { return (cscannerHelp_processSpec (QSPECIAL)); } +"anytype" { return (cscannerHelp_processSpec (QANYTYPE)); } +"integraltype" { return (cscannerHelp_processSpec (QINTEGRALTYPE)); } +"unsignedintegraltype" { return (cscannerHelp_processSpec (QUNSIGNEDINTEGRALTYPE)); } +"signedintegraltype" { return (cscannerHelp_processSpec (QSIGNEDINTEGRALTYPE)); } +"keep" { return (cscannerHelp_processSpec (QKEEP)); } +"null" { return (cscannerHelp_processSpec (QNULL)); } +"notnull" { return (cscannerHelp_processSpec (QNOTNULL)); } +"isnull" { return (cscannerHelp_processSpec (QISNULL)); } +"truenull" { return (cscannerHelp_processSpec (QTRUENULL)); } +"falsenull" { return (cscannerHelp_processSpec (QFALSENULL)); } +"nullwhentrue" { return (cscannerHelp_processSpec (QTRUENULL)); } +"nullwhenfalse" { return (cscannerHelp_processSpec (QFALSENULL)); } +"relnull" { return (cscannerHelp_processSpec (QRELNULL)); } +"reldef" { return (cscannerHelp_processSpec (QRELDEF)); } +"exposed" { return (cscannerHelp_processSpec (QEXPOSED)); } +"newref" { return (cscannerHelp_processSpec (QNEWREF)); } +"tempref" { return (cscannerHelp_processSpec (QTEMPREF)); } +"killref" { return (cscannerHelp_processSpec (QKILLREF)); } +"refcounted" { return (cscannerHelp_processSpec (QREFCOUNTED)); } +"checked" { return (cscannerHelp_processSpec (QCHECKED)); } +"checkmod" { return (cscannerHelp_processSpec (QCHECKMOD)); } +"checkedstrict" { return (cscannerHelp_processSpec (QCHECKEDSTRICT)); } +"unchecked" { return (cscannerHelp_processSpec (QUNCHECKED)); } +"only" { return (cscannerHelp_processSpec (QONLY)); } +"owned" { return (cscannerHelp_processSpec (QOWNED)); } +"observer" { return (cscannerHelp_processSpec (QOBSERVER)); } +"dependent" { return (cscannerHelp_processSpec (QDEPENDENT)); } +"unused" { return (cscannerHelp_processSpec (QUNUSED)); } +"external" { return (cscannerHelp_processSpec (QEXTERNAL)); } +"sef" { return (cscannerHelp_processSpec (QSEF)); } +"shared" { return (cscannerHelp_processSpec (QSHARED)); } +"yield" { return (cscannerHelp_processSpec (QYIELD)); } +"undef" { return (cscannerHelp_processSpec (QUNDEF)); } +"killed" { return (cscannerHelp_processSpec (QKILLED)); } +"nullterminated" { return (cscannerHelp_processSpec (QNULLTERMINATED));} +"MaxSet" { return (cscannerHelp_processSpec (QMAXSET));} +"MaxRead" { return (cscannerHelp_processSpec (QMAXREAD));} +"maxSet" { return (cscannerHelp_processSpec (QMAXSET));} +"maxRead" { return (cscannerHelp_processSpec (QMAXREAD));} + +{Letter}({Letter}|{Digit})* { int tok = cscannerHelp_processTextIdentifier (yytext); + if (tok != BADTOK) { return (tok); } } -0[xX]{H}+ { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_int, processHex ()); /* evs 2000-05-17 was ctype_uint */ +0[xX]{H}+ { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_int, cscannerHelp_processHex ()); /* evs 2000-05-17 was ctype_uint */ } -0[xX]{H}+{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_lint, processHex ()); } -0[xX]{H}+{L}{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_llint, processHex ()); } -0[xX]{H}+{U} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_uint, processHex ()); } -0[xX]{H}+{ULSuffix} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ulint, processHex ()); } -0[xX]{H}+{U}{L}{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ullint, processHex ()); } -0[xX]{H}+{L}{L}{U} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ullint, processHex ()); } -0{Digit}+ { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_int, processOctal ()); } -0{Digit}+{U} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_uint, processOctal ()); } -0{Digit}+{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_lint, processOctal ()); } -0{Digit}+{L}{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_llint, processOctal ()); } -0{Digit}+{ULSuffix} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ulint, processOctal ()); } -0{Digit}+{U}{L}{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ullint, processOctal ()); } -0{Digit}+{L}{L}{U} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ullint, processOctal ()); } -{Digit}+ { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_int, processDec ()); } -{Digit}+{U} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_uint, processDec ()); } -{Digit}+{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_lint, processDec ()); } -{Digit}+{L}{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_llint, processDec ()); } -{Digit}+{ULSuffix} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ulint, processDec ()); } -{Digit}+{U}{L}{L} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ullint, processDec ()); } -{Digit}+{L}{L}{U} { setTokLengthT (mstring_length (yytext)); - RETURN_INT (ctype_ullint, processDec ()); } -'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); - RETURN_CHAR (processChar ()); } -L'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); - RETURN_CHAR (processChar ()); } -{Digit}+{E}[fF] { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_float, processFloat ()); } -{Digit}+{E}[lL] { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_ldouble, processFloat ()); } -{Digit}+{E} { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_double, processFloat ()); } - -{Digit}*"."{Digit}+({E})?[fF] { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_float, processFloat ()); } -{Digit}*"."{Digit}+({E})?[lL] { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_ldouble, processFloat ()); } -{Digit}*"."{Digit}+({E})? { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_double, processFloat ()); } - -{Digit}+"."{Digit}*({E})?[fF] { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_float, processFloat ()); } -{Digit}+"."{Digit}*({E})?[lL] { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_ldouble, processFloat ()); } -{Digit}+"."{Digit}*({E})? { setTokLengthT (mstring_length (yytext)); - RETURN_FLOAT (ctype_double, processFloat ()); } - -">>=" { setTokLength (3); RETURN_TOK (RIGHT_ASSIGN); } -"<<=" { setTokLength (3); RETURN_TOK (LEFT_ASSIGN); } -"+=" { setTokLength (2); RETURN_TOK (ADD_ASSIGN); } -"-=" { setTokLength (2); RETURN_TOK (SUB_ASSIGN); } -"*=" { setTokLength (2); RETURN_TOK (MUL_ASSIGN); } -"/=" { setTokLength (2); RETURN_TOK (DIV_ASSIGN); } -"%=" { setTokLength (2); RETURN_TOK (MOD_ASSIGN); } -"&=" { setTokLength (2); RETURN_TOK (AND_ASSIGN); } -"^=" { setTokLength (2); RETURN_TOK (XOR_ASSIGN); } -"|=" { setTokLength (2); RETURN_TOK (OR_ASSIGN); } -">>" { setTokLength (2); RETURN_TOK (RIGHT_OP); } -"<<" { setTokLength (2); RETURN_TOK (LEFT_OP); } -"++" { setTokLength (2); RETURN_TOK (INC_OP); } -"--" { setTokLength (2); RETURN_TOK (DEC_OP); } -"->" { setTokLength (2); RETURN_TOK (ARROW_OP); } -"&&" { setTokLength (2); RETURN_TOK (AND_OP); } -"||" { setTokLength (2); RETURN_TOK (OR_OP); } -"<=" { setTokLength (2); RETURN_TOK (LE_OP); } -">=" { setTokLength (2); RETURN_TOK (GE_OP); } -"==" { setTokLength (2); RETURN_TOK (EQ_OP); } -"!=" { setTokLength (2); RETURN_TOK (NE_OP); } -";" { setTokLength (1); RETURN_TOK (TSEMI); } -"{" { setTokLength (1); RETURN_TOK (TLBRACE); } -"}" { setTokLength (1); RETURN_TOK (TRBRACE); } -"," { setTokLength (1); RETURN_TOK (TCOMMA); } -":" { setTokLength (1); RETURN_TOK (TCOLON); } -"=" { setTokLength (1); RETURN_TOK (TASSIGN); } -"(" { setTokLength (1); RETURN_TOK (TLPAREN); } -")" { setTokLength (1); RETURN_TOK (TRPAREN); } -"[" { setTokLength (1); RETURN_TOK (TLSQBR); } -"]" { setTokLength (1); RETURN_TOK (TRSQBR); } -"." { setTokLength (1); RETURN_TOK (TDOT); } -"&" { setTokLength (1); RETURN_TOK (TAMPERSAND); } -"!" { setTokLength (1); RETURN_TOK (TEXCL); } - - -"~" { setTokLength (1); RETURN_TOK (TTILDE); } -"-" { setTokLength (1); RETURN_TOK (TMINUS); } -"+" { setTokLength (1); RETURN_TOK (TPLUS); } -"*" { setTokLength (1); RETURN_TOK (TMULT); } -"/" { setTokLength (1); RETURN_TOK (TDIV); } -"%" { setTokLength (1); RETURN_TOK (TPERCENT); } -"<" { setTokLength (1); RETURN_TOK (TLT); } -">" { setTokLength (1); RETURN_TOK (TGT); } -"^" { setTokLength (1); RETURN_TOK (TCIRC); } -"|" { setTokLength (1); RETURN_TOK (TBAR); } -"?" { setTokLength (1); RETURN_TOK (TQUEST); } - - -"/\\" { setTokLength (1); RETURN_TOK (TCAND); } - +0[xX]{H}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processHex ()); } +0[xX]{H}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processHex ()); } +0[xX]{H}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processHex ()); } +0[xX]{H}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processHex ()); } +0[xX]{H}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processHex ()); } +0[xX]{H}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processHex ()); } +0{Digit}+ { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_int, cscannerHelp_processOctal ()); } +0{Digit}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processOctal ()); } +0{Digit}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processOctal ()); } +0{Digit}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processOctal ()); } +0{Digit}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processOctal ()); } +0{Digit}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processOctal ()); } +0{Digit}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processOctal ()); } +{Digit}+ { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_int, cscannerHelp_processDec ()); } +{Digit}+{U} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_uint, cscannerHelp_processDec ()); } +{Digit}+{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_lint, cscannerHelp_processDec ()); } +{Digit}+{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_llint, cscannerHelp_processDec ()); } +{Digit}+{ULSuffix} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ulint, cscannerHelp_processDec ()); } +{Digit}+{U}{L}{L} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processDec ()); } +{Digit}+{L}{L}{U} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnInt (ctype_ullint, cscannerHelp_processDec ()); } +'(\\.|[^\\'])+' { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnChar (cscannerHelp_processChar ()); } +L'(\\.|[^\\'])+' { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnChar (cscannerHelp_processChar ()); } +{Digit}+{E}[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); } +{Digit}+{E}[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); } +{Digit}+{E} { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); } + +{Digit}*"."{Digit}+({E})?[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); } +{Digit}*"."{Digit}+({E})?[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); } +{Digit}*"."{Digit}+({E})? { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); } + +{Digit}+"."{Digit}*({E})?[fF] { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_float, cscannerHelp_processFloat ()); } +{Digit}+"."{Digit}*({E})?[lL] { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_ldouble, cscannerHelp_processFloat ()); } +{Digit}+"."{Digit}*({E})? { cscannerHelp_setTokLengthT (mstring_length (yytext)); + return cscannerHelp_returnFloat (ctype_double, cscannerHelp_processFloat ()); } + +">>=" { return cscannerHelp_returnTokenLength (RIGHT_ASSIGN, 3); } +"<<=" { return cscannerHelp_returnTokenLength (LEFT_ASSIGN, 3); } +"+=" { return cscannerHelp_returnTokenLength (ADD_ASSIGN, 2); } +"-=" { return cscannerHelp_returnTokenLength (SUB_ASSIGN, 2); } +"*=" { return cscannerHelp_returnTokenLength (MUL_ASSIGN, 2); } +"/=" { return cscannerHelp_returnTokenLength (DIV_ASSIGN, 2); } +"%=" { return cscannerHelp_returnTokenLength (MOD_ASSIGN, 2); } +"&=" { return cscannerHelp_returnTokenLength (AND_ASSIGN, 2); } +"^=" { return cscannerHelp_returnTokenLength (XOR_ASSIGN, 2); } +"|=" { return cscannerHelp_returnTokenLength (OR_ASSIGN, 2); } +">>" { return cscannerHelp_returnTokenLength (RIGHT_OP, 2); } +"<<" { return cscannerHelp_returnTokenLength (LEFT_OP, 2); } +"++" { return cscannerHelp_returnTokenLength (INC_OP, 2); } +"--" { return cscannerHelp_returnTokenLength (DEC_OP, 2); } +"->" { return cscannerHelp_returnTokenLength (ARROW_OP, 2); } +"&&" { return cscannerHelp_returnTokenLength (AND_OP, 2); } +"||" { return cscannerHelp_returnTokenLength (OR_OP, 2); } +"/\\" { return cscannerHelp_returnTokenLength (TCAND, 2); } +"<=" { return cscannerHelp_returnTokenLength (LE_OP, 2); } +">=" { return cscannerHelp_returnTokenLength (GE_OP, 2); } +"==" { return cscannerHelp_returnTokenLength (EQ_OP, 2); } +"!=" { return cscannerHelp_returnTokenLength (NE_OP, 2); } +";" { return cscannerHelp_returnTokenLength (TSEMI, 1); } +"{" { return cscannerHelp_returnTokenLength (TLBRACE, 1); } +"}" { return cscannerHelp_returnTokenLength (TRBRACE, 1); } +"," { return cscannerHelp_returnTokenLength (TCOMMA, 1); } +":" { return cscannerHelp_returnTokenLength (TCOLON, 1); } +"=" { return cscannerHelp_returnTokenLength (TASSIGN, 1); } +"(" { return cscannerHelp_returnTokenLength (TLPAREN, 1); } +")" { return cscannerHelp_returnTokenLength (TRPAREN, 1); } +"[" { return cscannerHelp_returnTokenLength (TLSQBR, 1); } +"]" { return cscannerHelp_returnTokenLength (TRSQBR, 1); } +"." { return cscannerHelp_returnTokenLength (TDOT, 1); } +"&" { return cscannerHelp_returnTokenLength (TAMPERSAND, 1); } +"!" { return cscannerHelp_returnTokenLength (TEXCL, 1); } +"~" { return cscannerHelp_returnTokenLength (TTILDE, 1); } +"-" { return cscannerHelp_returnTokenLength (TMINUS, 1); } +"+" { return cscannerHelp_returnTokenLength (TPLUS, 1); } +"*" { return cscannerHelp_returnTokenLength (TMULT, 1); } +"/" { return cscannerHelp_returnTokenLength (TDIV, 1); } +"%" { return cscannerHelp_returnTokenLength (TPERCENT, 1); } +"<" { return cscannerHelp_returnTokenLength (TLT, 1); } +">" { return cscannerHelp_returnTokenLength (TGT, 1); } +"^" { return cscannerHelp_returnTokenLength (TCIRC, 1); } +"|" { return cscannerHelp_returnTokenLength (TBAR, 1); } +"?" { return cscannerHelp_returnTokenLength (TQUEST, 1); } [ \t\v\f] { incColumn (); } -\n { context_incLineno (); - if (tokLength != 0) { - tokLength = 0; - /* No error to report - voptgenerror - (FLG_SYNTAX, - message ("Likely parse error: token spans multiple lines."), - g_currentloc); - */ - } - - if (continueLine) - { - continueLine = FALSE; - } - else - { - if (context_inMacro ()) - { - /* Don't use RETURN_TOK */ - yylval.tok = lltok_create (TENDMACRO, fileloc_copy (g_currentloc)); /* !!! evans 2002-03-13 */ - lastWasString = FALSE; - return (TENDMACRO); - } - } - } -"@@MR@@" { setTokLength (6); +\n { int tok = cscannerHelp_handleNewLine (); + if (tok != BADTOK) return tok; } +"@@MR@@" { cscannerHelp_setTokLength (6); - if (processMacro ()) { + if (cscannerHelp_processMacro ()) { if (context_inIterDef ()) { - RETURN_TOK (LLMACROITER); + return cscannerHelp_returnToken (LLMACROITER); } if (context_inIterEnd ()) { - RETURN_TOK (LLMACROEND); + return cscannerHelp_returnToken (LLMACROEND); } if (context_inMacro ()) { - RETURN_TOK (LLMACRO); + return cscannerHelp_returnToken (LLMACRO); } } } "@QLMR" { if (context_inHeader () || context_inFunction ()) { - handleMacro (); + cscannerHelp_handleMacro (); } else { - int nspchar = ninput (); + int nspchar = cscannerHelp_ninput (); int nspaces; /* @@ -516,50 +375,50 @@ L'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); nspaces = nspchar - '0'; - setTokLength (5 + nspaces); + cscannerHelp_setTokLength (5 + nspaces); - if (processMacro ()) + if (cscannerHelp_processMacro ()) { DPRINTF (("Here we are: %s", context_unparse ())); if (context_inIterDef ()) { - RETURN_TOK (LLMACROITER); + return cscannerHelp_returnToken (LLMACROITER); } if (context_inIterEnd ()) { - RETURN_TOK (LLMACROEND); + return cscannerHelp_returnToken (LLMACROEND); } if (context_inMacro ()) { - RETURN_TOK (LLMACRO); + return cscannerHelp_returnToken (LLMACRO); } } } } -"@.CT" { setTokLength (4); lldiagmsg (ctype_unparseTable ()); } -"@.FA" { setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); } -"@.F" { setTokLength (3); +"@.CT" { cscannerHelp_setTokLength (4); lldiagmsg (ctype_unparseTable ()); } +"@.FA" { cscannerHelp_setTokLength (4); lldiagmsg (message ("Access types: %q", typeIdSet_unparse (context_fileAccessTypes ()))); } +"@.F" { cscannerHelp_setTokLength (3); lldiagmsg (message ("%q: *** marker ***", fileloc_unparse (g_currentloc))); } -"@.L" { setTokLength (3); usymtab_printLocal (); } -"@.A" { setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); } -"@.C" { setTokLength (3); lldiagmsg (context_unparse ()); } -"@.W" { setTokLength (3); lldiagmsg (context_unparseClauses ()); } -"@.G" { setTokLength (3); usymtab_printGuards (); } -"@.S" { setTokLength (3); usymtab_printOut (); } -"@.X" { setTokLength (3); usymtab_printAll (); } -"@.Z" { setTokLength (3); usymtab_printComplete (); } -"@.T" { setTokLength (3); usymtab_printTypes (); } -"@.K" { setTokLength (3); lldiagmsg (usymtab_unparseStack ()); } -"@.M" { setTokLength (3); +"@.L" { cscannerHelp_setTokLength (3); usymtab_printLocal (); } +"@.A" { cscannerHelp_setTokLength (3); lldiagmsg (usymtab_unparseAliases ()); } +"@.C" { cscannerHelp_setTokLength (3); lldiagmsg (context_unparse ()); } +"@.W" { cscannerHelp_setTokLength (3); lldiagmsg (context_unparseClauses ()); } +"@.G" { cscannerHelp_setTokLength (3); usymtab_printGuards (); } +"@.S" { cscannerHelp_setTokLength (3); usymtab_printOut (); } +"@.X" { cscannerHelp_setTokLength (3); usymtab_printAll (); } +"@.Z" { cscannerHelp_setTokLength (3); usymtab_printComplete (); } +"@.T" { cscannerHelp_setTokLength (3); usymtab_printTypes (); } +"@.K" { cscannerHelp_setTokLength (3); lldiagmsg (usymtab_unparseStack ()); } +"@.M" { cscannerHelp_setTokLength (3); lldiagmsg (message ("Can modify: %q", sRefSet_unparse (context_modList ()))); } "%{" { /* BEFORE_COMMENT_MARKER */ int tok; incColumn (); incColumn (); - tok = handleLlSpecial (); + tok = cscannerHelp_handleLlSpecial (); if (tok != BADTOK) { @@ -567,16 +426,15 @@ L'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); return (tok); } else { /* Beware - this bashes yylval! */ - RETURN_TOK (tok); + return cscannerHelp_returnToken (tok); } } } "%}" { /* AFTER_COMMENT_MARKER */ - setTokLength (2); - s_inSpecPart = FALSE; - s_whichSpecPart = BADTOK; - RETURN_TOK (QENDMACRO); } -"\\" { incColumn (); continueLine = TRUE; } + cscannerHelp_setTokLength (2); + cscannerHelp_exitSpecPart (); + return cscannerHelp_returnToken (QENDMACRO); } +"\\" { incColumn (); cscannerHelp_setContinueLine (); } . { incColumn (); if ((int) *yytext == 13 ) { ; @@ -591,2725 +449,18 @@ L'(\\.|[^\\'])+' { setTokLengthT (mstring_length (yytext)); %% /* -** Resets flags set by flex.head. -*/ - -/*@=allmacros@*/ -/*@=pred@*/ -/*@=globstate@*/ -/*@=null@*/ -/*@=boolint@*/ -/*@=charint@*/ -/*@=macrospec@*/ -/*@=macroredef@*/ -/*@=exitarg@*/ -/*@=compdef@*/ -/*@=uniondef@*/ -/*@=ignorequals@*/ -/*@=noreturn@*/ -/*@=mustfree@*/ -/*@=compdestroy@*/ -/*@=branchstate@*/ -/*@=unreachable@*/ -/*@=varuse@*/ -/*@=fcnuse@*/ -/*@=exportlocal@*/ -/*@=evalorderuncon@*/ -/*@=exportheader@*/ -/*@=redecl@*/ -/*@=loopswitchbreak@*/ -/*@=switchswitchbreak@*/ -/*@=sizeoftype@*/ -/*@=czechfcns@*/ -/*@=noparams@*/ -/*@=ansireserved@*/ -/*@=ifblock@*/ -/*@=whileblock@*/ -/*@=forblock@*/ -/*@=elseifcomplete@*/ -/*@=ptrnegate@*/ -/*@=onlytrans@*/ -/*@=temptrans@*/ -/*@=immediatetrans@*/ -/*@=namechecks@*/ -/*@=matchanyintegral@*/ -/*@=statictrans@*/ -/*@=compmempass@*/ -/*@=forempty@*/ -/*@=evalorder@*/ -/*@=retalias@*/ -/*@=redecl@*/ -/*@=retvalother@*/ -/*@=exportheader@*/ - -struct skeyword -{ - /*@null@*/ /*@observer@*/ char *name; - int token; -} ; - -/* -** These tokens are followed by syntax that is parsed by the -** grammar proper. -*/ - -static struct skeyword s_parsetable[] = { - { "modifies", QMODIFIES } , - { "globals", QGLOBALS } , - { "alt", QALT } , - { "warn", QWARN } , - { "constant", QCONSTANT } , - { "function", QFUNCTION } , - { "iter", QITER } , - { "defines", QDEFINES } , - { "uses", QUSES } , - { "allocates", QALLOCATES } , - { "sets", QSETS } , - { "releases", QRELEASES } , - { "pre", QPRECLAUSE } , - { "post", QPOSTCLAUSE } , - { "setBufferSize", QSETBUFFERSIZE}, - { "setStringLength", QSETSTRINGLENGTH}, - { "testinRange", QTESTINRANGE}, - { "requires", QPRECLAUSE } , - { "ensures", QPOSTCLAUSE } , - { "invariant", QINVARIANT} , - { NULL, BADTOK } -} ; - -/* -** These tokens are either stand-alone tokens, or followed by -** token-specific text. -*/ - -static struct skeyword s_keytable[] = { - { "anytype", QANYTYPE } , - { "integraltype", QINTEGRALTYPE } , - { "unsignedintegraltype", QUNSIGNEDINTEGRALTYPE } , - { "signedintegraltype", QSIGNEDINTEGRALTYPE } , - { "out", QOUT } , - { "in", QIN } , - { "only", QONLY } , - { "owned", QOWNED } , - { "dependent", QDEPENDENT } , - { "partial", QPARTIAL } , - { "special", QSPECIAL } , - { "truenull", QTRUENULL } , - { "falsenull", QFALSENULL } , - { "nullwhentrue", QTRUENULL } , - { "falsewhennull", QFALSENULL } , - { "keep", QKEEP } , - { "kept", QKEPT } , - { "notnull", QNOTNULL } , - { "abstract", QABSTRACT } , - { "numabstract", QNUMABSTRACT } , - { "concrete", QCONCRETE } , - { "mutable", QMUTABLE } , - { "immutable", QIMMUTABLE } , - { "unused", QUNUSED } , - { "external", QEXTERNAL } , - { "sef", QSEF } , - { "unique", QUNIQUE } , - { "returned", QRETURNED } , - { "exposed", QEXPOSED } , - { "refcounted", QREFCOUNTED } , - { "refs", QREFS } , - { "newref", QNEWREF } , - { "tempref", QTEMPREF } , - { "killref", QKILLREF } , - { "null", QNULL } , - { "relnull", QRELNULL } , - { "nullterminated", QNULLTERMINATED }, - { "setBufferSize", QSETBUFFERSIZE }, - { "testInRange", QTESTINRANGE}, - { "isnull", QISNULL }, - { "MaxSet", QMAXSET}, - { "MaxRead", QMAXREAD}, - { "maxSet", QMAXSET}, - { "maxRead", QMAXREAD}, - { "reldef", QRELDEF } , - { "observer", QOBSERVER } , - { "exits", QEXITS } , - { "noreturn", QEXITS } , - { "mayexit", QMAYEXIT } , - { "maynotreturn", QMAYEXIT } , - { "trueexit", QTRUEEXIT } , - { "falseexit", QFALSEEXIT } , - { "noreturnwhentrue", QTRUEEXIT } , - { "noreturnwhenfalse", QFALSEEXIT } , - { "neverexit", QNEVEREXIT } , - { "alwaysreturns", QNEVEREXIT } , - { "temp", QTEMP } , - { "shared", QSHARED } , - { "ref", QREF } , - { "unchecked", QUNCHECKED } , - { "checked", QCHECKED } , - { "checkmod", QCHECKMOD } , - { "checkedstrict", QCHECKEDSTRICT } , - { "innercontinue", QINNERCONTINUE } , - { "innerbreak", QINNERBREAK } , - { "loopbreak", QLOOPBREAK } , - { "switchbreak", QSWITCHBREAK } , - { "safebreak", QSAFEBREAK } , - { "fallthrough", QFALLTHROUGH } , - { "l_fallthrou", QLINTFALLTHROUGH } , - { "l_fallth", QLINTFALLTHRU } , - { "notreached", QNOTREACHED } , - { "l_notreach", QLINTNOTREACHED } , - { "printflike", QPRINTFLIKE } , - { "l_printfli", QLINTPRINTFLIKE } , - { "scanflike", QSCANFLIKE } , - { "messagelike", QMESSAGELIKE } , - { "l_argsus", QARGSUSED } , - { NULL, BADTOK } -} ; - -/* -** would be better if these weren't hard coded... -*/ - -static bool isArtificial (cstring s) -{ - return (cstring_equalLit (s, "modifies") - || cstring_equalLit (s, "globals") - || cstring_equalLit (s, "warn") - || cstring_equalLit (s, "alt")); -} - -void cscanner_swallowMacro (void) -{ - int i; - bool skipnext = FALSE; - - while ((i = lminput ()) != EOF) - { - char c = (char) i; - - if (c == '\\') - { - skipnext = TRUE; - } - else if (c == '\n') - { - if (skipnext) - { - skipnext = FALSE; - } - else - { - reader_checkUngetc (i, yyin); - return; - } - } - else - { - ; - } - } - - if (i != EOF) - { - reader_checkUngetc (i, yyin); - } -} - -static int commentMarkerToken (cstring s) -{ - int i = 0; - - 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; - } - - i++; - } - - return BADTOK; -} - -static int tokenMacroCode (cstring s) -{ - int i = 0; - - while (s_keytable[i].name != NULL) - { - if (cstring_equalLit (s, s_keytable[i].name)) - { - if (s_keytable[i].token == QLINTFALLTHROUGH) - { - voptgenerror - (FLG_WARNLINTCOMMENTS, - cstring_makeLiteral - ("Traditional lint comment /*FALLTHROUGH*/ used. " - "Splint interprets this in the same way as most Unix lints, but it is " - "preferable to replace it with the /*@fallthrough@*/ " - "semantic comment"), - g_currentloc); - return QFALLTHROUGH; - } - else if (s_keytable[i].token == QLINTFALLTHRU) - { - voptgenerror - (FLG_WARNLINTCOMMENTS, - cstring_makeLiteral - ("Traditional lint comment /*FALLTHRU*/ used. " - "Splint interprets this in the same way as most Unix lints, but it is " - "preferable to replace it with the /*@fallthrough@*/ " - "semantic comment"), - g_currentloc); - return QFALLTHROUGH; - } - else if (s_keytable[i].token == QLINTNOTREACHED) - { - voptgenerror - (FLG_WARNLINTCOMMENTS, - cstring_makeLiteral - ("Traditional lint comment /*NOTREACHED*/ used. " - "Splint interprets this in the same way as most Unix lints, but it is " - "preferable to replace it with the /*@notreached@*/ " - "semantic comment."), - g_currentloc); - - return QNOTREACHED; - } - else if (s_keytable[i].token == QPRINTFLIKE) - { - setSpecialFunction (qual_createPrintfLike ()); - return SKIPTOK; - } - else if (s_keytable[i].token == QLINTPRINTFLIKE) - { - voptgenerror - (FLG_WARNLINTCOMMENTS, - cstring_makeLiteral - ("Traditional lint comment /*PRINTFLIKE*/ used. " - "Splint interprets this in the same way as most Unix lints, but it is " - "preferable to replace it with either /*@printflike@*/, " - "/*@scanflike@*/ or /*@messagelike@*/."), - g_currentloc); - - setSpecialFunction (qual_createPrintfLike ()); - return SKIPTOK; - } - else if (s_keytable[i].token == QSCANFLIKE) - { - setSpecialFunction (qual_createScanfLike ()); - return SKIPTOK; - } - else if (s_keytable[i].token == QMESSAGELIKE) - { - setSpecialFunction (qual_createMessageLike ()); - return SKIPTOK; - } - else if (s_keytable[i].token == QARGSUSED) - { - voptgenerror - (FLG_WARNLINTCOMMENTS, - cstring_makeLiteral - ("Traditional lint comment /*ARGSUSED*/ used. " - "Splint interprets this in the same way as most Unix lints, but it is " - "preferable to use /*@unused@*/ annotations on " - "the unused parameters."), - g_currentloc); - - setArgsUsed (); - return SKIPTOK; - } - else - { - return s_keytable[i].token; - } - } - - i++; - } - - return BADTOK; -} - -static int lminput () -{ - if (savechar == '\0') - { - incColumn (); - return (input ()); - } - else - { - int save = (int) savechar; - savechar = '\0'; - return save; - } -} - -static void lmsavechar (char c) -{ - if (savechar == '\0') savechar = c; - else - { - llbuglit ("lmsavechar: override"); - } -} - -static int returnFloat (ctype ct, double f) -{ - yylval.expr = exprNode_floatLiteral (f, ct, cstring_fromChars (yytext), - fileloc_decColumn (g_currentloc, tokLength)); - tokLength = 0; - return (CCONSTANT); -} - -static int returnInt (ctype ct, long i) -{ - ctype c = ct; - - if (ctype_equal (ct, ctype_int)) - { - if (i == 0) - { - c = context_typeofZero (); - } - else if (i == 1) - { - c = context_typeofOne (); - } - else - { - ; - } - } - - yylval.expr = exprNode_numLiteral (c, cstring_fromChars (yytext), - fileloc_decColumn (g_currentloc, tokLength), i); - tokLength = 0; - return (CCONSTANT); -} - -static int returnChar (char c) -{ - yylval.expr = exprNode_charLiteral (c, cstring_fromChars (yytext), - fileloc_decColumn (g_currentloc, tokLength)); - tokLength = 0; - return (CCONSTANT); -} - -static int ninput () -{ - int c = lminput (); - - if (c != EOF && ((char)c == '\n')) - { - context_incLineno (); - } - - return c; -} - -static char macro_nextChar (void) -{ - static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE; - int ic; - char c; - - ic = lminput (); - c = char_fromInt (ic); - - if (!in_quote && !in_char && (c == '\\' || c == BEFORE_COMMENT_MARKER[0])) - { - if (c == '\\') - { - while ((c = char_fromInt (lminput ())) != '\0' && c != '\n') - { - ; /* skip to newline */ - } - - context_incLineno (); - - if (c != '\0') - { - return macro_nextChar (); - } - else - { - return c; - } - } - else /* if (c == '@') */ - { - llassert (FALSE); /*@i23@*/ - if (handleLlSpecial () != BADTOK) - { - llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax"); - } - - return macro_nextChar (); - } - } - else if (!in_escape && c == '\"') - { - in_quote = !in_quote; - } - else if (!in_escape && c == '\'') - { - in_char = !in_char; - } - else if ((in_quote || in_char) && c == '\\') - { - in_escape = !in_escape; - } - else if ((in_quote || in_char) && in_escape) - { - in_escape = FALSE; - } - else if (!in_quote && c == '/') - { - char c2; - - if ((c2 = char_fromInt (lminput ())) == '*') - { - while (c2 != '\0') - { - while ((c2 = char_fromInt (lminput ())) != '\0' - && c2 != '\n' && c2 != '*') - { - ; - } - - if (c2 == '*') - { - while ((c2 = char_fromInt (lminput ())) != '\0' - && c2 == '*') - { - ; - } - - if (c2 == '/') - { - goto outofcomment; - } - } - else - { - llfatalerror (cstring_makeLiteral ("Macro: bad comment!")); - } - } - outofcomment: - return macro_nextChar (); - } - else - { - /*** putchar does not work! why? puts to stdio...??! ***/ - lmsavechar (c2); - } - } - else - { - ; - } - - return c; -} - -/* -** keeps semantic comments -*/ - -static char macro_nextCharC (void) -{ - static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE; - char c; - - c = char_fromInt (lminput ()); - - if (!in_quote && !in_char && c == '\\') - { - while ((c = char_fromInt (lminput ())) != '\0' && c != '\n') - { - ; /* skip to newline */ - } - - context_incLineno (); - - if (c != '\0') - { - return macro_nextCharC (); - } - else - { - return c; - } - } - else if (!in_escape && c == '\"') - { - in_quote = !in_quote; - } - else if (!in_escape && c == '\'') - { - in_char = !in_char; - } - else if ((in_quote || in_char) && c == '\\') - { - in_escape = !in_escape; - } - else if ((in_quote || in_char) && in_escape) - { - in_escape = FALSE; - } - else if (!in_quote && c == '/') - { - char c2; - - if ((c2 = char_fromInt (lminput ())) == '*') - { - while (c2 != '\0') - { - while ((c2 = char_fromInt (lminput ())) != '\0' - && c2 != '\n' && c2 != '*') - { - ; - } - - if (c2 == '*') - { - while ((c2 = char_fromInt (lminput ())) != '\0' - && c2 == '*') - { - ; - } - - if (c2 == '/') - { - goto outofcomment; - } - } - else - { - llfatalerror (cstring_makeLiteral ("Macro: bad comment!")); - } - } - outofcomment: - return macro_nextCharC (); - } - else - { - lmsavechar (c2); - } - } - else /* normal character */ - { - ; - } - - return c; -} - -/* -** skips whitespace (handles line continuations) -** returns first non-whitespace character +** These need to go here, after flex-generated code defined input and unput. */ -static char skip_whitespace (void) -{ - char c; - - while ((c = macro_nextChar ()) == ' ' || c == '\t') - { - ; - } - - return c; -} - -static void handleMacro () +int cscanner_input (void) { - cstring mac = cstring_undefined; - int macrocode; - char c; - - while (currentColumn () > 2) - { - mac = cstring_appendChar (mac, ' '); - setTokLength (-1); - } - - c = macro_nextCharC (); - - if (c >= '0' && c <= '9') - { - int i; - - for (i = 0; i < (((int) (c - '0')) + 1); i++) - { - mac = cstring_appendChar (mac, ' '); - } - } - else - { - BADBRANCH; - } - - while (((c = macro_nextCharC ()) != '\0') && (c != '\n')) - { - mac = cstring_appendChar (mac, c); - } - - - macrocode = tokenMacroCode (mac); - - if (macrocode == BADTOK && !isArtificial (mac)) - { - context_addMacroCache (mac); - } - else - { - cstring_free (mac); - } - - if (c == '\n') - { - context_incLineno (); - } + return input (); /* input is a static procedure defined by flex-generated code */ } -static bool processMacro (void) +void cscanner_unput (int c) { - uentry e2; - ctype ct; - int noparams = 0; - cstring fname = cstring_undefined; - bool res = TRUE; - bool isspecfcn = FALSE; - bool isiter = FALSE; - bool skipparam = FALSE; - bool isenditer = FALSE; - bool unknownm = FALSE; - bool hasParams = FALSE; - bool emptyMacro = FALSE; - char c = skip_whitespace (); - fileloc loc = fileloc_noColumn (g_currentloc); - - /* are both of these necessary? what do they mean? */ - uentryList specparams = uentryList_undefined; - uentryList pn = uentryList_undefined; - - context_resetMacroMissingParams (); - - if (c == '\0' || c == '\n') - { - llcontbug (cstring_makeLiteral ("Bad macro")); - fileloc_free (loc); - return FALSE; - } - - fname = cstring_appendChar (fname, c); - - while ((c = macro_nextChar ()) != '(' && c != '\0' - && c != ' ' && c != '\t' && c != '\n') - { - fname = cstring_appendChar (fname, c); - } - - if (c == ' ' || c == '\t' || c == '\n') - { - char oldc = c; - - if (c != '\n') - { - while (c == ' ' || c == '\t') - { - c = macro_nextChar (); - } - unput ((int) c); - } - - if (c == '\n') - { - emptyMacro = TRUE; - unput ((int) c); - } - - c = oldc; - } - - hasParams = (c == '('); - - if (usymtab_exists (fname)) - { - e2 = usymtab_lookupExpose (fname); - ct = uentry_getType (e2); - - if (uentry_isCodeDefined (e2) - && fileloc_isUser (uentry_whereDefined (e2))) - { - if (optgenerror - (FLG_MACROREDEF, - message ("Macro %s already defined", fname), - loc)) - { - uentry_showWhereDefined (e2); - uentry_clearDefined (e2); - } - - if (uentry_isFunction (e2)) - { - uentry_setType (e2, ctype_unknown); - ct = ctype_unknown; - unknownm = TRUE; - context_enterUnknownMacro (e2); - } - else - { - context_enterConstantMacro (e2); - } - } - else - { - if (uentry_isForward (e2) && uentry_isFunction (e2)) - { - unknownm = TRUE; - - voptgenerror - (FLG_MACROFCNDECL, - message - ("Parameterized macro has no prototype or specification: %s ", - fname), - loc); - - ct = ctype_unknown; - uentry_setType (e2, ctype_unknown); - uentry_setFunctionDefined (e2, loc); - uentry_setUsed (e2, fileloc_undefined); - context_enterUnknownMacro (e2); - } - else - { - if (uentry_isIter (e2)) - { - isiter = TRUE; - specparams = uentry_getParams (e2); - noparams = uentryList_size (specparams); - uentry_setDefined (e2, loc); - context_enterIterDef (e2); - } - else if (uentry_isEndIter (e2)) - { - isenditer = TRUE; - uentry_setDefined (e2, loc); - context_enterIterEnd (e2); /* don't care about it now */ - /* but should parse like an iter! */ - } - else if (uentry_isConstant (e2)) - { - if (hasParams) - { - voptgenerror - (FLG_INCONDEFS, - message ("Constant %s implemented as parameterized macro", - fname), - g_currentloc); - - uentry_showWhereSpecified (e2); - uentry_setType (e2, ctype_unknown); - uentry_makeConstantFunction (e2); - uentry_setDefined (e2, g_currentloc); - uentry_setFunctionDefined (e2, g_currentloc); - context_enterUnknownMacro (e2); - } - else - { - if (!uentry_isSpecified (e2)) - { - fileloc oloc = uentry_whereDeclared (e2); - - if (fileloc_isLib (oloc)) - { - ; - } - else if (fileloc_isUndefined (oloc) - || fileloc_isPreproc (oloc)) - { - if (!emptyMacro) - { - voptgenerror - (FLG_MACROCONSTDECL, - message - ("Macro constant %q not declared", - uentry_getName (e2)), - loc); - } - } - else if (!fileloc_withinLines (oloc, loc, 2)) - { /* bogus! will give errors if there is too much whitespace */ - voptgenerror - (FLG_SYNTAX, - message - ("Macro constant name %s does not match name in " - "previous constant declaration. This constant " - "is declared at %q", fname, - fileloc_unparse (oloc)), - loc); - } - else - { - /* No warning */ - } - } - - context_enterConstantMacro (e2); - cstring_free (fname); - fileloc_free (loc); - return res; - } - - } - else if (ctype_isFunction (ct)) - { - isspecfcn = TRUE; - specparams = ctype_argsFunction (ct); - noparams = uentryList_size (specparams); - - uentry_setFunctionDefined (e2, loc); - context_enterMacro (e2); - } - else if (uentry_isVar (e2)) - { - if (hasParams) - { - voptgenerror - (FLG_INCONDEFS, - message ("Variable %s implemented as parameterized macro", - fname), - loc); - - uentry_showWhereSpecified (e2); - uentry_setType (e2, ctype_unknown); - uentry_makeVarFunction (e2); - uentry_setDefined (e2, g_currentloc); - uentry_setFunctionDefined (e2, g_currentloc); - context_enterUnknownMacro (e2); - } - else - { - uentry ucons = uentry_makeConstant (fname, - ctype_unknown, - loc); - if (uentry_isExpandedMacro (e2)) - { - ; /* okay */ - } - else - { - if (optgenerror - (FLG_INCONDEFS, - message ("Variable %s implemented by a macro", - fname), - loc)) - { - uentry_showWhereSpecified (e2); - } - } - - uentry_setDefined (e2, loc); - uentry_setUsed (ucons, loc); - - context_enterConstantMacro (ucons); - uentry_markOwned (ucons); - cstring_free (fname); - return res; - } - } - else - { - if (uentry_isDatatype (e2)) - { - vgenhinterror - (FLG_SYNTAX, - message ("Type implemented as macro: %x", - uentry_getName (e2)), - message ("A type is implemented using a macro definition. A " - "typedef should be used instead."), - g_currentloc); - - cscanner_swallowMacro (); - /* Must exit scope (not sure why a new scope was entered?) */ - usymtab_quietExitScope (g_currentloc); - uentry_setDefined (e2, g_currentloc); - res = FALSE; - } - else - { - llcontbug - (message ("Unexpanded macro not function or constant: %q", - uentry_unparse (e2))); - uentry_setType (e2, ctype_unknown); - - if (hasParams) - { - uentry_makeVarFunction (e2); - uentry_setDefined (e2, g_currentloc); - uentry_setFunctionDefined (e2, g_currentloc); - context_enterUnknownMacro (e2); - } - } - } - } - } - } - else - { - uentry ce; - - /* evans 2001-09-09 - if it has params, assume a function */ - if (hasParams) - { - voptgenerror - (FLG_MACROMATCHNAME, - message ("Unexpanded macro %s does not match name of a declared " - "function. The name used in the control " - "comment on the previous line should match.", - fname), - loc); - - ce = uentry_makeFunction (fname, ctype_unknown, - typeId_invalid, - globSet_undefined, - sRefSet_undefined, - warnClause_undefined, - fileloc_undefined); - uentry_setUsed (ce, loc); /* perhaps bogus? */ - e2 = usymtab_supEntryReturn (ce); - context_enterUnknownMacro (e2); - } - else - { - voptgenerror - (FLG_MACROMATCHNAME, - message ("Unexpanded macro %s does not match name of a constant " - "or iter declaration. The name used in the control " - "comment on the previous line should match. " - "(Assuming macro defines a constant.)", - fname), - loc); - - ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined); - uentry_setUsed (ce, loc); /* perhaps bogus? */ - e2 = usymtab_supEntryReturn (ce); - - context_enterConstantMacro (e2); - cstring_free (fname); - fileloc_free (loc); - return res; - } - } - - /* in macros, ( must follow immediatetly after name */ - - if (hasParams) - { - int paramno = 0; - - c = skip_whitespace (); - - while (c != ')' && c != '\0') - { - uentry param; - bool suppress = context_inSuppressRegion (); - cstring paramname = cstring_undefined; - - /* - ** save the parameter location - */ - - decColumn (); - context_saveLocation (); - incColumn (); - - while (c != ' ' && c != '\t' && c != ',' && c != '\0' && c != ')') - { - paramname = cstring_appendChar (paramname, c); - c = macro_nextChar (); - } - - if (c == ' ' || c == '\t') c = skip_whitespace (); - - if (c == ',') - { - c = macro_nextChar (); - if (c == ' ' || c == '\t') c = skip_whitespace (); - } - - if (c == '\0') - { - llfatalerror (cstring_makeLiteral - ("Bad macro syntax: uentryList")); - } - - if ((isspecfcn || isiter) && (paramno < noparams) - && !uentry_isElipsisMarker (uentryList_getN - (specparams, paramno))) - { - fileloc sloc = context_getSaveLocation (); - uentry decl = uentryList_getN (specparams, paramno); - sRef sr; - - param = uentry_nameCopy (paramname, decl); - - uentry_setParam (param); - sr = sRef_makeParam (paramno, uentry_getType (param), stateInfo_makeLoc (sloc)); - - if (sRef_getNullState (sr) == NS_ABSNULL) - { - ctype pt = ctype_realType (uentry_getType (param)); - - if (ctype_isUser (pt)) - { - uentry te = usymtab_getTypeEntrySafe (ctype_typeId (pt)); - - if (uentry_isValid (te)) - { - sRef_setStateFromUentry (sr, te); - } - } - else - { - sRef_setNullState (sr, NS_UNKNOWN, sloc); - } - } - - uentry_setSref (param, sr); - uentry_setDeclaredForceOnly (param, sloc); - - skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno)); - } - else - { - fileloc sloc = context_getSaveLocation (); - - param = uentry_makeVariableSrefParam - (paramname, ctype_unknown, fileloc_copy (sloc), - sRef_makeParam (paramno, ctype_unknown, stateInfo_makeLoc (sloc))); - DPRINTF (("Unknown param: %s", uentry_unparseFull (param))); - cstring_free (paramname); - - sRef_setPosNull (uentry_getSref (param), sloc); - uentry_setDeclaredForce (param, sloc); - - skipparam = FALSE; - fileloc_free (sloc); - } - - if (!skipparam) - { - llassert (!uentry_isElipsisMarker (param)); - - if (!suppress) - { - sRef_makeUnsafe (uentry_getSref (param)); - } - - pn = uentryList_add (pn, uentry_copy (param)); - usymtab_supEntry (param); - } - else - { - /* don't add param */ - uentry_free (param); - } - - if (c == ',') - { - (void) macro_nextChar (); - c = skip_whitespace (); - } - - paramno++; - } - - if (c == ')') - { - if (isspecfcn || isiter) - { - if (paramno != noparams && noparams >= 0) - { - advanceLine (); - - voptgenerror - (FLG_INCONDEFS, - message ("Macro %s specified with %d args, defined with %d", - fname, noparams, paramno), - g_currentloc); - - uentry_showWhereSpecified (e2); - uentry_resetParams (e2, pn); - } - } - else - { - uentry_resetParams (e2, pn); - } - } - } - else - { - /* - ** the form should be: - ** - ** # define newname oldname - ** where oldname refers to a function matching the specification - ** of newname. - */ - - if (unknownm) - { - sRef_setGlobalScope (); - usymtab_supGlobalEntry (uentry_makeVariableLoc (fname, ctype_unknown)); - sRef_clearGlobalScope (); - } - else - { - context_setMacroMissingParams (); - } - } - - - /* context_setuentryList (pn); */ - usymtab_enterScope (); - - fileloc_free (loc); - cstring_free (fname); - - return res; + unput (c); /* unput is a static procedure defined by flex-generated code */ } -static bool handleSpecial (char *yyt) -{ - char *l; /* !! = mstring_create (MAX_NAME_LENGTH); */ - int lineno = 0; - char c; - char *ol; - cstring olc; - size_t len_yyt; - - len_yyt = strlen (yyt +1) ; - - l = mstring_copy (yyt + 1); - - while ((c = char_fromInt (lminput ())) != '\n' && c != '\0') - { - l = mstring_append(l, c); - } - - /* Need to safe original l for deallocating. */ - ol = l; - - l += strlen (l); - - olc = cstring_fromChars (ol); - - if (cstring_equalPrefixLit (olc, "pragma")) - { - char *pname = mstring_create (size_fromInt (MAX_PRAGMA_LEN)); - char *opname = pname; - char *ptr = ol + 6; /* pragma is six characters, plus space */ - int len = 0; - - - /* skip whitespace */ - while (((c = *ptr) != '\0') && isspace (c)) - { - ptr++; - } - - - while (((c = *ptr) != '\0') && !isspace (c)) - { - len++; - - if (len > MAX_PRAGMA_LEN) - { - break; - } - - ptr++; - *pname++ = c; - } - - *pname = '\0'; - - if (len == PRAGMA_LEN_EXPAND - && mstring_equal (opname, PRAGMA_EXPAND)) - { - cstring exname = cstring_undefined; - uentry ue; - - ptr++; - while (((c = *ptr) != '\0') && !isspace (c)) - { - exname = cstring_appendChar (exname, c); - ptr++; - } - - - ue = usymtab_lookupExposeGlob (exname); - - if (uentry_isExpandedMacro (ue)) - { - if (fileloc_isPreproc (uentry_whereDefined (ue))) - { - fileloc_setColumn (g_currentloc, 1); - uentry_setDefined (ue, g_currentloc); - } - } - - cstring_free (exname); - } - } - else if (cstring_equalPrefixLit (olc, "ident")) - { - /* Some pre-processors will leave these in the code. Ignore rest of line */ - } - /* - ** Yuk...Win32 filenames can have spaces in them...we need to read - ** to the matching end quote. - */ - else if ((sscanf (ol, "line %d \"", &lineno) == 1) - || (sscanf (ol, " %d \"", &lineno) == 1)) - { - char *tmp = ol; - cstring fname; - fileId fid; - - /*@access cstring@*/ - while (*tmp != '\"' && *tmp != '\0') - { - tmp++; - } - - llassert (*tmp == '\"'); - - tmp++; - - fname = tmp; - - while (*tmp != '\"' && *tmp != '\0') - { - tmp++; - } - - llassert (*tmp == '\"'); - *tmp = '\0'; -# if defined(OS2) || defined(MSDOS) || defined(WIN32) - - /* - ** DOS-like path delimiters get delivered in pairs, something like - ** \"..\\\\file.h\", so we have to make it normal again. We do NOT - ** remove the pre dirs yet as we usually specify tmp paths relative - ** to the current directory, so tmp files would not get found in - ** the hash table. If this method fails we try it again later. - */ - - { - char *stmp = fname; - - /* - ** Skip past the drive marker. - */ - - if (strchr (stmp, ':') != NULL) - { - stmp = strchr (stmp, ':') + 1; - } - - while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL ) - { - if (*(stmp+1) == CONNECTCHAR) - { - memmove (stmp, stmp+1, strlen (stmp)); - } - - stmp++; - } - - fid = fileTable_lookupBase (context_fileTable (), fname); - if (!(fileId_isValid (fid))) - { - fname = removePreDirs (fname); - fid = fileTable_lookupBase (context_fileTable (), fname); - } - } -# else /* !defined(OS2) && !defined(MSDOS) */ - fname = removePreDirs (fname); - fid = fileTable_lookupBase (context_fileTable (), fname); -# endif /* !defined(OS2) && !defined(MSDOS) */ - - if (!(fileId_isValid (fid))) - { - if (context_inXHFile ()) - { - fid = fileTable_addXHFile (context_fileTable (), fname); - } - else if (isHeaderFile (fname)) - { - fid = fileTable_addHeaderFile (context_fileTable (), fname); - } - else - { - fid = fileTable_addFile (context_fileTable (), fname); - } - } - - setFileLine (fid, lineno); - /*@noaccess cstring@*/ - } - else if ((sscanf (ol, "line %d", &lineno) == 1) - || (sscanf (ol, " %d", &lineno) == 1)) - { - setLine (lineno); /* next line is */ - } - else - { - if (mstring_equal (ol, "")) { - DPRINTF (("Empty pp command!")); - /* - ** evs 2000-05-16: This is a horrible kludge, to get around a bug (well, difficulty) in the pre-processor. - ** We handle a plain # in the input file, by echoing it, and ignoring it in the post-pp-file. - */ - mstring_free (ol); - return FALSE; - } else { - voptgenerror - (FLG_UNRECOGDIRECTIVE, - message ("Unrecognized pre-processor directive: #%s", - cstring_fromChars (ol)), - g_currentloc); - } - - sfree (ol); - return FALSE; /* evans 2001-12-30: was: TRUE; */ - } - - sfree (ol); - return FALSE; -} - -static int handleLlSpecial (void) -{ - bool hasnl = FALSE; - int ic; - char c; - char *s = mstring_createEmpty (); - 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)) - { - c = (char) ic; - s = mstring_append (s, c); - 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 == (int) AFTER_COMMENT_MARKER[1]); - - if (*s == '\0') - { - sfree (os); - fileloc_free (loc); - return QNOMODS; /* special token no modifications token */ - } - } - - DPRINTF (("Coment marker: %s", os)); - tok = commentMarkerToken (cstring_fromChars (os)); - - if (tok != BADTOK) - { - tokLength = charsread; - sfree (os); - s_inSpecPart = TRUE; - s_whichSpecPart = tok; - 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++; - - while (((ic = ninput ()) != 0) && (ic != EOF) - && (ic != (int) AFTER_COMMENT_MARKER[0])) - { - c = (char) ic; - - /* evans 2001-09-01 added to prevent assertion failures for uncloses syntactic comments */ - - if (c == '\n') { - hasnl = TRUE; /* This prevents tokLength from being set later. */ - tokLength = 0; - - voptgenerror - (FLG_SYNTAX, - message ("Likely parse error: syntactic comment token spans multiple lines: %s", - cstring_fromChars (s)), - loc); - } - - s = mstring_append (s, c); - charsread++; - } - } - - DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc))); - - if (ic == (int) AFTER_COMMENT_MARKER[0]) - { - int nc = ninput (); - llassert ((char) nc == AFTER_COMMENT_MARKER[1]); - charsread++; - } - - os = s; - - while (*s == ' ' || *s == '\t' || *s == '\n') - { - s++; - } - - if (*s == '-' || *s == '+' || *s == '=') /* setting flags */ - { - c = *s; - - while (c == '-' || c == '+' || c == '=') - { - ynm set = ynm_fromCodeChar (c); - cstring thisflag; - - s++; - - thisflag = cstring_fromChars (s); - - while ((c = *s) != '\0' && (c != '-') && (c != '=') - && (c != '+') && (c != ' ') && (c != '\t') && (c != '\n')) - { - s++; - } - - *s = '\0'; - - if (!context_getFlag (FLG_NOCOMMENTS)) - { - cstring flagname = thisflag; - flagcode fflag = flags_identifyFlag (flagname); - - if (flagcode_isSkip (fflag)) - { - ; - } - else if (flagcode_isModeName (fflag)) - { - if (ynm_isMaybe (set)) - { - llerror - (FLG_BADFLAG, - message - ("Semantic comment attempts to restore flag %s. " - "A mode flag cannot be restored.", - flagname)); - } - else - { - context_setMode (flagname); - } - } - else if (flagcode_isInvalid (fflag)) - { - voptgenerror - (FLG_UNRECOGFLAGCOMMENTS, - message ("Unrecognized option in semantic comment: %s", - flagname), - loc); - } - else if (flagcode_isGlobalFlag (fflag)) - { - voptgenerror - (FLG_BADFLAG, - message - ("Semantic comment attempts to set global flag %s. " - "A global flag cannot be set locally.", - flagname), - loc); - } - else - { - context_fileSetFlag (fflag, set, loc); - - if (flagcode_hasArgument (fflag)) - { - if (ynm_isMaybe (set)) - { - voptgenerror - (FLG_BADFLAG, - message - ("Semantic comment attempts to restore flag %s. " - "A flag for setting a value cannot be restored.", - flagname), - loc); - } - else - { /* cut-and-pastied from llmain...blecch */ - cstring extra = cstring_undefined; - char *rest; - char *orest; - char rchar; - - *s = c; - rest = mstring_copy (s); - orest = rest; - *s = '\0'; - - while ((rchar = *rest) != '\0' - && (isspace (rchar))) - { - rest++; - s++; - } - - while ((rchar = *rest) != '\0' - && !isspace (rchar)) - { - extra = cstring_appendChar (extra, rchar); - rest++; - s++; - } - s--; /* evans 2002-07-12: this was previously only in the else branch. - Leads to an invalid read on the true branch. - */ - - sfree (orest); - - if (cstring_isUndefined (extra)) - { - llerror - (FLG_BADFLAG, - message - ("Flag %s (in semantic comment) must be followed by an argument", - flagcode_unparse (fflag))); - - } - else - { - if (flagcode_hasNumber (fflag)) - { - setValueFlag (fflag, extra); - } - else if (flagcode_hasChar (fflag)) - { - setValueFlag (fflag, extra); - } - else if (flagcode_hasString (fflag)) - { - setStringFlag (fflag, extra); - } - else - { - cstring_free (extra); - BADEXIT; - } - } - } - } - } - } - else - { - ; - } - - *s = c; - while ((c == ' ') || (c == '\t') || (c == '\n')) - { - c = *(++s); - } - } - - if (context_inHeader () && !isArtificial (cstring_fromChars (os))) - { - DPRINTF (("Here adding comment: %s", os)); - context_addComment (cstring_fromCharsNew (os), loc); - } - else - { - ; - } - } - else - { - char *t = s; - int macrocode; - char tchar = '\0'; - annotationInfo ainfo; - - while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n') - { - s++; - } - - if (*s != '\0') - { - tchar = *s; - *s = '\0'; - s++; - } - - t = cstring_toCharsSafe (cstring_downcase (cstring_fromChars (t))); - macrocode = tokenMacroCode (cstring_fromChars (t)); - - if (macrocode != BADTOK) - { - tokLength = hasnl ? 0 : size_toInt (mstring_length (t)); - - sfree (t); - sfree (os); - fileloc_free (loc); - - if (macrocode == SKIPTOK) - { - return BADTOK; - } - - 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') - { - *(s-1) = tchar; - } - - if ((context_inMacro () || context_inGlobalContext ()) - && macrocode != SKIPTOK - && !isArtificial (cstring_fromChars (os))) - { - if (context_processingMacros ()) - { - /* evans 2002-02-24: don't add comments when procssing macros */ - } - else - { - context_addComment (cstring_fromCharsNew (os), loc); - } - } - else - { - ; - } - - if (tchar != '\0') - { - *(s-1) = '\0'; - } - } - - if (mstring_equal (t, "ignore")) - { - if (!context_getFlag (FLG_NOCOMMENTS)) - { - context_enterSuppressRegion (loc); - } - } - else if ((*t == 'i' || *t == 't') - && (*(t + 1) == '\0')) - { - if (!context_getFlag (FLG_NOCOMMENTS) - && (*t == 'i' || context_getFlag (FLG_TMPCOMMENTS))) - { - context_enterSuppressLine (-1, loc); /* infinite suppression */ - } - } - else if (((*t == 'i') || (*t == 't')) - && ((*(t + 1) >= '0' && *(t + 1) <= '9'))) - { - bool tmpcomment = (*t == 't'); - int val = -1; - char *tt = t; /* don't mangle t, since it is free'd */ - char lc = *(++tt); - - if (lc >= '0' && lc <= '9') - { - val = (int)(lc - '0'); - - lc = *(++tt); - while (lc >= '0' && lc <= '9') - { - val *= 10; - val += (int) (lc - '0'); - lc = *(++tt); - } - } - - if (!context_getFlag (FLG_NOCOMMENTS) - && (!tmpcomment || context_getFlag (FLG_TMPCOMMENTS))) - { - DPRINTF (("Here: enter suppress: %s", fileloc_unparse (loc))); - context_enterSuppressLine (val, loc); - } - } - else if (mstring_equal (t, "end")) - { - if (!context_getFlag (FLG_NOCOMMENTS)) - { - context_exitSuppressRegion (loc); - } - } - else if (mstring_equal (t, "notfunction")) - { - ; /* handled by pcpp */ - } - else if (mstring_equal (t, "access")) - { - cstring tname; - - while (TRUE) - { - while (((c = *s) != '\0') && (c == ' ' || c == '\t' || c == '\n')) - { - s++; - } - - if (c == '\0') - { - break; - } - - tname = cstring_fromChars (s); - - while ((c = *s) != '\0' && c != ' ' - && c != '\t' && c != '\n' && c != ',') - { - s++; - } - - *s = '\0'; - - DPRINTF (("Access %s", tname)); - - if (!context_getFlag (FLG_NOCOMMENTS) - && !context_getFlag (FLG_NOACCESS)) - { - if (usymtab_existsType (tname)) - { - typeId uid = usymtab_getTypeId (tname); - uentry ue = usymtab_getTypeEntry (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), - loc); - } - } - else - { - if (!(context_inSuppressRegion () - || context_inSuppressZone (loc))) - { - voptgenerror - (FLG_COMMENTERROR, - message - ("Unrecognized type %s used in access comment", - tname), - loc); - } - } - } - - if (c != '\0') - { - s++; - } - - if (c != ',' && c != ' ') - { - break; - } - } - } - else if (mstring_equal (t, "noaccess")) - { - cstring tname; - char lc; - - while (TRUE) - { - while (((lc = *s) != '\0') && (lc == ' ' || lc == '\t' || lc == '\n')) - { - s++; - } - - if (lc == '\0') - { - break; - } - - tname = cstring_fromChars (s); - - while ((lc = *s) != '\0' && lc != ' ' && lc != '\t' - && lc != '\n' && lc != ',') - { - s++; - } - - *s = '\0'; - - if (!context_getFlag (FLG_NOCOMMENTS) - && !context_getFlag (FLG_NOACCESS)) - { - if (usymtab_existsType (tname)) - { - typeId tuid = usymtab_getTypeId (tname); - - if (context_couldHaveAccess (tuid)) - { - DPRINTF (("Removing access: %s", tname)); - context_removeFileAccessType (tuid); - } - else - { - if (!(context_inSuppressRegion () - || context_inSuppressZone (loc))) - { - uentry ue = usymtab_getTypeEntry (tuid); - - if (uentry_isAbstractDatatype (ue)) - { - voptgenerror - (FLG_COMMENTERROR, - message - ("Non-accessible abstract type %s used in noaccess comment", - tname), - loc); - } - else - { - voptgenerror - (FLG_COMMENTERROR, - message - ("Non-abstract type %s used in noaccess comment", - tname), - loc); - } - } - } - } - else - { - if (!(context_inSuppressRegion () - || context_inSuppressZone (loc))) - { - voptgenerror - (FLG_COMMENTERROR, - message - ("Unrecognized type %s used in noaccess comment", - tname), - loc); - } - } - } - - if (lc != '\0') - { - s++; - } - - if (lc != ',' && lc != ' ') - { - break; - } - } - } - else - { - voptgenerror (FLG_UNRECOGCOMMENTS, - message ("Semantic comment unrecognized: %s", - cstring_fromChars (os)), - loc); - } - - sfree (t); - } - - sfree (os); - fileloc_free (loc); - return BADTOK; -} - -static /*@only@*/ cstring makeIdentifier (char *s) -{ - char *c = mstring_create (strlen (s) + 1); - cstring id = cstring_fromChars (c); - - while (isalnum (*s) || (*s == '_') || (*s == '$')) - { - *c++ = *s++; - } - - *c = '\0'; - return (id); -} - -/*@observer@*/ /*@dependent@*/ uentry coerceId (cstring cn) -{ - if (!(usymtab_exists (cn))) - { - fileloc loc = fileloc_createExternal (); - - /* - ** We need to put this in a global scope, otherwise the sRef will be deallocated. - */ - - uentry ce = uentry_makeUnrecognized (cn, loc); - - if (!context_inIterEnd ()) - { - voptgenerror - (FLG_SYSTEMUNRECOG, - message ("Unrecognized (possibly system) identifier: %q", - uentry_getName (ce)), - g_currentloc); - } - - return ce; - } - - return (usymtab_lookup (cn)); -} - -/* -** like, coerceId, but doesn't supercede for iters -*/ - -/*@observer@*/ uentry coerceIterId (cstring cn) -{ - if (!(usymtab_exists (cn))) - { - return uentry_undefined; - } - - return (usymtab_lookup (cn)); -} - -/* -** Need to keep this in case there is a declaration that isn't processed until -** the scope exits. Would be good to rearrange the symbol table so this doesn't -** happen, and save all the cstring copying. -*/ - -/*@observer@*/ cstring cscanner_observeLastIdentifier () -{ - cstring res = s_lastidprocessed; - return res; -} - -static void cscanner_setLastIdentifier (/*@keep@*/ cstring id) /*@modifies s_lastidprocessed@*/ -{ - if (cstring_isDefined (s_lastidprocessed)) - { - cstring_free (s_lastidprocessed); - } - - s_lastidprocessed = id; -} - -static int processIdentifier (cstring id) -{ - uentry le; - - if (context_getFlag (FLG_GRAMMAR)) - { - lldiagmsg (message ("Process identifier: %s", id)); - } - - context_clearJustPopped (); - cscanner_setLastIdentifier (id); - - DPRINTF (("Context: %s", context_unparse ())); - - if (context_inFunctionHeader ()) - { - int tok = commentMarkerToken (id); - DPRINTF (("in function decl: %s", id)); - - if (tok != BADTOK) - { - return tok; - } - else - { - tok = tokenMacroCode (id); - - 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)); - } - } - } - } - - DPRINTF (("Here!")); - - /* Consider handling: Defined by C99 as static const char __func__[] */ - - if (context_getFlag (FLG_GNUEXTENSIONS)) - { - int tok = BADTOK; - - if (cstring_equalLit (id, "__stdcall") - || cstring_equalLit (id, "__cdecl") - || cstring_equalLit (id, "__extension__")) - { - return BADTOK; - } - else if (cstring_equalLit (id, "__volatile__")) - { - tok = QVOLATILE; - } - else if (cstring_equalLit (id, "__signed")) - { - tok = QSIGNED; - } - else if (cstring_equalLit (id, "__unsigned")) - { - tok = QUNSIGNED; - } - else if (cstring_equalLit (id, "__const__")) - { - tok = QCONST; - } - else if (cstring_equalLit (id, "__alignof__")) - { - tok = CALIGNOF; /* alignof is parsed like sizeof */ - } - else if (cstring_equalLit (id, "__typeof__")) - { - tok = CTYPEOF; - } - else if (cstring_equalLit (id, "typeof")) - { - tok = CTYPEOF; - } - else if (cstring_equalLit (id, "__FUNCTION__") - || cstring_equalLit (id, "__PRETTY_FUNCTION__")) - { - /* These tokens hold the name of the current function as strings */ - /* evans 2001-12-30: changed from exprNode_stringLiteral; bug reported by Jim Zelenka. */ - yylval.expr = exprNode_makeConstantString (id, fileloc_copy (g_currentloc)); - tokLength = 0; - lastWasString = TRUE; - tok = CCONSTANT; - return tok; - } - else if (cstring_equalLit (id, "__attribute__") - || cstring_equalLit (id, "__asm__") - || cstring_equalLit (id, "_asm") - || cstring_equalLit (id, "__asm") - || cstring_equalLit (id, "__declspec")) - { - int depth = 0; - bool useparens = FALSE; - bool usebraces = FALSE; - bool inquote = FALSE; - bool inescape = FALSE; - int ic; - - while ((ic = input ()) != EOF) - { - char cc = (char) ic; - - if (inescape) - { - inescape = FALSE; - } - else if (cc == '\\') - { - inescape = TRUE; - } - else if (cc == '\"') - { - inquote = !inquote; - } - else if (!inquote) - { - if (cc == '(') - { - if (!useparens) - { - if (!usebraces) - { - useparens = TRUE; - } - } - - if (useparens) - { - depth++; - } - } - else if (cc == '{') - { - if (!usebraces) - { - if (!useparens) - { - usebraces = TRUE; - } - } - - if (usebraces) - { - depth++; - } - } - else if (cc == ')' && useparens) - { - depth--; - if (depth == 0) break; - } - else if (cc == '}' && usebraces) - { - depth--; - if (depth == 0) break; - } - else if (cc == '}' - && !usebraces && !useparens - && cstring_equalLit (id, "__asm")) - { - /* - ** We need this because some MS VC++ include files - ** have __asm mov ... } - ** Its a kludge, but otherwise would need to parse - ** the asm code! - */ - return TRBRACE; - } - else - { - ; - } - } - else - { - ; - } - - if (cc == '\n') - { - context_incLineno (); - - if (cstring_equalLit (id, "__asm") - && !useparens && !usebraces) - { - break; - } - } - } - - llassert ((useparens && ic == (int) ')') - || (usebraces && ic == (int) '}') - || (!useparens && !usebraces)); - - return BADTOK; - } - else if (cstring_equalLit (id, "inline") - || cstring_equalLit (id, "__inline") - || cstring_equalLit (id, "_inline") - || cstring_equalLit (id, "__inline__")) - { - tok = QINLINE; - } - else - { - ; - } - - if (tok != BADTOK) - { - RETURN_TOK (tok); - } - } - - le = usymtab_lookupSafe (id); - - /*@-dependenttrans@*/ - - if (uentry_isIter (le)) - { - /*@i32@*/ yylval.entry = le; - return (ITER_NAME); - } - else if (uentry_isEndIter (le)) - { - /*@i32@*/ yylval.entry = le; - return (ITER_ENDNAME); - } - else if (uentry_isUndefined (le)) - { - yylval.cname = cstring_copy (id); - - /* avoid parse errors for certain system built ins */ - - if (g_expectingTypeName && (cstring_firstChar (id) == '_') - && (cstring_secondChar (id) == '_')) - { - return (TYPE_NAME_OR_ID); - } - - return (NEW_IDENTIFIER); - } - else if (!uentry_isDeclared (le) && !uentry_isCodeDefined (le)) - { - if (uentry_isDatatype (le)) - { - yylval.cname = cstring_copy (id); - return (NEW_IDENTIFIER); - } - else - { - /*@i32@*/ yylval.entry = le; - return (IDENTIFIER); - } - } - else if (uentry_isDatatype (le)) - { - if (!g_expectingTypeName) - { - yylval.cname = cstring_copy (id); - - return (NEW_IDENTIFIER); - } - else - { - yylval.ctyp = uentry_getAbstractType (le); - - uentry_setUsed (le, g_currentloc); - return (TYPE_NAME); - } - } - else - { - /*@i32@*/ yylval.entry = le; - return (IDENTIFIER); - } - - /*@=dependenttrans@*/ -} - -static bool processHashIdentifier (/*@only@*/ cstring id) -{ - if (context_inMacro () || context_inIterDef () || - context_inIterEnd ()) - { - uentry le; - - context_clearJustPopped (); - - le = usymtab_lookupSafe (id); - cscanner_setLastIdentifier (id); - - if (uentry_isParam (le) || uentry_isRefParam (le)) - { - return TRUE; - } - else - { - return FALSE; - } - } - else - { - /* - ** Will be handled by handleLlSpecial - */ - - cstring_free (id); - return FALSE; - } -} - - -static /*@only@*/ exprNode processString (void) -{ - exprNode res; - fileloc loc; - char *nl = strchr (yytext, '\n'); - cstring ns = cstring_fromCharsNew (yytext); - - if (nl == NULL) - { - loc = fileloc_copy (g_currentloc); - addColumn (size_toInt (cstring_length (ns))); - } - else - { - char *lastnl = nl; - - loc = fileloc_copy (g_currentloc); - - context_incLineno (); - - while ((nl = strchr ((nl + 1), '\n')) != NULL) - { - context_incLineno (); - lastnl = nl; - } - } - - - res = exprNode_stringLiteral (ns, loc); - return (res); -} - -/* -** process a wide character string L"...." -*/ - -static /*@only@*/ exprNode processWideString () -{ - exprNode res; - fileloc loc; - char *nl = strchr (yytext, '\n'); - cstring ns; - - llassert (*yytext == 'L'); - yytext++; - - ns = cstring_fromCharsNew (yytext); - - if (nl == NULL) - { - loc = fileloc_copy (g_currentloc); - addColumn (size_toInt (cstring_length (ns))); - } - else - { - char *lastnl = nl; - - loc = fileloc_copy (g_currentloc); - - context_incLineno (); - - while ((nl = strchr ((nl + 1), '\n')) != NULL) - { - context_incLineno (); - lastnl = nl; - } - } - - res = exprNode_wideStringLiteral (ns, loc); - return (res); -} - -static -char processChar () -{ - char fchar; - char next; - - llassert (*yytext != '\0'); - fchar = *(yytext + 1); - if (fchar != '\\') return fchar; - - next = *(yytext + 2); - - switch (next) - { - case 'n': return '\n'; - case 't': return '\t'; - case '\"': return '\"'; - case '\'': return '\''; - case '\\': return '\\'; - default: return '\0'; - } -} - -static -double processFloat () -{ - double ret = atof (yytext); - - return (ret); -} - -static -long processHex () -{ - int index = 2; - long val = 0; - - llassert (yytext[0] == '0' - && (yytext[1] == 'X' || yytext[1] == 'x')); - - while (yytext[index] != '\0') { - int tval; - char c = yytext[index]; - - if (c >= '0' && c <= '9') { - tval = (int) c - (int) '0'; - } else if (c >= 'A' && c <= 'F') { - 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, - message ("Invalid character (%c) in hex constant: %s", - c, cstring_fromChars (yytext)), - g_currentloc); - break; - } - - val = (val * 16) + tval; - index++; - } - - DPRINTF (("Hex constant: %s = %ld", yytext, val)); - return val; -} - -static -long processOctal () -{ - int index = 1; - long val = 0; - - llassert (yytext[0] == '0' && yytext[1] != 'X' && yytext[1] != 'x'); - - while (yytext[index] != '\0') { - int tval; - char c = yytext[index]; - - if (c >= '0' && c <= '7') { - tval = (int) c - (int) '0'; - } 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 octal constant: %s", - c, cstring_fromChars (yytext)), - g_currentloc); - } - index++; - } - - break; - } else { - voptgenerror - (FLG_SYNTAX, - message ("Invalid character (%c) in octal constant: %s", - c, cstring_fromChars (yytext)), - g_currentloc); - break; - } - - val = (val * 8) + tval; - index++; - } - - DPRINTF (("Octal constant: %s = %ld", yytext, val)); - return val; -} - -static -long processDec () -{ - return (atol (yytext)); -} - -static int -processSpec (int tok) -{ - size_t length = strlen (yytext); - - if (s_inSpecPart) - { - - /*drl 12/11/2002 - patched to fix assert failures in constraint code. - Added the else if test so that splint does not treat MaxSet and MaxRead - as identifies*/ - - if (s_whichSpecPart == QMODIFIES - || s_whichSpecPart == QDEFINES - || s_whichSpecPart == QUSES - || s_whichSpecPart == QALLOCATES - || s_whichSpecPart == QSETS - || s_whichSpecPart == QRELEASES) - - { - DPRINTF((message("Treating specifaction keyword %s as an identifiers. (This corresponds to" - " token %d and we're in the specification denoted by %d see cgrammar_tokens.h" - " for an explanation of these numbers", - yytext, tok, s_whichSpecPart) - )); - - ; /* Allow specificiation keywords to be used as identifiers in these contexts. */ - } - else if ( (s_whichSpecPart == QPRECLAUSE - || s_whichSpecPart == QPOSTCLAUSE - || s_whichSpecPart == QINVARIANT ) - && (!isConstraintToken(tok) ) - ) - { - DPRINTF((message("Treating specifaction keyword %s as an identifiers. (This corresponds to" - " token %d and we're in the specification denoted by %d see cgrammar_tokens.h" - " for an explanation of these numbers", - yytext, tok, s_whichSpecPart) - )); - - /* Allow specificiation keywords to be used as identifiers in these contexts. */ - } - else - { - setTokLengthT (length); - RETURN_TOK (tok); - } - } - - context_saveLocation (); - setTokLengthT (length); - return (processIdentifier (makeIdentifier (yytext))); -} - -void cscanner_expectingMetaStateName () -{ - llassert (!expectingMetaStateName); - llassert (context_inFunctionHeader ()); - expectingMetaStateName = TRUE; -} - -void cscanner_clearExpectingMetaStateName () -{ - llassert (expectingMetaStateName); - expectingMetaStateName = FALSE; -} - -/*drl added 12/11/2002 - Tell whether a token has special meaning - within a function constraint -*/ - -/*uncomment the additional if statement tests - when minSet and minRead are supported -*/ -int isConstraintToken(int tok) -{ - if ( tok == QMAXSET - || tok == QMAXREAD - - /* || tok == QMINREAD - || tok == QMINSET */ - - ) - { - return TRUE; - } - else - { - return FALSE; - } -} diff --git a/src/cscannerHelp.c b/src/cscannerHelp.c new file mode 100644 index 0000000..b4887f4 --- /dev/null +++ b/src/cscannerHelp.c @@ -0,0 +1,2832 @@ +/* +** Splint - annotation-assisted static program checker +** Copyright (C) 1994-2002 University of Virginia, +** Massachusetts Institute of Technology +** +** This program is free software; you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by the +** Free Software Foundation; either version 2 of the License, or (at your +** option) any later version. +** +** This program is distributed in the hope that it will be useful, but +** WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** The GNU General Public License is available from http://www.gnu.org/ or +** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +** MA 02111-1307, USA. +** +** For information on splint: info@splint.org +** To report a bug: splint-bug@splint.org +** For more information: http://www.splint.org +*/ +/* +** cscannerHelp.c - procedures for scanning C +** +** Most of this code was in cscanner.l, but moved here to separate it +** from the flex-generated code. +*/ + +# include "splintMacros.nf" +# include "basic.h" +# include "cscannerHelp.h" +# include "cscanner.h" +# include "cgrammar_tokens.h" + +static int lminput (void); +static int s_tokLength = 0; + +static /*@owned@*/ cstring s_lastidprocessed = cstring_undefined; +static bool s_inSpecPart = FALSE; +static int s_whichSpecPart; +static char s_savechar = '\0'; +static bool s_expectingMetaStateName = FALSE; +static bool s_lastWasString = FALSE; +static bool s_expectingTypeName = TRUE; + +struct skeyword +{ + /*@null@*/ /*@observer@*/ char *name; + int token; +} ; + +/* +** These tokens are followed by syntax that is parsed by the +** grammar proper. +*/ + +static struct skeyword s_parsetable[] = { + { "modifies", QMODIFIES } , + { "globals", QGLOBALS } , + { "alt", QALT } , + { "warn", QWARN } , + { "constant", QCONSTANT } , + { "function", QFUNCTION } , + { "iter", QITER } , + { "defines", QDEFINES } , + { "uses", QUSES } , + { "allocates", QALLOCATES } , + { "sets", QSETS } , + { "releases", QRELEASES } , + { "pre", QPRECLAUSE } , + { "post", QPOSTCLAUSE } , + { "setBufferSize", QSETBUFFERSIZE}, + { "setStringLength", QSETSTRINGLENGTH}, + { "testinRange", QTESTINRANGE}, + { "requires", QPRECLAUSE } , + { "ensures", QPOSTCLAUSE } , + { "invariant", QINVARIANT} , + { NULL, BADTOK } +} ; + +/* +** These tokens are either stand-alone tokens, or followed by +** token-specific text. +*/ + +static struct skeyword s_keytable[] = { + { "anytype", QANYTYPE } , + { "integraltype", QINTEGRALTYPE } , + { "unsignedintegraltype", QUNSIGNEDINTEGRALTYPE } , + { "signedintegraltype", QSIGNEDINTEGRALTYPE } , + { "out", QOUT } , + { "in", QIN } , + { "only", QONLY } , + { "owned", QOWNED } , + { "dependent", QDEPENDENT } , + { "partial", QPARTIAL } , + { "special", QSPECIAL } , + { "truenull", QTRUENULL } , + { "falsenull", QFALSENULL } , + { "nullwhentrue", QTRUENULL } , + { "falsewhennull", QFALSENULL } , + { "keep", QKEEP } , + { "kept", QKEPT } , + { "notnull", QNOTNULL } , + { "abstract", QABSTRACT } , + { "numabstract", QNUMABSTRACT } , + { "concrete", QCONCRETE } , + { "mutable", QMUTABLE } , + { "immutable", QIMMUTABLE } , + { "unused", QUNUSED } , + { "external", QEXTERNAL } , + { "sef", QSEF } , + { "unique", QUNIQUE } , + { "returned", QRETURNED } , + { "exposed", QEXPOSED } , + { "refcounted", QREFCOUNTED } , + { "refs", QREFS } , + { "newref", QNEWREF } , + { "tempref", QTEMPREF } , + { "killref", QKILLREF } , + { "null", QNULL } , + { "relnull", QRELNULL } , + { "nullterminated", QNULLTERMINATED }, + { "setBufferSize", QSETBUFFERSIZE }, + { "testInRange", QTESTINRANGE}, + { "isnull", QISNULL }, + { "MaxSet", QMAXSET}, + { "MaxRead", QMAXREAD}, + { "maxSet", QMAXSET}, + { "maxRead", QMAXREAD}, + { "reldef", QRELDEF } , + { "observer", QOBSERVER } , + { "exits", QEXITS } , + { "noreturn", QEXITS } , + { "mayexit", QMAYEXIT } , + { "maynotreturn", QMAYEXIT } , + { "trueexit", QTRUEEXIT } , + { "falseexit", QFALSEEXIT } , + { "noreturnwhentrue", QTRUEEXIT } , + { "noreturnwhenfalse", QFALSEEXIT } , + { "neverexit", QNEVEREXIT } , + { "alwaysreturns", QNEVEREXIT } , + { "temp", QTEMP } , + { "shared", QSHARED } , + { "ref", QREF } , + { "unchecked", QUNCHECKED } , + { "checked", QCHECKED } , + { "checkmod", QCHECKMOD } , + { "checkedstrict", QCHECKEDSTRICT } , + { "innercontinue", QINNERCONTINUE } , + { "innerbreak", QINNERBREAK } , + { "loopbreak", QLOOPBREAK } , + { "switchbreak", QSWITCHBREAK } , + { "safebreak", QSAFEBREAK } , + { "fallthrough", QFALLTHROUGH } , + { "l_fallthrou", QLINTFALLTHROUGH } , + { "l_fallth", QLINTFALLTHRU } , + { "notreached", QNOTREACHED } , + { "l_notreach", QLINTNOTREACHED } , + { "printflike", QPRINTFLIKE } , + { "l_printfli", QLINTPRINTFLIKE } , + { "scanflike", QSCANFLIKE } , + { "messagelike", QMESSAGELIKE } , + { "l_argsus", QARGSUSED } , + { NULL, BADTOK } +} ; + +/* +** would be better if these weren't hard coded... +*/ + +static bool isArtificial (cstring s) +{ + return (cstring_equalLit (s, "modifies") + || cstring_equalLit (s, "globals") + || cstring_equalLit (s, "warn") + || cstring_equalLit (s, "alt")); +} + +void cscannerHelp_swallowMacro (void) +{ + int i; + bool skipnext = FALSE; + + while ((i = lminput ()) != EOF) + { + char c = (char) i; + + if (c == '\\') + { + skipnext = TRUE; + } + else if (c == '\n') + { + if (skipnext) + { + skipnext = FALSE; + } + else + { + reader_checkUngetc (i, yyin); + return; + } + } + else + { + ; + } + } + + if (i != EOF) + { + reader_checkUngetc (i, yyin); + } +} + +static int commentMarkerToken (cstring s) +{ + int i = 0; + + 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; + } + + i++; + } + + return BADTOK; +} + +static int tokenMacroCode (cstring s) +{ + int i = 0; + + while (s_keytable[i].name != NULL) + { + if (cstring_equalLit (s, s_keytable[i].name)) + { + if (s_keytable[i].token == QLINTFALLTHROUGH) + { + voptgenerror + (FLG_WARNLINTCOMMENTS, + cstring_makeLiteral + ("Traditional lint comment /*FALLTHROUGH*/ used. " + "Splint interprets this in the same way as most Unix lints, but it is " + "preferable to replace it with the /*@fallthrough@*/ " + "semantic comment"), + g_currentloc); + return QFALLTHROUGH; + } + else if (s_keytable[i].token == QLINTFALLTHRU) + { + voptgenerror + (FLG_WARNLINTCOMMENTS, + cstring_makeLiteral + ("Traditional lint comment /*FALLTHRU*/ used. " + "Splint interprets this in the same way as most Unix lints, but it is " + "preferable to replace it with the /*@fallthrough@*/ " + "semantic comment"), + g_currentloc); + return QFALLTHROUGH; + } + else if (s_keytable[i].token == QLINTNOTREACHED) + { + voptgenerror + (FLG_WARNLINTCOMMENTS, + cstring_makeLiteral + ("Traditional lint comment /*NOTREACHED*/ used. " + "Splint interprets this in the same way as most Unix lints, but it is " + "preferable to replace it with the /*@notreached@*/ " + "semantic comment."), + g_currentloc); + + return QNOTREACHED; + } + else if (s_keytable[i].token == QPRINTFLIKE) + { + setSpecialFunction (qual_createPrintfLike ()); + return SKIPTOK; + } + else if (s_keytable[i].token == QLINTPRINTFLIKE) + { + voptgenerror + (FLG_WARNLINTCOMMENTS, + cstring_makeLiteral + ("Traditional lint comment /*PRINTFLIKE*/ used. " + "Splint interprets this in the same way as most Unix lints, but it is " + "preferable to replace it with either /*@printflike@*/, " + "/*@scanflike@*/ or /*@messagelike@*/."), + g_currentloc); + + setSpecialFunction (qual_createPrintfLike ()); + return SKIPTOK; + } + else if (s_keytable[i].token == QSCANFLIKE) + { + setSpecialFunction (qual_createScanfLike ()); + return SKIPTOK; + } + else if (s_keytable[i].token == QMESSAGELIKE) + { + setSpecialFunction (qual_createMessageLike ()); + return SKIPTOK; + } + else if (s_keytable[i].token == QARGSUSED) + { + voptgenerror + (FLG_WARNLINTCOMMENTS, + cstring_makeLiteral + ("Traditional lint comment /*ARGSUSED*/ used. " + "Splint interprets this in the same way as most Unix lints, but it is " + "preferable to use /*@unused@*/ annotations on " + "the unused parameters."), + g_currentloc); + + setArgsUsed (); + return SKIPTOK; + } + else + { + return s_keytable[i].token; + } + } + + i++; + } + + return BADTOK; +} + +static int lminput () +{ + if (s_savechar == '\0') + { + incColumn (); + return (cscanner_input ()); + } + else + { + int save = (int) s_savechar; + s_savechar = '\0'; + return save; + } +} + +static void lmsavechar (char c) +{ + if (s_savechar == '\0') + { + s_savechar = c; + } + else + { + llbuglit ("lmsavechar: override"); + } +} + +int cscannerHelp_ninput () +{ + int c = lminput (); + + if (c != EOF && ((char)c == '\n')) + { + context_incLineno (); + } + + return c; +} + +static char macro_nextChar (void) +{ + static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE; + int ic; + char c; + + ic = lminput (); + c = char_fromInt (ic); + + if (!in_quote && !in_char && (c == '\\' || c == BEFORE_COMMENT_MARKER[0])) + { + if (c == '\\') + { + while ((c = char_fromInt (lminput ())) != '\0' && c != '\n') + { + ; /* skip to newline */ + } + + context_incLineno (); + + if (c != '\0') + { + return macro_nextChar (); + } + else + { + return c; + } + } + else /* if (c == '@') */ + { + llassert (FALSE); /*@i23@*/ + if (cscannerHelp_handleLlSpecial () != BADTOK) + { + llerrorlit (FLG_SYNTAX, "Macro cannot use special syntax"); + } + + return macro_nextChar (); + } + } + else if (!in_escape && c == '\"') + { + in_quote = !in_quote; + } + else if (!in_escape && c == '\'') + { + in_char = !in_char; + } + else if ((in_quote || in_char) && c == '\\') + { + in_escape = !in_escape; + } + else if ((in_quote || in_char) && in_escape) + { + in_escape = FALSE; + } + else if (!in_quote && c == '/') + { + char c2; + + if ((c2 = char_fromInt (lminput ())) == '*') + { + while (c2 != '\0') + { + while ((c2 = char_fromInt (lminput ())) != '\0' + && c2 != '\n' && c2 != '*') + { + ; + } + + if (c2 == '*') + { + while ((c2 = char_fromInt (lminput ())) != '\0' + && c2 == '*') + { + ; + } + + if (c2 == '/') + { + goto outofcomment; + } + } + else + { + llfatalerror (cstring_makeLiteral ("Macro: bad comment!")); + } + } + outofcomment: + return macro_nextChar (); + } + else + { + /*** putchar does not work! why? puts to stdio...??! ***/ + lmsavechar (c2); + } + } + else + { + ; + } + + return c; +} + +/* +** keeps semantic comments +*/ + +static char macro_nextCharC (void) +{ + static bool in_quote = FALSE, in_escape = FALSE, in_char = FALSE; + char c; + + c = char_fromInt (lminput ()); + + if (!in_quote && !in_char && c == '\\') + { + while ((c = char_fromInt (lminput ())) != '\0' && c != '\n') + { + ; /* skip to newline */ + } + + context_incLineno (); + + if (c != '\0') + { + return macro_nextCharC (); + } + else + { + return c; + } + } + else if (!in_escape && c == '\"') + { + in_quote = !in_quote; + } + else if (!in_escape && c == '\'') + { + in_char = !in_char; + } + else if ((in_quote || in_char) && c == '\\') + { + in_escape = !in_escape; + } + else if ((in_quote || in_char) && in_escape) + { + in_escape = FALSE; + } + else if (!in_quote && c == '/') + { + char c2; + + if ((c2 = char_fromInt (lminput ())) == '*') + { + while (c2 != '\0') + { + while ((c2 = char_fromInt (lminput ())) != '\0' + && c2 != '\n' && c2 != '*') + { + ; + } + + if (c2 == '*') + { + while ((c2 = char_fromInt (lminput ())) != '\0' + && c2 == '*') + { + ; + } + + if (c2 == '/') + { + goto outofcomment; + } + } + else + { + llfatalerror (cstring_makeLiteral ("Macro: bad comment!")); + } + } + outofcomment: + return macro_nextCharC (); + } + else + { + lmsavechar (c2); + } + } + else /* normal character */ + { + ; + } + + return c; +} + +/* +** skips whitespace (handles line continuations) +** returns first non-whitespace character +*/ + +static char skip_whitespace (void) +{ + char c; + + while ((c = macro_nextChar ()) == ' ' || c == '\t') + { + ; + } + + return c; +} + +void cscannerHelp_handleMacro () +{ + cstring mac = cstring_undefined; + int macrocode; + char c; + + while (currentColumn () > 2) + { + mac = cstring_appendChar (mac, ' '); + cscannerHelp_setTokLength (-1); + } + + c = macro_nextCharC (); + + if (c >= '0' && c <= '9') + { + int i; + + for (i = 0; i < (((int) (c - '0')) + 1); i++) + { + mac = cstring_appendChar (mac, ' '); + } + } + else + { + BADBRANCH; + } + + while (((c = macro_nextCharC ()) != '\0') && (c != '\n')) + { + mac = cstring_appendChar (mac, c); + } + + + macrocode = tokenMacroCode (mac); + + if (macrocode == BADTOK && !isArtificial (mac)) + { + context_addMacroCache (mac); + } + else + { + cstring_free (mac); + } + + if (c == '\n') + { + context_incLineno (); + } +} + +bool cscannerHelp_handleSpecial (char *yyt) +{ + char *l; /* !! = mstring_create (MAX_NAME_LENGTH); */ + int lineno = 0; + char c; + char *ol; + cstring olc; + size_t len_yyt; + + len_yyt = strlen (yyt +1) ; + + l = mstring_copy (yyt + 1); + + while ((c = char_fromInt (lminput ())) != '\n' && c != '\0') + { + l = mstring_append(l, c); + } + + /* Need to safe original l for deallocating. */ + ol = l; + + l += strlen (l); + + olc = cstring_fromChars (ol); + + if (cstring_equalPrefixLit (olc, "pragma")) + { + char *pname = mstring_create (size_fromInt (MAX_PRAGMA_LEN)); + char *opname = pname; + char *ptr = ol + 6; /* pragma is six characters, plus space */ + int len = 0; + + + /* skip whitespace */ + while (((c = *ptr) != '\0') && isspace (c)) + { + ptr++; + } + + + while (((c = *ptr) != '\0') && !isspace (c)) + { + len++; + + if (len > MAX_PRAGMA_LEN) + { + break; + } + + ptr++; + *pname++ = c; + } + + *pname = '\0'; + + if (len == PRAGMA_LEN_EXPAND + && mstring_equal (opname, PRAGMA_EXPAND)) + { + cstring exname = cstring_undefined; + uentry ue; + + ptr++; + while (((c = *ptr) != '\0') && !isspace (c)) + { + exname = cstring_appendChar (exname, c); + ptr++; + } + + + ue = usymtab_lookupExposeGlob (exname); + + if (uentry_isExpandedMacro (ue)) + { + if (fileloc_isPreproc (uentry_whereDefined (ue))) + { + fileloc_setColumn (g_currentloc, 1); + uentry_setDefined (ue, g_currentloc); + } + } + + cstring_free (exname); + } + } + else if (cstring_equalPrefixLit (olc, "ident")) + { + /* Some pre-processors will leave these in the code. Ignore rest of line */ + } + /* + ** Yuk...Win32 filenames can have spaces in them...we need to read + ** to the matching end quote. + */ + else if ((sscanf (ol, "line %d \"", &lineno) == 1) + || (sscanf (ol, " %d \"", &lineno) == 1)) + { + char *tmp = ol; + cstring fname; + fileId fid; + + /*@access cstring@*/ + while (*tmp != '\"' && *tmp != '\0') + { + tmp++; + } + + llassert (*tmp == '\"'); + + tmp++; + + fname = tmp; + + while (*tmp != '\"' && *tmp != '\0') + { + tmp++; + } + + llassert (*tmp == '\"'); + + *tmp = '\0'; + +# if defined(OS2) || defined(MSDOS) || defined(WIN32) + + /* + ** DOS-like path delimiters get delivered in pairs, something like + ** \"..\\\\file.h\", so we have to make it normal again. We do NOT + ** remove the pre dirs yet as we usually specify tmp paths relative + ** to the current directory, so tmp files would not get found in + ** the hash table. If this method fails we try it again later. + */ + + { + char *stmp = fname; + + /* + ** Skip past the drive marker. + */ + + if (strchr (stmp, ':') != NULL) + { + stmp = strchr (stmp, ':') + 1; + } + + while ((stmp = strchr (stmp, CONNECTCHAR)) != NULL ) + { + if (*(stmp+1) == CONNECTCHAR) + { + memmove (stmp, stmp+1, strlen (stmp)); + } + + stmp++; + } + + fid = fileTable_lookupBase (context_fileTable (), fname); + if (!(fileId_isValid (fid))) + { + fname = removePreDirs (fname); + fid = fileTable_lookupBase (context_fileTable (), fname); + } + } +# else /* !defined(OS2) && !defined(MSDOS) */ + fname = removePreDirs (fname); + fid = fileTable_lookupBase (context_fileTable (), fname); +# endif /* !defined(OS2) && !defined(MSDOS) */ + + if (!(fileId_isValid (fid))) + { + if (context_inXHFile ()) + { + fid = fileTable_addXHFile (context_fileTable (), fname); + } + else if (isHeaderFile (fname)) + { + fid = fileTable_addHeaderFile (context_fileTable (), fname); + } + else + { + fid = fileTable_addFile (context_fileTable (), fname); + } + } + + setFileLine (fid, lineno); + /*@noaccess cstring@*/ + } + else if ((sscanf (ol, "line %d", &lineno) == 1) + || (sscanf (ol, " %d", &lineno) == 1)) + { + setLine (lineno); /* next line is */ + } + else + { + if (mstring_equal (ol, "")) { + DPRINTF (("Empty pp command!")); + /* + ** evs 2000-05-16: This is a horrible kludge, to get around a bug (well, difficulty) in the pre-processor. + ** We handle a plain # in the input file, by echoing it, and ignoring it in the post-pp-file. + */ + mstring_free (ol); + return FALSE; + } else { + voptgenerror + (FLG_UNRECOGDIRECTIVE, + message ("Unrecognized pre-processor directive: #%s", + cstring_fromChars (ol)), + g_currentloc); + } + + sfree (ol); + return FALSE; /* evans 2001-12-30: was: TRUE; */ + } + + sfree (ol); + return FALSE; +} + +int cscannerHelp_handleLlSpecial (void) +{ + bool hasnl = FALSE; + int ic; + char c; + char *s = mstring_createEmpty (); + char *os; + int tok; + int charsread = 0; + fileloc loc; + + loc = fileloc_copy (g_currentloc); + DPRINTF (("Handle special: %s", fileloc_unparse (loc))); + + while (((ic = cscannerHelp_ninput ()) != 0) && isalpha (ic)) + { + c = (char) ic; + s = mstring_append (s, c); + charsread++; + } + + DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc))); + os = s; + + if (charsread == 0 && ic == (int) AFTER_COMMENT_MARKER[0]) + { + ic = cscannerHelp_ninput (); + + llassert (ic == (int) AFTER_COMMENT_MARKER[1]); + + if (*s == '\0') + { + sfree (os); + fileloc_free (loc); + return QNOMODS; /* special token no modifications token */ + } + } + + DPRINTF (("Coment marker: %s", os)); + tok = commentMarkerToken (cstring_fromChars (os)); + + if (tok != BADTOK) + { + s_tokLength = charsread; + sfree (os); + s_inSpecPart = TRUE; + s_whichSpecPart = tok; + 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++; + + while (((ic = cscannerHelp_ninput ()) != 0) && (ic != EOF) + && (ic != (int) AFTER_COMMENT_MARKER[0])) + { + c = (char) ic; + + /* evans 2001-09-01 added to prevent assertion failures for uncloses syntactic comments */ + + if (c == '\n') { + hasnl = TRUE; /* This prevents tokLength from being set later. */ + s_tokLength = 0; + + voptgenerror + (FLG_SYNTAX, + message ("Likely parse error: syntactic comment token spans multiple lines: %s", + cstring_fromChars (s)), + loc); + } + + s = mstring_append (s, c); + charsread++; + } + /*@i888@*/ } + + DPRINTF (("Read: %s / %s", s, fileloc_unparse (g_currentloc))); + + if (ic == (int) AFTER_COMMENT_MARKER[0]) + { + int nc = cscannerHelp_ninput (); + llassert ((char) nc == AFTER_COMMENT_MARKER[1]); + charsread++; + } + + os = s; + + while (*s == ' ' || *s == '\t' || *s == '\n') + { + s++; + } + + if (*s == '-' || *s == '+' || *s == '=') /* setting flags */ + { + c = *s; + + while (c == '-' || c == '+' || c == '=') + { + ynm set = ynm_fromCodeChar (c); + cstring thisflag; + + s++; + + thisflag = cstring_fromChars (s); + + while ((c = *s) != '\0' && (c != '-') && (c != '=') + && (c != '+') && (c != ' ') && (c != '\t') && (c != '\n')) + { + s++; + } + + *s = '\0'; + + if (!context_getFlag (FLG_NOCOMMENTS)) + { + cstring flagname = thisflag; + flagcode fflag = flags_identifyFlag (flagname); + + if (flagcode_isSkip (fflag)) + { + ; + } + else if (flagcode_isModeName (fflag)) + { + if (ynm_isMaybe (set)) + { + llerror + (FLG_BADFLAG, + message + ("Semantic comment attempts to restore flag %s. " + "A mode flag cannot be restored.", + flagname)); + } + else + { + context_setMode (flagname); + } + } + else if (flagcode_isInvalid (fflag)) + { + voptgenerror + (FLG_UNRECOGFLAGCOMMENTS, + message ("Unrecognized option in semantic comment: %s", + flagname), + loc); + } + else if (flagcode_isGlobalFlag (fflag)) + { + voptgenerror + (FLG_BADFLAG, + message + ("Semantic comment attempts to set global flag %s. " + "A global flag cannot be set locally.", + flagname), + loc); + } + else + { + context_fileSetFlag (fflag, set, loc); + + if (flagcode_hasArgument (fflag)) + { + if (ynm_isMaybe (set)) + { + voptgenerror + (FLG_BADFLAG, + message + ("Semantic comment attempts to restore flag %s. " + "A flag for setting a value cannot be restored.", + flagname), + loc); + } + else + { /* cut-and-pastied from llmain...blecch */ + cstring extra = cstring_undefined; + char *rest; + char *orest; + char rchar; + + *s = c; + rest = mstring_copy (s); + orest = rest; + *s = '\0'; + + while ((rchar = *rest) != '\0' + && (isspace (rchar))) + { + rest++; + s++; + } + + while ((rchar = *rest) != '\0' + && !isspace (rchar)) + { + extra = cstring_appendChar (extra, rchar); + rest++; + s++; + } + s--; /* evans 2002-07-12: this was previously only in the else branch. + Leads to an invalid read on the true branch. + */ + + sfree (orest); + + if (cstring_isUndefined (extra)) + { + llerror + (FLG_BADFLAG, + message + ("Flag %s (in semantic comment) must be followed by an argument", + flagcode_unparse (fflag))); + + cstring_free (extra); + } + else + { + if (flagcode_hasNumber (fflag)) + { + flags_setValueFlag (fflag, extra); + } + else if (flagcode_hasChar (fflag)) + { + flags_setValueFlag (fflag, extra); + } + else if (flagcode_hasString (fflag)) + { + flags_setStringFlag (fflag, extra); + } + else + { + cstring_free (extra); + BADEXIT; + } + } + } + } + } + } + else + { + ; + } + + *s = c; + while ((c == ' ') || (c == '\t') || (c == '\n')) + { + c = *(++s); + } + } + + if (context_inHeader () && !isArtificial (cstring_fromChars (os))) + { + DPRINTF (("Here adding comment: %s", os)); + context_addComment (cstring_fromCharsNew (os), loc); + } + else + { + ; + } + } + else + { + char *t = s; + int macrocode; + char tchar = '\0'; + annotationInfo ainfo; + + while (*s != '\0' && *s != ' ' && *s != '\t' && *s != '\n') + { + s++; + } + + if (*s != '\0') + { + tchar = *s; + *s = '\0'; + s++; + } + + t = cstring_toCharsSafe (cstring_downcase (cstring_fromChars (t))); + macrocode = tokenMacroCode (cstring_fromChars (t)); + + if (macrocode != BADTOK) + { + s_tokLength = hasnl ? 0 : size_toInt (mstring_length (t)); + + sfree (t); + sfree (os); + fileloc_free (loc); + + if (macrocode == SKIPTOK) + { + return BADTOK; + } + + return macrocode; + } + + ainfo = context_lookupAnnotation (cstring_fromChars (os)); + + if (annotationInfo_isDefined (ainfo)) { + DPRINTF (("Found annotation: %s", annotationInfo_unparse (ainfo))); + /*@i324@*/ yylval.annotation = ainfo; + s_tokLength = 0; + sfree (os); + sfree (t); + fileloc_free (loc); + return CANNOTATION; + } + + if (context_inHeader ()) + { + if (tchar != '\0') + { + *(s-1) = tchar; + } + + if ((context_inMacro () || context_inGlobalContext ()) + && macrocode != SKIPTOK + && !isArtificial (cstring_fromChars (os))) + { + if (context_processingMacros ()) + { + /* evans 2002-02-24: don't add comments when procssing macros */ + } + else + { + context_addComment (cstring_fromCharsNew (os), loc); + } + } + else + { + ; + } + + if (tchar != '\0') + { + *(s-1) = '\0'; + } + } + + if (mstring_equal (t, "ignore")) + { + if (!context_getFlag (FLG_NOCOMMENTS)) + { + context_enterSuppressRegion (loc); + } + } + else if ((*t == 'i' || *t == 't') + && (*(t + 1) == '\0')) + { + if (!context_getFlag (FLG_NOCOMMENTS) + && (*t == 'i' || context_getFlag (FLG_TMPCOMMENTS))) + { + context_enterSuppressLine (-1, loc); /* infinite suppression */ + } + } + else if (((*t == 'i') || (*t == 't')) + && ((*(t + 1) >= '0' && *(t + 1) <= '9'))) + { + bool tmpcomment = (*t == 't'); + int val = -1; + char *tt = t; /* don't mangle t, since it is free'd */ + char lc = *(++tt); + + if (lc >= '0' && lc <= '9') + { + val = (int)(lc - '0'); + + lc = *(++tt); + while (lc >= '0' && lc <= '9') + { + val *= 10; + val += (int) (lc - '0'); + lc = *(++tt); + } + } + + if (!context_getFlag (FLG_NOCOMMENTS) + && (!tmpcomment || context_getFlag (FLG_TMPCOMMENTS))) + { + DPRINTF (("Here: enter suppress: %s", fileloc_unparse (loc))); + context_enterSuppressLine (val, loc); + } + } + else if (mstring_equal (t, "end")) + { + if (!context_getFlag (FLG_NOCOMMENTS)) + { + context_exitSuppressRegion (loc); + } + } + else if (mstring_equal (t, "notfunction")) + { + ; /* handled by pcpp */ + } + else if (mstring_equal (t, "access")) + { + cstring tname; + + while (TRUE) + { + while (((c = *s) != '\0') && (c == ' ' || c == '\t' || c == '\n')) + { + s++; + } + + if (c == '\0') + { + break; + } + + tname = cstring_fromChars (s); + + while ((c = *s) != '\0' && c != ' ' + && c != '\t' && c != '\n' && c != ',') + { + s++; + } + + *s = '\0'; + + DPRINTF (("Access %s", tname)); + + if (!context_getFlag (FLG_NOCOMMENTS) + && !context_getFlag (FLG_NOACCESS)) + { + if (usymtab_existsType (tname)) + { + typeId uid = usymtab_getTypeId (tname); + uentry ue = usymtab_getTypeEntry (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), + loc); + } + } + else + { + if (!(context_inSuppressRegion () + || context_inSuppressZone (loc))) + { + voptgenerror + (FLG_COMMENTERROR, + message + ("Unrecognized type %s used in access comment", + tname), + loc); + } + } + } + + if (c != '\0') + { + s++; + } + + if (c != ',' && c != ' ') + { + break; + } + } + } + else if (mstring_equal (t, "noaccess")) + { + cstring tname; + char lc; + + while (TRUE) + { + while (((lc = *s) != '\0') && (lc == ' ' || lc == '\t' || lc == '\n')) + { + s++; + } + + if (lc == '\0') + { + break; + } + + tname = cstring_fromChars (s); + + while ((lc = *s) != '\0' && lc != ' ' && lc != '\t' + && lc != '\n' && lc != ',') + { + s++; + } + + *s = '\0'; + + if (!context_getFlag (FLG_NOCOMMENTS) + && !context_getFlag (FLG_NOACCESS)) + { + if (usymtab_existsType (tname)) + { + typeId tuid = usymtab_getTypeId (tname); + + if (context_couldHaveAccess (tuid)) + { + DPRINTF (("Removing access: %s", tname)); + context_removeFileAccessType (tuid); + } + else + { + if (!(context_inSuppressRegion () + || context_inSuppressZone (loc))) + { + uentry ue = usymtab_getTypeEntry (tuid); + + if (uentry_isAbstractDatatype (ue)) + { + voptgenerror + (FLG_COMMENTERROR, + message + ("Non-accessible abstract type %s used in noaccess comment", + tname), + loc); + } + else + { + voptgenerror + (FLG_COMMENTERROR, + message + ("Non-abstract type %s used in noaccess comment", + tname), + loc); + } + } + } + } + else + { + if (!(context_inSuppressRegion () + || context_inSuppressZone (loc))) + { + voptgenerror + (FLG_COMMENTERROR, + message + ("Unrecognized type %s used in noaccess comment", + tname), + loc); + } + } + } + + if (lc != '\0') + { + s++; + } + + if (lc != ',' && lc != ' ') + { + break; + } + } + } + else + { + voptgenerror (FLG_UNRECOGCOMMENTS, + message ("Semantic comment unrecognized: %s", + cstring_fromChars (os)), + loc); + /*@i888@*/ } + + sfree (t); + } + + sfree (os); + fileloc_free (loc); + return BADTOK; +} + +/*@only@*/ cstring cscannerHelp_makeIdentifier (char *s) +{ + char *c = mstring_create (strlen (s) + 1); + cstring id = cstring_fromChars (c); + + while (isalnum (*s) || (*s == '_') || (*s == '$')) + { + *c++ = *s++; + } + + *c = '\0'; + return (id); +} + +/*@observer@*/ /*@dependent@*/ uentry cscannerHelp_coerceId (cstring cn) +{ + if (!(usymtab_exists (cn))) + { + fileloc loc = fileloc_createExternal (); + + /* + ** We need to put this in a global scope, otherwise the sRef will be deallocated. + */ + + uentry ce = uentry_makeUnrecognized (cn, loc); + + if (!context_inIterEnd ()) + { + voptgenerror + (FLG_SYSTEMUNRECOG, + message ("Unrecognized (possibly system) identifier: %q", + uentry_getName (ce)), + g_currentloc); + } + + return ce; + } + + return (usymtab_lookup (cn)); +} + +/* +** like, cscannerHelp_coerceId, but doesn't supercede for iters +*/ + +/*@observer@*/ uentry cscannerHelp_coerceIterId (cstring cn) +{ + if (!(usymtab_exists (cn))) + { + return uentry_undefined; + } + + return (usymtab_lookup (cn)); +} + +/* +** Need to keep this in case there is a declaration that isn't processed until +** the scope exits. Would be good to rearrange the symbol table so this doesn't +** happen, and save all the cstring copying. +*/ + +/*@observer@*/ cstring cscannerHelp_observeLastIdentifier () +{ + cstring res = s_lastidprocessed; + return res; +} + +static void cscanner_setLastIdentifier (/*@keep@*/ cstring id) /*@modifies s_lastidprocessed@*/ +{ + if (cstring_isDefined (s_lastidprocessed)) + { + cstring_free (s_lastidprocessed); + } + + s_lastidprocessed = id; +} + +int cscannerHelp_processIdentifier (cstring id) +{ + uentry le; + + if (context_getFlag (FLG_GRAMMAR)) + { + lldiagmsg (message ("Process identifier: %s", id)); + } + + context_clearJustPopped (); + cscanner_setLastIdentifier (id); + + DPRINTF (("Context: %s", context_unparse ())); + + if (context_inFunctionHeader ()) + { + int tok = commentMarkerToken (id); + DPRINTF (("in function decl: %s", id)); + + if (tok != BADTOK) + { + return tok; + } + else + { + tok = tokenMacroCode (id); + + if (tok != BADTOK) + { + return tok; + } + else + { + annotationInfo ainfo; + + if (s_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)); + } + } + } + } + + DPRINTF (("Here!")); + + /* Consider handling: Defined by C99 as static const char __func__[] */ + + if (context_getFlag (FLG_GNUEXTENSIONS)) + { + int tok = BADTOK; + + if (cstring_equalLit (id, "__stdcall") + || cstring_equalLit (id, "__cdecl") + || cstring_equalLit (id, "__extension__")) + { + return BADTOK; + } + else if (cstring_equalLit (id, "__volatile__")) + { + tok = QVOLATILE; + } + else if (cstring_equalLit (id, "__signed")) + { + tok = QSIGNED; + } + else if (cstring_equalLit (id, "__unsigned")) + { + tok = QUNSIGNED; + } + else if (cstring_equalLit (id, "__const__")) + { + tok = QCONST; + } + else if (cstring_equalLit (id, "__alignof__")) + { + tok = CALIGNOF; /* alignof is parsed like sizeof */ + } + else if (cstring_equalLit (id, "__typeof__")) + { + tok = CTYPEOF; + } + else if (cstring_equalLit (id, "typeof")) + { + tok = CTYPEOF; + } + else if (cstring_equalLit (id, "__FUNCTION__") + || cstring_equalLit (id, "__PRETTY_FUNCTION__")) + { + /* These tokens hold the name of the current function as strings */ + /* evans 2001-12-30: changed from exprNode_stringLiteral; bug reported by Jim Zelenka. */ + yylval.expr = exprNode_makeConstantString (id, fileloc_copy (g_currentloc)); + s_tokLength = 0; + s_lastWasString = TRUE; + tok = CCONSTANT; + return tok; + } + else if (cstring_equalLit (id, "__attribute__") + || cstring_equalLit (id, "__asm__") + || cstring_equalLit (id, "_asm") + || cstring_equalLit (id, "__asm") + || cstring_equalLit (id, "__declspec")) + { + int depth = 0; + bool useparens = FALSE; + bool usebraces = FALSE; + bool inquote = FALSE; + bool inescape = FALSE; + int ic; + + while ((ic = cscanner_input ()) != EOF) + { + char cc = (char) ic; + + if (inescape) + { + inescape = FALSE; + } + else if (cc == '\\') + { + inescape = TRUE; + } + else if (cc == '\"') + { + inquote = !inquote; + } + else if (!inquote) + { + if (cc == '(') + { + if (!useparens) + { + if (!usebraces) + { + useparens = TRUE; + } + } + + if (useparens) + { + depth++; + } + } + else if (cc == '{') + { + if (!usebraces) + { + if (!useparens) + { + usebraces = TRUE; + } + } + + if (usebraces) + { + depth++; + } + } + else if (cc == ')' && useparens) + { + depth--; + if (depth == 0) break; + } + else if (cc == '}' && usebraces) + { + depth--; + if (depth == 0) break; + } + else if (cc == '}' + && !usebraces && !useparens + && cstring_equalLit (id, "__asm")) + { + /* + ** We need this because some MS VC++ include files + ** have __asm mov ... } + ** Its a kludge, but otherwise would need to parse + ** the asm code! + */ + return TRBRACE; + } + else + { + ; + } + } + else + { + ; + } + + if (cc == '\n') + { + context_incLineno (); + + if (cstring_equalLit (id, "__asm") + && !useparens && !usebraces) + { + break; + } + } + } + + llassert ((useparens && ic == (int) ')') + || (usebraces && ic == (int) '}') + || (!useparens && !usebraces)); + + return BADTOK; + } + else if (cstring_equalLit (id, "inline") + || cstring_equalLit (id, "__inline") + || cstring_equalLit (id, "_inline") + || cstring_equalLit (id, "__inline__")) + { + tok = QINLINE; + } + else + { + ; + } + + if (tok != BADTOK) + { + return (cscannerHelp_returnToken (tok)); + } + } + + le = usymtab_lookupSafe (id); + + /*@-dependenttrans@*/ + + if (uentry_isIter (le)) + { + /*@i32@*/ yylval.entry = le; + return (ITER_NAME); + } + else if (uentry_isEndIter (le)) + { + /*@i32@*/ yylval.entry = le; + return (ITER_ENDNAME); + } + else if (uentry_isUndefined (le)) + { + yylval.cname = cstring_copy (id); + + /* avoid parse errors for certain system built ins */ + + if (s_expectingTypeName && (cstring_firstChar (id) == '_') + && (cstring_secondChar (id) == '_')) + { + return (TYPE_NAME_OR_ID); + } + + return (NEW_IDENTIFIER); + } + else if (!uentry_isDeclared (le) && !uentry_isCodeDefined (le)) + { + if (uentry_isDatatype (le)) + { + yylval.cname = cstring_copy (id); + return (NEW_IDENTIFIER); + } + else + { + /*@i32@*/ yylval.entry = le; + return (IDENTIFIER); + } + } + else if (uentry_isDatatype (le)) + { + if (!s_expectingTypeName) + { + yylval.cname = cstring_copy (id); + + return (NEW_IDENTIFIER); + } + else + { + yylval.ctyp = uentry_getAbstractType (le); + + uentry_setUsed (le, g_currentloc); + return (TYPE_NAME); + } + } + else + { + /*@i32@*/ yylval.entry = le; + return (IDENTIFIER); + } + + /*@=dependenttrans@*/ +} + +bool cscannerHelp_processHashIdentifier (/*@only@*/ cstring id) +{ + if (context_inMacro () || context_inIterDef () || + context_inIterEnd ()) + { + uentry le; + + context_clearJustPopped (); + + le = usymtab_lookupSafe (id); + cscanner_setLastIdentifier (id); + + if (uentry_isParam (le) || uentry_isRefParam (le)) + { + return TRUE; + } + else + { + return FALSE; + } + } + else + { + /* + ** Will be handled by handleLlSpecial + */ + + cstring_free (id); + return FALSE; + } +} + +/*@only@*/ exprNode cscannerHelp_processString (void) +{ + exprNode res; + fileloc loc; + char *nl = strchr (yytext, '\n'); + cstring ns = cstring_fromCharsNew (yytext); + + if (nl == NULL) + { + loc = fileloc_copy (g_currentloc); + addColumn (size_toInt (cstring_length (ns))); + } + else + { + char *lastnl = nl; + + loc = fileloc_copy (g_currentloc); + + context_incLineno (); + + while ((nl = strchr ((nl + 1), '\n')) != NULL) + { + context_incLineno (); + lastnl = nl; + } + } + + + res = exprNode_stringLiteral (ns, loc); + return (res); +} + +/* +** process a wide character string L"...." +*/ + +/*@only@*/ exprNode cscannerHelp_processWideString () +{ + exprNode res; + fileloc loc; + char *nl = strchr (yytext, '\n'); + cstring ns; + + llassert (*yytext == 'L'); + yytext++; + + ns = cstring_fromCharsNew (yytext); + + if (nl == NULL) + { + loc = fileloc_copy (g_currentloc); + addColumn (size_toInt (cstring_length (ns))); + } + else + { + char *lastnl = nl; + + loc = fileloc_copy (g_currentloc); + + context_incLineno (); + + while ((nl = strchr ((nl + 1), '\n')) != NULL) + { + context_incLineno (); + lastnl = nl; + } + } + + res = exprNode_wideStringLiteral (ns, loc); + return (res); +} + +char cscannerHelp_processChar () +{ + char fchar; + char next; + + llassert (*yytext != '\0'); + fchar = *(yytext + 1); + if (fchar != '\\') return fchar; + + next = *(yytext + 2); + + switch (next) + { + case 'n': return '\n'; + case 't': return '\t'; + case '\"': return '\"'; + case '\'': return '\''; + case '\\': return '\\'; + default: return '\0'; + } +} + +double cscannerHelp_processFloat () +{ + double ret = atof (yytext); + + return (ret); +} + +long cscannerHelp_processHex () +{ + int index = 2; + long val = 0; + + llassert (yytext[0] == '0' + && (yytext[1] == 'X' || yytext[1] == 'x')); + + while (yytext[index] != '\0') { + int tval; + char c = yytext[index]; + + if (c >= '0' && c <= '9') { + tval = (int) c - (int) '0'; + } else if (c >= 'A' && c <= 'F') { + 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, + message ("Invalid character (%c) in hex constant: %s", + c, cstring_fromChars (yytext)), + g_currentloc); + break; + } + + val = (val * 16) + tval; + index++; + } + + DPRINTF (("Hex constant: %s = %ld", yytext, val)); + return val; +} + +long cscannerHelp_processOctal () +{ + int index = 1; + long val = 0; + + llassert (yytext[0] == '0' && yytext[1] != 'X' && yytext[1] != 'x'); + + while (yytext[index] != '\0') { + int tval; + char c = yytext[index]; + + if (c >= '0' && c <= '7') { + tval = (int) c - (int) '0'; + } 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 octal constant: %s", + c, cstring_fromChars (yytext)), + g_currentloc); + } + index++; + } + + break; + } else { + voptgenerror + (FLG_SYNTAX, + message ("Invalid character (%c) in octal constant: %s", + c, cstring_fromChars (yytext)), + g_currentloc); + break; + } + + val = (val * 8) + tval; + index++; + } + + DPRINTF (("Octal constant: %s = %ld", yytext, val)); + return val; +} + +long cscannerHelp_processDec () +{ + return (atol (yytext)); +} + +int cscannerHelp_processSpec (int tok) +{ + size_t length = strlen (yytext); + + if (s_inSpecPart) + { + + /*drl 12/11/2002 + patched to fix assert failures in constraint code. + Added the else if test so that splint does not treat MaxSet and MaxRead + as identifies*/ + + if (s_whichSpecPart == QMODIFIES + || s_whichSpecPart == QDEFINES + || s_whichSpecPart == QUSES + || s_whichSpecPart == QALLOCATES + || s_whichSpecPart == QSETS + || s_whichSpecPart == QRELEASES) + + { + DPRINTF((message("Treating specifaction keyword %s as an identifiers. (This corresponds to" + " token %d and we're in the specification denoted by %d see cgrammar_tokens.h" + " for an explanation of these numbers", + yytext, tok, s_whichSpecPart) + )); + + ; /* Allow specificiation keywords to be used as identifiers in these contexts. */ + } + else if ( (s_whichSpecPart == QPRECLAUSE + || s_whichSpecPart == QPOSTCLAUSE + || s_whichSpecPart == QINVARIANT ) + && (!cscannerHelp_isConstraintToken(tok) ) + ) + { + DPRINTF((message("Treating specifaction keyword %s as an identifiers. (This corresponds to" + " token %d and we're in the specification denoted by %d see cgrammar_tokens.h" + " for an explanation of these numbers", + yytext, tok, s_whichSpecPart) + )); + + /* Allow specificiation keywords to be used as identifiers in these contexts. */ + } + else + { + cscannerHelp_setTokLengthT (length); + return cscannerHelp_returnToken (tok); + } + } + + context_saveLocation (); + cscannerHelp_setTokLengthT (length); + return (cscannerHelp_processIdentifier (cscannerHelp_makeIdentifier (yytext))); +} + +void cscannerHelp_expectingMetaStateName () +{ + llassert (!s_expectingMetaStateName); + llassert (context_inFunctionHeader ()); + s_expectingMetaStateName = TRUE; +} + +void cscannerHelp_clearExpectingMetaStateName () +{ + llassert (s_expectingMetaStateName); + s_expectingMetaStateName = FALSE; +} + +bool cscannerHelp_isConstraintToken (int tok) + /* drl added 12/11/2002 + Tell whether a token has special meaning + within a function constraint + */ +{ + return (tok == QMAXSET || tok == QMAXREAD); + /* || tok == QMINREAD || tok == QMINSET */ + /*@i4523@*/ + /* uncomment the additional if statement tests when minSet and minRead are supported */ +} + +bool cscannerHelp_processMacro (void) +{ + uentry e2; + ctype ct; + int noparams = 0; + cstring fname = cstring_undefined; + bool res = TRUE; + bool isspecfcn = FALSE; + bool isiter = FALSE; + bool skipparam = FALSE; + bool isenditer = FALSE; + bool unknownm = FALSE; + bool hasParams = FALSE; + bool emptyMacro = FALSE; + char c = skip_whitespace (); + fileloc loc = fileloc_noColumn (g_currentloc); + + /* are both of these necessary? what do they mean? */ + uentryList specparams = uentryList_undefined; + uentryList pn = uentryList_undefined; + + context_resetMacroMissingParams (); + + if (c == '\0' || c == '\n') + { + llcontbug (cstring_makeLiteral ("Bad macro")); + fileloc_free (loc); + return FALSE; + } + + fname = cstring_appendChar (fname, c); + + while ((c = macro_nextChar ()) != '(' && c != '\0' + && c != ' ' && c != '\t' && c != '\n') + { + fname = cstring_appendChar (fname, c); + } + + if (c == ' ' || c == '\t' || c == '\n') + { + char oldc = c; + + if (c != '\n') + { + while (c == ' ' || c == '\t') + { + c = macro_nextChar (); + } + cscanner_unput ((int) c); + } + + if (c == '\n') + { + emptyMacro = TRUE; + cscanner_unput ((int) c); + } + + c = oldc; + } + + hasParams = (c == '('); + + if (usymtab_exists (fname)) + { + e2 = usymtab_lookupExpose (fname); + ct = uentry_getType (e2); + + if (uentry_isCodeDefined (e2) + && fileloc_isUser (uentry_whereDefined (e2))) + { + if (optgenerror + (FLG_MACROREDEF, + message ("Macro %s already defined", fname), + loc)) + { + uentry_showWhereDefined (e2); + uentry_clearDefined (e2); + } + + if (uentry_isFunction (e2)) + { + uentry_setType (e2, ctype_unknown); + ct = ctype_unknown; + unknownm = TRUE; + context_enterUnknownMacro (e2); + } + else + { + context_enterConstantMacro (e2); + } + } + else + { + if (uentry_isForward (e2) && uentry_isFunction (e2)) + { + unknownm = TRUE; + + voptgenerror + (FLG_MACROFCNDECL, + message + ("Parameterized macro has no prototype or specification: %s ", + fname), + loc); + + ct = ctype_unknown; + uentry_setType (e2, ctype_unknown); + uentry_setFunctionDefined (e2, loc); + uentry_setUsed (e2, fileloc_undefined); + context_enterUnknownMacro (e2); + } + else + { + if (uentry_isIter (e2)) + { + isiter = TRUE; + specparams = uentry_getParams (e2); + noparams = uentryList_size (specparams); + uentry_setDefined (e2, loc); + context_enterIterDef (e2); + } + else if (uentry_isEndIter (e2)) + { + isenditer = TRUE; + uentry_setDefined (e2, loc); + context_enterIterEnd (e2); /* don't care about it now */ + /* but should parse like an iter! */ + } + else if (uentry_isConstant (e2)) + { + if (hasParams) + { + voptgenerror + (FLG_INCONDEFS, + message ("Constant %s implemented as parameterized macro", + fname), + g_currentloc); + + uentry_showWhereSpecified (e2); + uentry_setType (e2, ctype_unknown); + uentry_makeConstantFunction (e2); + uentry_setDefined (e2, g_currentloc); + uentry_setFunctionDefined (e2, g_currentloc); + context_enterUnknownMacro (e2); + } + else + { + if (!uentry_isSpecified (e2)) + { + fileloc oloc = uentry_whereDeclared (e2); + + if (fileloc_isLib (oloc)) + { + ; + } + else if (fileloc_isUndefined (oloc) + || fileloc_isPreproc (oloc)) + { + if (!emptyMacro) + { + voptgenerror + (FLG_MACROCONSTDECL, + message + ("Macro constant %q not declared", + uentry_getName (e2)), + loc); + } + } + else if (!fileloc_withinLines (oloc, loc, 2)) + { /* bogus! will give errors if there is too much whitespace */ + voptgenerror + (FLG_SYNTAX, + message + ("Macro constant name %s does not match name in " + "previous constant declaration. This constant " + "is declared at %q", fname, + fileloc_unparse (oloc)), + loc); + } + else + { + /* No warning */ + } + } + + context_enterConstantMacro (e2); + cstring_free (fname); + fileloc_free (loc); + return res; + } + + } + else if (ctype_isFunction (ct)) + { + isspecfcn = TRUE; + specparams = ctype_argsFunction (ct); + noparams = uentryList_size (specparams); + + uentry_setFunctionDefined (e2, loc); + context_enterMacro (e2); + } + else if (uentry_isVar (e2)) + { + if (hasParams) + { + voptgenerror + (FLG_INCONDEFS, + message ("Variable %s implemented as parameterized macro", + fname), + loc); + + uentry_showWhereSpecified (e2); + uentry_setType (e2, ctype_unknown); + uentry_makeVarFunction (e2); + uentry_setDefined (e2, g_currentloc); + uentry_setFunctionDefined (e2, g_currentloc); + context_enterUnknownMacro (e2); + } + else + { + uentry ucons = uentry_makeConstant (fname, + ctype_unknown, + loc); + if (uentry_isExpandedMacro (e2)) + { + ; /* okay */ + } + else + { + if (optgenerror + (FLG_INCONDEFS, + message ("Variable %s implemented by a macro", + fname), + loc)) + { + uentry_showWhereSpecified (e2); + } + } + + uentry_setDefined (e2, loc); + uentry_setUsed (ucons, loc); + + context_enterConstantMacro (ucons); + uentry_markOwned (ucons); + cstring_free (fname); + return res; + } + } + else + { + if (uentry_isDatatype (e2)) + { + vgenhinterror + (FLG_SYNTAX, + message ("Type implemented as macro: %x", + uentry_getName (e2)), + message ("A type is implemented using a macro definition. A " + "typedef should be used instead."), + g_currentloc); + + cscannerHelp_swallowMacro (); + /* Must exit scope (not sure why a new scope was entered?) */ + usymtab_quietExitScope (g_currentloc); + uentry_setDefined (e2, g_currentloc); + res = FALSE; + } + else + { + llcontbug + (message ("Unexpanded macro not function or constant: %q", + uentry_unparse (e2))); + uentry_setType (e2, ctype_unknown); + + if (hasParams) + { + uentry_makeVarFunction (e2); + uentry_setDefined (e2, g_currentloc); + uentry_setFunctionDefined (e2, g_currentloc); + context_enterUnknownMacro (e2); + } + } + } + } + } + } + else + { + uentry ce; + + /* evans 2001-09-09 - if it has params, assume a function */ + if (hasParams) + { + voptgenerror + (FLG_MACROMATCHNAME, + message ("Unexpanded macro %s does not match name of a declared " + "function. The name used in the control " + "comment on the previous line should match.", + fname), + loc); + + ce = uentry_makeFunction (fname, ctype_unknown, + typeId_invalid, + globSet_undefined, + sRefSet_undefined, + warnClause_undefined, + fileloc_undefined); + uentry_setUsed (ce, loc); /* perhaps bogus? */ + e2 = usymtab_supEntryReturn (ce); + context_enterUnknownMacro (e2); + } + else + { + voptgenerror + (FLG_MACROMATCHNAME, + message ("Unexpanded macro %s does not match name of a constant " + "or iter declaration. The name used in the control " + "comment on the previous line should match. " + "(Assuming macro defines a constant.)", + fname), + loc); + + ce = uentry_makeConstant (fname, ctype_unknown, fileloc_undefined); + uentry_setUsed (ce, loc); /* perhaps bogus? */ + e2 = usymtab_supEntryReturn (ce); + + context_enterConstantMacro (e2); + cstring_free (fname); + fileloc_free (loc); + return res; + } + } + + /* in macros, ( must follow immediatetly after name */ + + if (hasParams) + { + int paramno = 0; + + c = skip_whitespace (); + + while (c != ')' && c != '\0') + { + uentry param; + bool suppress = context_inSuppressRegion (); + cstring paramname = cstring_undefined; + + /* + ** save the parameter location + */ + + decColumn (); + context_saveLocation (); + incColumn (); + + while (c != ' ' && c != '\t' && c != ',' && c != '\0' && c != ')') + { + paramname = cstring_appendChar (paramname, c); + c = macro_nextChar (); + } + + if (c == ' ' || c == '\t') c = skip_whitespace (); + + if (c == ',') + { + c = macro_nextChar (); + if (c == ' ' || c == '\t') c = skip_whitespace (); + } + + if (c == '\0') + { + llfatalerror (cstring_makeLiteral + ("Bad macro syntax: uentryList")); + } + + if ((isspecfcn || isiter) && (paramno < noparams) + && !uentry_isElipsisMarker (uentryList_getN + (specparams, paramno))) + { + fileloc sloc = context_getSaveLocation (); + uentry decl = uentryList_getN (specparams, paramno); + sRef sr; + + param = uentry_nameCopy (paramname, decl); + + uentry_setParam (param); + sr = sRef_makeParam (paramno, uentry_getType (param), + stateInfo_makeLoc (sloc, SA_DECLARED)); + + if (sRef_getNullState (sr) == NS_ABSNULL) + { + ctype pt = ctype_realType (uentry_getType (param)); + + if (ctype_isUser (pt)) + { + uentry te = usymtab_getTypeEntrySafe (ctype_typeId (pt)); + + if (uentry_isValid (te)) + { + sRef_setStateFromUentry (sr, te); + } + } + else + { + sRef_setNullState (sr, NS_UNKNOWN, sloc); + } + } + + uentry_setSref (param, sr); + uentry_setDeclaredForceOnly (param, sloc); + + skipparam = isiter && uentry_isOut (uentryList_getN (specparams, paramno)); + } + else + { + fileloc sloc = context_getSaveLocation (); + + param = uentry_makeVariableSrefParam + (paramname, ctype_unknown, fileloc_copy (sloc), + sRef_makeParam (paramno, ctype_unknown, + stateInfo_makeLoc (sloc, SA_DECLARED))); + DPRINTF (("Unknown param: %s", uentry_unparseFull (param))); + cstring_free (paramname); + + sRef_setPosNull (uentry_getSref (param), sloc); + uentry_setDeclaredForce (param, sloc); + + skipparam = FALSE; + fileloc_free (sloc); + } + + if (!skipparam) + { + llassert (!uentry_isElipsisMarker (param)); + + if (!suppress) + { + sRef_makeUnsafe (uentry_getSref (param)); + } + + pn = uentryList_add (pn, uentry_copy (param)); + usymtab_supEntry (param); + } + else + { + /* don't add param */ + uentry_free (param); + } + + if (c == ',') + { + (void) macro_nextChar (); + c = skip_whitespace (); + } + + paramno++; + } + + if (c == ')') + { + if (isspecfcn || isiter) + { + if (paramno != noparams && noparams >= 0) + { + cscannerHelp_advanceLine (); + + voptgenerror + (FLG_INCONDEFS, + message ("Macro %s specified with %d args, defined with %d", + fname, noparams, paramno), + g_currentloc); + + uentry_showWhereSpecified (e2); + uentry_resetParams (e2, pn); + } + } + else + { + uentry_resetParams (e2, pn); + } + } + } + else + { + /* + ** the form should be: + ** + ** # define newname oldname + ** where oldname refers to a function matching the specification + ** of newname. + */ + + if (unknownm) + { + sRef_setGlobalScope (); + usymtab_supGlobalEntry (uentry_makeVariableLoc (fname, ctype_unknown)); + sRef_clearGlobalScope (); + } + else + { + context_setMacroMissingParams (); + } + } + + + /* context_setuentryList (pn); */ + usymtab_enterScope (); + + fileloc_free (loc); + cstring_free (fname); + + return res; +} + +void cscannerHelp_setTokLength (int len) +{ + addColumn (len); + s_tokLength = len; + DPRINTF (("Set tok length: %d", len)); +} + +void cscannerHelp_setTokLengthT (size_t len) +{ + cscannerHelp_setTokLength (size_toInt (len)); +} + +void cscannerHelp_advanceLine (void) +{ + s_tokLength = 0; + beginLine (); +} + +int cscannerHelp_returnToken (int t) +{ + yylval.tok = lltok_create (t, fileloc_decColumn (g_currentloc, s_tokLength)); + s_tokLength = 0; + s_lastWasString = FALSE; + return (t); +} + +int cscannerHelp_returnTokenLength (int t, int length) +{ + cscannerHelp_setTokLength (length); + return cscannerHelp_returnToken (t); +} + +int cscannerHelp_returnString (cstring s) +{ + yylval.expr = exprNode_stringLiteral (s, fileloc_decColumn (g_currentloc, s_tokLength)); + s_tokLength = 0; + s_lastWasString = TRUE; + return (CCONSTANT); +} + +int cscannerHelp_returnInt (ctype ct, long val) +{ + ctype c = ct; + + if (ctype_equal (ct, ctype_int)) + { + if (val == 0) + { + c = context_typeofZero (); + } + else if (val == 1) + { + c = context_typeofOne (); + } + else + { + ; + } + } + + yylval.expr = exprNode_numLiteral (c, cstring_fromChars (yytext), + fileloc_decColumn (g_currentloc, s_tokLength), + val); + s_tokLength = 0; + s_lastWasString = FALSE; + return (CCONSTANT); +} + +int cscannerHelp_returnFloat (ctype ct, double f) +{ + yylval.expr = exprNode_floatLiteral (f, ct, cstring_fromChars (yytext), + fileloc_decColumn (g_currentloc, s_tokLength)); + s_tokLength = 0; + s_lastWasString = FALSE; + return (CCONSTANT); +} + +int cscannerHelp_returnChar (char c) +{ + yylval.expr = exprNode_charLiteral (c, cstring_fromChars (yytext), + fileloc_decColumn (g_currentloc, s_tokLength)); + s_tokLength = 0; + s_lastWasString = FALSE; + return (CCONSTANT); +} + +int cscannerHelp_returnType (int tok, ctype ct) +{ + yylval.ctyp = ct; + s_tokLength = 0; + s_lastWasString = FALSE; + return tok; +} + +int cscannerHelp_returnExpr (exprNode e) +{ + yylval.expr = e; + s_tokLength = 0; + s_lastWasString = TRUE; + return (CCONSTANT); +} + +void cscannerHelp_setExpectingTypeName () +{ + s_expectingTypeName = TRUE; +} + +void cscannerHelp_clearExpectingTypeName () +{ + s_expectingTypeName = FALSE; +} + +bool cscannerHelp_isExpectingTypeName () +{ + return s_expectingTypeName; +} + +int cscannerHelp_processTextIdentifier (char *text) +{ + context_saveLocation (); + cscannerHelp_setTokLength (size_toInt (mstring_length (text))); + return cscannerHelp_processIdentifier (cscannerHelp_makeIdentifier (text)); +} + +static bool s_continueLine = FALSE; + +int cscannerHelp_handleNewLine () +{ + context_incLineno (); + + if (s_tokLength != 0) { + s_tokLength = 0; + /* No error to report + voptgenerror + (FLG_SYNTAX, + message ("Likely parse error: token spans multiple lines."), + g_currentloc); + */ + } + + if (s_continueLine) + { + s_continueLine = FALSE; + } + else + { + if (context_inMacro ()) + { + /* Don't use return cscannerHelp_returnToken */ + /* !!! evans 2002-03-13 */ + yylval.tok = lltok_create (TENDMACRO, fileloc_copy (g_currentloc)); + s_lastWasString = FALSE; + return TENDMACRO; + } + } + + return BADTOK; +} + +void cscannerHelp_setContinueLine () +{ + s_continueLine = TRUE; +} + +void cscannerHelp_exitSpecPart () +{ + llassert (s_inSpecPart); + s_inSpecPart = FALSE; + s_whichSpecPart = BADTOK; +} diff --git a/src/ctbase.i b/src/ctbase.i index 893738a..667cb6c 100644 --- a/src/ctbase.i +++ b/src/ctbase.i @@ -34,8 +34,11 @@ abst_typedef /*@null@*/ struct s_ctbase *ctbase; /*@function static bool ctuid_isAnyUserType (sef ctuid p_cid) @*/ +/*@i888@*/ +/*@-macrofcndecl@*/ /*@-macroparams@*/ # define ctuid_isAnyUserType(cid) \ ((cid) == CT_ABST || (cid) == CT_USER || (cid) == CT_NUMABST) +/*@=macrofcndecl@*/ /*@=macroparams@*/ /*@private@*/ typedef struct { ctkind kind; diff --git a/src/exprNode.c b/src/exprNode.c index 828ef6c..97cab2a 100644 --- a/src/exprNode.c +++ b/src/exprNode.c @@ -30,6 +30,7 @@ # include "basic.h" # include "cgrammar.h" # include "cscanner.h" +# include "cscannerHelp.h" # include "cgrammar_tokens.h" # include "exprChecks.h" @@ -1036,7 +1037,7 @@ exprNode_fromIdentifier (/*@observer@*/ uentry c) if (context_justPopped ()) /* watch out! c could be dead */ { - uentry ce = usymtab_lookupSafe (cscanner_observeLastIdentifier ()); + uentry ce = usymtab_lookupSafe (cscannerHelp_observeLastIdentifier ()); if (uentry_isValid (ce)) { @@ -10192,16 +10193,20 @@ exprNode_checkUse (exprNode e, /*@exposed@*/ sRef s, fileloc loc) { lastRef = errorRef; errorRef = s; + DPRINTF (("Setting ERROR: %s", sRef_unparseFull (s))); deadRef = sRef_isDead (errorRef); unuseable = sRef_isUnuseable (errorRef); errorMaybe = FALSE; } + /* if (!sRef_isPartial (s)) { DPRINTF (("Defining! %s", sRef_unparseFull (s))); - sRef_setDefined (s, fileloc_undefined); + sRef_setDefined (s, loc); + DPRINTF (("Defining! %s", sRef_unparseFull (s))); } + */ } s = sRef_getBaseSafe (s); @@ -10213,6 +10218,7 @@ exprNode_checkUse (exprNode e, /*@exposed@*/ sRef s, fileloc loc) && sRef_isPointer (errorRef)) { errorRef = lastRef; + DPRINTF (("errorRef: %s", sRef_unparseFull (errorRef))); } if (deadRef) @@ -10236,7 +10242,7 @@ exprNode_checkUse (exprNode e, /*@exposed@*/ sRef s, fileloc loc) } else { - DPRINTF (("HERE: %s", sRef_unparse (errorRef))); + DPRINTF (("HERE: %s", sRef_unparseFull (errorRef))); if (optgenerror (FLG_USERELEASED, @@ -10273,13 +10279,16 @@ exprNode_checkUse (exprNode e, /*@exposed@*/ sRef s, fileloc loc) { DPRINTF (("HERE: %s", sRef_unparseFull (errorRef))); - voptgenerror - (FLG_USEDEF, - message ("%q %q%qused before definition", - sRef_unparseKindName (errorRef), - sRef_unparseOpt (errorRef), - cstring_makeLiteral (errorMaybe ? "may be " : "")), - loc); + if (optgenerror + (FLG_USEDEF, + message ("%q %q%qused before definition", + sRef_unparseKindName (errorRef), + sRef_unparseOpt (errorRef), + cstring_makeLiteral (errorMaybe ? "may be " : "")), + loc)) + { + ; + } DPRINTF (("Error: %s", sRef_unparseFull (errorRef))); } @@ -10875,12 +10884,24 @@ abstractOpError (ctype tr1, ctype tr2, lltok op, } else { - return optgenerror - (FLG_ABSTRACT, - message ("Operands of %s are abstract type (%t): %s %s %s", - lltok_unparse (op), tr1, - exprNode_unparse (e1), lltok_unparse (op), exprNode_unparse (e2)), - loc1); + if (lltok_isEqOp (op) || lltok_isNotEqOp (op)) + { + return optgenerror + (FLG_ABSTRACTCOMPARE, + message ("Object equality comparison (%s) on objects of abstract type (%t): %s %s %s", + lltok_unparse (op), tr1, + exprNode_unparse (e1), lltok_unparse (op), exprNode_unparse (e2)), + loc1); + } + else + { + return optgenerror + (FLG_ABSTRACT, + message ("Operands of %s are abstract type (%t): %s %s %s", + lltok_unparse (op), tr1, + exprNode_unparse (e1), lltok_unparse (op), exprNode_unparse (e2)), + loc1); + } } } else diff --git a/src/flags.c b/src/flags.c index a067490..6738754 100644 --- a/src/flags.c +++ b/src/flags.c @@ -1267,7 +1267,7 @@ flags_identifyFlagAux (cstring s, bool quiet) return res; } -void setValueFlag (flagcode opt, cstring arg) +void flags_setValueFlag (flagcode opt, cstring arg) { switch (opt) { @@ -1276,6 +1276,7 @@ void setValueFlag (flagcode opt, cstring arg) case FLG_LIMIT: case FLG_LINELEN: case FLG_INDENTSPACES: + case FLG_LOCINDENTSPACES: case FLG_BUGSLIMIT: case FLG_EXTERNALNAMELEN: case FLG_INTERNALNAMELEN: @@ -1317,11 +1318,11 @@ void setValueFlag (flagcode opt, cstring arg) } } break; - BADDEFAULT; + BADDEFAULT; } } -void setStringFlag (flagcode opt, /*@only@*/ cstring arg) +void flags_setStringFlag (flagcode opt, /*@only@*/ cstring arg) { switch (opt) { @@ -1787,7 +1788,7 @@ flags_processFlags (bool inCommandLine, { if (++i < argc) { - setValueFlag (opt, cstring_fromChars (argv[i])); + flags_setValueFlag (opt, cstring_fromCharsNew (argv[i])); } else { @@ -1803,7 +1804,7 @@ flags_processFlags (bool inCommandLine, { if (++i < argc) { - setValueFlag (opt, cstring_fromChars (argv[i])); + flags_setValueFlag (opt, cstring_fromCharsNew (argv[i])); } else { @@ -1863,7 +1864,7 @@ flags_processFlags (bool inCommandLine, } else { - setStringFlag (opt, cstring_copy (arg)); + flags_setStringFlag (opt, cstring_copy (arg)); } } } diff --git a/src/flags.def b/src/flags.def index 29d9527..afc3cff 100644 --- a/src/flags.def +++ b/src/flags.def @@ -472,6 +472,15 @@ static flaglist flags = "An abstraction barrier is broken. If necessary, use /*@access @*/ to allow access to an abstract type.", 0, 0 }, + { + FK_ABSTRACT, FK_NONE, modeFlag, + "abstractcompare", + FLG_ABSTRACTCOMPARE, + "object equality comparison on abstract type operands", + "An object comparison (== or !=) is used on operands of abstract type.", + 0, 0 + }, + { FK_ABSTRACT, FK_NONE, plainFlag, "numabstract", @@ -3287,6 +3296,20 @@ static flaglist flags = "set number of spaces to indent sub-messages", NULL, 0, 0 }, + { + FK_FORMAT, FK_DISPLAY, valueFlag, + "locindentspaces", + FLG_LOCINDENTSPACES, + "set number of spaces to indent sub-messages that start with file locations", + NULL, 0, 0 + }, + { + FK_FORMAT, FK_DISPLAY, plainFlag, + "showdeephistory", + FLG_SHOWDEEPHISTORY, + "show all available information about storage mentioned in warnings", + NULL, 0, 0 + }, { FK_FORMAT, FK_DISPLAY, plainFlag, "showcolumn", diff --git a/src/llerror.c b/src/llerror.c index 6736658..99d6ce8 100644 --- a/src/llerror.c +++ b/src/llerror.c @@ -595,9 +595,12 @@ void llgenindentmsg (/*@only@*/ cstring s, fileloc fl) { cstring flstring = fileloc_unparse (fl); - + int indentspaces = context_getLocIndentSpaces (); prepareMessage (); - (void) printIndentMessage (g_warningstream, message ("%q: %q", flstring, s), context_getIndentSpaces ()); + + (void) printIndentMessage (g_warningstream, message ("%q: %q", flstring, s), + indentspaces); + closeMessage (); } diff --git a/src/llmain.c b/src/llmain.c index 887ec77..cf70ca7 100644 --- a/src/llmain.c +++ b/src/llmain.c @@ -554,7 +554,7 @@ int main (int argc, char *argv[]) if (++i < argc) { fname = cstring_fromChars (argv[i]); - setStringFlag (opt, fname); + flags_setStringFlag (opt, fname); } else { diff --git a/src/lltok.c b/src/lltok.c index 941b596..1d19d4c 100644 --- a/src/lltok.c +++ b/src/lltok.c @@ -43,35 +43,40 @@ lltok_isMult (lltok tok) return (tok->tok == TMULT); } -bool lltok_isInc_Op (lltok tok) +bool lltok_isIncOp (lltok tok) { return (tok->tok == INC_OP); } -bool lltok_isDec_Op (lltok tok) +bool lltok_isDecOp (lltok tok) { return (tok->tok == DEC_OP); } /* DRL added this function 10/23/2000 for boolean stuff */ -bool lltok_isEq_Op (lltok tok) +bool lltok_isEqOp (lltok tok) { return (tok->tok == EQ_OP); } +bool lltok_isNotEqOp (lltok tok) +{ + return (tok->tok == NE_OP); +} + /* DRL added this function 10/25/2000 for boolean stuff */ -bool lltok_isAnd_Op (lltok tok) +bool lltok_isAndOp (lltok tok) { return (tok->tok == AND_OP); } -bool lltok_isOr_Op (lltok tok) +bool lltok_isOrOp (lltok tok) { return (tok->tok == OR_OP); } -bool lltok_isNot_Op (lltok tok) +bool lltok_isNotOp (lltok tok) { return (tok->tok == TEXCL); } diff --git a/src/loopHeuristics.c b/src/loopHeuristics.c index a0c857a..3d926af 100644 --- a/src/loopHeuristics.c +++ b/src/loopHeuristics.c @@ -155,7 +155,7 @@ static bool canGetForTimes (/*@notnull@*/ exprNode forPred, /*@notnull@*/ exprNo } tok = (exprData_getUopTok (inc->edata)); - if (lltok_isInc_Op (tok) ) + if (lltok_isIncOp (tok) ) { t1 = exprData_getUopNode (test->edata); t2 = exprData_getUopNode (inc->edata); @@ -293,7 +293,7 @@ static /*@only@*/ constraintExpr getForTimes (/*@notnull@*/ exprNode forPred, /* } tok = (exprData_getUopTok (inc->edata)); - if (lltok_isInc_Op (tok) ) + if (lltok_isIncOp (tok) ) { t1 = exprData_getUopNode (test->edata); t2 = exprData_getUopNode (inc->edata); diff --git a/src/nameChecks.c b/src/nameChecks.c index d17a941..f78a6d1 100644 --- a/src/nameChecks.c +++ b/src/nameChecks.c @@ -1336,7 +1336,20 @@ checkAnsiName (uentry ue) uentry_whereLast (ue)); } - DPRINTF (("Here...")); + /* + ** evans - 2002-12-16: added this check (even though it is not required by ISO) + */ + + if (fchar == 'S' && schar == 'A' && tchar == '_') + { + hasError |= optgenerror2 + (FLG_ISORESERVED, FLG_NAMECHECKS, + message + ("Name %s may be defined as a macro by Linux library. " + "It is not research by the ISO specification, but may produce conflicts on some systems.", + name), + uentry_whereLast (ue)); + } if ((uentry_isVisibleExternally (ue) && !uentry_isAnyTag (ue)) || context_getFlag (FLG_ISORESERVEDLOCAL)) diff --git a/src/sRef.c b/src/sRef.c index 9a32bb5..523329e 100644 --- a/src/sRef.c +++ b/src/sRef.c @@ -189,7 +189,8 @@ static void sinfo_free (/*@special@*/ /*@temp@*/ /*@notnull@*/ sRef p_s) static /*@null@*/ sinfo sinfo_copy (/*@notnull@*/ sRef p_s) /*@*/ ; static void sRef_setPartsFromUentry (sRef p_s, uentry p_ue) /*@modifies p_s@*/ ; -static bool checkDeadState (/*@notnull@*/ sRef p_el, bool p_tbranch, fileloc p_loc); +static bool checkDeadState (/*@notnull@*/ sRef p_el, /*@null@*/ sRef p_e2, + bool p_tbranch, fileloc p_loc); static /*@dependent@*/ sRef sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef p_t) /*@*/ ; static void @@ -655,22 +656,19 @@ static void sRef_setTypeState (sRef s) } } -static bool - sRef_hasAliasInfoLoc (sRef s) +bool sRef_hasAliasInfoLoc (sRef s) { return (sRef_isReasonable (s) && (s->aliasinfo != NULL) && (fileloc_isDefined (s->aliasinfo->loc))); } -static /*@falsewhennull@*/ bool -sRef_hasStateInfoLoc (sRef s) +/*@falsewhennull@*/ bool sRef_hasStateInfoLoc (sRef s) { return (sRef_isReasonable (s) && (s->definfo != NULL) && (fileloc_isDefined (s->definfo->loc))); } -static /*@falsewhennull@*/ bool -sRef_hasExpInfoLoc (sRef s) +/*@falsewhennull@*/ bool sRef_hasExpInfoLoc (sRef s) { return (sRef_isReasonable (s) && (s->expinfo != NULL) && (fileloc_isDefined (s->expinfo->loc))); @@ -2459,9 +2457,11 @@ static /*@exposed@*/ sRef sRef_undumpBody (char **c) switch (p) { case 'g': - return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c)), ctype_unknown, stateInfo_currentLoc ())); + return (sRef_makeGlobal (usymId_fromInt (reader_getInt (c)), + ctype_unknown, stateInfo_currentLoc ())); case 'p': - return (sRef_makeParam (reader_getInt (c), ctype_unknown, stateInfo_makeLoc (g_currentloc))); + return (sRef_makeParam (reader_getInt (c), ctype_unknown, + stateInfo_makeLoc (g_currentloc, SA_DECLARED))); case 'r': return (sRef_makeResult (ctype_undump (c))); case 'a': @@ -3381,7 +3381,8 @@ static bool sRef_isZerothArrayFetch (/*@notnull@*/ sRef s) } llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, + stateInfo_makeLoc (g_currentloc, SA_CREATED)); return s; } } @@ -3554,7 +3555,7 @@ sRef_makeObject (ctype o) s->info = (sinfo) dmalloc (sizeof (*s->info)); s->info->object = o; llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED)); return s; } @@ -3573,7 +3574,7 @@ sRef sRef_makeExternal (sRef t) s->type = t->type; s->info->ref = t; /* sRef_copy (t); */ /*@i32 was exposed@*/ llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_DECLARED)); return s; } @@ -3589,7 +3590,7 @@ sRef sRef_makeExternal (sRef t) s->type = t->type; llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED)); return s; } else @@ -3727,6 +3728,7 @@ sRef_mergeStateQuietReverse (/*@dependent@*/ sRef res, /*@dependent@*/ sRef othe if (other->defstate != SS_UNKNOWN) { res->defstate = other->defstate; + res->definfo = stateInfo_update (res->definfo, other->definfo); } } @@ -3740,7 +3742,8 @@ sRef_mergeStateQuietReverse (/*@dependent@*/ sRef res, /*@dependent@*/ sRef othe } else { - if (sRef_getNullState (other) != NS_UNKNOWN && sRef_getNullState (other) != sRef_getNullState (res)) + if (sRef_getNullState (other) != NS_UNKNOWN + && sRef_getNullState (other) != sRef_getNullState (res)) { changed = TRUE; sRef_updateNullState (res, other); @@ -3862,6 +3865,7 @@ sRef_mergeStateAux (/*@notnull@*/ sRef res, /*@notnull@*/ sRef other, res->defstate = SS_DEAD; } + res->definfo = stateInfo_update (res->definfo, other->definfo); sRef_clearDerived (other); sRef_clearDerived (res); } @@ -4128,13 +4132,16 @@ sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other, el->defstate == SS_PDEFINED) { el->defstate = SS_ALLOCATED; + el->definfo = stateInfo_update (el->definfo, e2->definfo); sRef_clearDerived (el); } else if ((el->defstate == SS_DEAD || sRef_isKept (el)) && (e2->defstate == SS_DEFINED && !sRef_isKept (e2))) { - - if (checkDeadState (el, TRUE, loc)) + DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el), + sRef_unparseFull (e2))); + + if (checkDeadState (el, e2, TRUE, loc)) { if (sRef_isThroughArrayFetch (el)) { @@ -4146,8 +4153,10 @@ sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other, else if ((e2->defstate == SS_DEAD || sRef_isKept (e2)) && (el->defstate == SS_DEFINED && !sRef_isKept (el))) { - - if (checkDeadState (e2, FALSE, loc)) + DPRINTF (("Checking dead: %s / %s", sRef_unparseFull (el), + sRef_unparseFull (e2))); + + if (checkDeadState (e2, el, FALSE, loc)) { if (sRef_isThroughArrayFetch (el)) { @@ -4161,12 +4170,14 @@ sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other, { DPRINTF (("set pdefined: %s", sRef_unparseFull (el))); el->defstate = SS_PDEFINED; + el->definfo = stateInfo_update (el->definfo, e2->definfo); } else if (e2->defstate == SS_DEFINED && el->defstate == SS_PDEFINED) { DPRINTF (("set pdefined: %s", sRef_unparseFull (e2))); e2->defstate = SS_PDEFINED; + e2->definfo = stateInfo_update (e2->definfo, el->definfo); } else { @@ -4205,7 +4216,8 @@ sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other, } else /* not defined */ { - (void) checkDeadState (el, TRUE, loc); + DPRINTF (("Checking dead: %s", sRef_unparseFull (el))); + (void) checkDeadState (el, e2, TRUE, loc); } } } end_sRefSet_allElements; @@ -4214,7 +4226,8 @@ sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other, { if (sRef_isReasonable (el)) { - (void) checkDeadState (el, FALSE, loc); + DPRINTF (("Checking dead: %s", sRef_unparseFull (el))); + (void) checkDeadState (el, sRef_undefined, FALSE, loc); } } end_sRefSet_allElements; @@ -4226,7 +4239,7 @@ sRef_mergeDerivs (/*@only@*/ sRefSet res, sRefSet other, ** Returns TRUE is there is an error. */ -static bool checkDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc) +static bool checkDeadState (/*@notnull@*/ sRef el, sRef e2, bool tbranch, fileloc loc) { /* ** usymtab_isGuarded --- the utab should still be in the @@ -4243,7 +4256,8 @@ static bool checkDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc) if ((sRef_isDead (el) || sRef_isKept (el)) - && !sRef_isDeepUnionField (el) && !sRef_isThroughArrayFetch (el)) + && !sRef_isDeepUnionField (el) + && !sRef_isThroughArrayFetch (el)) { if (!tbranch) @@ -4278,10 +4292,21 @@ static bool checkDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc) sRef_showStateInfo (el); } + if (sRef_isValid (e2)) + { + if (sRef_isKept (e2)) + { + sRef_showAliasInfo (e2); + } + else + { + sRef_showStateInfo (e2); + } + } + /* prevent further errors */ el->defstate = SS_UNKNOWN; - sRef_setAliasKind (el, AK_ERROR, fileloc_undefined); - + sRef_setAliasKind (el, AK_ERROR, fileloc_undefined); return FALSE; } } @@ -4292,14 +4317,13 @@ static bool checkDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc) static void checkDerivDeadState (/*@notnull@*/ sRef el, bool tbranch, fileloc loc) { - - if (checkDeadState (el, tbranch, loc)) + if (checkDeadState (el, sRef_undefined, tbranch, loc)) { sRefSet_allElements (el->deriv, t) { if (sRef_isReasonable (t)) { - checkDerivDeadState (t, tbranch, loc); + checkDerivDeadState (t, tbranch, loc); } } end_sRefSet_allElements; } @@ -4342,7 +4366,7 @@ static sRefSet { if (!opt) { - checkDerivDeadState (el, (cl == FALSECLAUSE), loc); + checkDerivDeadState (el, (cl == FALSECLAUSE), loc); } ret = sRefSet_insert (ret, el); @@ -4394,6 +4418,8 @@ sRef sRef_makeConj (/*@exposed@*/ /*@returned@*/ sRef a, /*@exposed@*/ sRef b) if (a->defstate == b->defstate) { s->defstate = a->defstate; + s->definfo = stateInfo_update (s->definfo, a->definfo); + s->definfo = stateInfo_update (s->definfo, b->definfo); } else { @@ -4406,7 +4432,7 @@ sRef sRef_makeConj (/*@exposed@*/ /*@returned@*/ sRef a, /*@exposed@*/ sRef b) s->aliaskind = alkind_resolve (a->aliaskind, b->aliaskind); llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_MERGED)); return s; } else @@ -4506,7 +4532,7 @@ sRef_makeResult (ctype c) s->aliaskind = AK_UNKNOWN; sRef_setNullStateN (s, NS_UNKNOWN); llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_DECLARED)); DPRINTF (("Result: [%p] %s", s, sRef_unparseFull (s))); return s; @@ -4591,10 +4617,11 @@ sRef_makeUnsafe (sRef s) { if (sRef_isInvalid (s)) return (cstring_undefined); - return (message ("[%p] %q - %q [%s] { %q } < %q >", + return (message ("[%p] %q - %q { %q } [%s] { %q } < %q >", s, sRef_unparseDebug (s), sRef_unparseState (s), + stateInfo_unparse (s->definfo), exkind_unparse (s->oexpkind), sRefSet_unparseDebug (s->deriv), valueTable_unparse (s->state))); @@ -4983,7 +5010,7 @@ void sRef_setAliasKind (sRef s, alkind kind, fileloc loc) if ((kind != s->aliaskind && kind != s->oaliaskind) && fileloc_isDefined (loc)) { - s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc); + s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, stateAction_fromAlkind (kind), loc); } s->aliaskind = kind; @@ -5055,7 +5082,7 @@ void sRef_setExKind (sRef s, exkind exp, fileloc loc) { if (s->expkind != exp) { - s->expinfo = stateInfo_updateLoc (s->expinfo, loc); + s->expinfo = stateInfo_updateLoc (s->expinfo, stateAction_fromExkind (exp), loc); } s->expkind = exp; @@ -5115,11 +5142,7 @@ void sRef_setUndefined (sRef s, fileloc loc) if (sRef_isReasonable (s)) { s->defstate = SS_UNDEFINED; - - if (fileloc_isDefined (loc)) - { - s->definfo = stateInfo_updateLoc (s->definfo, loc); - } + s->definfo = stateInfo_updateLoc (s->definfo, SA_UNDEFINED, loc); sRef_clearDerived (s); } @@ -5132,11 +5155,7 @@ static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear) DPRINTF (("Set defined: %s", sRef_unparseFull (s))); - if (s->defstate != SS_DEFINED && fileloc_isDefined (loc)) - { - s->definfo = stateInfo_updateLoc (s->definfo, loc); - } - + s->definfo = stateInfo_updateLoc (s->definfo, SA_DEFINED, loc); s->defstate = SS_DEFINED; DPRINTF (("Set defined: %s", sRef_unparseFull (s))); @@ -5236,7 +5255,7 @@ static void sRef_setDefinedAux (sRef s, fileloc loc, bool clear) el->defstate = SS_DEFINED; } end_sRefSet_elements ; } - + DPRINTF (("Set defined: %s", sRef_unparseFull (s))); } @@ -5341,12 +5360,7 @@ void sRef_setPdefined (sRef s, fileloc loc) return; } - if (s->defstate != SS_PDEFINED && fileloc_isDefined (loc)) - { - s->definfo = stateInfo_updateLoc (s->definfo, loc); - } - - DPRINTF (("set pdefined: %s", sRef_unparseFull (s))); + s->definfo = stateInfo_updateLoc (s->definfo, SA_PDEFINED, loc); s->defstate = SS_PDEFINED; /* e.g., if x is allocated, *x = 3 defines x */ @@ -5374,13 +5388,16 @@ static void sRef_setStateAux (sRef s, sstate ss, fileloc loc) { sRef_checkMutable (s); + DPRINTF (("Set state: %s => %s", sRef_unparseFull (s), sstate_unparse (ss))); + if (sRef_isReasonable (s)) { /* if (s->defstate == SS_RELDEF) return; */ if (s->defstate != ss && fileloc_isDefined (loc)) { - s->definfo = stateInfo_updateLoc (s->definfo, loc); + s->definfo = stateInfo_updateLoc (s->definfo, + stateAction_fromSState (ss), loc); } s->defstate = ss; @@ -5424,11 +5441,7 @@ static void sRef_setAllocatedShallow (sRef s, fileloc loc) if (s->defstate == SS_DEAD || s->defstate == SS_UNDEFINED) { s->defstate = SS_ALLOCATED; - - if (fileloc_isDefined (loc)) - { - s->definfo = stateInfo_updateLoc (s->definfo, loc); - } + s->definfo = stateInfo_updateLoc (s->definfo, SA_ALLOCATED, loc); } } } @@ -5458,7 +5471,7 @@ void sRef_setShared (sRef s, fileloc loc) { if (s->aliaskind != AK_SHARED && fileloc_isDefined (loc)) { - s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc); + s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_SHARED, loc); } s->aliaskind = AK_SHARED; @@ -5473,7 +5486,7 @@ void sRef_setLastReference (sRef s, /*@exposed@*/ sRef ref, fileloc loc) if (sRef_isReasonable (s)) { s->aliaskind = sRef_getAliasKind (ref); - s->aliasinfo = stateInfo_updateRefLoc (s->aliasinfo, ref, loc); + s->aliasinfo = stateInfo_updateRefLoc (s->aliasinfo, ref, stateAction_fromAlkind (s->aliaskind), loc); } } @@ -5486,7 +5499,7 @@ void sRef_setNullStateAux (/*@notnull@*/ sRef s, nstate ns, fileloc loc) if (fileloc_isDefined (loc)) { - s->nullinfo = stateInfo_updateLoc (s->nullinfo, loc); + s->nullinfo = stateInfo_updateLoc (s->nullinfo, stateAction_fromNState (ns), loc); } } @@ -5622,7 +5635,7 @@ void sRef_setOnly (sRef s, fileloc loc) { sRef_checkMutable (s); s->aliaskind = AK_ONLY; - s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc); + s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_ONLY, loc); } } @@ -5633,7 +5646,7 @@ void sRef_setDependent (sRef s, fileloc loc) sRef_checkMutable (s); DPRINTF (("Setting dependent: %s", sRef_unparseFull (s))); s->aliaskind = AK_DEPENDENT; - s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc); + s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_DEPENDENT, loc); } } @@ -5643,7 +5656,7 @@ void sRef_setOwned (sRef s, fileloc loc) { sRef_checkMutable (s); s->aliaskind = AK_OWNED; - s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc); + s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_OWNED, loc); } } @@ -5669,7 +5682,7 @@ void sRef_setKept (sRef s, fileloc loc) sRef_checkMutable (s); s->aliaskind = AK_KEPT; - s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc); + s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_KEPT, loc); } } @@ -5705,7 +5718,7 @@ void sRef_setFresh (sRef s, fileloc loc) { sRef_checkMutable (s); s->aliaskind = AK_FRESH; - s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, loc); + s->aliasinfo = stateInfo_updateLoc (s->aliasinfo, SA_CREATED, loc); DPRINTF (("SetFresh: %s", sRef_unparseFull (s))); } } @@ -5735,8 +5748,8 @@ void sRef_kill (sRef s, fileloc loc) s->aliaskind = s->oaliaskind; s->defstate = SS_DEAD; - s->definfo = stateInfo_updateLoc (s->definfo, loc); - + s->definfo = stateInfo_updateLoc (s->definfo, SA_KILLED, loc); + DPRINTF (("State info: %s", stateInfo_unparse (s->definfo))); sRef_clearDerived (s); } } @@ -5765,7 +5778,9 @@ void sRef_maybeKill (sRef s, fileloc loc) s->aliaskind = s->oaliaskind; s->defstate = SS_HOFFA; - s->definfo = stateInfo_updateLoc (s->definfo, loc); + s->definfo = stateInfo_updateLoc (s->definfo, SA_PKILLED, loc); + DPRINTF (("State info: %s / %s", sRef_unparse (s), + stateInfo_unparse (s->definfo))); sRef_clearDerived (s); } @@ -5884,7 +5899,7 @@ sRef sRef_copy (sRef s) t->deriv = sRefSet_newDeepCopy (s->deriv); t->state = valueTable_copy (s->state); - + DPRINTF (("Made copy: %s => %s", sRef_unparseFull (s), sRef_unparseFull (t))); return t; } @@ -6314,7 +6329,7 @@ sRef_buildNCField (/*@exposed@*/ sRef rec, /*@exposed@*/ cstring f) s->oaliaskind = s->aliaskind; s->oexpkind = s->expkind; - + DPRINTF (("sref: %s", sRef_unparseFull (s))); } else @@ -6428,9 +6443,11 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, if (ctype_isMutable (s->type)) { - sRef_setExKind (s, sRef_getExKind (sp), fileloc_undefined); - + s->expkind = sRef_getExKind (sp); + s->expinfo = stateInfo_copy (sp->expinfo); + s->aliaskind = sp->aliaskind; + s->aliasinfo = stateInfo_copy (sp->aliasinfo); } s->defstate = sp->defstate; @@ -6474,8 +6491,9 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, */ } - sRef_setExKind (s, sRef_getExKind (arr), g_currentloc); - + s->expkind = sRef_getExKind (arr); + s->expinfo = stateInfo_copy (arr->expinfo); + if (arr->aliaskind == AK_LOCAL || arr->aliaskind == AK_FRESH) { s->aliaskind = AK_LOCAL; @@ -6592,6 +6610,7 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, if (sRef_isObserver (arr)) { s->expkind = XO_OBSERVER; + s->expinfo = stateInfo_copy (arr->expinfo); } } @@ -6623,7 +6642,9 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, return res; } - sRef_setExKind (s, sRef_getExKind (arr), g_currentloc); + s->expkind = sRef_getExKind (arr); + s->expinfo = stateInfo_copy (arr->expinfo); + return s; } else @@ -6649,7 +6670,8 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, if (valueTable_isUndefined (s->state)) { - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable + (s, stateInfo_makeLoc (g_currentloc, SA_CREATED)); } return (s); @@ -6688,7 +6710,9 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, return res; } - sRef_setExKind (s, sRef_getExKind (arr), g_currentloc); + s->expkind = sRef_getExKind (arr); + s->expinfo = stateInfo_copy (arr->expinfo); + llassert (s->info->arrayfetch->arr == arr); return s; } @@ -6711,7 +6735,7 @@ void sRef_setArrayFetchState (/*@notnull@*/ /*@exposed@*/ sRef s, sRef_addDeriv (arr, s); llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED)); return (s); } } @@ -6821,8 +6845,9 @@ sRef_setStateFromUentry (sRef s, uentry ue) if (sRef_isReasonable (s)) { - - sRef_setExKind (s, sRef_getExKind (t), g_currentloc); + s->expkind = sRef_getExKind (t); + s->expinfo = stateInfo_copy (t->expinfo); + s->oaliaskind = s->aliaskind; s->oexpkind = s->expkind; @@ -6919,14 +6944,17 @@ sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t) if (t->defstate == SS_UNDEFINED) { s->defstate = SS_UNUSEABLE; + s->definfo = stateInfo_copy (t->definfo); } else if ((t->defstate == SS_ALLOCATED) && !ctype_isSU (st)) { s->defstate = SS_UNDEFINED; + s->definfo = stateInfo_copy (t->definfo); } else { s->defstate = t->defstate; + s->definfo = stateInfo_copy (t->definfo); } if (t->aliaskind == AK_LOCAL || t->aliaskind == AK_FRESH) @@ -6938,7 +6966,9 @@ sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t) s->aliaskind = AK_UNKNOWN; } - sRef_setExKind (s, sRef_getExKind (t), fileloc_undefined); + s->expkind = sRef_getExKind (t); + s->expinfo = stateInfo_copy (t->expinfo); + sRef_setTypeState (s); s->oaliaskind = s->aliaskind; @@ -6946,9 +6976,10 @@ sRef_constructPointerAux (/*@notnull@*/ /*@exposed@*/ sRef t) if (valueTable_isUndefined (s->state)) { - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED)); } + DPRINTF (("pointer: %s", sRef_unparseFull (s))); return s; } @@ -6991,7 +7022,7 @@ sRef_clearDerivedComplete (sRef s) { sRef res = sRef_buildPointer (s); - DPRINTF (("Res: %s", sRef_unparse (res))); + DPRINTF (("Res: %s", sRef_unparseFull (res))); return res; } @@ -7298,7 +7329,7 @@ sRef_makeType (ctype ct) s->oaliaskind = s->aliaskind; s->oexpkind = s->expkind; llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED)); DPRINTF (("Create: %s", sRef_unparseFull (s))); return s; @@ -7336,7 +7367,7 @@ sRef_makeConst (ctype ct) s->oexpkind = s->expkind; llassert (valueTable_isUndefined (s->state)); - s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc)); + s->state = context_createValueTable (s, stateInfo_makeLoc (g_currentloc, SA_CREATED)); return s; } @@ -7751,9 +7782,14 @@ sRef_showRefLost (sRef s) void sRef_showRefKilled (sRef s) { - if (sRef_hasStateInfoLoc (s)) + if (sRef_isValid (s)) { - stateInfo_display (s->definfo, sRef_unparse (s)); + DPRINTF (("Killed: %s", sRef_unparseFull (s))); + if (context_getLocIndentSpaces () == 0) { + stateInfo_display (s->definfo, message (" Storage %q", sRef_unparseOpt (s))); + } else { + stateInfo_display (s->definfo, message ("Storage %q", sRef_unparseOpt (s))); + } } } @@ -7772,49 +7808,25 @@ sRef_showStateInconsistent (sRef s) void sRef_showStateInfo (sRef s) { - if (sRef_hasStateInfoLoc (s)) - { - if (s->defstate == SS_DEAD) - { - llgenindentmsg - (message ("Storage %qis released", sRef_unparseOpt (s)), - sRef_getStateInfoLoc (s)); - } - else if (s->defstate == SS_ALLOCATED || s->defstate == SS_DEFINED) - { - llgenindentmsg - (message ("Storage %qis %s", sRef_unparseOpt (s), - sstate_unparse (s->defstate)), - sRef_getStateInfoLoc (s)); - } - else if (s->defstate == SS_UNUSEABLE) - { - llgenindentmsg - (message ("Storage %qbecomes inconsistent (clauses merge with" - "%qreleased on one branch)", - sRef_unparseOpt (s), - sRef_unparseOpt (s)), - sRef_getStateInfoLoc (s)); - } - else - { - llgenindentmsg (message ("Storage %qbecomes %s", - sRef_unparseOpt (s), - sstate_unparse (s->defstate)), - sRef_getStateInfoLoc (s)); - } + if (sRef_isValid (s)) { + if (context_getLocIndentSpaces () == 0) { + stateInfo_display (s->definfo, message (" Storage %q", sRef_unparseOpt (s))); + } else { + stateInfo_display (s->definfo, message ("Storage %q", sRef_unparseOpt (s))); } + } } void sRef_showExpInfo (sRef s) { - if (sRef_hasExpInfoLoc (s)) - { - llgenindentmsg (message ("Storage %qbecomes %s", sRef_unparseOpt (s), - exkind_unparse (s->expkind)), - sRef_getExpInfoLoc (s)); + if (sRef_isValid (s)) { + if (context_getLocIndentSpaces () == 0) { + stateInfo_display (s->expinfo, message (" Storage %q", sRef_unparseOpt (s))); + } else { + stateInfo_display (s->expinfo, message ("Storage %q", sRef_unparseOpt (s))); } + } } void @@ -7911,24 +7923,23 @@ sRef_showNullInfo (sRef s) void sRef_showAliasInfo (sRef s) { - if (sRef_hasAliasInfoLoc (s)) + if (sRef_isValid (s)) { if (sRef_isFresh (s)) { - llgenindentmsg - (message ("Fresh storage %qallocated", sRef_unparseOpt (s)), - sRef_getAliasInfoLoc (s)); + if (context_getLocIndentSpaces () == 0) { + stateInfo_display (s->aliasinfo, message (" Fresh storage %q", sRef_unparseOpt (s))); + } else { + stateInfo_display (s->aliasinfo, message ("Fresh storage %q", sRef_unparseOpt (s))); + } } - else + else { - if (!sRef_isRefCounted (s)) - { - llgenindentmsg - (message ("Storage %qbecomes %s", - sRef_unparseOpt (s), - alkind_unparse (sRef_getAliasKind (s))), - sRef_getAliasInfoLoc (s)); - } + if (context_getLocIndentSpaces () == 0) { + stateInfo_display (s->aliasinfo, message (" Storage %q", sRef_unparseOpt (s))); + } else { + stateInfo_display (s->aliasinfo, message ("Storage %q", sRef_unparseOpt (s))); + } } } } @@ -9857,9 +9868,11 @@ void sRef_reflectAnnotation (sRef s, annotationInfo a, fileloc loc) if (!valueTable_isDefined (s->state)) { s->state = valueTable_create (1); - valueTable_insert (s->state, - cstring_copy (metaStateInfo_getName (annotationInfo_getState (a))), - stateValue_create (annotationInfo_getValue (a), stateInfo_makeLoc (loc))); + valueTable_insert + (s->state, + cstring_copy (metaStateInfo_getName (annotationInfo_getState (a))), + stateValue_create (annotationInfo_getValue (a), + stateInfo_makeLoc (loc, SA_DECLARED))); } else { @@ -9867,8 +9880,9 @@ void sRef_reflectAnnotation (sRef s, annotationInfo a, fileloc loc) valueTable_update (s->state, metaStateInfo_getName (annotationInfo_getState (a)), - stateValue_create (annotationInfo_getValue (a), stateInfo_makeLoc (loc))); - DPRINTF (("state info: %s", stateInfo_unparse (stateInfo_makeLoc (loc)))); + stateValue_create (annotationInfo_getValue (a), + stateInfo_makeLoc (loc, SA_DECLARED))); + DPRINTF (("sref: %s", sRef_unparse (s))); DPRINTF (("sref: %s", sRef_unparseFull (s))); } @@ -9904,7 +9918,8 @@ void sRef_setMetaStateValue (sRef s, cstring key, int value, fileloc loc) DPRINTF (("inserting state: %s: %s %d", sRef_unparse (s), key, value)); s->state = valueTable_create (1); valueTable_insert (s->state, cstring_copy (key), - stateValue_create (value, stateInfo_makeLoc (loc))); + stateValue_create (value, + stateInfo_makeLoc (loc, SA_CHANGED))); } else { @@ -9913,12 +9928,14 @@ void sRef_setMetaStateValue (sRef s, cstring key, int value, fileloc loc) if (valueTable_contains (s->state, key)) { valueTable_update - (s->state, key, stateValue_create (value, stateInfo_makeLoc (loc))); + (s->state, key, stateValue_create (value, + stateInfo_makeLoc (loc, SA_CHANGED))); } else { valueTable_insert - (s->state, cstring_copy (key), stateValue_create (value, stateInfo_makeLoc (loc))); + (s->state, cstring_copy (key), + stateValue_create (value, stateInfo_makeLoc (loc, SA_CHANGED))); } DPRINTF (("After: %s", sRef_unparseFull (s))); diff --git a/src/stateInfo.c b/src/stateInfo.c index 7da32bb..01e213b 100644 --- a/src/stateInfo.c +++ b/src/stateInfo.c @@ -25,6 +25,8 @@ # include "splintMacros.nf" # include "basic.h" +static /*@observer@*/ cstring stateAction_unparse (stateAction p_sa) /*@*/ ; + void stateInfo_free (/*@only@*/ stateInfo a) { if (a != NULL) @@ -43,6 +45,7 @@ void stateInfo_free (/*@only@*/ stateInfo a) { if (old == NULL) { + DPRINTF (("Update state ==> %s", stateInfo_unparse (newinfo))); return stateInfo_copy (newinfo); } else if (newinfo == NULL) @@ -52,42 +55,136 @@ void stateInfo_free (/*@only@*/ stateInfo a) } else { - stateInfo snew = stateInfo_makeRefLoc (newinfo->ref, newinfo->loc); - llassert (snew->previous == NULL); - snew->previous = old; - return snew; + if (fileloc_equal (old->loc, newinfo->loc) + && old->action == newinfo->action + /*@-abstractcompare@*/ && old->ref == newinfo->ref /*@=abstractcompare@*/) + { + /* + ** Duplicate (change through alias most likely) + ** don't add this info + */ + + return old; + } + else + { + stateInfo snew = stateInfo_makeRefLoc (newinfo->ref, + newinfo->loc, newinfo->action); + llassert (snew->previous == NULL); + snew->previous = old; + DPRINTF (("Update state ==> %s", stateInfo_unparse (snew))); + return snew; + } } } -/*@only@*/ stateInfo stateInfo_updateLoc (/*@only@*/ stateInfo old, fileloc loc) +static /*@observer@*/ stateInfo stateInfo_sort (/*@temp@*/ stateInfo sinfo) + /* Sorts in reverse location order */ { - if (old == NULL) + DPRINTF (("Sorting: %s", stateInfo_unparse (sinfo))); + + if (sinfo == NULL || sinfo->previous == NULL) { - old = stateInfo_makeLoc (loc); + return sinfo; } else { - old->loc = fileloc_update (old->loc, loc); - old->ref = sRef_undefined; - } + stateInfo snext = stateInfo_sort (sinfo->previous); + stateInfo sfirst = snext; - return old; + DPRINTF (("sinfo/sext: %s // %s", stateInfo_unparse (sinfo), stateInfo_unparse (snext))); + llassert (snext != NULL); + + if (!fileloc_lessthan (sinfo->loc, snext->loc)) + { + /*@i888@*/ sinfo->previous = sfirst; + DPRINTF (("Sorted ==> %s", stateInfo_unparse (sinfo))); + /*@i888@*/ return sinfo; + } + else + { + while (snext != NULL && fileloc_lessthan (sinfo->loc, snext->loc)) + { + /* + ** swap the order + */ + fileloc tloc = snext->loc; + stateAction taction = snext->action; + sRef tref = snext->ref; + + DPRINTF (("in while: sinfo/sext: %s // %s", stateInfo_unparse (sinfo), stateInfo_unparse (snext))); + + snext->loc = sinfo->loc; + snext->action = sinfo->action; + /*@i888@*/ snext->ref = sinfo->ref; + + sinfo->loc = tloc; + sinfo->action = taction; + sinfo->ref = tref; + /*@i888@*/ sinfo->previous = snext->previous; + snext = snext->previous; + DPRINTF (("in while: sinfo/sext: %s // %s", stateInfo_unparse (sinfo), stateInfo_unparse (snext))); + } + + DPRINTF (("Sorted ==> %s", stateInfo_unparse (sfirst))); + /*@i888@*/ return sfirst; + } + } } /*@only@*/ stateInfo - stateInfo_updateRefLoc (/*@only@*/ stateInfo old, /*@exposed@*/ sRef ref, fileloc loc) +stateInfo_updateLoc (/*@only@*/ stateInfo old, stateAction action, fileloc loc) { - if (old == NULL) + if (fileloc_isUndefined (loc)) { + loc = fileloc_copy (g_currentloc); + } + + if (old != NULL && fileloc_equal (old->loc, loc) && old->action == action) { - old = stateInfo_makeRefLoc (ref, loc); + /* + ** Duplicate (change through alias most likely) + ** don't add this info + */ + + return old; } else { - old->loc = fileloc_update (old->loc, loc); - old->ref = ref; + stateInfo snew = stateInfo_makeLoc (loc, action); + llassert (snew->previous == NULL); + snew->previous = old; + DPRINTF (("Update state ==> %s", stateInfo_unparse (snew))); + return snew; } +} - return old; +/*@only@*/ stateInfo +stateInfo_updateRefLoc (/*@only@*/ stateInfo old, /*@exposed@*/ sRef ref, + stateAction action, fileloc loc) +{ + if (fileloc_isUndefined (loc)) { + loc = fileloc_copy (g_currentloc); + } + + if (old != NULL && fileloc_equal (old->loc, loc) + && old->action == action + /*@-abstractcompare*/ && old->ref == ref /*@=abstractcompare@*/) + { + /* + ** Duplicate (change through alias most likely) + ** don't add this info + */ + + return old; + } + else + { + stateInfo snew = stateInfo_makeRefLoc (ref, loc, action); + llassert (snew->previous == NULL); + snew->previous = old; + DPRINTF (("Update state ==> %s", stateInfo_unparse (snew))); + return snew; + } } /*@only@*/ stateInfo stateInfo_copy (stateInfo a) @@ -102,6 +199,7 @@ void stateInfo_free (/*@only@*/ stateInfo a) ret->loc = fileloc_copy (a->loc); /*< should report bug without copy! >*/ ret->ref = a->ref; + ret->action = a->action; ret->previous = stateInfo_copy (a->previous); return ret; @@ -111,29 +209,42 @@ void stateInfo_free (/*@only@*/ stateInfo a) /*@only@*/ /*@notnull@*/ stateInfo stateInfo_currentLoc (void) { - return stateInfo_makeLoc (g_currentloc); + return stateInfo_makeLoc (g_currentloc, SA_DECLARED); } /*@only@*/ /*@notnull@*/ stateInfo -stateInfo_makeLoc (fileloc loc) +stateInfo_makeLoc (fileloc loc, stateAction action) { stateInfo ret = (stateInfo) dmalloc (sizeof (*ret)); - ret->loc = fileloc_copy (loc); /* don't need to copy! */ + if (fileloc_isUndefined (loc)) { + ret->loc = fileloc_copy (g_currentloc); + } else { + ret->loc = fileloc_copy (loc); + } + ret->ref = sRef_undefined; + ret->action = action; ret->previous = stateInfo_undefined; + DPRINTF (("Make loc ==> %s", stateInfo_unparse (ret))); return ret; } /*@only@*/ /*@notnull@*/ stateInfo -stateInfo_makeRefLoc (/*@exposed@*/ sRef ref, fileloc loc) +stateInfo_makeRefLoc (/*@exposed@*/ sRef ref, fileloc loc, stateAction action) /*@post:isnull result->previous@*/ { stateInfo ret = (stateInfo) dmalloc (sizeof (*ret)); - ret->loc = fileloc_copy (loc); + if (fileloc_isUndefined (loc)) { + ret->loc = fileloc_copy (g_currentloc); + } else { + ret->loc = fileloc_copy (loc); + } + ret->ref = ref; + ret->action = action; ret->previous = stateInfo_undefined; return ret; @@ -142,18 +253,19 @@ stateInfo_makeRefLoc (/*@exposed@*/ sRef ref, fileloc loc) /*@only@*/ cstring stateInfo_unparse (stateInfo s) { - if (stateInfo_isDefined (s) && fileloc_isDefined (s->loc)) - { - if (stateInfo_isDefined (s->previous)) { - return message ("%q; %q", fileloc_unparse (s->loc), stateInfo_unparse (s->previous)); - } else { - return fileloc_unparse (s->loc); - } - } - else - { - return cstring_makeLiteral (""); - } + cstring res = cstring_makeLiteral (""); + + while (stateInfo_isDefined (s)) { + res = message ("%q%q: ", res, fileloc_unparse (s->loc)); + if (sRef_isValid (s->ref)) { + res = message ("%q through alias %q ", res, sRef_unparse (s->ref)); + } + + res = message ("%q%s; ", res, stateAction_unparse (s->action)); + s = s->previous; + } + + return res; } fileloc stateInfo_getLoc (stateInfo info) @@ -166,18 +278,194 @@ fileloc stateInfo_getLoc (stateInfo info) return fileloc_undefined; } +stateAction stateAction_fromNState (nstate ns) +{ + switch (ns) + { + case NS_ERROR: + case NS_UNKNOWN: + return SA_UNKNOWN; + case NS_NOTNULL: + case NS_MNOTNULL: + return SA_BECOMESNONNULL; + case NS_RELNULL: + case NS_CONSTNULL: + return SA_DECLARED; + case NS_POSNULL: + return SA_BECOMESPOSSIBLYNULL; + case NS_DEFNULL: + return SA_BECOMESNULL; + case NS_ABSNULL: + return SA_BECOMESPOSSIBLYNULL; + } +} + +stateAction stateAction_fromExkind (exkind ex) +{ + switch (ex) + { + case XO_UNKNOWN: + case XO_NORMAL: + return SA_UNKNOWN; + case XO_EXPOSED: + return SA_EXPOSED; + case XO_OBSERVER: + return SA_OBSERVER; + } + + BADBRANCH; + /*@notreached@*/ return SA_UNKNOWN; +} + +stateAction stateAction_fromAlkind (alkind ak) +{ + switch (ak) + { + case AK_UNKNOWN: + case AK_ERROR: + return SA_UNKNOWN; + case AK_ONLY: + return SA_ONLY; + case AK_IMPONLY: + return SA_IMPONLY; + case AK_KEEP: + return SA_KEEP; + case AK_KEPT: + return SA_KEPT; + case AK_TEMP: + return SA_TEMP; + case AK_IMPTEMP: + return SA_IMPTEMP; + case AK_SHARED: + return SA_SHARED; + case AK_UNIQUE: + case AK_RETURNED: + return SA_DECLARED; + case AK_FRESH: + return SA_FRESH; + case AK_STACK: + return SA_XSTACK; + case AK_REFCOUNTED: + return SA_REFCOUNTED; + case AK_REFS: + return SA_REFS; + case AK_KILLREF: + return SA_KILLREF; + case AK_NEWREF: + return SA_NEWREF; + case AK_OWNED: + return SA_OWNED; + case AK_DEPENDENT: + return SA_DEPENDENT; + case AK_IMPDEPENDENT: + return SA_IMPDEPENDENT; + case AK_STATIC: + return SA_STATIC; + case AK_LOCAL: + return SA_LOCAL; + } + + BADBRANCH; + /*@notreached@*/ return SA_UNKNOWN; +} + +stateAction stateAction_fromSState (sstate ss) +{ + switch (ss) + { + case SS_UNKNOWN: return SA_DECLARED; + case SS_UNUSEABLE: return SA_KILLED; + case SS_UNDEFINED: return SA_UNDEFINED; + case SS_MUNDEFINED: return SA_MUNDEFINED; + case SS_ALLOCATED: return SA_ALLOCATED; + case SS_PDEFINED: return SA_PDEFINED; + case SS_DEFINED: return SA_DEFINED; + case SS_PARTIAL: return SA_PDEFINED; + case SS_DEAD: return SA_RELEASED; + case SS_HOFFA: return SA_PKILLED; + case SS_SPECIAL: return SA_DECLARED; + case SS_RELDEF: return SA_DECLARED; + case SS_FIXED: + case SS_UNDEFGLOB: + case SS_KILLED: + case SS_UNDEFKILLED: + case SS_LAST: + llbug (message ("Unexpected sstate: %s", sstate_unparse (ss))); + /*@notreached@*/ return SA_UNKNOWN; + } +} + +static /*@observer@*/ cstring stateAction_unparse (stateAction sa) +{ + switch (sa) + { + case SA_UNKNOWN: return cstring_makeLiteralTemp ("changed "); + case SA_CHANGED: return cstring_makeLiteralTemp ("changed"); + + case SA_CREATED: return cstring_makeLiteralTemp ("created"); + case SA_DECLARED: return cstring_makeLiteralTemp ("declared"); + case SA_DEFINED: return cstring_makeLiteralTemp ("defined"); + case SA_PDEFINED: return cstring_makeLiteralTemp ("partially defined"); + case SA_RELEASED: return cstring_makeLiteralTemp ("released"); + case SA_ALLOCATED: return cstring_makeLiteralTemp ("allocated"); + case SA_KILLED: return cstring_makeLiteralTemp ("released"); + case SA_PKILLED: return cstring_makeLiteralTemp ("possibly released"); + case SA_MERGED: return cstring_makeLiteralTemp ("merged"); + case SA_UNDEFINED: return cstring_makeLiteralTemp ("becomes undefined"); + case SA_MUNDEFINED: return cstring_makeLiteralTemp ("possibly undefined"); + + case SA_SHARED: return cstring_makeLiteralTemp ("becomes shared"); + case SA_ONLY: return cstring_makeLiteralTemp ("becomes only"); + case SA_IMPONLY: return cstring_makeLiteralTemp ("becomes implicitly only"); + case SA_OWNED: return cstring_makeLiteralTemp ("becomes owned"); + case SA_DEPENDENT: return cstring_makeLiteralTemp ("becomes dependent"); + case SA_IMPDEPENDENT: return cstring_makeLiteralTemp ("becomes implicitly dependent"); + case SA_KEPT: return cstring_makeLiteralTemp ("becomes kept"); + case SA_KEEP: return cstring_makeLiteralTemp ("becomes keep"); + case SA_FRESH: return cstring_makeLiteralTemp ("becomes fresh"); + case SA_TEMP: return cstring_makeLiteralTemp ("becomes temp"); + case SA_IMPTEMP: return cstring_makeLiteralTemp ("becomes implicitly temp"); + case SA_XSTACK: return cstring_makeLiteralTemp ("becomes stack-allocated storage"); + case SA_STATIC: return cstring_makeLiteralTemp ("becomes static"); + case SA_LOCAL: return cstring_makeLiteralTemp ("becomes local"); + + case SA_REFCOUNTED: return cstring_makeLiteralTemp ("becomes refcounted"); + case SA_REFS: return cstring_makeLiteralTemp ("becomes refs"); + case SA_NEWREF: return cstring_makeLiteralTemp ("becomes newref"); + case SA_KILLREF: return cstring_makeLiteralTemp ("becomes killref"); + + case SA_OBSERVER: return cstring_makeLiteralTemp ("becomes observer"); + case SA_EXPOSED: return cstring_makeLiteralTemp ("becomes exposed"); + + case SA_BECOMESNULL: return cstring_makeLiteralTemp ("becomes null"); + case SA_BECOMESNONNULL: return cstring_makeLiteralTemp ("becomes non-null"); + case SA_BECOMESPOSSIBLYNULL: return cstring_makeLiteralTemp ("becomes possibly null"); + } + + DPRINTF (("Bad state action: %d", sa)); + BADBRANCH; +} + void stateInfo_display (stateInfo s, cstring sname) { + bool showdeep = context_flagOn (FLG_SHOWDEEPHISTORY, g_currentloc); + + s = stateInfo_sort (s); + while (stateInfo_isDefined (s)) { - cstring msg = message ("Storage %s ", sname); - + cstring msg = message ("%s%s", sname, stateAction_unparse (s->action)); + if (sRef_isValid (s->ref)) { - msg = message ("%q through alias %q ", msg, sRef_unparse (s->ref)); + msg = message ("%q (through alias %q)", msg, sRef_unparse (s->ref)); } - - msg = message ("%qreleased", msg); /* For now, just used for release...need to make this work. */ + llgenindentmsg (msg, s->loc); + + if (!showdeep) { + break; + } + s = s->previous; } diff --git a/src/stateValue.c b/src/stateValue.c index aacffde..61ea45b 100644 --- a/src/stateValue.c +++ b/src/stateValue.c @@ -101,10 +101,7 @@ void stateValue_updateValueLoc (stateValue s, int value, fileloc loc) fileloc_unparse (loc))); s->value = value; - - if (fileloc_isDefined (loc)) { - s->info = stateInfo_updateLoc (s->info, loc); - } + s->info = stateInfo_updateLoc (s->info, SA_CHANGED, loc); } void stateValue_update (stateValue res, stateValue val) diff --git a/src/uentry.c b/src/uentry.c index 855a770..669b6cf 100644 --- a/src/uentry.c +++ b/src/uentry.c @@ -3072,7 +3072,7 @@ uentry_isSpecialFunction (uentry ue) ctype ct = idDecl_getCtype (t); ctype base = ct; fileloc loc = setLocation (); - sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc)); + sRef pref = sRef_makeParam (i, ct, stateInfo_makeLoc (loc, SA_CREATED)); uentry ue = uentry_makeVariableSrefParam (idDecl_observeId (t), ct, loc, pref); DPRINTF (("Make param: %s", uentry_unparseFull (ue))); @@ -10060,20 +10060,43 @@ branchStateError (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, sRef_stateAltVerb (res->sref), clause_nameFlip (cl, !flip)), loc)) { + DPRINTF (("Here: %s / %s", sRef_unparseFull (res->sref), sRef_unparseFull (other->sref))); + if (sRef_isDead (res->sref)) { - sRef_showStateInfo (res->sref); - sRef_showStateInfo (other->sref); + if (sRef_hasStateInfoLoc (res->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc); + sRef_showStateInfo (res->sref); + } + + if (sRef_hasStateInfoLoc (other->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc); + sRef_showStateInfo (other->sref); + } } else if (sRef_isKept (res->sref)) { - sRef_showAliasInfo (res->sref); - sRef_showAliasInfo (other->sref); + if (sRef_hasAliasInfoLoc (res->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc); + sRef_showAliasInfo (res->sref); + } + + if (sRef_hasAliasInfoLoc (other->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc); + sRef_showAliasInfo (other->sref); + } } else /* dependent */ { - sRef_showAliasInfo (res->sref); - sRef_showAliasInfo (other->sref); + if (sRef_hasAliasInfoLoc (res->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc); + sRef_showAliasInfo (res->sref); + } + + if (sRef_hasAliasInfoLoc (other->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc); + sRef_showAliasInfo (other->sref); + } } sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined); @@ -10114,11 +10137,27 @@ static void { if (sRef_isDead (other->sref)) { - sRef_showStateInfo (other->sref); + if (sRef_hasStateInfoLoc (other->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc); + sRef_showStateInfo (other->sref); + } + + if (sRef_hasStateInfoLoc (res->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc); + sRef_showStateInfo (res->sref); + } } else /* kept */ { - sRef_showAliasInfo (other->sref); + if (sRef_hasAliasInfoLoc (other->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, flip)), loc); + sRef_showAliasInfo (other->sref); + } + + if (sRef_hasAliasInfoLoc (res->sref)) { + llgenindentmsg (message ("%s:", clause_nameFlip (cl, !flip)), loc); + sRef_showAliasInfo (res->sref); + } } sRef_setAliasKind (res->sref, AK_ERROR, fileloc_undefined); @@ -10210,7 +10249,7 @@ uentry_mergeAliasStates (/*@notnull@*/ uentry res, /*@notnull@*/ uentry other, } else { - branchStateError (res, other, flip, cl, loc); + branchStateError (res, other, !flip, cl, loc); /* evans 2002-12-15: changed flip to !flip */ } } } diff --git a/src/usymtab.c b/src/usymtab.c index a1f4a3a..555a1b9 100644 --- a/src/usymtab.c +++ b/src/usymtab.c @@ -529,9 +529,10 @@ usymtab_addEntryBase (/*@notnull@*/ usymtab s, /*@only@*/ uentry e) if (uentry_isVar (e)) { - uentry_setSref (e, sRef_makeCvar (globScope, thisentry, - uentry_getType (e), - stateInfo_makeLoc (uentry_whereLast (e)))); + uentry_setSref + (e, sRef_makeCvar (globScope, thisentry, + uentry_getType (e), + stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED))); } usymtab_addEntryQuiet (s, e); @@ -569,9 +570,10 @@ usymtab_addEntryAlways (/*@notnull@*/ usymtab s, /*@only@*/ uentry e) if (uentry_isVar (e) && !uentry_isGlobalMarker (e)) { - uentry_setSref (e, sRef_makeCvar (globScope, thisentry, - uentry_getType (e), - stateInfo_makeLoc (uentry_whereLast (e)))); + uentry_setSref + (e, sRef_makeCvar (globScope, thisentry, + uentry_getType (e), + stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED))); } usymtab_addEntryQuiet (s, e); @@ -612,7 +614,8 @@ usymtab_addEntryAux (/*@notnull@*/ usymtab st, /*@keep@*/ uentry e, bool isSref) if (uentry_isStatic (e)) { - sRef sr = sRef_makeCvar (st->lexlevel, thisentry, ct, stateInfo_makeLoc (uentry_whereLast (e))); + sRef sr = sRef_makeCvar (st->lexlevel, thisentry, ct, + stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED)); if (sRef_isStack (sr) || sRef_isLocalState (sr)) { @@ -624,7 +627,9 @@ usymtab_addEntryAux (/*@notnull@*/ usymtab st, /*@keep@*/ uentry e, bool isSref) } else { - uentry_setSref (e, sRef_makeCvar (st->lexlevel, thisentry, ct, stateInfo_makeLoc (uentry_whereLast (e)))); + uentry_setSref + (e, sRef_makeCvar (st->lexlevel, thisentry, ct, + stateInfo_makeLoc (uentry_whereLast (e), SA_DECLARED))); } } @@ -941,7 +946,9 @@ usymtab_supEntryAux (/*@notnull@*/ usymtab st, ct = ctype_getReturnType (ct); } - uentry_setSref (ce, sRef_makeCvar (st->lexlevel, eindex, ct, stateInfo_makeLoc (uentry_whereLast (ce)))); + uentry_setSref + (ce, sRef_makeCvar (st->lexlevel, eindex, ct, + stateInfo_makeLoc (uentry_whereLast (ce), SA_DECLARED))); } } else /* no previous entry */ diff --git a/test/Makefile.am b/test/Makefile.am index cff0f86..5dc3f99 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -631,9 +631,9 @@ nullassign: .PHONY: numabstract numabstract: - -$(SPLINTR) numabstract.c -expect 8 - -$(SPLINTR) numabstract.c +numabstractlit -expect 7 - -$(SPLINTR) numabstract.c -numabstractcast -expect 7 + -$(SPLINTR) numabstract.c -expect 11 + -$(SPLINTR) numabstract.c +numabstractlit -expect 9 + -$(SPLINTR) numabstract.c -numabstractcast -expect 10 # # Before 2.4, expected one more because error was reported both as diff --git a/test/Makefile.in b/test/Makefile.in index 2d5e2b6..e5b7ad8 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1392,11 +1392,12 @@ mystrncat: noeffect: ${SPLINTP} noeffect.c +allmacros +checks -expect 3 + .PHONY: numabstract numabstract: - -$(SPLINTR) numabstract.c -expect 8 - -$(SPLINTR) numabstract.c +numabstractlit -expect 7 - -$(SPLINTR) numabstract.c -numabstractcast -expect 7 + -$(SPLINTR) numabstract.c -expect 11 + -$(SPLINTR) numabstract.c +numabstractlit -expect 9 + -$(SPLINTR) numabstract.c -numabstractcast -expect 10 ### ### 2002-01-01: null1.c: expect increased to 15 because out must be defined diff --git a/test/alias.expect b/test/alias.expect index 6cbe10b..89df276 100644 --- a/test/alias.expect +++ b/test/alias.expect @@ -114,7 +114,7 @@ alias5.c:13:3: Possible undocumented modification of p->x through alias p2->x: p2->x++ alias5.c: (in function incx2) alias5.c:22:2: Fresh storage p2 not released before return - alias5.c:20:3: Fresh storage p2 allocated + alias5.c:20:3: Fresh storage p2 created alias5.c: (in function incx3) alias5.c:27:3: Only storage p2->x (type int *) not released before assignment: p2->x = p->x diff --git a/test/arraylit.expect b/test/arraylit.expect index 4dc7e25..dd21b08 100644 --- a/test/arraylit.expect +++ b/test/arraylit.expect @@ -4,6 +4,7 @@ arraylit.c:7:34: String literal with 6 characters is assigned to char [5] (no room for null terminator): "12345" arraylit.c:13:3: Suspect modification of observer unmodstr[0]: unmodstr[0] = 'U' + arraylit.c:5:24: Storage unmodstr[0] becomes observer Finished checking --- 2 code warnings, as expected @@ -16,5 +17,6 @@ arraylit.c:9:34: String literal with 6 characters is assigned to char [7] (possible waste of storage): "12345" arraylit.c:13:3: Suspect modification of observer unmodstr[0]: unmodstr[0] = 'U' + arraylit.c:5:24: Storage unmodstr[0] becomes observer Finished checking --- 4 code warnings, as expected diff --git a/test/cases.expect b/test/cases.expect index 3825245..2061b3e 100644 --- a/test/cases.expect +++ b/test/cases.expect @@ -11,22 +11,26 @@ Finished checking --- 5 code warnings, as expected cases2.c: (in function f2) cases2.c:26:5: Variable x is released in one possible execution, but live in other possible execution. - cases2.c:23:16: Storage x is released + cases2.c:26:5: in one possible execution: + cases2.c:23:16: Storage x released cases2.c: (in function f3) cases2.c:37:5: Variable x is released in one possible execution, but live in other possible execution. - cases2.c:36:16: Storage x is released + cases2.c:37:5: in one possible execution: + cases2.c:36:16: Storage x released Finished checking --- 2 code warnings, as expected cases2.c: (in function f2) cases2.c:26:5: Variable x is released in one possible execution, but live in other possible execution. - cases2.c:23:16: Storage x is released + cases2.c:26:5: in one possible execution: + cases2.c:23:16: Storage x released cases2.c: (in function f3) cases2.c:37:5: Variable x is released in one possible execution, but live in other possible execution. - cases2.c:36:16: Storage x is released + cases2.c:37:5: in one possible execution: + cases2.c:36:16: Storage x released cases2.c:1:24: Function g declared but not defined Finished checking --- 3 code warnings, as expected diff --git a/test/chararraylit.expect b/test/chararraylit.expect index ec76a4e..43dfab3 100644 --- a/test/chararraylit.expect +++ b/test/chararraylit.expect @@ -3,5 +3,6 @@ chararraylit.c: (in function f) chararraylit.c:8:16: String literal with 4 characters is assigned to char [3] (no room for null terminator): "abc" chararraylit.c:13:3: Suspect modification of observer p: *p = 'c' + chararraylit.c:9:13: Storage *p becomes observer Finished checking --- 2 code warnings, as expected diff --git a/test/clauses.expect b/test/clauses.expect index 3ef4575..b726830 100644 --- a/test/clauses.expect +++ b/test/clauses.expect @@ -1,16 +1,20 @@ clauses.c: (in function f) clauses.c:6:5: Variable x is released in true branch, but live in continuation. - clauses.c:5:13: Storage x is released + clauses.c:6:5: in true branch: + clauses.c:5:13: Storage x released clauses.c:11:5: Variable y is released in while body, but live if loop is not taken. - clauses.c:10:13: Storage y is released + clauses.c:11:5: in while body: + clauses.c:10:13: Storage y released clauses.c:20:5: Variable z2 is released in false branch, but live in true branch. - clauses.c:19:13: Storage z2 is released + clauses.c:20:5: in false branch: + clauses.c:19:13: Storage z2 released clauses.c:20:5: Variable z is released in true branch, but live in false branch. - clauses.c:15:13: Storage z is released + clauses.c:20:5: in true branch: + clauses.c:15:13: Storage z released Finished checking --- 4 code warnings, as expected @@ -18,10 +22,10 @@ Finished checking --- no warnings clauses3.c: (in function h) clauses3.c:48:5: Storage x->x is released in one path, but live in another. - clauses3.c:46:10: Storage x->x is released + clauses3.c:46:10: Storage x->x released clauses3.c: (in function m) clauses3.c:61:5: Storage x->x is released in one path, but live in another. - clauses3.c:60:13: Storage x->x is released + clauses3.c:60:13: Storage x->x released Finished checking --- 2 code warnings, as expected @@ -30,11 +34,11 @@ Command Line: Selecting unix library. Unix library is ad hoc addition to POSIX -warnunixlib to suppress this message. clauses3.c: (in function h) clauses3.c:48:5: Storage x->x is released in one path, but live in another. - clauses3.c:46:10: Storage x->x is released + clauses3.c:46:10: Storage x->x released clauses3.c: (in function m) clauses3.c:60:13: Possibly null storage x->x passed as non-null param: free (x->x) clauses3.c:61:5: Storage x->x is released in one path, but live in another. - clauses3.c:60:13: Storage x->x is released + clauses3.c:60:13: Storage x->x released Finished checking --- 3 code warnings, as expected diff --git a/test/compdestroy.expect b/test/compdestroy.expect index 6c0cdd2..9e05b62 100644 --- a/test/compdestroy.expect +++ b/test/compdestroy.expect @@ -17,7 +17,7 @@ Finished checking --- 2 code warnings, as expected compdestroy.c: (in function sip_free) compdestroy.c:16:13: Possibly dead storage x->ips[] passed as out parameter: x->ips[i] - compdestroy.c:15:13: Storage x->ips[] becomes probably dead + compdestroy.c:15:13: Storage x->ips[] possibly released compdestroy.c:19:9: Only storage x->ips[] (type oip) derived from released storage may not have been released: x->ips compdestroy.c: (in function sip_free2) @@ -29,7 +29,7 @@ Finished checking --- 3 code warnings, as expected compdestroy.c: (in function sip_free) compdestroy.c:16:13: Possibly dead storage x->ips[] passed as out parameter: x->ips[i] - compdestroy.c:15:13: Storage x->ips[] becomes probably dead + compdestroy.c:15:13: Storage x->ips[] possibly released compdestroy.c:19:9: Only storage x->ips[] (type oip) derived from released storage may not have been released: x->ips compdestroy.c: (in function sip_free2) diff --git a/test/db1.expect b/test/db1.expect index cf203e4..0132b0a 100644 --- a/test/db1.expect +++ b/test/db1.expect @@ -24,10 +24,6 @@ empset.c:135: Variable e declared but not used ereftab.c: (in function ereftab_lookup) ereftab.c:34: Undocumented modification of t possible from call to erc_iterStart: erc_iterStart(t) -erc.c: (in function erc_member) -erc.c:47: Operands of == are abstract type (eref): tmpc->val == er -erc.c: (in function erc_delete) -erc.c:78: Operands of == are abstract type (eref): elem->val == er erc.c: (in function erc_sprint) erc.c:141: Function malloc expects arg 1 to be size_t gets int: erc_size(c) * (employeePrintSize + 1) + 1 @@ -47,7 +43,7 @@ drive.c:118: Buffer overflow possible with sprintf. Recommend using snprintf instead: sprintf drive.c:123: Return value (type db_status) ignored: hire(e) -Finished checking --- 21 code warnings, as expected +Finished checking --- 19 code warnings, as expected employee.h:2: Name EMPLOYEE_H is reserved for future library extensions. Macros beginning with E and a digit or uppercase letter may be added to . @@ -278,14 +274,15 @@ erc.c:13: Argument to exit has implementation defined behavior: 1 erc.c:18: Null storage c->vals derivable from return value: c erc.c:16: Storage c->vals becomes null erc.c:18: Fresh storage returned as unqualified (should be only): c - erc.c:8: Fresh storage c allocated + erc.c:8: Fresh storage c created erc.c: (in function erc_clear) erc.c:34: Function returns with null storage derivable from parameter c->vals erc.c:32: Storage c->vals becomes null erc.c: (in function erc_final) erc.c:39: Implicitly temp storage c passed as only param: free (c) erc.c: (in function erc_member) -erc.c:47: Operands of == are abstract type (eref): tmpc->val == er +erc.c:47: Object equality comparison (==) on objects of abstract type (eref): + tmpc->val == er erc.c:47: Body of if statement is not a block: return TRUE erc.c:47: Body of for statement is not a block: if (tmpc->val == er) return TRUE @@ -293,26 +290,28 @@ erc.c: (in function erc_insert) erc.c:55: Parameter to sizeof is type ercElem: sizeof(ercElem) erc.c:60: Argument to exit has implementation defined behavior: 1 erc.c: (in function erc_delete) -erc.c:78: Operands of == are abstract type (eref): elem->val == er +erc.c:78: Object equality comparison (==) on objects of abstract type (eref): + elem->val == er erc.c:83: Implicitly only storage prev->next (type struct _elem *) not released before assignment: prev->next = elem->next erc.c:84: Clauses exit with elem referencing implicitly only storage in true branch, local storage in false branch - erc.c:81: Storage elem becomes implicitly only + erc.c:81: Storage elem becomes implicitly only (through alias c->vals) erc.c:87: Released storage c->vals reachable from parameter at return point - erc.c:85: Storage c->vals is released + erc.c:85: Storage c->vals released erc.c: (in function erc_iterStart) erc.c:98: Parameter to sizeof is type ercList: sizeof(ercList) erc.c:103: Argument to exit has implementation defined behavior: 1 erc.c:107: Fresh storage returned as unqualified (should be only): result - erc.c:98: Fresh storage result allocated + erc.c:98: Fresh storage result created erc.c:108: Suspect object listed in modifies of erc_iterStart not modified: c erc.lcl:49: Specification of erc_iterStart erc.c: (in function erc_yield) erc.c:117: Implicitly temp storage it passed as only param: free (it) erc.c:117: Unreachable code: free(it) erc.c:118: Variable it is released in true branch, but live in continuation. - erc.c:117: Storage it is released + erc.c:118: in true branch: + erc.c:117: Storage it released erc.c:121: Only storage *it->next assigned to unqualified: *(it) = (*it)->next erc.c: (in function erc_join) erc.c:130: Body of for statement is not a block: erc_insert(c1, tmpc->val); @@ -323,7 +322,7 @@ erc.c:146: Argument to exit has implementation defined behavior: 1 erc.c:151: Undocumented modification of c possible from call to erc_iterStart: erc_iterStart(c) erc.c:159: Fresh storage returned as unqualified (should be only): result - erc.c:140: Fresh storage result allocated + erc.c:140: Fresh storage result created erc.h: (in macro erc_choose) erc.h:15: Macro parameter used without parentheses: c erc.h: (in macro erc_initMod) @@ -630,7 +629,7 @@ compdef 3 0 incondefs 0 1 sizeoftype 7 0 formalarray 0 24 -abstract 2 0 +abstractcompare 2 0 mustfreeonly 3 0 usereleased 1 0 compdestroy 1 0 diff --git a/test/db1/Makefile b/test/db1/Makefile index 17a6756..024cee9 100644 --- a/test/db1/Makefile +++ b/test/db1/Makefile @@ -25,8 +25,10 @@ test: ### Removed +showscan, produces different results on different platforms ### +### evans 2002-12-17: 2 fewer weak errors because of -abstractcompare default in weak + check: $(LCSFILES) - -$(SPLINT) -showcol -weak $(MODULES) -expect 21 + -$(SPLINT) -showcol -weak $(MODULES) -expect 19 -$(SPLINT) -showcol +strict -modfilesystem +showsummary $(MODULES) -expect 338 # evans 2002-07-09: 5 bufferoverflowhigh warnings for using sprintf diff --git a/test/db2.expect b/test/db2.expect index 2817986..24a5672 100644 --- a/test/db2.expect +++ b/test/db2.expect @@ -16,19 +16,19 @@ eref.c:45: Storage eref_Pool.conts reachable from global is only (should be eref.c: (in function eref_initMod) eref.c:84: Storage eref_Pool.conts reachable from global is fresh (should be unqualified) - eref.c:62: Fresh storage eref_Pool.conts allocated + eref.c:62: Fresh storage eref_Pool.conts created eref.c:84: Global storage *(eref_Pool.conts) contains 5 undefined fields when call returns: ssNum, name, salary, gen, j eref.c:84: Storage eref_Pool.status reachable from global is fresh (should be unqualified) - eref.c:70: Fresh storage eref_Pool.status allocated + eref.c:70: Fresh storage eref_Pool.status created eref.c:84: Global storage eref_Pool contains 1 undefined field when call returns: status erc.c: (in function erc_create) erc.c:33: Null storage c->vals derivable from return value: c erc.c:31: Storage c->vals becomes null erc.c:33: Fresh storage returned as unqualified (should be only): c - erc.c:23: Fresh storage c allocated + erc.c:23: Fresh storage c created erc.c: (in function erc_clear) erc.c:49: Function returns with null storage derivable from parameter c->vals erc.c:47: Storage c->vals becomes null @@ -36,10 +36,10 @@ erc.c: (in function erc_final) erc.c:54: Implicitly temp storage c passed as only param: free (c) erc.c: (in function erc_delete) erc.c:102: Released storage c->vals reachable from parameter at return point - erc.c:100: Storage c->vals is released + erc.c:100: Storage c->vals released erc.c: (in function erc_sprint) erc.c:141: Fresh storage returned as unqualified (should be only): result - erc.c:122: Fresh storage result allocated + erc.c:122: Fresh storage result created Finished checking --- 15 code warnings, as expected @@ -59,7 +59,7 @@ eref.c:84: Global storage eref_Pool contains 1 undefined field when call returns: status empset.c: (in function empset_intersect) empset.c:126: Fresh storage toDelete not released before return - empset.c:112: Fresh storage toDelete allocated + empset.c:112: Fresh storage toDelete created erc.c: (in function erc_create) erc.c:33: Null storage c->vals derivable from return value: c erc.c:31: Storage c->vals becomes null @@ -73,9 +73,9 @@ erc.c:98: Implicitly only storage prev->next (type struct _elem *) not released before assignment: prev->next = elem->next erc.c:98: Clauses exit with elem referencing implicitly only storage in true branch, local storage in false branch - erc.c:96: Storage elem becomes implicitly only + erc.c:96: Storage elem becomes implicitly only (through alias c->vals) erc.c:102: Released storage c->vals reachable from parameter at return point - erc.c:100: Storage c->vals is released + erc.c:100: Storage c->vals released drive.c: (in function main) drive.c:49: Variable m_res name is not a macro variable (it is a local variable), but matches the macro variable namespace prefix "m_" @@ -91,21 +91,21 @@ drive.c:135: Variable m_res name is not a macro variable (it is a local variable), but matches the macro variable namespace prefix "m_" drive.c:140: Fresh storage em1 (type empset) not released before assignment: em1 = empset_create() - drive.c:35: Fresh storage em1 allocated + drive.c:35: Fresh storage em1 created drive.c:146: Fresh storage em2 (type empset) not released before assignment: em2 = empset_create() - drive.c:74: Fresh storage em2 allocated + drive.c:74: Fresh storage em2 created drive.c:147: Fresh storage em3 (type empset) not released before assignment: em3 = empset_disjointUnion(em2, em1) - drive.c:87: Fresh storage em3 allocated + drive.c:87: Fresh storage em3 created drive.c:159: Variable m_res name is not a macro variable (it is a local variable), but matches the macro variable namespace prefix "m_" drive.c:163: Fresh storage em1 not released before return - drive.c:140: Fresh storage em1 allocated + drive.c:140: Fresh storage em1 created drive.c:163: Fresh storage em2 not released before return - drive.c:146: Fresh storage em2 allocated + drive.c:146: Fresh storage em2 created drive.c:163: Fresh storage em3 not released before return - drive.c:147: Fresh storage em3 allocated + drive.c:147: Fresh storage em3 created Finished checking --- 25 code warnings, as expected diff --git a/test/deadparam.expect b/test/deadparam.expect index f8e8db5..0f78439 100644 --- a/test/deadparam.expect +++ b/test/deadparam.expect @@ -1,9 +1,9 @@ deadparam.c: (in function t) deadparam.c:7:6: Dead storage s1 passed as out parameter to f: s1 - deadparam.c:6:9: Storage s1 is released + deadparam.c:6:9: Storage s1 released deadparam.c:10:6: Dead storage s2 passed as special parameter to g: s2 - deadparam.c:9:9: Storage s2 is released + deadparam.c:9:9: Storage s2 released deadparam.c:10:6: Allocated storage s2 corresponds to storage listed in allocates clause of called function: s2 diff --git a/test/fields.expect b/test/fields.expect index 5975e12..2f7135d 100644 --- a/test/fields.expect +++ b/test/fields.expect @@ -2,10 +2,10 @@ fields.c: (in function pair_create1) fields.c:37:10: Storage p->z reachable from return value is owned (should be dependent) - fields.c:34:3: Storage p->z becomes owned + fields.c:34:3: Storage p->z becomes owned (through alias p->y) fields.c: (in function mangle) fields.c:43:2: Released storage p->x reachable from parameter at return point - fields.c:42:9: Storage p->x is released + fields.c:42:9: Storage p->x released fields.c: (in function mangle2) fields.c:49:2: Storage p->y reachable from parameter is dependent (should be owned) diff --git a/test/keep.expect b/test/keep.expect index 7020421..bc0545d 100644 --- a/test/keep.expect +++ b/test/keep.expect @@ -10,7 +10,10 @@ keep.c:36:10: Keep storage x not transferred before return keep.c:34:39: Storage x becomes keep keep.c: (in function f6) keep.c:44:5: Variable x is kept in true branch, but not kept in continuation. + keep.c:44:5: in true branch: keep.c:43:11: Storage x becomes kept + keep.c:44:5: in continuation: + keep.c:39:26: Storage x becomes keep keep.c:46:7: Kept storage x passed as keep param: f2 (x) keep.c:44:5: Storage x becomes kept keep.c: (in function f7) diff --git a/test/linked.expect b/test/linked.expect index 3abc4e6..5cf80f3 100644 --- a/test/linked.expect +++ b/test/linked.expect @@ -20,7 +20,7 @@ linked2.c:23:15: Possibly null storage nn passed as non-null param: node_free1 (nn) linked2.c:21:13: Storage nn may become null linked2.c:23:15: Dependent storage nn passed as only param: node_free1 (nn) - linked2.c:23:15: Storage nn becomes dependent + linked2.c:23:15: Storage nn becomes dependent (through alias n->next) Finished checking --- 3 code warnings, as expected diff --git a/test/list.expect b/test/list.expect index 4804e29..b8f57d8 100644 --- a/test/list.expect +++ b/test/list.expect @@ -1,7 +1,10 @@ list.c: (in function list_addh) list.c:24:5: Variable e is kept in true branch, but not kept in continuation. + list.c:24:5: in true branch: list.c:23:7: Storage e becomes kept + list.c:24:5: in continuation: + list.c:12:22: Storage e becomes only list.c:25:2: Storage *(l->next) reachable from parameter contains 1 undefined field: next list.c: (in function list_addh2) diff --git a/test/manual.expect b/test/manual.expect index 9b96ad9..e5471d8 100644 --- a/test/manual.expect +++ b/test/manual.expect @@ -1,7 +1,7 @@ sample.c:11: Fresh storage x not released before return - sample.c:5: Fresh storage x allocated + sample.c:5: Fresh storage x created sample.c:5: Variable x declared but not used Finished checking --- 2 code warnings, as expected @@ -63,7 +63,7 @@ only.c:13: Variable x used after being released only.c:14: Implicitly temp storage z returned as only: z only.c:14: Fresh storage m not released before return - only.c:9: Fresh storage m allocated + only.c:9: Fresh storage m created Finished checking --- 6 code warnings, as expected @@ -71,10 +71,12 @@ stack.c:12: Stack-allocated storage &loc reachable from return value: &loc stack.c:12: Stack-allocated storage *x reachable from parameter x - stack.c:10: Storage *x becomes stack + stack.c:10: Storage *x becomes stack-allocated + storage stack.c:12: Stack-allocated storage glob reachable from global glob - stack.c:9: Storage glob becomes stack + stack.c:9: Storage glob becomes stack-allocated + storage Finished checking --- 3 code warnings, as expected @@ -95,9 +97,10 @@ exposure.c:6: Return value exposes rep of employee: e->name exposure.c:6: Released storage e->name reachable from parameter at return point - exposure.c:6: Storage e->name is released + exposure.c:6: Storage e->name released exposure.c:23: Suspect modification of observer name: *name = toupper(*name) + exposure.c:22: Storage *name becomes observer Finished checking --- 4 code warnings, as expected diff --git a/test/mystrncat.expect b/test/mystrncat.expect index 065c32c..66dc82c 100644 --- a/test/mystrncat.expect +++ b/test/mystrncat.expect @@ -4,6 +4,7 @@ mystrncat.c:12:13: Passed storage buffer not completely defined (*buffer is undefined): mystrncat (buffer, ...) mystrncat.c:13:13: Passed storage b not completely defined (*b is undefined): mystrncat (b, ...) + mystrncat.c:10:3: Storage *b allocated mystrncat.c:12:3: Possible out-of-bounds store: mystrncat(buffer, str, sizeof((buffer)) - 1) Unable to resolve constraint: diff --git a/test/null.expect b/test/null.expect index 821bbae..e621ac2 100644 --- a/test/null.expect +++ b/test/null.expect @@ -6,12 +6,13 @@ null1.c:19:20: Implicitly temp storage x returned as only: x null1.c:19:20: Possibly null storage x returned as non-null: x null1.c:10:35: Storage x may become null null1.c:19:22: Fresh storage y not released before return - null1.c:12:41: Fresh storage y allocated + null1.c:12:41: Fresh storage y created null1.c:31:4: Dereference of possibly null pointer y: *y null1.c:12:12: Storage y may become null null1.c:34:5: Possibly null storage z passed as non-null param: g (z) null1.c:25:7: Storage z may become null null1.c:34:5: Passed storage z not completely defined (*z is undefined): g (z) + null1.c:25:3: Storage *z allocated null1.c:39:14: Dereference of null pointer z: *z null1.c:25:7: Storage z becomes null null1.c:43:22: Dereference of possibly null pointer z4: *z4 @@ -27,17 +28,18 @@ null1.c:59:23: Dereference of possibly null pointer z5: *z5 null1.c:67:10: Possibly null storage z returned as non-null: z null1.c:25:7: Storage z may become null null1.c:67:12: Fresh storage z3 not released before return - null1.c:27:3: Fresh storage z3 allocated + null1.c:27:3: Fresh storage z3 created Finished checking --- 15 code warnings, as expected null1.c: (in function f) null1.c:19:20: Implicitly temp storage x returned as only: x null1.c:19:22: Fresh storage y not released before return - null1.c:12:41: Fresh storage y allocated + null1.c:12:41: Fresh storage y created null1.c:34:5: Passed storage z not completely defined (*z is undefined): g (z) + null1.c:25:3: Storage *z allocated null1.c:67:12: Fresh storage z3 not released before return - null1.c:27:3: Fresh storage z3 allocated + null1.c:27:3: Fresh storage z3 created Finished checking --- 4 code warnings, as expected @@ -81,14 +83,16 @@ null3.c:53:3: Only storage gip (type int *) not released before assignment (z null3.c:5:17: Storage gip becomes only null3.c:55:3: Only storage gnip (type nip) not released before assignment: gnip = aip - null3.c:53:3: Storage gnip becomes only + ??? null3.c:53:3: Storage gnip becomes kept [[[ look into this one, seems odd ]]] null3.c:60:14: Returned storage y not completely defined (*y is undefined): y + null3.c:24:42: Storage *y allocated null3.c:60:16: Function returns with non-null global gip referencing null storage null3.c:53:9: Storage gip may become null null3.c:65:14: Possibly null storage y returned as non-null: y null3.c:24:12: Storage y may become null null3.c:65:14: Returned storage y not completely defined (*y is undefined): y + null3.c:24:42: Storage *y allocated null3.c:65:16: Function returns with non-null global gip referencing null storage null3.c:53:9: Storage gip may become null @@ -119,14 +123,16 @@ null3.c:53:3: Only storage gip (type int *) not released before assignment (z null3.c:5:17: Storage gip becomes only null3.c:55:3: Only storage gnip (type nip) not released before assignment: gnip = aip - null3.c:53:3: Storage gnip becomes only + null3.c:53:3: Storage gnip becomes kept null3.c:60:14: Returned storage y not completely defined (*y is undefined): y + null3.c:24:42: Storage *y allocated null3.c:60:16: Function returns with non-null global gip referencing null storage null3.c:53:9: Storage gip may become null null3.c:65:14: Possibly null storage y returned as non-null: y null3.c:24:12: Storage y may become null null3.c:65:14: Returned storage y not completely defined (*y is undefined): y + null3.c:24:42: Storage *y allocated null3.c:65:16: Function returns with non-null global gip referencing null storage null3.c:53:9: Storage gip may become null diff --git a/test/numabstract.c b/test/numabstract.c index be3a008..1345a2f 100644 --- a/test/numabstract.c +++ b/test/numabstract.c @@ -9,10 +9,10 @@ int adding (apples a, oranges o) int i; apples a2; a++; /* Okay */ - a2 = 13; /* error (unless -numabstractlit) ? */ + a2 = 13; /* error (unless +numabstractlit) ? */ a2 = 'a'; /* error */ i = 'c'; /* error */ - a2 = (apples) 13; /* unless +numabstractcast */ + a2 = (apples) 13; /* warning if +numabstractcast */ a2 = a + 5; /* okay */ a2 = o; /* error */ a2 = a2 - a; /* okay */ @@ -20,3 +20,30 @@ int adding (apples a, oranges o) i = a2 + a; /* error */ return a + o; /* error */ } + +int comparing (apples a, oranges o, apples a2) +{ + if (a < 3) { /* error unless +numabstractlit */ + return 3; + } + + if (a < o) { /* error */ + return 5; + } + + if (a == o) { /* error */ + return 6; + } + + if (a == a2) { /* okay */ + return 23; + } + + --a2; + + if (a >= a2) { + return 523; + } + + return 7; +} diff --git a/test/numabstract.expect b/test/numabstract.expect index fa798de..05ace97 100644 --- a/test/numabstract.expect +++ b/test/numabstract.expect @@ -9,8 +9,14 @@ numabstract.c:19:3: Assignment of oranges to int: i = o numabstract.c:20:3: Assignment of apples to int: i = a2 + a numabstract.c:21:10: Operands of + are different numabstract types (apples, oranges): a + o +numabstract.c: (in function comparing) +numabstract.c:26:7: Operands of < have incompatible types (apples, int): a < 3 +numabstract.c:30:7: Operands of < are different numabstract types (apples, + oranges): a < o +numabstract.c:34:7: Operands of == are different numabstract types (apples, + oranges): a == o -Finished checking --- 8 code warnings, as expected +Finished checking --- 11 code warnings, as expected numabstract.c: (in function adding) numabstract.c:13:3: Assignment of char to apples: a2 = 'a' @@ -21,8 +27,13 @@ numabstract.c:19:3: Assignment of oranges to int: i = o numabstract.c:20:3: Assignment of apples to int: i = a2 + a numabstract.c:21:10: Operands of + are different numabstract types (apples, oranges): a + o +numabstract.c: (in function comparing) +numabstract.c:30:7: Operands of < are different numabstract types (apples, + oranges): a < o +numabstract.c:34:7: Operands of == are different numabstract types (apples, + oranges): a == o -Finished checking --- 7 code warnings, as expected +Finished checking --- 9 code warnings, as expected numabstract.c: (in function adding) numabstract.c:13:3: Assignment of char to apples: a2 = 'a' @@ -33,5 +44,11 @@ numabstract.c:19:3: Assignment of oranges to int: i = o numabstract.c:20:3: Assignment of apples to int: i = a2 + a numabstract.c:21:10: Operands of + are different numabstract types (apples, oranges): a + o +numabstract.c: (in function comparing) +numabstract.c:26:7: Operands of < have incompatible types (apples, int): a < 3 +numabstract.c:30:7: Operands of < are different numabstract types (apples, + oranges): a < o +numabstract.c:34:7: Operands of == are different numabstract types (apples, + oranges): a == o -Finished checking --- 7 code warnings, as expected +Finished checking --- 10 code warnings, as expected diff --git a/test/observer.expect b/test/observer.expect index 571cd93..9a96e8b 100644 --- a/test/observer.expect +++ b/test/observer.expect @@ -4,9 +4,10 @@ observer.c:9:10: Function returns reference to parameter x: (x->name) observer.c:9:10: Return value exposes rep of stx: (x->name) observer.c:9:20: Released storage x->name reachable from parameter at return point - observer.c:9:10: Storage x->name is released + observer.c:9:10: Storage x->name released observer.c: (in function f) observer.c:33:3: Suspect modification of observer s: *s = 'x' + observer.c:32:7: Storage *s becomes observer observer.c:34:9: Function call may modify observer s: s observer.c:32:7: Storage s becomes observer observer.c:34:9: Observer storage s passed as only param: free (s) @@ -14,6 +15,7 @@ observer.c:34:9: Observer storage s passed as only param: free (s) observer.c:38:9: Exposed storage s passed as only param: free (s) observer.c:36:3: Storage s becomes exposed observer.c:41:10: Observer storage *s reachable from unqualified return value + observer.c:40:7: Storage *s becomes observer observer.c:41:10: Observer storage s returned without qualification: s observer.c:40:7: Storage s becomes observer @@ -23,9 +25,10 @@ observer.c: (in function stx_name) observer.c:9:10: Function returns reference to parameter x: (x->name) observer.c:9:20: Released storage x->name reachable from parameter at return point - observer.c:9:10: Storage x->name is released + observer.c:9:10: Storage x->name released observer.c: (in function f) observer.c:33:3: Suspect modification of observer s: *s = 'x' + observer.c:32:7: Storage *s becomes observer observer.c:34:9: Function call may modify observer s: s observer.c:32:7: Storage s becomes observer observer.c:34:9: Observer storage s passed as only param: free (s) @@ -33,6 +36,7 @@ observer.c:34:9: Observer storage s passed as only param: free (s) observer.c:38:9: Exposed storage s passed as only param: free (s) observer.c:36:3: Storage s becomes exposed observer.c:41:10: Observer storage *s reachable from unqualified return value + observer.c:40:7: Storage *s becomes observer observer.c:41:10: Observer storage s returned without qualification: s observer.c:40:7: Storage s becomes observer @@ -41,9 +45,10 @@ Finished checking --- 8 code warnings, as expected observer.c: (in function stx_name) observer.c:9:20: Released storage x->name reachable from parameter at return point - observer.c:9:10: Storage x->name is released + observer.c:9:10: Storage x->name released observer.c: (in function f) observer.c:33:3: Suspect modification of observer s: *s = 'x' + observer.c:32:7: Storage *s becomes observer observer.c:34:9: Function call may modify observer s: s observer.c:32:7: Storage s becomes observer observer.c:34:9: Observer storage s passed as only param: free (s) @@ -51,6 +56,7 @@ observer.c:34:9: Observer storage s passed as only param: free (s) observer.c:38:9: Exposed storage s passed as only param: free (s) observer.c:36:3: Storage s becomes exposed observer.c:41:10: Observer storage *s reachable from unqualified return value + observer.c:40:7: Storage *s becomes observer observer.c:41:10: Observer storage s returned without qualification: s observer.c:40:7: Storage s becomes observer diff --git a/test/outglob.expect b/test/outglob.expect index d63b95d..e9ae294 100644 --- a/test/outglob.expect +++ b/test/outglob.expect @@ -11,10 +11,10 @@ outglob.c:21:10: Undef global x1 used before definition outglob.c:22:10: Global x2 used by function undefined before call: g outglob.c:27:10: Undef global x3 used before definition outglob.c:37:14: Function returns with global x3 undefined - outglob.lcl:3: Storage x3 becomes undefined + outglob.c:5:20: Storage x3 defined [[[ error - look into this ]]] outglob.c:41:13: Function returns with global x2 undefined - outglob.lcl:3: Storage x2 becomes undefined + outglob.c:1:12: Storage x2 defined outglob.c:41:13: Function returns with global x3 undefined - outglob.lcl:3: Storage x3 becomes undefined + outglob.c:5:20: Storage x3 defined Finished checking --- 10 code warnings, as expected diff --git a/test/outparam.expect b/test/outparam.expect index 1b9334b..6ffb831 100644 --- a/test/outparam.expect +++ b/test/outparam.expect @@ -15,6 +15,6 @@ outparam.c:44:3: Variable t3 used before definition outparam.c:47:5: Arrow access from possibly null pointer t4: t4->a outparam.c:46:8: Storage t4 may become null outparam.c:48:13: Fresh storage t4 not released before return - outparam.c:46:3: Fresh storage t4 allocated + outparam.c:46:3: Fresh storage t4 created Finished checking --- 12 code warnings, as expected diff --git a/test/refcounts.expect b/test/refcounts.expect index 662988a..2711f2f 100644 --- a/test/refcounts.expect +++ b/test/refcounts.expect @@ -6,7 +6,7 @@ refcounts.c:24:10: New reference returned as temp reference: rp_create2() refcounts.c: (in function rp_f) refcounts.c:32:3: Kill reference parameter r2 (type rp) not released before assignment: r2 = rp_temp() - refcounts.c:27:50: Storage r2 becomes newref + refcounts.c:27:50: Storage r2 becomes killref refcounts.c: (in function rp_ref) refcounts.c:48:10: Reference counted storage returned without modifying reference count: x diff --git a/test/repexpose.expect b/test/repexpose.expect index 41ce332..151535f 100644 --- a/test/repexpose.expect +++ b/test/repexpose.expect @@ -19,7 +19,7 @@ repexpose.c:19:12: Storage *globstring reachable from global is kept (should be repexpose.c: (in function abst_name) repexpose.c:26:18: Released storage a->name reachable from parameter at return point - repexpose.c:26:10: Storage a->name is released + repexpose.c:26:10: Storage a->name released repexpose.c: (in function abst_parent) repexpose.c:45:15: Dependent storage b->parent returned as only: b->parent repexpose.c:45:25: Only storage a not released before return @@ -52,7 +52,7 @@ repexpose.c: (in function abst_name) repexpose.c:26:10: Function returns reference to parameter a: a->name repexpose.c:26:18: Released storage a->name reachable from parameter at return point - repexpose.c:26:10: Storage a->name is released + repexpose.c:26:10: Storage a->name released repexpose.c: (in function abst_aval) repexpose.c:37:10: Function returns reference to parameter a: (&(a->val)) repexpose.c: (in function abst_parent) @@ -102,7 +102,7 @@ repexpose.c:26:10: Function returns reference to parameter a: a->name repexpose.c:26:10: Return value exposes rep of abst: a->name repexpose.c:26:18: Released storage a->name reachable from parameter at return point - repexpose.c:26:10: Storage a->name is released + repexpose.c:26:10: Storage a->name released repexpose.c: (in function abst_aval) repexpose.c:37:10: Function returns reference to parameter a: (&(a->val)) repexpose.c:37:10: Return value exposes rep of abst: (&(a->val)) diff --git a/test/sharing.expect b/test/sharing.expect index eb82955..ece9000 100644 --- a/test/sharing.expect +++ b/test/sharing.expect @@ -28,6 +28,7 @@ sharing1.c:48:14: Possibly null storage y3 passed as non-null param: sharing1.c:37:13: Storage y3 may become null sharing1.c:48:14: Passed storage y3 not completely defined (*y3 is undefined): f2 (y3, ...) + sharing1.c:37:33: Storage *y3 allocated sharing1.c:48:18: Parameter 2 (y3) to function f2 is declared only but is aliased by parameter 1 (y3) sharing1.c:50:4: Variable y3 used after being released @@ -36,6 +37,7 @@ sharing1.c:51:12: Possibly null storage y passed as non-null param: f (y, ...) sharing1.c:35:12: Storage y may become null sharing1.c:51:12: Passed storage y not completely defined (*y is undefined): f (y, ...) + sharing1.c:35:32: Storage *y allocated sharing1.c:52:12: Shared storage globshared1 passed as only param: f (globshared1, ...) sharing1.c:4:19: Storage globshared1 becomes shared @@ -45,10 +47,10 @@ sharing1.c:56:9: Shared storage globshared2 passed as only param: sharing1.c:59:11: Variable y used after being released sharing1.c:51:12: Storage y released sharing1.c:59:13: Fresh storage y2 not released before return - sharing1.c:36:33: Fresh storage y2 allocated + sharing1.c:36:33: Fresh storage y2 created sharing1.c:59:13: Function returns with global globonly referencing released storage - sharing1.c:57:9: Storage globonly is released + sharing1.c:57:9: Storage globonly released Finished checking --- 21 code warnings, as expected @@ -58,7 +60,7 @@ sharing3.c: (in function string_free1) sharing3.c:32:9: Implicitly temp storage s passed as only param: free (s) sharing3.c: (in function string_free3) sharing3.c:45:2: Fresh storage t not released before return - sharing3.c:42:29: Fresh storage t allocated + sharing3.c:42:29: Fresh storage t created Finished checking --- 3 code warnings, as expected @@ -95,7 +97,7 @@ sharing4.c:42:12: Only storage only3 not released before return sharing4.c:12:72: Storage only3 becomes only sharing4.c:42:12: Function returns with global globonly3 referencing released storage - sharing4.c:21:9: Storage globonly3 is released + sharing4.c:21:9: Storage globonly3 released Finished checking --- 13 code warnings, as expected @@ -130,7 +132,7 @@ sharing4.c:42:12: Only storage only3 not released before return sharing4.c:12:72: Storage only3 becomes only sharing4.c:42:12: Function returns with global globonly3 referencing released storage - sharing4.c:21:9: Storage globonly3 is released + sharing4.c:21:9: Storage globonly3 released Finished checking --- 12 code warnings, as expected @@ -147,7 +149,7 @@ sharing5.c:27:4: Dereference of possibly null pointer localp: *localp sharing5.c:26:12: Storage localp may become null sharing5.c:32:3: Fresh storage localp (type char **) not released before assignment: localp = &only3 - sharing5.c:26:3: Fresh storage localp allocated + sharing5.c:26:3: Fresh storage localp created sharing5.c:33:2: Only storage only3 not released before return sharing5.c:4:73: Storage only3 becomes only diff --git a/test/stack.expect b/test/stack.expect index df2f771..da3b44b 100644 --- a/test/stack.expect +++ b/test/stack.expect @@ -1,9 +1,9 @@ stack.c: (in function stack1) stack.c:10:2: Stack-allocated storage *x reachable from parameter x - stack.c:9:3: Storage *x becomes stack + stack.c:9:3: Storage *x becomes stack-allocated storage stack.c:10:2: Stack-allocated storage glob reachable from global glob - stack.c:8:3: Storage glob becomes stack + stack.c:8:3: Storage glob becomes stack-allocated storage stack.c: (in function f) stack.c:20:14: Stack-allocated storage &x reachable from return value: &x stack.c:31:11: Stack-allocated storage sa reachable from return value: sa diff --git a/test/strchr.expect b/test/strchr.expect index 0b3b813..092ab78 100644 --- a/test/strchr.expect +++ b/test/strchr.expect @@ -1,7 +1,8 @@ strchr.c: (in function func) -strchr.c:6:4: Dereference of possibly null pointer c: *c - strchr.c:5:7: Storage c may become null -strchr.c:6:3: Suspect modification of observer c: *c = 'd' +strchr.c:5:4: Dereference of possibly null pointer c: *c + strchr.c:4:7: Storage c may become null +strchr.c:5:3: Suspect modification of observer c: *c = 'd' + strchr.c:4:7: Storage *c becomes observer Finished checking --- 2 code warnings, as expected diff --git a/test/strchr/.splintrc b/test/strchr/.splintrc index e5bf9d7..8b13789 100644 --- a/test/strchr/.splintrc +++ b/test/strchr/.splintrc @@ -1,3 +1 @@ --no-lib -+fcnconstraint diff --git a/test/strchr/strchr.c b/test/strchr/strchr.c index 3529d0f..1d97c23 100644 --- a/test/strchr/strchr.c +++ b/test/strchr/strchr.c @@ -1,5 +1,4 @@ - void func () { char *c; c = strchr("dfdfedfd", 'e'); diff --git a/test/strings.expect b/test/strings.expect index f614215..1d835e1 100644 --- a/test/strings.expect +++ b/test/strings.expect @@ -2,6 +2,7 @@ strings.c:21:6: Function main declared to return void, should return int strings.c: (in function main) strings.c:24:14: Function call may modify observer: "hullo" + strings.c:24:14: Storage becomes observer strings.c:25:7: Observer storage passed as only param: f3 ("hullo") strings.c:25:7: Storage becomes observer @@ -15,6 +16,7 @@ strings.c: (in function main) strings.c:23:14: Call to unconstrained function f1 may modify observer: "hullo" strings.c:23:14: Storage becomes observer strings.c:24:14: Function call may modify observer: "hullo" + strings.c:24:14: Storage becomes observer strings.c:25:7: Call to unconstrained function f3 may modify observer: "hullo" strings.c:25:7: Storage becomes observer strings.c:25:7: Observer storage passed as only param: f3 ("hullo") diff --git a/test/structassign.expect b/test/structassign.expect index 14d5a00..d6a0733 100644 --- a/test/structassign.expect +++ b/test/structassign.expect @@ -2,15 +2,15 @@ structassign.c: (in function copyrecord) structassign.c:15:15: Released storage x.name reachable from parameter at return point - structassign.c:14:19: Storage x.name is released + structassign.c:14:19: Storage x.name released structassign.c: (in function copyrecord2) structassign.c:23:15: Released storage x.name reachable from parameter at return point - structassign.c:22:3: Storage x.name is released + structassign.c:22:3: Storage x.name released structassign.c: (in function copyrecord3) structassign.c:28:12: Released storage x.name reachable from parameter at return point - structassign.c:28:12: Storage x.name is released + structassign.c:28:12: Storage x.name released structassign.c: (in function main) structassign.c:45:14: Only storage rc.name (type char *) derived from variable declared in this scope is not released (memory leak) diff --git a/test/tests2.5.expect b/test/tests2.5.expect index c0ef24c..0217256 100644 --- a/test/tests2.5.expect +++ b/test/tests2.5.expect @@ -42,7 +42,7 @@ immutable.c: (in function immutable_create) immutable.c:7:6: Arrow access from possibly null pointer res: res->x immutable.c:5:19: Storage res may become null immutable.c:8:10: Fresh storage returned as unqualified (should be only): res - immutable.c:5:54: Fresh storage res allocated + immutable.c:5:54: Fresh storage res created Finished checking --- 2 code warnings, as expected diff --git a/test/union.expect b/test/union.expect index 648fbcc..e9f103a 100644 --- a/test/union.expect +++ b/test/union.expect @@ -12,14 +12,14 @@ union.c:66:3: Implicitly temp storage p assigned to implicitly only: u->st.ip = p union.c: (in function ut_mangle1) union.c:73:2: Released storage u->ox reachable from parameter at return point - union.c:72:9: Storage u->ox is released + union.c:72:9: Storage u->ox released union.c: (in function ut_mangle2) union.c:78:2: Released storage u->st.ip reachable from parameter at return point - union.c:77:9: Storage u->st.ip is released + union.c:77:9: Storage u->st.ip released union.c: (in function ut_mangle3) union.c:84:2: Released storage u->st.ip reachable from parameter at return point - union.c:82:9: Storage u->st.ip is released + union.c:82:9: Storage u->st.ip released Finished checking --- 8 code warnings, as expected -- 2.45.1