AW: @tiny statement (fwd)
-- Forwarded message -- Date: Wed, 2 Oct 2002 07:33:31 +0200 From: [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: AW: @tiny statement Hello, I have had the same problem too. I also programming an embedded system using splint. A other way is to activate the switch -syntax to ignore the @ char. In the next step I defined a macro tiny for splint checking. (with the -Dtiny switch) So the splint also ignore the statment @tiny. I know this is not a good way but we have auto-generated code that we can't change and so this is the only way to check the code. -Ursprüngliche Nachricht- Von: Simon Hosie [mailto:[EMAIL PROTECTED]] Gesendet: Mittwoch, 2. Oktober 2002 01:06 An: [EMAIL PROTECTED] Betreff: RE: @tiny statement Filippo Ferrara: I have some problem with the Cosmic compiler statement @tiny which is not recognised by Splint. What can I do to make Splint ignore @tiny (without commenting it)? or what ca I do to Splint to recognise such statement? I'm inclined to infer that if you don't want to comment it then it's not actually conflicting with Splint annotations, and the statement appears naked in the code. In that case: Firstly, see if you can acheive the same result with #pragma. That's the normal way of doing things that aren't portable (if you can't, you may want to coax the author into adding something like that). Otherwise, if the compiler provides some pre-defined macro to identify itself to the source code (assume it's __COSMIC__) add something like this in a header file common to all the source files: #ifdef __COSMIC__ #define AT_TINY @tiny #else #define AT_TINY #endif or if they don't provide a macro: #ifndef S_SPLINT_S #define AT_TINY #else #define AT_TINY @tiny #endif Then replace all your '@tiny's with 'AT_TINY'. Doing a search I see that Cosmic's an embedded compiler. Are there a lot of embedded programmers using splint? ** Besuchen Sie unsere neue Homepage http://www.magnasteyr.com Please visit our new homepage http://www.magnasteyr.com This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the system manager. This footnote also confirms that this email message has been swept for the presence of computer viruses. **
Re: @tiny statement
You can use the commentchar flag to set splint's command character to something other than . For example, -commentchar # (and then the splint annotations would be marked as /*#only#*/. --- Dave On Tue, 1 Oct 2002, Filippo Ferrara wrote: Hi to everybody I have some problem with the Cosmic compiler statement tiny which is not recognised by Splint. What can I do to make Splint ignore tiny (without commenting it)? or what ca I do to Splint to recognise such statement? Filippo Ferrara
Re: deallocation subroutine
Hi David, You need to add an annotation to your DeAllocateStruct procedure to document that it deallocates the passed pointer: int DeAllocateStruct(/*@only*/ struct testStruct **local); See http://www.splint.org/manual/html/sec5.html for more on the /*@only*/ annotation. --- Dave On Thu, 19 Sep 2002, David Djajaputra wrote: Perhaps this is because I'm doing something really stupid here, but I have not been able to modify the following simple test program to clear all splint complaints. The main problem is splint doesn't seem able to recognize that I deallocate my pointers using the DeAllocateStruct routine. And I don't want to use the -mustfreefresh flag because I do want to check the other situations where I free my memory explicitly in the main program. Any suggestions/comments? Thanks. David #include stdio.h #include stdlib.h #include string.h struct testStruct { char *testStructString; }; int DeAllocateStruct(struct testStruct **local); /**/ int main () { struct testStruct *localStruct; struct testStruct *secondStruct; char *localString1 = 1 localStruct\n; char *localString2 = 2 localStruct\n; char *secondString1 = 1 secondStruct\n; char *secondString2 = 2 secondStruct\n; /**/ localStruct = malloc(sizeof(localStruct)); if (localStruct != NULL) { printf(\nlocalStruct ready to work\n); localStruct-testStructString = malloc(sizeof(localString1)); if (localStruct-testStructString != NULL) { strcpy(localStruct-testStructString,localString1); printf(string = %s,localStruct-testStructString); strcpy((*localStruct).testStructString,localString2); printf(string = %s,(*localStruct).testStructString); } } /**/ secondStruct = malloc(sizeof(secondStruct)); if (secondStruct != NULL) { printf(\nsecondStruct ready to work\n); secondStruct-testStructString = malloc(sizeof(secondString1)); if (secondStruct-testStructString != NULL) { strcpy(secondStruct-testStructString,secondString1); printf(string = %s,secondStruct-testStructString); strcpy((*secondStruct).testStructString,secondString2); printf(string = %s,(*secondStruct).testStructString); } } /**/ (void) DeAllocateStruct(localStruct); (void) DeAllocateStruct(secondStruct); /**/ /* The following will never be executed if the deallocation is successful */ if (localStruct != NULL) { printf(string = %s,localStruct-testStructString); } if (secondStruct != NULL) { printf(string = %s,secondStruct-testStructString); } return(0); } /**/ int DeAllocateStruct(struct testStruct **local) { free((*local)-testStructString); (*local)-testStructString = NULL; free(*local); *local = NULL; return(0); } /**/
Re: Typechecking integral types, retaining most access.
You could fake this by making them enum types: # ifdef S_SPLINT_S typedef enum { S_JUNK1 } seconds; typedef enum { S_JUNK2 } minutes; # else typedef int seconds; typedef int minutes; # endif If you used the -enumint flag, then you'll get the warnings you want for this. --- Dave On Wed, 21 Aug 2002, Simon Hosie wrote: Was searching the archives and found the post about using /*@abstract*/ in a typedef. That's almost what I'm after, but it's much too obstructive for me. What I'd like is something along these lines: typedef /*@abstract*/ int seconds; typedef /*@abstract*/ int minutes; void test(void) { seconds tod_sec = (seconds)5; // legal minutes tod_min = (minutes)7; // legal tod_min++; // legal tod_sec = tod_min; // illegal tod_min = 10; // illegal if (tod_min tod_sec) // illegal ; } 'tod_min = 10' may be clear in context, but it could easily be obfuscated by macros or less obvious variable names... so I'd be happy to see it trapped.
Re: Uninitialized global variables
The only way to get warnings for uninitalized non-local variables is by using annotations (/*@globals undef a@*/). In the example you have, its simple enough to do a flow analysis to see that a is used before it is initialized, but in general doing that type of global flow analysis is expensive. --- Dave On Tue, 13 Aug 2002, Massimiliano Cialdi wrote: I need to search for uninitialized variables in a not-instrumented source code (w/o annotations). No problem with local (automatic) variables but I don't know how to analize global variables. for example: -- static int a; static void s() { if(a==34) a=33; } int main(void) { int r; if(r==66) r = 65; s(); return 0; } in this case splint only report Variable r used before definition, but nothing about a. thanks -- Massimiliano Cialdi [EMAIL PROTECTED] [EMAIL PROTECTED]
Re: #define tmError(lev, fmt, ...)
Hi Torsten, Splint doesn't support ... in macro definitions. Variadic macros (as used in your example) are in ISO C99 though, so they should be supported. Splint supports gcc's __attribute__ syntax at the level of ignoring it (but parsing it without complaint). --- Dave On Mon, 12 Aug 2002, Torsten Mohr wrote: Hi, i use gcc and some of its extensions, for example: #define tmError(lev, fmt, ...)\ tmErrorFunc(lev, __FILE__, __LINE__, fmt, __VA_ARGS__) It seems that +gnuextensions doesn't enable this syntax. This would also be great for some embedded code that uses extensions like __attribute__ ((section)). Is there some other way to express the above #define in ANSI C? Best regards, Torsten.
Re: annotating use of memory
Hi, The first warning is: widget.h:18:103: Released storage x-name reachable from parameter at return point for, /*@null@*/ extern inline char *widgetName(/*@null@*/ widget *x) { return (x != NULL) ? x-name : NULL; } What you need here is an /*@observer@*/ annotation to indicate that the caller should not modify the result (even though it is a mutable object). This will override the implicit only on the function result. This leaves 2 warnings in widgetNew: widget.c:9:49: Only storage str not released before return widget.c:6:22: Storage str becomes only widget.c:13:32: Fresh storage str not released before return widget.c:10:5: Fresh storage str allocated The first results from the /*@only@*/ annotation on the local variable declaration. This isn't necessary --- splint should be able to figure out there is no memory leak anyway, but it doesn't (there should probably be a warning for memory annotations on local declarations, since local declarations are permitted to change state, it doesn't really make sense to annotate them). The warning for line 13 is a legitimate memory leak --- we should free str before returning. The warnings for widgetInit are similar: widget.c:26:52: Only storage str not released before return Since str is declared with /*@only@*/ in widget.h, the implementation of widgetInit is responsible for its storage. We should free it before returning. Similarly, for x for the next return. After these changes, splint doesn't produce any warnings. The modified code is below. Best, --- Dave widget *widgetNew(const size_t size) { char *str; widget *x; if (size 1) { errno = EINVAL; return NULL; } str = (char *) malloc(size); if (str == NULL) return NULL; /* malloc sets errno */ x = (widget *) malloc(sizeof(struct widget)); if (x == NULL) { free (str); return NULL; /* malloc sets errno */ } if (widgetInit(x,str,1) == NULL) return NULL; x-flags |= WIDGET_MALLOCED; return x; } widget *widgetInit(widget *x, const char *str, const unsigned int initialize) { if (x == NULL) { errno = EINVAL; if (str != NULL) free (str); return NULL; } if (str == NULL) { errno = EINVAL; widgetFree (x); return NULL; } x-name = (char *) str; if (initialize != 0) *x-name = '\0'; x-flags = 0; return x; } On Tue, 23 Jul 2002 [EMAIL PROTECTED] wrote: Hello all, First let me say thank you for splint. When I use it, I feel like I have an experienced and meticulous C coder looking over my shoulder. Lately, I've tried something a little more ambitious, and either I don't understand what is wrong with my code or I'm failing to annotate it properly, so I'm coming to you for help. I've made a small example to show what approach I'm using and what messages splint is generating. Essentially I want to malloc memory for a structure and a string component of the structure, use it, and later free all the memory. Optionally, I want to be able to use a non-dynamically allocated structure and string. I'm including below the .splintrc file, widget.h, widget.c, and the splint messages. I'd be very grateful to anyone who can help me understand what I need to do here. Thanks. -Dan Good __.splintrc_ -unrecog #-mustfreefresh #-usereleased -compdef #-mustfreeonly #-compmempass -exportlocal __widget.h__ #ifndef _WIDGET_H #define _WIDGET_H 1 #define WIDGET_MALLOCED 1 struct widget { /*@only@*/ char *name; unsigned int flags; }; typedef /*@abstract@*/ struct widget widget; /*@null@*/ /*@only@*/ widget *widgetNew(const size_t size); /*@null@*/ widget *widgetInit(/*@null@*/ /*@partial@*/ /*@only@*/ widget *x, /*@null@*/ /*@only@*/ const char *str, const unsigned int initialize); void widgetFree(/*@null@*/ /*@only@*/ widget *x); /*@null@*/ extern inline char *widgetName(/*@null@*/ widget *x) { return (x != NULL) ? x-name : NULL; } #endif __widget.c__ #include stdlib.h #include errno.h #include widget.h widget *widgetNew(const size_t size) { /*@only@*/ char *str; widget *x; if (size 1) { errno = EINVAL; return NULL; } str = (char *) malloc(size); if (str == NULL) return NULL; /* malloc sets errno */ x = (widget *) malloc(sizeof(struct widget)); if (x == NULL) return NULL; /* malloc sets errno */ if (widgetInit(x,str,1) == NULL) return NULL; x-flags |= WIDGET_MALLOCED; return x; } widget *widgetInit(widget *x, const char *str, const unsigned int initialize) { if (x == NULL) { errno = EINVAL; return NULL; } if (str == NULL) { errno = EINVAL; return NULL; } x-name = (char *) str; if (initialize != 0) *x-name = '\0'; x-flags = 0; return x; } void widgetFree(widget *x) { if (x != NULL (x-flags WIDGET_MALLOCED)
Re: char a = 0
Hi Deepak, You can use +charint to allow any int to be used as a char, but there is no way to allow 0 but not 1. I recommend using char a = '\0'; instead. --- Dave On Mon, 22 Jul 2002, Deepak Mohan wrote: Hi, I've just started using splint. How do I prevent splint for saying that '0' is of type 'int' and that the assignment type is wrong? I want splint to display the error when 'char a = 1' is used though. Deepak
Re: Assigning a malloced data to a member of a returned struct
I think you want: struct freecell_solver_append_string_struct { /*@null@*/ /*@reldef@*/ /*@owned@*/ char *buffer; /*@null@*/ /*@reldef@*/ /*@dependent@*/ char *end_of_buffer; size_t max_size; int size_of_margin; }; This indicates that the buffer field is responsible for the storage it points to, but there may be other references to that storate; the end_of_buffer is a dependent reference (since it points to somewhere in the buffer). The reldef annotations are used to indicate that the fields may not be defined, since freecell_solver_append_string_alloc returns an allocated by not defined structure. --- Dave On Mon, 22 Jul 2002, Shlomi Fish wrote: I have the following header: /** app_str.h ***/ #include string.h #include stdio.h #include stdarg.h #include stdlib.h #ifndef __APP_STR_H #define __APP_STR_H #ifdef __cplusplus extern C { #endif struct freecell_solver_append_string_struct { /*@kept@*/ /*@out@*/ char * buffer; char * end_of_buffer; size_t max_size; int size_of_margin; }; typedef struct freecell_solver_append_string_struct freecell_solver_append_string_t; extern /*@null@*/ freecell_solver_append_string_t * freecell_solver_append_string_alloc(int size_margin); extern int freecell_solver_append_string_sprintf( freecell_solver_append_string_t * app_str, char * format, ... ); extern char * freecell_solver_append_string_finalize( freecell_solver_append_string_t * app_str ); #ifdef __cplusplus } #endif #endif /* #ifndef __APP_STR_H */ /***/ And the following module: /*** app_str.c */ #include string.h #include stdio.h #include stdarg.h #include stdlib.h #include app_str.h #define GROW_BY 4000 freecell_solver_append_string_t * freecell_solver_append_string_alloc(int size_margin) { freecell_solver_append_string_t * app_str; if (size_margin GROW_BY) { return NULL; } app_str = malloc(sizeof(freecell_solver_append_string_t)); if (app_str == NULL) { return NULL; } app_str-max_size = GROW_BY; app_str-end_of_buffer = app_str-buffer = malloc(app_str-max_size); if (app_str-buffer == NULL) { free(app_str); return NULL; } app_str-size_of_margin = size_margin; return app_str; } int freecell_solver_append_string_sprintf( freecell_solver_append_string_t * app_str, char * format, ... ) { int num_chars_written; va_list my_va_list; va_start(my_va_list, format); num_chars_written = vsprintf(app_str-end_of_buffer, format, my_va_list); app_str-end_of_buffer += num_chars_written; /* * Check to see if we don't have enough space in which case we should * resize * */ if (app_str-buffer + app_str-max_size - app_str-end_of_buffer app_str-size_of_margin) { char * old_buffer = app_str-buffer; app_str-max_size += GROW_BY; app_str-buffer = realloc(app_str-buffer, app_str-max_size); /* * Adjust end_of_buffer to the new buffer start * */ app_str-end_of_buffer = app_str-buffer + (app_str-end_of_buffer - old_buffer); } return num_chars_written; } char * freecell_solver_append_string_finalize( freecell_solver_append_string_t * app_str ) { char * ret; ret = strdup(app_str-buffer); free(app_str-buffer); free(app_str); return ret; } /*/ When I process it with splint (ver. 3.0.1.3.1) I get a gazillion of warnings. The first ones are: app_str.c: (in function freecell_solver_append_string_alloc) app_str.c:27:30: Only storage assigned to kept: app_str-buffer = malloc(app_str-max_size) The only reference to this storage is transferred to another reference (e.g., by returning it) that does not have the only annotation. This may lead to a memory leak, since the new reference is not necessarily released. (Use -onlytrans to inhibit warning) app_str.c:27:5: Kept storage app_str-buffer assigned to implicitly only: app_str-end_of_buffer = app_str-buffer = malloc(app_str-max_size) storage is transferred to a non-temporary reference after being passed as keep parameter. The storage may be released or new aliases created. (Use -kepttrans to inhibit warning) How do I get rid of them? Regards, Shlomi Fish -- Shlomi Fish[EMAIL PROTECTED] Home Page: http://t2.technion.ac.il/~shlomif/ Home E-mail: [EMAIL PROTECTED] He who re-invents the wheel, understands much better how a wheel works.
Re: Wish: more checks and
# [olheureu@WKS13 gnss 339] $ splint +boundswrite +boundsread ../tst5.c # Splint 3.0.1.6 --- 27 Mar 2002 # # tst5.c: (in function main) # tst5.c:12:36: Right operand of may be negative (int): 19 n # The right operand to a shift operator may be negative (behavior undefined). # (Use -shiftnegative to inhibit warning) # # Finished checking --- 1 code warning Do somebody has a clue to let Splint report the first warning, and not the second? One way to eliminate this warning would be to declare n as unsigned int. Splint isn't doing enough numerical analysis here to know that it is non-negative. --- Dave
Re: unused code, calltree
Yes, you can use splint to find unused global functions. If you check complete programs use the +topuse flag. See http://www.splint.org/manual/html/sec13.html for details. Splint doesn't produce call trees, but +show-all-uses will display information where all external identifiers are used. --- Dave On Sun, 30 Jun 2002, Torsten Mohr wrote: Hi everybody, i have two questions regarding splint, can i use it somehow to test a large project for unused code? It must be easy to test for unused static functions in a file, but can it find unused global functions somehow? Another question, can splint generate a calltree? Some way of visualisation which function calls which other? Thank you for any hints, Torsten.
Re: Newbie: Typechecking integral types
Hi Andreas, Normal typedef's are checked by structure. To get checking by name, you want to use abstract types. Splint supports this using the /*@abstract*/ annotation in the type definition. For example: typedef /*@abstract*/ int Type1; typedef /*@abstract*/ int Type2; /*@noaccess Type1, Type2@*/ void test() { Type1 a = 0; Type2 b = 0; a=b; } You will get warnings for the assignment (as well as the initializations). You need the /*@noaccess Type1, Type2@*/, since by default code in the file that defines the types is permitted to access the type representations. See Section 4.3 of the Splint manual for information on Splint's support for abstract types (http://www.splint.org/manual/html/sec4.html). --- Dave On Fri, 12 Apr 2002, Andreas Rasmusson wrote: Hi, Is it possible to get warnings if two typedef:ed integer types are assigned to eachother? I.e i would like a warning when assigning a=b in the example below. cheers, Andreas Example Program: typedef int Type1; typedef int Type2; void test() { Type1 a = 0; Type2 b = 0; a=b; } Splint output: --- splint test.c Splint 3.0.1.6 --- 27 Mar 2002 Finished checking --- no warnings ---
Re: Manual versions
On Fri, 15 Mar 2002, Alexander Mai wrote: Browsing on the website I can see two manual versions, 3.0.1 from January and 3.0.6 from February. This should be sync'ed ? Unfortunately, I know of no way to create a document that is both suitable for web viewing and printing. Hence, some hand editing is required to produce the HTML version and we only do this when there are new sub-versions (the 3.0.1.6 manual is the latest PDF-available version; we'll update the web version for 3.0.2). If someone has a better solution for this, or can volunteer to produce good HTML from our Word document, we'd be appreciative. Also the HTML complete file which one might be tempted to download is not a stand-alone file, IIRC it links images, style-sheets, etc. Perhaps one should offer a package for offline viewing? (some .tar.gz archive perhaps including all required files). The pdf version http://www.splint.org/downloads/manual.pdf is your best option for off-line viewing. --- Dave --- Alexander Mai [EMAIL PROTECTED]
Does this feature exists? (fwd)
-- Forwarded message -- Date: Tue, 26 Feb 2002 10:59:46 +0100 From: Raimar Falke [EMAIL PROTECTED] Reply-To: [EMAIL PROTECTED] To: [EMAIL PROTECTED] Subject: Does this feature exists? Suppose I have the following code: int foo(int m) { int i, result = 0, j; for(i = 0; i m; i++) { j = bar(i); foobar(j); result += j; } return result; } Can splint be instructed to produce an error message like: Warning: line 123: variable j is used only used in a deeper scope. The declaring of variable j can be moved in the scope starting at line 456. If not: do you know any program which can do this? Raimar -- email: [EMAIL PROTECTED] There are three ways to get something done. Do it yourself, hire someone to do it for you or forbid your kids to do it.
Moderating List
Sorry about the spam messages that been sent through the lclint-interest mailing list. At this time, we are not able to set the list up to only allow list members to post to the list, so I have temporarily set the list to be moderated by me. I hope this is a temporary measure, but until we have a better solution to the spam problem, I will moderate the list (but not prevent any message postings other than spam). --- Dave
Re: Questions about libraries
Hello, I have two specific questions about the supplied libraries and a more general one. Experience is with the current alpha version, BTW. 1) PATH_MAX is not within the posix-lib. I don't have the old Posix standard nor the Programming Guide at my hands but within the draft for the new posix (Austin group) it's already in. Somehow I believe it's missing ... 2) Checking some code I get Access non-existent field st_mtime of struct stat: though unix-lib was supplied. Why is this field missing? Bugs in the libraries! Thanks for reporting them. Finally the 'general' question: code which does checks on macros from the system libs (ansi, unix, etc.) like the following #if 1 UCHAR_MAX will always fail if I use the supplied libs? Yes. --- Dave