[StaticAnalyzer] How to suppress bug reports when a checker reached a noreturn function

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[StaticAnalyzer] How to suppress bug reports when a checker reached a noreturn function

Sumner, Brian via cfe-dev
Hi,

I am working on a checker and I would like to suppress bug reports when a path reached a function with [[noreturn]] attribute. For example:

typedef uint32_t mx_handle_t;
typedef int32_t mx_status_t;

mx_status_t mx_channel_create(
uint32_t options,
mx_handle_t* out0,
mx_handle_t* out1);

[[noreturn]] void noreturnFunc();

void checkNoReturn() {
  mx_handle_t sa, sb;
  mx_channel_create(0, &sa, &sb);
  //...
  noreturnFunc();
}

Function mx_channel_create will allocate two handles(file descriptors) and save them to 'sa' and 'sb'. Since there is no other call to release these two handles, the checker will report them as leaked. But in this special case, there is a call to 'noreturnFunc()' which will terminate the process and leaked handles will be recycled by the OS so it is may not necessary to report these bugs. The source code of the checker can be found in D35968, D36022, D36023, D36024.

My first thought is that I can use REGISTER_TRAIT_WITHPROGRAMSTATE macro to add a bool flag in the ProgramState and this flag will be set if the FunctionDecl->isNoReturn() returns true in the evalCall callback. Then in the checkDeadSymbols callback, do not report any leaked symbols if the flag registered through REGISTER_TRAIT_WITHPROGRAMSTATE is set. However, I did some experiment and found out that in the code example, the symbols in 'sa' and 'sb' were dead in the checkDeadSymbols before the evalCall on 'noreturnFunc' was invoked. Further experiment showed that the checkDeadSymbols on 'sa' and 'sb' was invoked even before checkPreStmt(const CallExpr *, CheckerContext &) callback. So this solution does not work.

Is there anything I can do in the checker to solve this problem?

Thanks for any help.

Haowei

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [StaticAnalyzer] How to suppress bug reports when a checker reached a noreturn function

Sumner, Brian via cfe-dev
Hi Haowei!

There is a heuristic already in the analyzer to suppress such cases. There is a method in BugType called setSuppressOnSink. Could you check if setting this to true would help?

Regards,
Gábor



On 31 July 2017 at 19:51, Haowei Wu via cfe-dev <[hidden email]> wrote:
Hi,

I am working on a checker and I would like to suppress bug reports when a path reached a function with [[noreturn]] attribute. For example:

typedef uint32_t mx_handle_t;
typedef int32_t mx_status_t;

mx_status_t mx_channel_create(
uint32_t options,
mx_handle_t* out0,
mx_handle_t* out1);

[[noreturn]] void noreturnFunc();

void checkNoReturn() {
  mx_handle_t sa, sb;
  mx_channel_create(0, &sa, &sb);
  //...
  noreturnFunc();
}

Function mx_channel_create will allocate two handles(file descriptors) and save them to 'sa' and 'sb'. Since there is no other call to release these two handles, the checker will report them as leaked. But in this special case, there is a call to 'noreturnFunc()' which will terminate the process and leaked handles will be recycled by the OS so it is may not necessary to report these bugs. The source code of the checker can be found in D35968, D36022, D36023, D36024.

My first thought is that I can use REGISTER_TRAIT_WITHPROGRAMSTATE macro to add a bool flag in the ProgramState and this flag will be set if the FunctionDecl->isNoReturn() returns true in the evalCall callback. Then in the checkDeadSymbols callback, do not report any leaked symbols if the flag registered through REGISTER_TRAIT_WITHPROGRAMSTATE is set. However, I did some experiment and found out that in the code example, the symbols in 'sa' and 'sb' were dead in the checkDeadSymbols before the evalCall on 'noreturnFunc' was invoked. Further experiment showed that the checkDeadSymbols on 'sa' and 'sb' was invoked even before checkPreStmt(const CallExpr *, CheckerContext &) callback. So this solution does not work.

Is there anything I can do in the checker to solve this problem?

Thanks for any help.

Haowei

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [StaticAnalyzer] How to suppress bug reports when a checker reached a noreturn function

Sumner, Brian via cfe-dev
Hi Gábor,

This setting helps. But I have a follow up question. Is it possible to treat return from 'int main(int argc, char* argv[])' as a sink just like the [[noreturn]] functions?

For example, like the previous example,

typedef uint32_t mx_handle_t;
typedef int32_t mx_status_t;

mx_status_t mx_channel_create(
uint32_t options,
mx_handle_t* out0,
mx_handle_t* out1);

int main(int argc, char* argv[]) {
  mx_handle_t sa, sb;
  mx_channel_create(0, &sa, &sb);
  //...
  return 0;
}

The program will quit if it returns from main and it would not be very helpful to report these leaks as well.

Thanks,
Haowei

On Tue, Aug 1, 2017 at 2:55 AM, Gábor Horváth <[hidden email]> wrote:
Hi Haowei!

There is a heuristic already in the analyzer to suppress such cases. There is a method in BugType called setSuppressOnSink. Could you check if setting this to true would help?

Regards,
Gábor



On 31 July 2017 at 19:51, Haowei Wu via cfe-dev <[hidden email]> wrote:
Hi,

I am working on a checker and I would like to suppress bug reports when a path reached a function with [[noreturn]] attribute. For example:

typedef uint32_t mx_handle_t;
typedef int32_t mx_status_t;

mx_status_t mx_channel_create(
uint32_t options,
mx_handle_t* out0,
mx_handle_t* out1);

[[noreturn]] void noreturnFunc();

void checkNoReturn() {
  mx_handle_t sa, sb;
  mx_channel_create(0, &sa, &sb);
  //...
  noreturnFunc();
}

Function mx_channel_create will allocate two handles(file descriptors) and save them to 'sa' and 'sb'. Since there is no other call to release these two handles, the checker will report them as leaked. But in this special case, there is a call to 'noreturnFunc()' which will terminate the process and leaked handles will be recycled by the OS so it is may not necessary to report these bugs. The source code of the checker can be found in D35968, D36022, D36023, D36024.

My first thought is that I can use REGISTER_TRAIT_WITHPROGRAMSTATE macro to add a bool flag in the ProgramState and this flag will be set if the FunctionDecl->isNoReturn() returns true in the evalCall callback. Then in the checkDeadSymbols callback, do not report any leaked symbols if the flag registered through REGISTER_TRAIT_WITHPROGRAMSTATE is set. However, I did some experiment and found out that in the code example, the symbols in 'sa' and 'sb' were dead in the checkDeadSymbols before the evalCall on 'noreturnFunc' was invoked. Further experiment showed that the checkDeadSymbols on 'sa' and 'sb' was invoked even before checkPreStmt(const CallExpr *, CheckerContext &) callback. So this solution does not work.

Is there anything I can do in the checker to solve this problem?

Thanks for any help.

Haowei

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...