Analyzing Program Performance With Sun WorkShop

LockLint Naming Conventions

Many LockLint subcommands require you to specify names of locks, variables, pointers, and functions. In C, it is possible for names to be ambiguous; for example, there may be several variables named foo, one of them extern and others static.

The C language does not provide a way of referring to ambiguously named variables that are hidden by the scoping rules. In LockLint, however, a way of referring to such variables is needed. Therefore, every symbol in the code being analyzed is given a formal name, a name that LockLint uses when referring to the symbol. Table A-3 lists some examples of formal names for a function.

Table A-3 Sample Formal Function Names

Formal Name 

Definition 

:func

extern function

file:func

static function

Table A-4 lists the formal names for a variable, depending on its use as a lock, a pointer, or an actual variable.

Table A-4 Sample Formal Variable Names

Formal Name 

Definition 

:var

extern variable

file:var

static variable with file scope

:func/var

Variable defined in an extern function

file:func/var

Variable defined in a static function

tag::mbr

Member of an unnamed struct

file@line::mbr

Member of an unnamed, untagged struct

In addition, any of these may be followed by an arbitrary number of .mbr specifications to denote members of a structure.

Table A-5 contains some examples of the LockLint naming scheme.

Table A-5 LockLint Naming Scheme Examples

Example 

Meaning 

:bar

External variable or function bar

:main/bar

static variable bar that is defined within extern function main

zot.c:foo/bar.zot

Member zot of static variable bar, which is defined within static function foo in file zot.c

foo::bar.zot.bim

Member bim of member zot of member bar of a struct with tag foo, where no name is associated with that instance of the struct (it was accessed through a pointer)

While LockLint refers to symbols in this way, you are not required to. You may use as little of the name as is required to unambiguously identify it. For example, you could refer to zot.c:foo/bar as foo/bar as long as there is only one function foo defining a variable bar. You can even refer to it simply as bar as long as there is no other variable by that name.

C allows the programmer to declare a structure without assigning it a tag. When you use a pointer to such a structure, LockLint must make up a tag by which to refer to the structure. It generates a tag of the format filename@line_number. For example, if you declare a structure without a tag at line 42 of file foo.c, and then refer to member bar of an instance of that structure using a pointer, as in:


typedef struct { ...  } foo;
foo *p;
func1() { p->bar = 0; }

LockLint sees that as a reference to foo.c@42::bar.

Because members of a union share the same memory location, LockLint treats all members of a union as the same variable. This is accomplished by using a member name of % regardless of which member is accessed. Since bit fields typically involve sharing of memory between variables, they are handled similarly: % is used in place of the bit field member name.

When you list locks and variables, you are only seeing those locks and variables that are actually used within the code represented by the .ll files. No information is available from LockLint on locks, variables, pointers, and functions that are declared but not used. Likewise, no information is available for accesses through pointers to simple types, such as this one:


int *ip = &i;
*ip = 0;

When simple names (for example, foo) are used, there is the possibility of conflict with keywords in the subcommand language. Such conflicts can be resolved by surrounding the word with double quotes, but remember that you are typing commands to a shell, and shells typically consume the outermost layer of quotes. Therefore you have to escape the quotes, as in this example:


% lock_lint ignore foo in func \"func\"

If two files with the same base name are included in an analysis, and these two files contain static variables by the same name, confusion can result. LockLint thinks the two variables are the same.

If you duplicate the definition for a struct with no tag, LockLint does not recognize the definitions as the same struct. The problem is that LockLint makes up a tag based on the file and line number where the struct is defined (such as x.c@24), and that tag differs for the two copies of the definition.

If a function contains multiple automatic variables of the same name, LockLint cannot tell them apart. Because LockLint ignores automatic variables except when they are used as function pointers, this does not come up often. In the following code, for example, LockLint uses the name :foo/fp for both function pointers:


int foo(void (*fp)()) {
	(*fp)();
	{
			void (*fp)() = get_func();
			(*fp)();
		 ...