From bogus@does.not.exist.com Wed Mar 22 17:09:41 2006 From: bogus@does.not.exist.com () Date: Wed Mar 22 17:09:59 2006 Subject: No subject Message-ID: to run on all that source - I'm very keen to find a work-round. There must be a way...? Best Regards -- Richard Meek Design Manager, GE Protimeter plc. mailto:richard.meek@indsys.ge.com http://www.protimeter.com Telephone 01628 472722 (switchboard) - 470528 (direct) - 474312 (fax) Legal Notice: "This e-mail may contain information that is confidential or proprietary to General Electric Company. Any unauthorised disclosure, distribution or other use is prohibited. If you received this e-mail in error, please notify the sender, permanently delete it, and destroy any printout." From bogus@does.not.exist.com Wed Mar 22 17:09:41 2006 From: bogus@does.not.exist.com () Date: Wed Mar 22 17:10:03 2006 Subject: No subject Message-ID: ============================================== #LcLint settings -weak -larchpath c:\travail\splint-3.0.1.6\lib #-larchpath c:\travail\lclint-2.5q\lib -lclimportdir \imports -sys-dirs c:\progra~1\hew\tools\hitachi\h8\3_0a_0\include\ #-sys-dir-errors -sys-unrecog -maintype #Below are the flags that should be re-inserted #retvalother #+forempty #+forblock #+usedef /* this is to check pointer to an object that is not ...*/ #+impouts /* initialised when the code try to use it */ #+paramuse #+topuse /* this is for unused object that are exported */ #fcnuse #varuse #unrecog ================================================= All new files that has been inserted in the project use local Splint directives to make the checks more robust such as below: ========================= /** default file settings **/ /****************************************/ /* Splint Directives */ /*@i@*/ /*@+standard@*/ /*@+exportheader@*/ /*@+exportlocal@*/ /*@+constuse@*/ /*@+ifblock@*/ /*@+whileblock@*/ /*@+whileempty@*/ /*@+charindex@*/ /*@+enumindex@*/ /*@-enumint@*/ /*@-mustfreefresh@*/ /*@-boolint@*/ /*@+predbool@*/ /*@+predassign@*/ ============================== Finally we have moved the previous settings on many of the initial files of the projects. This is probably not the Ideal way, however this seems to be a good way if you want to keep the balance on the time you have to spend to lurn Splint and the time you have to developt your project (wich is always too short anyway!). Howdy, troop. I'm considering using splint for a large-scale open-source development effort that is currently in very early development, although a fair chunk of code has been written. This means that there's going to be a lot of code coming in, and most of it, initially, won't be annotated. (And some more, naturally, won't be annotated correctly.) So: Has anyone written an "annotation primer" that is a one or two page distillation of the splint manual? I'm envisioning something like this: When you're doing this: Annotate thus: - returning the only copy /*@only@*/ of a data item - temporarily using a data /*@temp@*/ item but not taking responsibility for it Maybe with more info, or less. Also, does anyone have any experience with implementing Splint on a large software project early in the development cycle -- what to expect, what payoffs, what kind of things are helpful? =Austin _______________________________________________ splint-discuss mailing list splint-discuss@cs.virginia.edu http://www.splint.org/mailman/listinfo/splint-discuss ------------------------------------------------------------- Stephane Martin, ing. Kontron Canada Low Level Software Engineer 616 Cure-Boivin From bogus@does.not.exist.com Wed Mar 22 17:09:41 2006 From: bogus@does.not.exist.com () Date: Wed Mar 22 17:10:07 2006 Subject: No subject Message-ID: "fileSystem -- The function modifies the file system. Any modification that may change the system state is considered a file system modification." It should probably be called systemState or something. This is an issue I notice with splint all over the place. All the tokens cover concepts much broader than their names, which eats away at the self-documenting nature of annotations. I don't suppose the current situation can be fixed, but it's worth remembering in future development. From george.camann at gmail.com Mon Mar 13 09:36:36 2006 From: george.camann at gmail.com (George Camann) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] HOWTO ignore sprintf() without -bufferoverflowhigh flag? Message-ID: <001801c646ab$8a2af1e0$7a2110ac@ad.calspan.com> I'm getting the following warning: vrs_interface.c:242:9: Buffer overflow possible with sprintf. Recommend using snprintf instead: sprintf Use of function that may lead to buffer overflow. (Use -bufferoverflowhigh to inhibit warning) I use sprintf() a lot and my library doesn't have snprintf(). I would like splint to not display this warning for sprintf(), but I don't want to turn off the -bufferoverflowhigh check (even on a per file basis). Is there a way to do this? Thanks, George Camann -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.cs.Virginia.EDU/pipermail/splint-discuss/attachments/20060313/bfae341d/attachment.htm From beebe at math.utah.edu Mon Mar 13 09:43:51 2006 From: beebe at math.utah.edu (Nelson H. F. Beebe) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] Re: splint and snprintf vs sprintf Message-ID: "George Camann" asks on Mon, 13 Mar 2006 09:36:36 -0500 about splint's recommendation to use snprintf() instead of sprintf(). Of the more than twenty flavors of Unix in my development lab, only one lacks snprintf: Compaq/DEC Alpha OSF/1 4.0. Since snprintf() is part of POSIX (aka IEEE Std 1003.1-2001), and widely used in software packages, I provide a local library with an implementation of snprintf(), using the portable version available at http://www.ijs.si/software/snprintf/snprintf_2.2.tar.gz ------------------------------------------------------------------------------- - Nelson H. F. Beebe Tel: +1 801 581 5254 - - University of Utah FAX: +1 801 581 4148 - - Department of Mathematics, 110 LCB Internet e-mail: beebe@math.utah.edu - - 155 S 1400 E RM 233 beebe@acm.org beebe@computer.org - - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ - ------------------------------------------------------------------------------- From Michael.Wojcik at MicroFocus.com Mon Mar 13 18:46:57 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] Re: splint and snprintf vs sprintf Message-ID: <11352F9641010A418AD5057945A3A6594CB9E2@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > Nelson H. F. Beebe > Sent: Monday, 13 March, 2006 07:44 > To: splint-discuss@ares.cs.Virginia.EDU > > "George Camann" asks on Mon, 13 Mar 2006 > 09:36:36 -0500 about splint's recommendation to use snprintf() instead > of sprintf(). > > Of the more than twenty flavors of Unix in my development lab, only > one lacks snprintf: Compaq/DEC Alpha OSF/1 4.0. Since snprintf() is > part of POSIX (aka IEEE Std 1003.1-2001), and widely used in software > packages, I provide a local library with an implementation of > snprintf(), using the portable version available at > > http://www.ijs.si/software/snprintf/snprintf_2.2.tar.gz Note, though, that some snprintf implementations predate the current POSIX / C99 specification, and have the old return value semantics: if the formatted string does not fit into the buffer, they will return -1, rather than the minimum buffer size required to hold the formatted string. That can have unfortunate consequences for programs that rely on the new semantics. Implementations that still have the old semantics include the current HP C compilers for Tru64 and HP-UX and Microsoft C from v6 on. So a portable, open-source, conforming snprintf implementation, like Mark Martinec's (the one linked to above) is useful even on some platforms that *do* provide an snprintf. -- Michael Wojcik Principal Software Systems Developer, Micro Focus From venkiah at ensea.fr Tue Mar 14 09:09:21 2006 From: venkiah at ensea.fr (Auguste Venkiah) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] parse error because of const In-Reply-To: <1139822315.16800.51.camel@idefix.ensea.fr> References: <1139578250.13122.69.camel@idefix.ensea.fr> <1139587110.13122.79.camel@idefix.ensea.fr> <20060210172340.GA4694@812165098-VISIT-ADSL-LKOPING-NET.host.songnetworks.se> <1139822315.16800.51.camel@idefix.ensea.fr> Message-ID: <1142345360.9900.19.camel@idefix.ensea.fr> Hello, Splint wants all declarations to be done before code execution. However, I want to declare a constant int that is provided as an argument to main : int main (int argc, char* argv[]) { /* Some variable declaration */ /* .... */ const int i = atoi(argv(1)); ... } it seems to me that the parse error is because declaration of a variable and code execution take place at the same time. However, I prefer NOT separate them, because const type makes gcc complain : warning: assignment of read-only variable Do you have a suggestion to get away with this ? Thank you very much From Michael.Wojcik at MicroFocus.com Tue Mar 14 10:25:56 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] parse error because of const Message-ID: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > Auguste Venkiah > Sent: Tuesday, 14 March, 2006 07:09 > > Splint wants all declarations to be done before code execution. > However, I want to declare a constant int that is provided as an > argument to main : > > int main (int argc, char* argv[]) > { > > /* Some variable declaration */ > /* .... */ > const int i = atoi(argv(1)); > > ... > } Either you have a typo above (it's best to include *actual* source), or you have a bug in your program. You want "argv[1]", not "argv(1)". The former (correct) form works fine for me (as a complete program, with the proper headers included) with Splint 3.1.1. What version of Splint are you running? > it seems to me that the parse error What parse error? If you're getting an error message from Splint, please quote it in your message. > is because declaration of a variable > and code execution take place at the same time. Since non-constant initializers are perfectly legal for block-scope variables that don't have external or internal linkage in C, and are commonly used in C source, that seems rather unlikely. Note, though, that this code is suspect anyway; and while Splint with the default flags doesn't complain about it, it'd be better if it did. argv[1] is not guaranteed to be a non-null pointer, in which case you've just invoked UB. It's not even guaranteed to exist; it's perfectly legal for argc to be 0, in which case argv[0] will be null and argv[1] need not exist, or can be uninitialized. This is a bad construct. You can't make it safe in C. The proper thing would be to make "i" non-const-qualified and verify that argv[1] exists and is non-null before trying to convert it. (Also, atoi is a lousy function; its error signal is in the function's successful range. Prefer strtol et al.) -- Michael Wojcik Principal Software Systems Developer, Micro Focus From luke.w.imhoff at medtronic.com Tue Mar 14 10:33:58 2006 From: luke.w.imhoff at medtronic.com (Imhoff, Luke) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] Annotation for conditionally defined storage Message-ID: <88BB13D21A4BBB409F1F60D31E08252A016F72CD@MSPM1BMSGM14.ent.core.medtronic.com> In the code I'm trying to splint there are many functions that have /*@out@*/ arguments, but they are only defined if some condition passes, such as a range check or something similar. For example: PASS_FAIL_TYPE EM_LogEntryGet( /*@out@*/ EVENT_LOG_ENTRY_TYPE **ptr, // address of pointer to structure being read from the log U16 readIndex) // where to read from log, 0...(EVENT_LOG_ENTRIES-1) { // make sure index is within the total log if( (readIndex > EVENT_LOG_INDEX_MAX) || (readIndex < EVENT_LOG_INDEX_MIN)) { return(FAIL); } // return pointer to structure in the event window *ptr = EM_LoadPageRegister(readIndex); return(PASS); } There are other examples with more complex copying involved. Suffice it to say, initializing the /*@out@*/ to some default value is not the desired behavior. Is there anyway to tell splint if the return is FAIL that the /*@out@*/ won't be defined? -Luke Imhoff From venkiah at ensea.fr Tue Mar 14 11:59:54 2006 From: venkiah at ensea.fr (Auguste Venkiah) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] parse error because of const In-Reply-To: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> References: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> Message-ID: <1142355594.9900.56.camel@idefix.ensea.fr> Sorry for the argv(1) ... I did misspell argv[1] when typing the mail. The fact that parse error occured at initialization of a constant mislead me; as you suggested, the actual problem was indeed before : I test value of argc to check that enough arguments are provided. The problem is that splint complains (because code executes before all declarations ?). However, I __have__ to test argc before I do somthing like const int i = atoi(argv[1]); I had : int main (int argc, char* argv[]) { /*@ignore@*/ if (argc < 5) { printf("My error message\n"); return(EXIT_FAILURE); }/*@end@*/ const int i = atoi(argv[1]); //..... return(EXIT_SUCCESS); } thinking that splint would __not__ look at the piece of code after 'ignore'. Eventually, this works : int main (int argc, char* argv[]) { #ifndef S_SPLINT_S if (argc < 5) { printf("My error message\n"); return(EXIT_FAILURE); } #endif const int i = atoi(argv[1]); //..... return(EXIT_SUCCESS); } which means that I misunderstand the meaning of /*@ignore@*/ The error occured at the line where const int i = atoi(argv[1]); because splint did NOT ignore, and a declaration occured after execution of code (if argc ...). This is what splint complains : main.c:241:10: Parse Error. (For help on parse errors, see splint -help parseerrors.) *** Cannot continue. Also, I did not understand your point about 'atoi'. However I remember that atoi is deprecated in BSD. As you suggest, I will take a look at 'strtol' (which will require me to cast result to int, as 'strtol' returns a long int :S ... ) Thank you very much for your help. I was stuck thinking that constant declaration and initialization requiring code execution was a problem for splint .... Le mar 14/03/2006 ? 16:25, Michael Wojcik a ?crit : > > From: splint-discuss-bounces@cs.virginia.edu > > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > > Auguste Venkiah > > Sent: Tuesday, 14 March, 2006 07:09 > > > > Splint wants all declarations to be done before code execution. > > However, I want to declare a constant int that is provided as an > > argument to main : > > > > int main (int argc, char* argv[]) > > { > > > > /* Some variable declaration */ > > /* .... */ > > const int i = atoi(argv(1)); > > > > ... > > } > > Either you have a typo above (it's best to include *actual* source), or > you have a bug in your program. You want "argv[1]", not "argv(1)". > > The former (correct) form works fine for me (as a complete program, with > the proper headers included) with Splint 3.1.1. What version of Splint > are you running? > > > it seems to me that the parse error > > What parse error? If you're getting an error message from Splint, > please quote it in your message. > > > is because declaration of a variable > > and code execution take place at the same time. > > Since non-constant initializers are perfectly legal for block-scope > variables that don't have external or internal linkage in C, and are > commonly used in C source, that seems rather unlikely. > > Note, though, that this code is suspect anyway; and while Splint with > the default flags doesn't complain about it, it'd be better if it did. > argv[1] is not guaranteed to be a non-null pointer, in which case you've > just invoked UB. It's not even guaranteed to exist; it's perfectly > legal for argc to be 0, in which case argv[0] will be null and argv[1] > need not exist, or can be uninitialized. > > This is a bad construct. You can't make it safe in C. The proper thing > would be to make "i" non-const-qualified and verify that argv[1] exists > and is non-null before trying to convert it. (Also, atoi is a lousy > function; its error signal is in the function's successful range. > Prefer strtol et al.) From roland.illig at gmx.de Tue Mar 14 12:17:56 2006 From: roland.illig at gmx.de (Roland Illig) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] parse error because of const In-Reply-To: <1142355594.9900.56.camel@idefix.ensea.fr> References: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> <1142355594.9900.56.camel@idefix.ensea.fr> Message-ID: <4416FAC4.8090607@gmx.de> Auguste Venkiah wrote: > int main (int argc, char* argv[]) > { > #ifndef S_SPLINT_S > if (argc < 5) { > printf("My error message\n"); > return(EXIT_FAILURE); > } > #endif > > const int i = atoi(argv[1]); > > //..... > return(EXIT_SUCCESS); > } ISO C90 does not allow intermixed code and declarations. All declarations have to be at the top of a block. You can, of course, write this: int main(int argc, char **argv) { if (argc < 5) { fprintf(stderr, "usage: foo 1 2 3 4\n"); return EXIT_FAILURE; } { /* FIXME: Do proper input validation. */ const int i = atoi(argv[1]); /* ... */ } return EXIT_SUCCESS; } Roland From Michael.Wojcik at MicroFocus.com Tue Mar 14 17:12:33 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] parse error because of const Message-ID: <11352F9641010A418AD5057945A3A6594CB9F0@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > Auguste Venkiah > Sent: Tuesday, 14 March, 2006 10:00 > > Sorry for the argv(1) ... I did misspell argv[1] when typing the mail. That's fine - I just wanted to make sure that wasn't the error. (It'd be an easy mistake to make in real code, and if you had just tried to splint it without compiling first, it might have been easy to miss.) > I test value of argc to check that enough arguments are provided. > The problem is that splint complains (because code executes before all > declarations ?). However, I __have__ to test argc before I do somthing > like > const int i = atoi(argv[1]); > > I had : > int main (int argc, char* argv[]) > { > /*@ignore@*/ > if (argc < 5) { > printf("My error message\n"); > return(EXIT_FAILURE); > }/*@end@*/ > > const int i = atoi(argv[1]); Ah. This is another reason to post the real code; otherwise you may inadvertently remove the source of the error. Prior to C99, C required all block-scope declarations be at the beginning of a block. What you have here is not legal C. It's probably legal "GNU C", which is a language similar to, but different from, C. Splint understands C90 (and, I suppose, the minor 1994 additions), not C99. > Eventually, this works : > > int main (int argc, char* argv[]) > { > #ifndef S_SPLINT_S > if (argc < 5) { > printf("My error message\n"); > return(EXIT_FAILURE); > } > #endif > > const int i = atoi(argv[1]); Yes, that's OK. > Also, I did not understand your point about 'atoi'. If you pass a string that doesn't represent valid input to atoi, it returns -1. If you pass the string "-1" to atoi, it returns -1. You have no way of distinguishing between the former case (an input error) and the latter (a valid conversion). > As you suggest, I will take a look at > 'strtol' (which will require me to cast result to int, as 'strtol' > returns a long int :S ... ) strtol has better error reporting. The best way to convert a string to an int in C is to do something like: 1. Set errno to 0. This is so you can check for ERANGE below. 2. Verify that your input string pointer is valid (non-null). 3. Call strtol. Supply an "end" pointer. Use the appropriate "base" argument; only use 0 for base if you have defined the input as using C-style base representation (for decimal, octal, and hexadecimal). 4. If errno is ERANGE, then the value overflowed. 5. Check to see that the end pointer does not point to the beginning of the string; if it does, no number was found in the string (it's empty or just contains whitespace). 5. Scan the string pointed to by end, to make sure there isn't anything after the value that you don't expect. (For many applications, the end-string should be empty or contain only whitespace.) 6. Now that you know that you have a valid long value, check to see that it's in the range of int by comparing it with INT_MAX and INT_MIN. 7. If it's in range, convert it by assigning it to an int variable. This does not actually require a cast, but many implementations will complain if you don't use one. That probably seems like a lot of work, but that's what's necessary to do a safe conversion with no integer-overflow or invalid-data vulnerabilities. You can always wrap it in a function of its own. -- Michael Wojcik Principal Software Systems Developer, Micro Focus From ok at cs.otago.ac.nz Tue Mar 14 17:49:06 2006 From: ok at cs.otago.ac.nz (Richard A. O'Keefe) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] parse error because of const Message-ID: <200603142249.k2EMn6V8359319@atlas.otago.ac.nz> Auguste Venkiah wrote: Splint wants all declarations to be done before code execution. Wrong way to say it. The right way to say it is that Splint is a checker for ISO C90, in which all the declarations in a block must precede all the statements. However, I want to declare a constant int that is provided as an argument to main : int main (int argc, char* argv[]) { /* Some variable declaration */ /* .... */ const int i = atoi(argv(1)); ... } Presumably argv(1) was a typo. What exactly stops you writing int main(int argc, char **argv) { int const i = argc < 2 ? 0 : atoi(argv[1]); /* other variable declarations */ /* statmeents */ } Or int main(int argc, char **argv) { /* some declarations */ /* some statements that might change argc or argv */ /* and might perhaps check the argument count. */ { int const i = atoi(argv[1]); /* more declarations */ /* statements using i */ } /* statements not using i */ } I some someone sometime can get some funding to bring Splint up to date with ISO C99. From spam_account at sympatico.ca Thu Mar 16 16:12:27 2006 From: spam_account at sympatico.ca (Bill Pringlemeir) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] Structure redefinitions. Message-ID: Here are two files, [bar.c] /* File name & Package Name */ struct sqlcxp { unsigned short fillen; char filnam[10]; }; /*@unused@*/static struct sqlcxp sqlfpn = { 14, "123456.pc" }; [foo.c] /* File name & Package Name */ struct sqlcxp { unsigned short fillen; char filnam[15]; }; /*@unused@*/static struct sqlcxp sqlfpn = { 14, "12345678901.pc" }; The code is an extract of some machine generated SQL. I have added the "/*@unused@*/". I run splint on both files below, the second time with the file names re-ordered. > splint +weak -typeuse -fcnuse -redef foo.c bar.c Splint 3.1.1.2 --- 08 Mar 2006 Finished checking --- no warnings > splint +weak -typeuse -fcnuse -redef bar.c foo.c Splint 3.1.1.2 --- 08 Mar 2006 foo.c:48:5: String literal with 15 characters (counting null terminator) is assigned to char [10] (insufficient storage available): "12345678901.pc" A string literal is assigned to a char array too small to hold it. (Use -stringliteraltoolong to inhibit warning) Finished checking --- 1 code warning My guess is that splint is keeping the first structure definition in a symbol table and is not recording (or utilizing) the second definition. The warning in this case is not correct. The new structure definition with the same name does have enough storage. There maybe many things wrong with this code [like it does nothing], but the reported error is not valid. Also, if you have a large project where foo.c and bar.c are not close together and you did not see a structure re-definition warning (like when -redef inhibits it), it can be very confusing to see this error message. In my case, there were many re-definition message as the embedded SQL pre-processor adds many identical structure in every file it analyzes. It was close enough to realize what the problem was. However, this looks like a systemic problem internal to splint in it's handling of re-definitions. Re-definitions are not good practice, but they are valid 'C'. This is a mis-match in how splint is parsing 'C' and how the ANSI spec would specify parsing... I think more confusing error message could result by making the re-defined structures diverge more in their content. I am using a CVS version of splint (Circa march 8th). Regards, Bill Pringlemeir. From niall at xrnd.com Fri Mar 17 10:01:21 2006 From: niall at xrnd.com (Niall Dalton) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] array parameter qualifiers Message-ID: <441ACF41.9070200@xrnd.com> Hello, splint 3.1.1 does not appear to support array parameter qualifiers - either the cv-qualifiers within the [] of an array parameter or use of static as a minimum size specifier. The latter is one I'm interested in. int sum(int a[static 10]) { // a has at least a[0] to a[9] existing and contiguous ... } Am I correct that this is seen as a parse error currently by splint? Are there plans to make use of this information? Regards, Niall From luke.w.imhoff at medtronic.com Fri Mar 17 10:10:47 2006 From: luke.w.imhoff at medtronic.com (Imhoff, Luke) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] array parameter qualifiers Message-ID: <88BB13D21A4BBB409F1F60D31E08252A01733AE4@MSPM1BMSGM14.ent.core.medtronic.com> Splint doesn't support array parameters at all really. It just assumes it's a pointer. Splint should emit some warning about the size being dropped. What standard is the inner 'static' from? -----Original Message----- From: splint-discuss-bounces@cs.virginia.edu [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of Niall Dalton Sent: Friday, March 17, 2006 9:01 AM To: splint-discuss@ares.cs.Virginia.EDU Subject: [splint-discuss] array parameter qualifiers Hello, splint 3.1.1 does not appear to support array parameter qualifiers - either the cv-qualifiers within the [] of an array parameter or use of static as a minimum size specifier. The latter is one I'm interested in. int sum(int a[static 10]) { // a has at least a[0] to a[9] existing and contiguous ... } Am I correct that this is seen as a parse error currently by splint? Are there plans to make use of this information? Regards, Niall _______________________________________________ splint-discuss mailing list splint-discuss@ares.cs.Virginia.EDU http://www.cs.Virginia.EDU/mailman-2.1.5/listinfo/splint-discuss From niall at xrnd.com Fri Mar 17 10:19:24 2006 From: niall at xrnd.com (Niall Dalton) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] array parameter qualifiers In-Reply-To: <88BB13D21A4BBB409F1F60D31E08252A01733AE4@MSPM1BMSGM14.ent.core.medtronic.com> References: <88BB13D21A4BBB409F1F60D31E08252A01733AE4@MSPM1BMSGM14.ent.core.medtronic.com> Message-ID: <441AD37C.1050401@xrnd.com> Imhoff, Luke wrote: > Splint doesn't support array parameters at all really. It just assumes > it's a pointer. Splint should emit some warning about the size being > dropped. What standard is the inner 'static' from? C99. Just looking at the ISO C99 committee draft of May 6 2005, its in section 6.7.5.3 (page 119, point 7) on the semantics of function declarators. niall From luke.w.imhoff at medtronic.com Fri Mar 17 10:25:00 2006 From: luke.w.imhoff at medtronic.com (Imhoff, Luke) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] array parameter qualifiers Message-ID: <88BB13D21A4BBB409F1F60D31E08252A01733B18@MSPM1BMSGM14.ent.core.medtronic.com> Splint comforms to C90 at best. -----Original Message----- From: splint-discuss-bounces@cs.virginia.edu [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of Niall Dalton Sent: Friday, March 17, 2006 9:19 AM To: Discussions about the Splint annotation-assisted static analysis project Subject: Re: [splint-discuss] array parameter qualifiers Imhoff, Luke wrote: > Splint doesn't support array parameters at all really. It just > assumes it's a pointer. Splint should emit some warning about the > size being dropped. What standard is the inner 'static' from? C99. Just looking at the ISO C99 committee draft of May 6 2005, its in section 6.7.5.3 (page 119, point 7) on the semantics of function declarators. niall _______________________________________________ splint-discuss mailing list splint-discuss@ares.cs.Virginia.EDU http://www.cs.Virginia.EDU/mailman-2.1.5/listinfo/splint-discuss From ai2097 at yahoo.com Mon Mar 20 05:48:15 2006 From: ai2097 at yahoo.com (Quandary) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] Foo exported, but not specified Message-ID: <20060320104815.4217.qmail@web51704.mail.yahoo.com> Hey all, I'm using splint -strict to try and shake down software as I write it. However, I've run into a set of warnings (export-all) I can't seem to cleanly resolve. I can't figure out any way to "specify" the values, so that splint stops complaining. All I can do is relax the checks, or include the header files on the splint command line, both of which are wrong, and the latter of which causes a whole slew of different errors. Here's some sample code, along with splint's output: ###test.h### enum e_my_enum { FOOENUM = 0 }; typedef enum e_my_enum my_enum; /*@unused@*/ extern my_enum g_my_global; ###test.c#### #include "test.h" my_enum g_my_global; int main(/*@unused@*/int argc, /*@unused@*/char** argv) { return (int)FOOENUM; } ###splint output### $ splint -strict test.c Splint 3.1.1 --- 08 Dec 2005 test.h:2:5: Constant exported, but not specified: FOOENUM A constant is exported, but not specified. (Use -exportconst to inhibit warning) test.h:5:24: Type exported, but not specified: my_enum A type is exported, but not specified. (Use -exporttype to inhibit warning) test.h:8:16: Variable exported, but not specified: g_my_global A variable is exported, but not specified. (Use -exportvar to inhibit warning) Finished checking --- 3 code warnings ###END### What is the proper way to fix these warnings? __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From Michael.Wojcik at MicroFocus.com Mon Mar 20 11:42:19 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Wed Mar 22 17:11:26 2006 Subject: [splint-discuss] Foo exported, but not specified Message-ID: <11352F9641010A418AD5057945A3A6594CBA18@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of Quandary > Sent: Monday, 20 March, 2006 05:48 > > I'm using splint -strict to try and shake down > software as I write it. However, I've run into a set > of warnings (export-all) I can't seem to cleanly > resolve. I can't figure out any way to "specify" the > values, so that splint stops complaining. All I can do > is relax the checks, or include the header files on > the splint command line, both of which are wrong, and > the latter of which causes a whole slew of different > errors. > > Here's some sample code, along with splint's output: [snipped] > > test.h:2:5: Constant exported, but not specified: > FOOENUM > A constant is exported, but not specified. (Use > -exportconst to inhibit warning) One of splint's many poorly-worded messages. "specified" how? Obviously "specified" doesn't mean "declared" or "defined" in the sense those terms are used by the C standard, since clearly FOOENUM is both. So "specified" here is some term of art specific to splint - but it's not explained by the error text, nor by the documentation, which is woefully out of date. (I'm gradually coming to the conclusion that splint in its current form is not suitable for general serious use, and won't be until it has a new maintainer who can fix the problems with message text and documentation. Some of the splint source is pretty lousy too, eg with unspecified function parameter lists. And while I'd like to volunteer for the job, I can't make that sort of time commitment right now.) In this case, what the message means within splint is that FOOENUM is declared in a header, which is not part of a library, and is not an "import"; and FOOENUM itself is not static (always true for a type, since types don't have storage classes). (See exprChecks_checkExport in exprChecks.c.) I *think* splint is complaining because you're taking a value you've defined internally (that is, splint assumes that only you will be using test.h), and you're publishing it to the world by returning it from a function. So what you want to do is to tell splint that it's OK to do this. In the splint code, it appears your only options for doing that are to hoist the definition out of test.h into test.c (though that might produce a different warning), or tell splint that test.h should have the "library" or "import" flag attached to it, or suppress the warning. Setting the "library" or "import" flag means getting splint to set one of the following for the "kind" field of the file structure for test.h: FL_LIB, FL_STDHDR, FL_STDLIB, or FL_IMPORT. Clearly the middle two aren't appropriate, which leaves FL_LIB and FL_IMPORT. It appears that FL_LIB is only set when processing something splint believes is part of the standard library, so that's out. FL_IMPORT is set when processing files via symtable_import (symtable.c), and appears to be used only for preprocessed LCL files, so that's out. In short, I don't think there's any way to suppress this warning short of disabling this particular check, which the error message does indirectly tell you how to do. Bracket the definition of FOOENUM with -exportconst: enum e_my_enum { /*@-exportconst@*/ FOOENUM = 0 /*@=exportconst@*/ }; > test.h:5:24: Type exported, but not specified: my_enum > A type is exported, but not specified. (Use > -exporttype to inhibit warning) > test.h:8:16: Variable exported, but not specified: > g_my_global > A variable is exported, but not specified. (Use > -exportvar to inhibit > warning) These can be suppressed similarly. Combining all three: ---- test.h ---- enum e_my_enum { /*@-exportconst@*/ FOOENUM = 0 /*@=exportconst@*/ }; /*@-exporttype@*/ typedef enum e_my_enum my_enum; /*@=exporttype@*/ /*@unused@*/ /*@-exportvar@*/ extern my_enum g_my_global; /*@=exportvar@*/ ---- test.h ---- -- Michael Wojcik Principal Software Systems Developer, Micro Focus From ai2097 at yahoo.com Mon Mar 20 20:21:52 2006 From: ai2097 at yahoo.com (Quandary) Date: Wed Mar 22 17:11:27 2006 Subject: [splint-discuss] Foo exported, but not specified In-Reply-To: <11352F9641010A418AD5057945A3A6594CBA18@MTV-EXCHANGE.microfocus.com> Message-ID: <20060321012152.73526.qmail@web51705.mail.yahoo.com> --- Michael Wojcik wrote: > (I'm gradually coming to the conclusion that splint > in its current form is not suitable for general > serious use, and won't be until it has a new > maintainer who can fix the problems with message > text and documentation. Some of the splint source is > pretty lousy too, eg with unspecified function > parameter lists. And while I'd like to volunteer for > the job, I can't make that sort of time commitment > right now.) I came to a similar conclusion the last time I gave splint a shot -- it has tons of potential, but enough rough edges to make it unpalatable at best for "real" use. I've toyed with the idea of trying to fix splint or write a similar tool from scratch, but, like you, I can't dedicate the resources required to undertake such a project. > In short, I don't think there's any way to suppress > this warning short of disabling this particular > check, which the error message does indirectly tell > you how to do. I went with a similar workaround, but instead used /*@-exportany@*/ at the start of each header file. Since the flag is limited in scope to the file, and these errors never appear if the headers are processed directly by splint, I think (hope?) that this is a sane solution for the time being. Thanks again, -- Q __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From michael.winkler at lvf.liebherr.com Tue Mar 21 12:20:03 2006 From: michael.winkler at lvf.liebherr.com (michael.winkler) Date: Wed Mar 22 17:11:27 2006 Subject: [splint-discuss] [Likely SPAM] the file Message-ID: <200603211720.k2LHK3FE000228@ares.cs.Virginia.EDU> how are you? i send the details. OK ? -------------- next part -------------- From george.camann at gmail.com Mon Mar 13 09:36:42 2006 From: george.camann at gmail.com (George Camann) Date: Fri Jun 9 09:13:51 2006 Subject: [splint-discuss] HOWTO ignore sprintf() without -bufferoverflowhigh flag? Message-ID: <001801c646ab$8a2af1e0$7a2110ac@ad.calspan.com> I'm getting the following warning: vrs_interface.c:242:9: Buffer overflow possible with sprintf. Recommend using snprintf instead: sprintf Use of function that may lead to buffer overflow. (Use -bufferoverflowhigh to inhibit warning) I use sprintf() a lot and my library doesn't have snprintf(). I would like splint to not display this warning for sprintf(), but I don't want to turn off the -bufferoverflowhigh check (even on a per file basis). Is there a way to do this? Thanks, George Camann -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.cs.Virginia.EDU/pipermail/splint-discuss/attachments/20060313/bfae341d/attachment-0001.htm From beebe at math.utah.edu Mon Mar 13 09:43:56 2006 From: beebe at math.utah.edu (Nelson H. F. Beebe) Date: Fri Jun 9 09:13:52 2006 Subject: [splint-discuss] Re: splint and snprintf vs sprintf Message-ID: "George Camann" asks on Mon, 13 Mar 2006 09:36:36 -0500 about splint's recommendation to use snprintf() instead of sprintf(). Of the more than twenty flavors of Unix in my development lab, only one lacks snprintf: Compaq/DEC Alpha OSF/1 4.0. Since snprintf() is part of POSIX (aka IEEE Std 1003.1-2001), and widely used in software packages, I provide a local library with an implementation of snprintf(), using the portable version available at http://www.ijs.si/software/snprintf/snprintf_2.2.tar.gz ------------------------------------------------------------------------------- - Nelson H. F. Beebe Tel: +1 801 581 5254 - - University of Utah FAX: +1 801 581 4148 - - Department of Mathematics, 110 LCB Internet e-mail: beebe@math.utah.edu - - 155 S 1400 E RM 233 beebe@acm.org beebe@computer.org - - Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ - ------------------------------------------------------------------------------- From Michael.Wojcik at MicroFocus.com Mon Mar 13 18:47:34 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Fri Jun 9 09:14:24 2006 Subject: [splint-discuss] Re: splint and snprintf vs sprintf Message-ID: <11352F9641010A418AD5057945A3A6594CB9E2@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > Nelson H. F. Beebe > Sent: Monday, 13 March, 2006 07:44 > To: splint-discuss@ares.cs.Virginia.EDU > > "George Camann" asks on Mon, 13 Mar 2006 > 09:36:36 -0500 about splint's recommendation to use snprintf() instead > of sprintf(). > > Of the more than twenty flavors of Unix in my development lab, only > one lacks snprintf: Compaq/DEC Alpha OSF/1 4.0. Since snprintf() is > part of POSIX (aka IEEE Std 1003.1-2001), and widely used in software > packages, I provide a local library with an implementation of > snprintf(), using the portable version available at > > http://www.ijs.si/software/snprintf/snprintf_2.2.tar.gz Note, though, that some snprintf implementations predate the current POSIX / C99 specification, and have the old return value semantics: if the formatted string does not fit into the buffer, they will return -1, rather than the minimum buffer size required to hold the formatted string. That can have unfortunate consequences for programs that rely on the new semantics. Implementations that still have the old semantics include the current HP C compilers for Tru64 and HP-UX and Microsoft C from v6 on. So a portable, open-source, conforming snprintf implementation, like Mark Martinec's (the one linked to above) is useful even on some platforms that *do* provide an snprintf. -- Michael Wojcik Principal Software Systems Developer, Micro Focus From venkiah at ensea.fr Tue Mar 14 09:09:25 2006 From: venkiah at ensea.fr (Auguste Venkiah) Date: Fri Jun 9 09:14:35 2006 Subject: [splint-discuss] parse error because of const In-Reply-To: <1139822315.16800.51.camel@idefix.ensea.fr> References: <1139578250.13122.69.camel@idefix.ensea.fr> <1139587110.13122.79.camel@idefix.ensea.fr> <20060210172340.GA4694@812165098-VISIT-ADSL-LKOPING-NET.host.songnetworks.se> <1139822315.16800.51.camel@idefix.ensea.fr> Message-ID: <1142345360.9900.19.camel@idefix.ensea.fr> Hello, Splint wants all declarations to be done before code execution. However, I want to declare a constant int that is provided as an argument to main : int main (int argc, char* argv[]) { /* Some variable declaration */ /* .... */ const int i = atoi(argv(1)); ... } it seems to me that the parse error is because declaration of a variable and code execution take place at the same time. However, I prefer NOT separate them, because const type makes gcc complain : warning: assignment of read-only variable Do you have a suggestion to get away with this ? Thank you very much From Michael.Wojcik at MicroFocus.com Tue Mar 14 10:26:38 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Fri Jun 9 09:14:42 2006 Subject: [splint-discuss] parse error because of const Message-ID: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > Auguste Venkiah > Sent: Tuesday, 14 March, 2006 07:09 > > Splint wants all declarations to be done before code execution. > However, I want to declare a constant int that is provided as an > argument to main : > > int main (int argc, char* argv[]) > { > > /* Some variable declaration */ > /* .... */ > const int i = atoi(argv(1)); > > ... > } Either you have a typo above (it's best to include *actual* source), or you have a bug in your program. You want "argv[1]", not "argv(1)". The former (correct) form works fine for me (as a complete program, with the proper headers included) with Splint 3.1.1. What version of Splint are you running? > it seems to me that the parse error What parse error? If you're getting an error message from Splint, please quote it in your message. > is because declaration of a variable > and code execution take place at the same time. Since non-constant initializers are perfectly legal for block-scope variables that don't have external or internal linkage in C, and are commonly used in C source, that seems rather unlikely. Note, though, that this code is suspect anyway; and while Splint with the default flags doesn't complain about it, it'd be better if it did. argv[1] is not guaranteed to be a non-null pointer, in which case you've just invoked UB. It's not even guaranteed to exist; it's perfectly legal for argc to be 0, in which case argv[0] will be null and argv[1] need not exist, or can be uninitialized. This is a bad construct. You can't make it safe in C. The proper thing would be to make "i" non-const-qualified and verify that argv[1] exists and is non-null before trying to convert it. (Also, atoi is a lousy function; its error signal is in the function's successful range. Prefer strtol et al.) -- Michael Wojcik Principal Software Systems Developer, Micro Focus From luke.w.imhoff at medtronic.com Tue Mar 14 10:34:06 2006 From: luke.w.imhoff at medtronic.com (Imhoff, Luke) Date: Fri Jun 9 09:14:44 2006 Subject: [splint-discuss] Annotation for conditionally defined storage Message-ID: <88BB13D21A4BBB409F1F60D31E08252A016F72CD@MSPM1BMSGM14.ent.core.medtronic.com> In the code I'm trying to splint there are many functions that have /*@out@*/ arguments, but they are only defined if some condition passes, such as a range check or something similar. For example: PASS_FAIL_TYPE EM_LogEntryGet( /*@out@*/ EVENT_LOG_ENTRY_TYPE **ptr, // address of pointer to structure being read from the log U16 readIndex) // where to read from log, 0...(EVENT_LOG_ENTRIES-1) { // make sure index is within the total log if( (readIndex > EVENT_LOG_INDEX_MAX) || (readIndex < EVENT_LOG_INDEX_MIN)) { return(FAIL); } // return pointer to structure in the event window *ptr = EM_LoadPageRegister(readIndex); return(PASS); } There are other examples with more complex copying involved. Suffice it to say, initializing the /*@out@*/ to some default value is not the desired behavior. Is there anyway to tell splint if the return is FAIL that the /*@out@*/ won't be defined? -Luke Imhoff From venkiah at ensea.fr Tue Mar 14 12:00:06 2006 From: venkiah at ensea.fr (Auguste Venkiah) Date: Fri Jun 9 09:15:02 2006 Subject: [splint-discuss] parse error because of const In-Reply-To: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> References: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> Message-ID: <1142355594.9900.56.camel@idefix.ensea.fr> Sorry for the argv(1) ... I did misspell argv[1] when typing the mail. The fact that parse error occured at initialization of a constant mislead me; as you suggested, the actual problem was indeed before : I test value of argc to check that enough arguments are provided. The problem is that splint complains (because code executes before all declarations ?). However, I __have__ to test argc before I do somthing like const int i = atoi(argv[1]); I had : int main (int argc, char* argv[]) { /*@ignore@*/ if (argc < 5) { printf("My error message\n"); return(EXIT_FAILURE); }/*@end@*/ const int i = atoi(argv[1]); //..... return(EXIT_SUCCESS); } thinking that splint would __not__ look at the piece of code after 'ignore'. Eventually, this works : int main (int argc, char* argv[]) { #ifndef S_SPLINT_S if (argc < 5) { printf("My error message\n"); return(EXIT_FAILURE); } #endif const int i = atoi(argv[1]); //..... return(EXIT_SUCCESS); } which means that I misunderstand the meaning of /*@ignore@*/ The error occured at the line where const int i = atoi(argv[1]); because splint did NOT ignore, and a declaration occured after execution of code (if argc ...). This is what splint complains : main.c:241:10: Parse Error. (For help on parse errors, see splint -help parseerrors.) *** Cannot continue. Also, I did not understand your point about 'atoi'. However I remember that atoi is deprecated in BSD. As you suggest, I will take a look at 'strtol' (which will require me to cast result to int, as 'strtol' returns a long int :S ... ) Thank you very much for your help. I was stuck thinking that constant declaration and initialization requiring code execution was a problem for splint .... Le mar 14/03/2006 ? 16:25, Michael Wojcik a ?crit : > > From: splint-discuss-bounces@cs.virginia.edu > > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > > Auguste Venkiah > > Sent: Tuesday, 14 March, 2006 07:09 > > > > Splint wants all declarations to be done before code execution. > > However, I want to declare a constant int that is provided as an > > argument to main : > > > > int main (int argc, char* argv[]) > > { > > > > /* Some variable declaration */ > > /* .... */ > > const int i = atoi(argv(1)); > > > > ... > > } > > Either you have a typo above (it's best to include *actual* source), or > you have a bug in your program. You want "argv[1]", not "argv(1)". > > The former (correct) form works fine for me (as a complete program, with > the proper headers included) with Splint 3.1.1. What version of Splint > are you running? > > > it seems to me that the parse error > > What parse error? If you're getting an error message from Splint, > please quote it in your message. > > > is because declaration of a variable > > and code execution take place at the same time. > > Since non-constant initializers are perfectly legal for block-scope > variables that don't have external or internal linkage in C, and are > commonly used in C source, that seems rather unlikely. > > Note, though, that this code is suspect anyway; and while Splint with > the default flags doesn't complain about it, it'd be better if it did. > argv[1] is not guaranteed to be a non-null pointer, in which case you've > just invoked UB. It's not even guaranteed to exist; it's perfectly > legal for argc to be 0, in which case argv[0] will be null and argv[1] > need not exist, or can be uninitialized. > > This is a bad construct. You can't make it safe in C. The proper thing > would be to make "i" non-const-qualified and verify that argv[1] exists > and is non-null before trying to convert it. (Also, atoi is a lousy > function; its error signal is in the function's successful range. > Prefer strtol et al.) From roland.illig at gmx.de Tue Mar 14 12:18:05 2006 From: roland.illig at gmx.de (Roland Illig) Date: Fri Jun 9 09:15:12 2006 Subject: [splint-discuss] parse error because of const In-Reply-To: <1142355594.9900.56.camel@idefix.ensea.fr> References: <11352F9641010A418AD5057945A3A6594CB9E7@MTV-EXCHANGE.microfocus.com> <1142355594.9900.56.camel@idefix.ensea.fr> Message-ID: <4416FAC4.8090607@gmx.de> Auguste Venkiah wrote: > int main (int argc, char* argv[]) > { > #ifndef S_SPLINT_S > if (argc < 5) { > printf("My error message\n"); > return(EXIT_FAILURE); > } > #endif > > const int i = atoi(argv[1]); > > //..... > return(EXIT_SUCCESS); > } ISO C90 does not allow intermixed code and declarations. All declarations have to be at the top of a block. You can, of course, write this: int main(int argc, char **argv) { if (argc < 5) { fprintf(stderr, "usage: foo 1 2 3 4\n"); return EXIT_FAILURE; } { /* FIXME: Do proper input validation. */ const int i = atoi(argv[1]); /* ... */ } return EXIT_SUCCESS; } Roland From Michael.Wojcik at MicroFocus.com Tue Mar 14 17:13:23 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Fri Jun 9 09:15:23 2006 Subject: [splint-discuss] parse error because of const Message-ID: <11352F9641010A418AD5057945A3A6594CB9F0@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of > Auguste Venkiah > Sent: Tuesday, 14 March, 2006 10:00 > > Sorry for the argv(1) ... I did misspell argv[1] when typing the mail. That's fine - I just wanted to make sure that wasn't the error. (It'd be an easy mistake to make in real code, and if you had just tried to splint it without compiling first, it might have been easy to miss.) > I test value of argc to check that enough arguments are provided. > The problem is that splint complains (because code executes before all > declarations ?). However, I __have__ to test argc before I do somthing > like > const int i = atoi(argv[1]); > > I had : > int main (int argc, char* argv[]) > { > /*@ignore@*/ > if (argc < 5) { > printf("My error message\n"); > return(EXIT_FAILURE); > }/*@end@*/ > > const int i = atoi(argv[1]); Ah. This is another reason to post the real code; otherwise you may inadvertently remove the source of the error. Prior to C99, C required all block-scope declarations be at the beginning of a block. What you have here is not legal C. It's probably legal "GNU C", which is a language similar to, but different from, C. Splint understands C90 (and, I suppose, the minor 1994 additions), not C99. > Eventually, this works : > > int main (int argc, char* argv[]) > { > #ifndef S_SPLINT_S > if (argc < 5) { > printf("My error message\n"); > return(EXIT_FAILURE); > } > #endif > > const int i = atoi(argv[1]); Yes, that's OK. > Also, I did not understand your point about 'atoi'. If you pass a string that doesn't represent valid input to atoi, it returns -1. If you pass the string "-1" to atoi, it returns -1. You have no way of distinguishing between the former case (an input error) and the latter (a valid conversion). > As you suggest, I will take a look at > 'strtol' (which will require me to cast result to int, as 'strtol' > returns a long int :S ... ) strtol has better error reporting. The best way to convert a string to an int in C is to do something like: 1. Set errno to 0. This is so you can check for ERANGE below. 2. Verify that your input string pointer is valid (non-null). 3. Call strtol. Supply an "end" pointer. Use the appropriate "base" argument; only use 0 for base if you have defined the input as using C-style base representation (for decimal, octal, and hexadecimal). 4. If errno is ERANGE, then the value overflowed. 5. Check to see that the end pointer does not point to the beginning of the string; if it does, no number was found in the string (it's empty or just contains whitespace). 5. Scan the string pointed to by end, to make sure there isn't anything after the value that you don't expect. (For many applications, the end-string should be empty or contain only whitespace.) 6. Now that you know that you have a valid long value, check to see that it's in the range of int by comparing it with INT_MAX and INT_MIN. 7. If it's in range, convert it by assigning it to an int variable. This does not actually require a cast, but many implementations will complain if you don't use one. That probably seems like a lot of work, but that's what's necessary to do a safe conversion with no integer-overflow or invalid-data vulnerabilities. You can always wrap it in a function of its own. -- Michael Wojcik Principal Software Systems Developer, Micro Focus From ok at cs.otago.ac.nz Tue Mar 14 17:49:28 2006 From: ok at cs.otago.ac.nz (Richard A. O'Keefe) Date: Fri Jun 9 09:15:25 2006 Subject: [splint-discuss] parse error because of const Message-ID: <200603142249.k2EMn6V8359319@atlas.otago.ac.nz> Auguste Venkiah wrote: Splint wants all declarations to be done before code execution. Wrong way to say it. The right way to say it is that Splint is a checker for ISO C90, in which all the declarations in a block must precede all the statements. However, I want to declare a constant int that is provided as an argument to main : int main (int argc, char* argv[]) { /* Some variable declaration */ /* .... */ const int i = atoi(argv(1)); ... } Presumably argv(1) was a typo. What exactly stops you writing int main(int argc, char **argv) { int const i = argc < 2 ? 0 : atoi(argv[1]); /* other variable declarations */ /* statmeents */ } Or int main(int argc, char **argv) { /* some declarations */ /* some statements that might change argc or argv */ /* and might perhaps check the argument count. */ { int const i = atoi(argv[1]); /* more declarations */ /* statements using i */ } /* statements not using i */ } I some someone sometime can get some funding to bring Splint up to date with ISO C99. From spam_account at sympatico.ca Thu Mar 16 16:14:51 2006 From: spam_account at sympatico.ca (Bill Pringlemeir) Date: Fri Jun 9 09:16:38 2006 Subject: [splint-discuss] Structure redefinitions. Message-ID: Here are two files, [bar.c] /* File name & Package Name */ struct sqlcxp { unsigned short fillen; char filnam[10]; }; /*@unused@*/static struct sqlcxp sqlfpn = { 14, "123456.pc" }; [foo.c] /* File name & Package Name */ struct sqlcxp { unsigned short fillen; char filnam[15]; }; /*@unused@*/static struct sqlcxp sqlfpn = { 14, "12345678901.pc" }; The code is an extract of some machine generated SQL. I have added the "/*@unused@*/". I run splint on both files below, the second time with the file names re-ordered. > splint +weak -typeuse -fcnuse -redef foo.c bar.c Splint 3.1.1.2 --- 08 Mar 2006 Finished checking --- no warnings > splint +weak -typeuse -fcnuse -redef bar.c foo.c Splint 3.1.1.2 --- 08 Mar 2006 foo.c:48:5: String literal with 15 characters (counting null terminator) is assigned to char [10] (insufficient storage available): "12345678901.pc" A string literal is assigned to a char array too small to hold it. (Use -stringliteraltoolong to inhibit warning) Finished checking --- 1 code warning My guess is that splint is keeping the first structure definition in a symbol table and is not recording (or utilizing) the second definition. The warning in this case is not correct. The new structure definition with the same name does have enough storage. There maybe many things wrong with this code [like it does nothing], but the reported error is not valid. Also, if you have a large project where foo.c and bar.c are not close together and you did not see a structure re-definition warning (like when -redef inhibits it), it can be very confusing to see this error message. In my case, there were many re-definition message as the embedded SQL pre-processor adds many identical structure in every file it analyzes. It was close enough to realize what the problem was. However, this looks like a systemic problem internal to splint in it's handling of re-definitions. Re-definitions are not good practice, but they are valid 'C'. This is a mis-match in how splint is parsing 'C' and how the ANSI spec would specify parsing... I think more confusing error message could result by making the re-defined structures diverge more in their content. I am using a CVS version of splint (Circa march 8th). Regards, Bill Pringlemeir. From niall at xrnd.com Fri Mar 17 10:03:01 2006 From: niall at xrnd.com (Niall Dalton) Date: Fri Jun 9 09:16:54 2006 Subject: [splint-discuss] array parameter qualifiers Message-ID: <441ACF41.9070200@xrnd.com> Hello, splint 3.1.1 does not appear to support array parameter qualifiers - either the cv-qualifiers within the [] of an array parameter or use of static as a minimum size specifier. The latter is one I'm interested in. int sum(int a[static 10]) { // a has at least a[0] to a[9] existing and contiguous ... } Am I correct that this is seen as a parse error currently by splint? Are there plans to make use of this information? Regards, Niall From luke.w.imhoff at medtronic.com Fri Mar 17 10:10:53 2006 From: luke.w.imhoff at medtronic.com (Imhoff, Luke) Date: Fri Jun 9 09:16:55 2006 Subject: [splint-discuss] array parameter qualifiers Message-ID: <88BB13D21A4BBB409F1F60D31E08252A01733AE4@MSPM1BMSGM14.ent.core.medtronic.com> Splint doesn't support array parameters at all really. It just assumes it's a pointer. Splint should emit some warning about the size being dropped. What standard is the inner 'static' from? -----Original Message----- From: splint-discuss-bounces@cs.virginia.edu [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of Niall Dalton Sent: Friday, March 17, 2006 9:01 AM To: splint-discuss@ares.cs.Virginia.EDU Subject: [splint-discuss] array parameter qualifiers Hello, splint 3.1.1 does not appear to support array parameter qualifiers - either the cv-qualifiers within the [] of an array parameter or use of static as a minimum size specifier. The latter is one I'm interested in. int sum(int a[static 10]) { // a has at least a[0] to a[9] existing and contiguous ... } Am I correct that this is seen as a parse error currently by splint? Are there plans to make use of this information? Regards, Niall _______________________________________________ splint-discuss mailing list splint-discuss@ares.cs.Virginia.EDU http://www.cs.Virginia.EDU/mailman-2.1.5/listinfo/splint-discuss From niall at xrnd.com Fri Mar 17 10:21:04 2006 From: niall at xrnd.com (Niall Dalton) Date: Fri Jun 9 09:16:56 2006 Subject: [splint-discuss] array parameter qualifiers In-Reply-To: <88BB13D21A4BBB409F1F60D31E08252A01733AE4@MSPM1BMSGM14.ent.core.medtronic.com> References: <88BB13D21A4BBB409F1F60D31E08252A01733AE4@MSPM1BMSGM14.ent.core.medtronic.com> Message-ID: <441AD37C.1050401@xrnd.com> Imhoff, Luke wrote: > Splint doesn't support array parameters at all really. It just assumes > it's a pointer. Splint should emit some warning about the size being > dropped. What standard is the inner 'static' from? C99. Just looking at the ISO C99 committee draft of May 6 2005, its in section 6.7.5.3 (page 119, point 7) on the semantics of function declarators. niall From luke.w.imhoff at medtronic.com Fri Mar 17 10:25:06 2006 From: luke.w.imhoff at medtronic.com (Imhoff, Luke) Date: Fri Jun 9 09:16:58 2006 Subject: [splint-discuss] array parameter qualifiers Message-ID: <88BB13D21A4BBB409F1F60D31E08252A01733B18@MSPM1BMSGM14.ent.core.medtronic.com> Splint comforms to C90 at best. -----Original Message----- From: splint-discuss-bounces@cs.virginia.edu [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of Niall Dalton Sent: Friday, March 17, 2006 9:19 AM To: Discussions about the Splint annotation-assisted static analysis project Subject: Re: [splint-discuss] array parameter qualifiers Imhoff, Luke wrote: > Splint doesn't support array parameters at all really. It just > assumes it's a pointer. Splint should emit some warning about the > size being dropped. What standard is the inner 'static' from? C99. Just looking at the ISO C99 committee draft of May 6 2005, its in section 6.7.5.3 (page 119, point 7) on the semantics of function declarators. niall _______________________________________________ splint-discuss mailing list splint-discuss@ares.cs.Virginia.EDU http://www.cs.Virginia.EDU/mailman-2.1.5/listinfo/splint-discuss From ai2097 at yahoo.com Mon Mar 20 05:48:22 2006 From: ai2097 at yahoo.com (Quandary) Date: Fri Jun 9 09:17:26 2006 Subject: [splint-discuss] Foo exported, but not specified Message-ID: <20060320104815.4217.qmail@web51704.mail.yahoo.com> Hey all, I'm using splint -strict to try and shake down software as I write it. However, I've run into a set of warnings (export-all) I can't seem to cleanly resolve. I can't figure out any way to "specify" the values, so that splint stops complaining. All I can do is relax the checks, or include the header files on the splint command line, both of which are wrong, and the latter of which causes a whole slew of different errors. Here's some sample code, along with splint's output: ###test.h### enum e_my_enum { FOOENUM = 0 }; typedef enum e_my_enum my_enum; /*@unused@*/ extern my_enum g_my_global; ###test.c#### #include "test.h" my_enum g_my_global; int main(/*@unused@*/int argc, /*@unused@*/char** argv) { return (int)FOOENUM; } ###splint output### $ splint -strict test.c Splint 3.1.1 --- 08 Dec 2005 test.h:2:5: Constant exported, but not specified: FOOENUM A constant is exported, but not specified. (Use -exportconst to inhibit warning) test.h:5:24: Type exported, but not specified: my_enum A type is exported, but not specified. (Use -exporttype to inhibit warning) test.h:8:16: Variable exported, but not specified: g_my_global A variable is exported, but not specified. (Use -exportvar to inhibit warning) Finished checking --- 3 code warnings ###END### What is the proper way to fix these warnings? __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From Michael.Wojcik at MicroFocus.com Mon Mar 20 11:45:24 2006 From: Michael.Wojcik at MicroFocus.com (Michael Wojcik) Date: Fri Jun 9 09:17:45 2006 Subject: [splint-discuss] Foo exported, but not specified Message-ID: <11352F9641010A418AD5057945A3A6594CBA18@MTV-EXCHANGE.microfocus.com> > From: splint-discuss-bounces@cs.virginia.edu > [mailto:splint-discuss-bounces@cs.virginia.edu] On Behalf Of Quandary > Sent: Monday, 20 March, 2006 05:48 > > I'm using splint -strict to try and shake down > software as I write it. However, I've run into a set > of warnings (export-all) I can't seem to cleanly > resolve. I can't figure out any way to "specify" the > values, so that splint stops complaining. All I can do > is relax the checks, or include the header files on > the splint command line, both of which are wrong, and > the latter of which causes a whole slew of different > errors. > > Here's some sample code, along with splint's output: [snipped] > > test.h:2:5: Constant exported, but not specified: > FOOENUM > A constant is exported, but not specified. (Use > -exportconst to inhibit warning) One of splint's many poorly-worded messages. "specified" how? Obviously "specified" doesn't mean "declared" or "defined" in the sense those terms are used by the C standard, since clearly FOOENUM is both. So "specified" here is some term of art specific to splint - but it's not explained by the error text, nor by the documentation, which is woefully out of date. (I'm gradually coming to the conclusion that splint in its current form is not suitable for general serious use, and won't be until it has a new maintainer who can fix the problems with message text and documentation. Some of the splint source is pretty lousy too, eg with unspecified function parameter lists. And while I'd like to volunteer for the job, I can't make that sort of time commitment right now.) In this case, what the message means within splint is that FOOENUM is declared in a header, which is not part of a library, and is not an "import"; and FOOENUM itself is not static (always true for a type, since types don't have storage classes). (See exprChecks_checkExport in exprChecks.c.) I *think* splint is complaining because you're taking a value you've defined internally (that is, splint assumes that only you will be using test.h), and you're publishing it to the world by returning it from a function. So what you want to do is to tell splint that it's OK to do this. In the splint code, it appears your only options for doing that are to hoist the definition out of test.h into test.c (though that might produce a different warning), or tell splint that test.h should have the "library" or "import" flag attached to it, or suppress the warning. Setting the "library" or "import" flag means getting splint to set one of the following for the "kind" field of the file structure for test.h: FL_LIB, FL_STDHDR, FL_STDLIB, or FL_IMPORT. Clearly the middle two aren't appropriate, which leaves FL_LIB and FL_IMPORT. It appears that FL_LIB is only set when processing something splint believes is part of the standard library, so that's out. FL_IMPORT is set when processing files via symtable_import (symtable.c), and appears to be used only for preprocessed LCL files, so that's out. In short, I don't think there's any way to suppress this warning short of disabling this particular check, which the error message does indirectly tell you how to do. Bracket the definition of FOOENUM with -exportconst: enum e_my_enum { /*@-exportconst@*/ FOOENUM = 0 /*@=exportconst@*/ }; > test.h:5:24: Type exported, but not specified: my_enum > A type is exported, but not specified. (Use > -exporttype to inhibit warning) > test.h:8:16: Variable exported, but not specified: > g_my_global > A variable is exported, but not specified. (Use > -exportvar to inhibit > warning) These can be suppressed similarly. Combining all three: ---- test.h ---- enum e_my_enum { /*@-exportconst@*/ FOOENUM = 0 /*@=exportconst@*/ }; /*@-exporttype@*/ typedef enum e_my_enum my_enum; /*@=exporttype@*/ /*@unused@*/ /*@-exportvar@*/ extern my_enum g_my_global; /*@=exportvar@*/ ---- test.h ---- -- Michael Wojcik Principal Software Systems Developer, Micro Focus From ai2097 at yahoo.com Mon Mar 20 20:21:59 2006 From: ai2097 at yahoo.com (Quandary) Date: Fri Jun 9 09:18:46 2006 Subject: [splint-discuss] Foo exported, but not specified In-Reply-To: <11352F9641010A418AD5057945A3A6594CBA18@MTV-EXCHANGE.microfocus.com> Message-ID: <20060321012152.73526.qmail@web51705.mail.yahoo.com> --- Michael Wojcik wrote: > (I'm gradually coming to the conclusion that splint > in its current form is not suitable for general > serious use, and won't be until it has a new > maintainer who can fix the problems with message > text and documentation. Some of the splint source is > pretty lousy too, eg with unspecified function > parameter lists. And while I'd like to volunteer for > the job, I can't make that sort of time commitment > right now.) I came to a similar conclusion the last time I gave splint a shot -- it has tons of potential, but enough rough edges to make it unpalatable at best for "real" use. I've toyed with the idea of trying to fix splint or write a similar tool from scratch, but, like you, I can't dedicate the resources required to undertake such a project. > In short, I don't think there's any way to suppress > this warning short of disabling this particular > check, which the error message does indirectly tell > you how to do. I went with a similar workaround, but instead used /*@-exportany@*/ at the start of each header file. Since the flag is limited in scope to the file, and these errors never appear if the headers are processed directly by splint, I think (hope?) that this is a sane solution for the time being. Thanks again, -- Q __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com From michael.winkler at lvf.liebherr.com Tue Mar 21 12:20:09 2006 From: michael.winkler at lvf.liebherr.com (michael.winkler) Date: Fri Jun 9 09:19:28 2006 Subject: [splint-discuss] [Likely SPAM] the file Message-ID: <200603211720.k2LHK3FE000228@ares.cs.Virginia.EDU> how are you? i send the details. OK ? -------------- next part --------------