From please.no.spam.here at gmail.com Sun Mar 4 05:01:23 2007 From: please.no.spam.here at gmail.com (Jorge Peixoto de Morais Neto) Date: Sun Mar 4 05:01:29 2007 Subject: [splint-discuss] how to annotate a pointer to static memory returned by a function Message-ID: static char *statictest(){ static char buff[10]; return buff; } int main(){ /*@unused@*/ char *p=statictest(); return 0; } When the above program is fed to splint, the following output results: statictest.c: (in function statictest) statictest.c:3:10: Unqualified static storage buff returned as implicitly only: buff Static storage is transferred in an inconsistent way. (Use -statictrans to inhibit warning) statictest.c: (in function main) statictest.c:8:12: Fresh storage p not released before return A memory leak has been detected. Storage allocated locally is not released before the last reference to it is lost. (Use -mustfreefresh to inhibit warning) statictest.c:7:24: Fresh storage p created Finished checking --- 2 code warnings How can I correctly annotate the code to avoid this? I couldn't find in the manual. Thank you in advance. -- Software is like sex: it is better when it is free. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.cs.Virginia.EDU/pipermail/splint-discuss/attachments/20070304/f47c2f57/attachment.htm From ptp at lysator.liu.se Sun Mar 4 16:11:38 2007 From: ptp at lysator.liu.se (Tommy Pettersson) Date: Sun Mar 4 16:12:47 2007 Subject: [splint-discuss] how to annotate a pointer to static memory returned by a function In-Reply-To: References: Message-ID: <20070304211138.GA10487@static-81.216.50.98.addr.tdcsong.se> On Sun, Mar 04, 2007 at 07:01:23AM -0300, Jorge Peixoto de Morais Neto wrote: > static char *statictest(){ > static char buff[10]; > return buff; > } > int main(){ > /*@unused@*/ > char *p=statictest(); > return 0; > } > When the above program is fed to splint, the following output results: [...] > How can I correctly annotate the code to avoid this? I couldn't find in the > manual. Splint has a model for memory management. It is much more complex than the usual pointers and types in C. It is also far more restrictive in how pointers can be used. The purpose is to make it impossible to get memory faults. Though, for practical use it is sometimes too restrictive. It can not, for one thing, handle dynamically changing properties. It is also incapable of modeling the realloc() function. So, the task is not always how to "correctly annotate the code", because splint's model is just not always powerful enough. In such cases one must resort to more relaxed checking, or even ignore some (false) warnings. This does not mean the code is necessarily bad, it just means splint can't be used to verify it is all good. In your case, however, the problem is quite simple. The statictest() function has no annotation for what kind (in the splint model) of pointer it returns, so splint uses the default, which is 'only pointer'. This is supposed to be memory that you have allocated in the function, and that you return to the calling function together with the obligation to free it. This is clearly not the case. The ownership of the static array 'buff' should not be transfered out of the function, and certainly not free()ed by the calling function. I think /*@dependent@*/ or /*@shared@*/ could both work, i.e., "static /*@dependent@*/ char *statictest(){..." The way you put your question makes me thing that you perhaps is not yet entirely familiar with the more complex way of looking at memory that splint uses. That is understandable. There is something with the splint manual that makes it hard to understand. At least I think so. I had to read it many, many times before I got (most of) it. But once you do, the warnings from splint becomes very precise and to the point about what splint is upset about. -- Tommy Pettersson From please.no.spam.here at gmail.com Mon Mar 5 09:45:26 2007 From: please.no.spam.here at gmail.com (Jorge Peixoto de Morais Neto) Date: Mon Mar 5 09:53:06 2007 Subject: [splint-discuss] how to annotate a pointer to static memory returned by a function In-Reply-To: <20070304211138.GA10487@static-81.216.50.98.addr.tdcsong.se> References: <20070304211138.GA10487@static-81.216.50.98.addr.tdcsong.se> Message-ID: > > > I think /*@dependent@*/ or /*@shared@*/ could both work, i.e., > "static /*@dependent@*/ char *statictest(){..." > > at memory that splint uses. That is understandable. There is > something with the splint manual that makes it hard to > understand. At least I think so. I was thinking about saying *precisely the same thing* in my first post, but I thought that I would be flamed with comments like "If you don't know what is the problem than shut up". I also have read it multiple times, and find it hard to understand. In my real program, (not the one I put in my first post) I had already tried to use /*@shared@*/, but splint complained "Fresh storage returned as shared (should be only): ret Fresh storage (newly allocated in this function) is transferred in a way that the obligation to release storage is not propagated. Use the /*@only@*/ annotation to indicate the a return value is the only reference to the returned storage. (Use -freshtrans to inhibit warning) arrumanomes.c:56:46: Fresh storage ret created" The only storage was being returned by function basename. It turns out that basename does not seem to have an annotated version for splint; therefore, splint assumes it returns only storage. I have now worked around the problem with the following code in the beginning of the program: #ifdef S_SPLINT_S //if this macro is defined, then the program is being analyzed by splint. splint doesn't seem to understand that the functions dirname and basename return pointers to static storage; the annotations below tell this to splint. /*@shared@*/ extern char *dirname(char *path); /*@shared@*/ extern char *__xpg_basename (char *__path); #define basename __xpg_basename #else #include //basename,dirname #endif //S_SPLINT_S Perhaps I would have seen this workaround earlier if the splint warning told me that if the storage should not have been created with only, I should annotate the function that creates it with /*@shared*@/, since /*@only@*/ is implicit. Perhaps this could be emphasized in the splint manual too. It should be emphasized that only is the default and that if splint does not understand that some memory does not need to be deallocated, perhaps the culprit is a function that is not annotated. Anyway, The biggest problem is that, since I was using +unixlib (also tried with +posixlib), I thought that basename and dirname would be correctly annotated. At first I didn't even consider the possibility that {base,dir}name lacked annotations. I was trying to solve the problem by annotating my variables and functions, and even considered the possibility that {base,dir}name did in fact return dynamically allocated memory that should be freed (I have studied them and found out that the storage they return should *not* be freed). Perhaps the splint's unixlib should be enhanced? PS: How would owned/dependent work? splint would still expect the memory to be deallocated, wouldn't it? -- Software is like sex: it is better when it is free. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.cs.Virginia.EDU/pipermail/splint-discuss/attachments/20070305/068cb4ab/attachment.htm From Tehn_Chin at aapl.com.au Mon Mar 5 22:56:42 2007 From: Tehn_Chin at aapl.com.au (Tehn Chin) Date: Mon Mar 5 23:12:23 2007 Subject: [splint-discuss] MISRA for splint Message-ID: <93CB419709EE7D44806A26CC8B6A0ED789BAA8@aaplcdex4.aapl.com.au> Is there a MISRA annotation for splint? I have check through the archive and fail to find any mention of it. Many thanks, -- Tehn Yit Chin Embedded System Engineer, AAPL - The contents of this email, and any attachments, are strictly private and confidential. - It may contain legally privileged or sensitive information and is intended solely for the individual or entity to which it is addressed. - Only the intended recipient may review, reproduce, retransmit, disclose, disseminate or otherwise use or take action in reliance upon the information contained in this email and any attachments, with the permission of Australian Arrow Pty. Ltd. - If you have received this communication in error, please reply to the sender immediately and promptly delete the email and attachments, together with any copies, from all computers. - It is your responsibility to scan this communication and any attached files for computer viruses and other defects and we recommend that it be subjected to your virus checking procedures prior to use. - Australian Arrow Pty. Ltd. does not accept liability for any loss or damage of any nature, howsoever caused, which may result directly or indirectly from this communication or any attached files. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.cs.Virginia.EDU/pipermail/splint-discuss/attachments/20070306/69f8a296/attachment.htm From please.no.spam.here at gmail.com Tue Mar 6 10:52:13 2007 From: please.no.spam.here at gmail.com (Jorge Peixoto de Morais Neto) Date: Tue Mar 6 10:52:43 2007 Subject: [splint-discuss] How does splint check a pointer to constant Message-ID: When I feed the program #include int main(void){ /*@unused@*/ const char *p="a"; /*@unused@*/ char *x=p; return EXIT_SUCCESS; } to splint +checks, it gives me no warning. But when I compile it with gcc, I am warned that "test.c:5: warning: initialization discards qualifiers from pointer target type". However, when I feed to splint the program #include int main(void){ /*@unused@*/ char const * const teststringarray[]={"a"}; return EXIT_SUCCESS; } , splint warns me that test.c: (in function main) test.c:3:54: Read-only string literal storage used as initial value for unqualified storage: teststringarray[0] = "a" A read-only string literal is assigned to a non-observer reference. (Use -readonlytrans to inhibit warning) , while gcc warns me of nothing (except that the variable teststringarray is unused). The behavior in the program is bugging me (I have similar case in a real program). Why does this happen? There is nothing wrong or suspect in initializing with a string literal an array of const pointers to constants (const * const) How can I fix this? In the manual, I only found something about /*@observer@*/, but this seems absurd, since I am not dealing with an abstract type. Thanks in advance. -- Software is like sex: it is better when it is free. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.cs.Virginia.EDU/pipermail/splint-discuss/attachments/20070306/e214241b/attachment.htm From lholzheid at bihl-wiedemann.de Tue Mar 6 17:02:36 2007 From: lholzheid at bihl-wiedemann.de (Ludolf Holzheid) Date: Tue Mar 6 17:04:25 2007 Subject: [splint-discuss] MISRA for splint In-Reply-To: <93CB419709EE7D44806A26CC8B6A0ED789BAA8@aaplcdex4.aapl.com.au> References: <93CB419709EE7D44806A26CC8B6A0ED789BAA8@aaplcdex4.aapl.com.au> Message-ID: <20070306220236.GA15879@svr5.bihl-wiedemann.de> On Tue, 2007-03-06 14:56:42 +1100, Tehn Chin wrote: > Is there a MISRA annotation for splint? > > I have check through the archive and fail to find any mention of it. As you might already have noticed, there is no '-misra' switch for splint and there are 'required' MISRA rules splint cannot check for, (e.g. rule 14.4, no 'goto'). I am using splint for static code analysis of safety-related software anyway, so I do have a set of switches for splint (see attachment). However, the biggest part of using splint (or any other static analyzer) for claiming MISRA compliance is completing the 'compliance matrix', which also involves defining which rules apply for a certain project and how to check for the rules splint does not help with. Cheers, Ludolf -- --------------------------------------------------------------- Ludolf Holzheid Tel: +49 621 339960 Bihl+Wiedemann GmbH Fax: +49 621 3392239 Flo?w?rthstra?e 41 e-mail: lholzheid@bihl-wiedemann.de D-68199 Mannheim, Germany --------------------------------------------------------------- -------------- next part -------------- #-hints #-forcehints -linelen 120 -parenfileformat +quiet -booltype bool -booltrue true -boolfalse false -standard +strictlib # the flags commented out below are switched on by default or the # '-standard' shortcut. +ansi89limits #+boolops #+casebreak #-charint +cppnames +declundef +elseifcomplete #+evalorder +exportheader +exportheadervar #+exportlocal -externalnamelen 31 +fcnmacros #+firstcase #-floatdouble +forblock #+gnuextensions +ifblock #-ignorequals #-ignoresigns #+imptype #+incompletetype #+incondefs #+initsize -internalnamelen 31 +isoreserved +isoreservedinternal #-longintegral #-longunsignedintegral #+macroassign #+macrofcndecl #+macroparams #+macroparens #+macrostmt -maintype #-matchanyintegral #-modfilesystem #+namechecks #+nestcomment #+noeffect +noparams #+noret +oldstyle #+predassign #+predboolint +protoparammatch #-protoparamname +ptrarith #+realcompare +redecl #+redef -relaxquals #-relaxtypes +retval #+shadow #+shiftimplementation #+shiftnegative +slashslashcomment #+stackref #+sysunrecog #+type #+unreachable #+unrecog #+unrecogdirective #+usedef #+usevarargs +whileblock From ptp at lysator.liu.se Sat Mar 10 06:51:21 2007 From: ptp at lysator.liu.se (Tommy Pettersson) Date: Sat Mar 10 11:45:31 2007 Subject: [splint-discuss] how to annotate a pointer to static memory returned by a function In-Reply-To: References: <20070304211138.GA10487@static-81.216.50.98.addr.tdcsong.se> Message-ID: <20070310145121.GA31033@static-81.216.50.98.addr.tdcsong.se> On Mon, Mar 05, 2007 at 11:45:26AM -0300, Jorge Peixoto de Morais Neto wrote: > > Perhaps the splint's unixlib should be enhanced? They are old and don't know about dirname and basename. It is not very difficult to update them and generate new(er) lcd files, but no one is currently maintaining the splint source. > PS: How would owned/dependent work? splint would still expect the memory to > be deallocated, wouldn't it? I don't know the exact rules, but a dependent pointer can be free:ed wheres free:ing a shared pointer generates a splint warning, so you are right that shared is the better choice. -- Tommy Pettersson From ptp at lysator.liu.se Sat Mar 10 07:13:22 2007 From: ptp at lysator.liu.se (Tommy Pettersson) Date: Sat Mar 10 11:45:33 2007 Subject: [splint-discuss] How does splint check a pointer to constant In-Reply-To: References: Message-ID: <20070310151322.GB31033@static-81.216.50.98.addr.tdcsong.se> On Tue, Mar 06, 2007 at 12:52:13PM -0300, Jorge Peixoto de Morais Neto wrote: > #include > int main(void){ > > /*@unused@*/ const char *p="a"; > /*@unused@*/ char *x=p; > return EXIT_SUCCESS; > } [...] > #include > int main(void){ > /*@unused@*/ char const * const teststringarray[]={"a"}; > return EXIT_SUCCESS; > } [...] > The behavior in the program is bugging me (I have similar case in a real > program). Why does this happen? There is nothing wrong or suspect in > initializing with a string literal an array of const pointers to constants > (const * const) How can I fix this? In the manual, I only found something > about /*@observer@*/, but this seems absurd, since I am not dealing with an > abstract type. splint is ignorant about the const declaration, so an extra /*@observer@*/ is unfortunately required. I'm not sure about the second example, but I think it could have to do with the "inner storage" thing. In the first example I think splint automatically detects that p is an /*@observer@*/ since it is assigned a string literal. But apparently not in the second example. A problem is that there is no easy way to tell splint what the pointers "inside" the array are. Here is how to work around it: typedef /*@observer@*/ char * const_char_ptr_t; const_char_ptr_t teststringarray[] = { "a" }; -- Tommy Pettersson From binary.chen at gmail.com Fri Mar 16 21:08:04 2007 From: binary.chen at gmail.com (Bin Chen) Date: Fri Mar 16 21:08:43 2007 Subject: [splint-discuss] splint can't detect the array overflow? Message-ID: <45FB77B4.3090906@gmail.com> A simple program with splint run with 'splint a.c': binch@binch:/tmp$ splint b.c Splint 3.1.1 --- 20 Jun 2006 b.c: (in function main) b.c:6:2: Path with no return in function declared to return int There is a path through a function declared to return a value on which there is no return statement. This means the execution may fall through without returning a meaningful result to the caller. (Use -noret to inhibit warning) b.c:1:5: Variable exported but not used outside b: b A declaration is exported, but not used outside this module. Declaration can use static qualifier. (Use -exportlocal to inhibit warning) Finished checking --- 2 code warnings binch@binch:/tmp$ cat b.c int b[3]; main() { b[8] = 5; } I can't believe that splint can't point out the overflow, maybe I miss some argument to invoke splint? Thanks in advance. ABAI From wenzel at bbr-vt.de Sun Mar 18 23:18:50 2007 From: wenzel at bbr-vt.de (Wenzel, Bodo) Date: Sun Mar 18 23:34:50 2007 Subject: [splint-discuss] Re: splint can't detect the array overflow? Message-ID: <45FE4769.29474.1C3BA9@wenzel.bbr-vt.de> RTFM: you have to enable bounds checks with "+bounds" Mit freundlichen Gr??en, Bodo Wenzel - Entwicklung Software - -- BBR - Baudis Bergmann R?sch Verkehrstechnik GmbH Pillaustra?e 1e D - 38126 Braunschweig T: +49.531.27300-766 F: +49.531.27300-999 @: wenzel@bbr-vt.de W: http://www.bbr-vt.de Registergericht: AG Braunschweig HRB 3037 Gesch?ftsf?hrer: Dipl.-Ing. Arne Baudis Dipl.-Ing. Thomas Bergmann Dipl.-Ing. Frank-Michael R?sch USt.-ID-Nr.: DE 114 877 881