[cfe-dev] NonNull attribute, bug report. (Or misunderstanding)
Ted Kremenek
kremenek at apple.com
Thu Dec 4 10:39:37 PST 2008
On Dec 4, 2008, at 4:27 AM, Paolo Bolzoni wrote:
> Simple declaration:
> extern void* my_memcpy (void *dest, const void *src, unsigned long
> len)
> __attribute__((nonnull (1, 2)));
>
>
>
> The relative AST vertex do have the clang::Attr pointer. But this
> simple loop
> outputs nothing:
>
> my_decl is a clang::FunctionDecl* relative to the function
> declaration.
> non_null_attribute is a clang::NonNullAttr* relative to the non null
> attribute
> of my_decl.
>
> for (unsigned int e = my_decl-> getNumParams(), b = 1; b <= e; ++b) {
> if (non_null_attribute-> isNonNull(b)) {
> std::cout << "Yes, parameter " << b << "is non-null!" <<
> std::endl;
> }
> }
>
> What am I doing wrong? Or there indeed is a clang bug somewhere?
Hi Paolo,
You should use a zero-indexed numbering of the attributes. '1' and
'2' getting converted internally to '0' and '1' to match with the
indexing of parameters in the ASTs.
It may also be instructive to look at how the static analyzer consults
this attribute (this is in GRExprEngineInternalChecks.cpp):
FunctionDecl* FD =
dyn_cast<FunctionDecl>(cast<loc::FuncVal>(X).getDecl());
const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
if (!Att)
return false;
// Iterate through the arguments of CE and check them for null.
unsigned idx = 0;
bool hasError = false;
for (CallExpr::arg_iterator I=CE->arg_begin(), E=CE->arg_end(); I!
=E;
++I, ++idx) {
if (!VMgr.isEqual(state, *I, 0) || !Att->isNonNull(idx))
continue;
RangedBugReport R(BT, N);
R.addRange((*I)->getSourceRange());
Reports.push_back(R);
hasError = true;
}
Since this code is so similar to yours, I'm a little confused why you
don't get even one "Yes, parameter X is non-null" anywhere. One thing
worth verifying is that 'e' is non-zero (i.e., is the look ever
entered). Inserting breakpoints in gdb would be my next step.
There is also a test case for the static analyzer in test/Analysis
that might be useful to compare against:
$ cd test/Analysis
$ clang -checker-simple null-deref-ps.c
...
ANALYZE: null-deref-ps.c f6
null-deref-ps.c:64:15: warning: Null pointer passed as an argument to
a 'nonnull' parameter
return !p ? bar(p, 1) // expected-warning {{Null pointer passed as
an argument to a 'nonnull' parameter}}
^ ~
ANALYZE: null-deref-ps.c f6b
null-deref-ps.c:71:15: warning: Null pointer passed as an argument to
a 'nonnull' parameter
return !p ? bar2(p, 1) // expected-warning {{Null pointer passed as
an argument to a 'nonnull' parameter}}
^ ~
...
More information about the cfe-dev
mailing list