The user annotation mechanism can help you additionally configure the diagnostic rules of the analyzer. One of the options for user annotations are function annotations.
Here is an example of such an annotation:
//V_FORMATTED_IO_FUNC, function:Log, format_arg:1, ellipsis_arg:2
void Log(const char *fmt, ...);
However, annotations are not applied to virtual functions by default. The V016 diagnostic warning informs a user that their annotation has not been applied to a virtual function. To fix that, you need to append the following flags to the annotation:
For example, the annotation for the 'Log' virtual function of the 'Base' class will look like this:
// The comment should be placed on the same line
//V_FORMATTED_IO_FUNC, function:Base::Log,
format_arg:1, ellipsis_arg:2,
enable_on_virtual
struct Base
{
virtual void Log(const char *fmt, ...);
}
The 'propagate_on_virtual' flag can be written instead of 'enable_on_virtual'. Then the annotation will be applied to function overrides in derived classes as well:
// The comment should be located on the same line
//V_FORMATTED_IO_FUNC, function: Base::Log,
format_arg:1, ellipsis_arg:2,
propagate_on_virtual
struct Base
{
virtual void Log(const char *fmt, ...);
}
struct Derived
{
// The annotation will also apply to this function
virtual void Log(const char *fmt, ...) override;
}