Reputation: 22717
In a large code base, I want to find all calls to a certain set of functions. Clang's deprecated
and unavailable
attributes don't quite do what I want, at least as of the Apple LLVM-6.0 version. Example:
__attribute__((deprecated)) void A();
__attribute__((deprecated)) void B();
void C();
void A()
{
B();
}
void B()
{
A();
}
void C()
{
A();
B();
}
The compiler gives warnings about the calls to A and B from C, but not the call of A to B or vice versa.
There are many of the functions in question, so it doesn't seem practical to just comment out declarations one by one.
Upvotes: 0
Views: 121
Reputation: 22717
I ended up writing a little program to search for the calls that were missed by the __attribute__((unavailable))
trick.
Upvotes: 0
Reputation: 755094
I think the reason for not warning about the call to A()
from within B()
and the call to B()
from within A()
is that those calls are in the bodies of deprecated functions. Since the functions themselves are deprecated, there isn't a lot of virtue in reporting on deprecated calls made within those functions; omitting those errors avoids some 'false positives'. When you eliminate the deprecated functions, there won't be a problem with the calls from within them.
I compiled a mildly modified version of your code with XCode 6.4 — running gcc --version
yielded:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
Code unavailable.c
:
__attribute__((deprecated)) void A(void);
__attribute__((deprecated)) void B(void);
void C(void);
void A(void)
{
B();
}
void B(void)
{
A();
}
void C(void)
{
A();
B();
}
Compilation:
$ make unavailable.o
gcc -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -c unavailable.c
unavailable.c:17:5: error: 'A' is deprecated [-Werror,-Wdeprecated-declarations]
A();
^
unavailable.c:5:6: note: 'A' has been explicitly marked deprecated here
void A(void)
^
unavailable.c:18:5: error: 'B' is deprecated [-Werror,-Wdeprecated-declarations]
B();
^
unavailable.c:10:6: note: 'B' has been explicitly marked deprecated here
void B(void)
^
2 errors generated.
rmk: error code 1
$
I had to add the void
parameters to the C functions because in C, a function declared void C();
has no prototype — C
is a function that takes an unspecified (but not variadic) argument list and returns no value. (The 'not variadic' bit means it does not have ellipsis ...
at the end of the argument list. You must always have a prototype in scope before calling such a function.)
Upvotes: 1