llvm-project/clang/test/Analysis/NewDelete-checker-test.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

406 lines
9.5 KiB
C++
Raw Normal View History

[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks %s \
// RUN: -verify=expected,newdelete \
[analyzer] Reimplement dependencies between checkers Unfortunately, up until now, the fact that certain checkers depended on one another was known, but how these actually unfolded was hidden deep within the implementation. For example, many checkers (like RetainCount, Malloc or CString) modelled a certain functionality, and exposed certain reportable bug types to the user. For example, while MallocChecker models many many different types of memory handling, the actual "unix.MallocChecker" checker the user was exposed to was merely and option to this modeling part. Other than this being an ugly mess, this issue made resolving the checker naming issue almost impossible. (The checker naming issue being that if a checker registered more than one checker within its registry function, both checker object recieved the same name) Also, if the user explicitly disabled a checker that was a dependency of another that _was_ explicitly enabled, it implicitly, without "telling" the user, reenabled it. Clearly, changing this to a well structured, declarative form, where the handling of dependencies are done on a higher level is very much preferred. This patch, among the detailed things later, makes checkers declare their dependencies within the TableGen file Checkers.td, and exposes the same functionality to plugins and statically linked non-generated checkers through CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies, makes sure that checkers are added to CheckerManager in the correct order, and makes sure that if a dependency is disabled, so will be every checker that depends on it. In detail: * Add a new field to the Checker class in CheckerBase.td called Dependencies, which is a list of Checkers. * Move unix checkers before cplusplus, as there is no forward declaration in tblgen :/ * Add the following new checkers: - StackAddrEscapeBase - StackAddrEscapeBase - CStringModeling - DynamicMemoryModeling (base of the MallocChecker family) - IteratorModeling (base of the IteratorChecker family) - ValistBase - SecuritySyntaxChecker (base of bcmp, bcopy, etc...) - NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker) - IvarInvalidationModeling (base of IvarInvalidation checker family) - RetainCountBase (base of RetainCount and OSObjectRetainCount) * Clear up and registry functions in MallocChecker, happily remove old FIXMEs. * Add a new addDependency function to CheckerRegistry. * Neatly format RUN lines in files I looked at while debugging. Big thanks to Artem Degrachev for all the guidance through this project! Differential Revision: https://reviews.llvm.org/D54438 llvm-svn: 352287
2019-01-27 04:06:54 +08:00
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete
//
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// RUN: %clang_analyze_cc1 -DLEAKS -std=c++11 -fblocks %s \
// RUN: -verify=expected,newdelete,leak \
[analyzer] Reimplement dependencies between checkers Unfortunately, up until now, the fact that certain checkers depended on one another was known, but how these actually unfolded was hidden deep within the implementation. For example, many checkers (like RetainCount, Malloc or CString) modelled a certain functionality, and exposed certain reportable bug types to the user. For example, while MallocChecker models many many different types of memory handling, the actual "unix.MallocChecker" checker the user was exposed to was merely and option to this modeling part. Other than this being an ugly mess, this issue made resolving the checker naming issue almost impossible. (The checker naming issue being that if a checker registered more than one checker within its registry function, both checker object recieved the same name) Also, if the user explicitly disabled a checker that was a dependency of another that _was_ explicitly enabled, it implicitly, without "telling" the user, reenabled it. Clearly, changing this to a well structured, declarative form, where the handling of dependencies are done on a higher level is very much preferred. This patch, among the detailed things later, makes checkers declare their dependencies within the TableGen file Checkers.td, and exposes the same functionality to plugins and statically linked non-generated checkers through CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies, makes sure that checkers are added to CheckerManager in the correct order, and makes sure that if a dependency is disabled, so will be every checker that depends on it. In detail: * Add a new field to the Checker class in CheckerBase.td called Dependencies, which is a list of Checkers. * Move unix checkers before cplusplus, as there is no forward declaration in tblgen :/ * Add the following new checkers: - StackAddrEscapeBase - StackAddrEscapeBase - CStringModeling - DynamicMemoryModeling (base of the MallocChecker family) - IteratorModeling (base of the IteratorChecker family) - ValistBase - SecuritySyntaxChecker (base of bcmp, bcopy, etc...) - NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker) - IvarInvalidationModeling (base of IvarInvalidation checker family) - RetainCountBase (base of RetainCount and OSObjectRetainCount) * Clear up and registry functions in MallocChecker, happily remove old FIXMEs. * Add a new addDependency function to CheckerRegistry. * Neatly format RUN lines in files I looked at while debugging. Big thanks to Artem Degrachev for all the guidance through this project! Differential Revision: https://reviews.llvm.org/D54438 llvm-svn: 352287
2019-01-27 04:06:54 +08:00
// RUN: -analyzer-checker=core \
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// RUN: -analyzer-checker=cplusplus.NewDelete \
[analyzer] Reimplement dependencies between checkers Unfortunately, up until now, the fact that certain checkers depended on one another was known, but how these actually unfolded was hidden deep within the implementation. For example, many checkers (like RetainCount, Malloc or CString) modelled a certain functionality, and exposed certain reportable bug types to the user. For example, while MallocChecker models many many different types of memory handling, the actual "unix.MallocChecker" checker the user was exposed to was merely and option to this modeling part. Other than this being an ugly mess, this issue made resolving the checker naming issue almost impossible. (The checker naming issue being that if a checker registered more than one checker within its registry function, both checker object recieved the same name) Also, if the user explicitly disabled a checker that was a dependency of another that _was_ explicitly enabled, it implicitly, without "telling" the user, reenabled it. Clearly, changing this to a well structured, declarative form, where the handling of dependencies are done on a higher level is very much preferred. This patch, among the detailed things later, makes checkers declare their dependencies within the TableGen file Checkers.td, and exposes the same functionality to plugins and statically linked non-generated checkers through CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies, makes sure that checkers are added to CheckerManager in the correct order, and makes sure that if a dependency is disabled, so will be every checker that depends on it. In detail: * Add a new field to the Checker class in CheckerBase.td called Dependencies, which is a list of Checkers. * Move unix checkers before cplusplus, as there is no forward declaration in tblgen :/ * Add the following new checkers: - StackAddrEscapeBase - StackAddrEscapeBase - CStringModeling - DynamicMemoryModeling (base of the MallocChecker family) - IteratorModeling (base of the IteratorChecker family) - ValistBase - SecuritySyntaxChecker (base of bcmp, bcopy, etc...) - NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker) - IvarInvalidationModeling (base of IvarInvalidation checker family) - RetainCountBase (base of RetainCount and OSObjectRetainCount) * Clear up and registry functions in MallocChecker, happily remove old FIXMEs. * Add a new addDependency function to CheckerRegistry. * Neatly format RUN lines in files I looked at while debugging. Big thanks to Artem Degrachev for all the guidance through this project! Differential Revision: https://reviews.llvm.org/D54438 llvm-svn: 352287
2019-01-27 04:06:54 +08:00
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
//
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks %s \
// RUN: -verify=expected,newdelete \
[analyzer] Reimplement dependencies between checkers Unfortunately, up until now, the fact that certain checkers depended on one another was known, but how these actually unfolded was hidden deep within the implementation. For example, many checkers (like RetainCount, Malloc or CString) modelled a certain functionality, and exposed certain reportable bug types to the user. For example, while MallocChecker models many many different types of memory handling, the actual "unix.MallocChecker" checker the user was exposed to was merely and option to this modeling part. Other than this being an ugly mess, this issue made resolving the checker naming issue almost impossible. (The checker naming issue being that if a checker registered more than one checker within its registry function, both checker object recieved the same name) Also, if the user explicitly disabled a checker that was a dependency of another that _was_ explicitly enabled, it implicitly, without "telling" the user, reenabled it. Clearly, changing this to a well structured, declarative form, where the handling of dependencies are done on a higher level is very much preferred. This patch, among the detailed things later, makes checkers declare their dependencies within the TableGen file Checkers.td, and exposes the same functionality to plugins and statically linked non-generated checkers through CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies, makes sure that checkers are added to CheckerManager in the correct order, and makes sure that if a dependency is disabled, so will be every checker that depends on it. In detail: * Add a new field to the Checker class in CheckerBase.td called Dependencies, which is a list of Checkers. * Move unix checkers before cplusplus, as there is no forward declaration in tblgen :/ * Add the following new checkers: - StackAddrEscapeBase - StackAddrEscapeBase - CStringModeling - DynamicMemoryModeling (base of the MallocChecker family) - IteratorModeling (base of the IteratorChecker family) - ValistBase - SecuritySyntaxChecker (base of bcmp, bcopy, etc...) - NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker) - IvarInvalidationModeling (base of IvarInvalidation checker family) - RetainCountBase (base of RetainCount and OSObjectRetainCount) * Clear up and registry functions in MallocChecker, happily remove old FIXMEs. * Add a new addDependency function to CheckerRegistry. * Neatly format RUN lines in files I looked at while debugging. Big thanks to Artem Degrachev for all the guidance through this project! Differential Revision: https://reviews.llvm.org/D54438 llvm-svn: 352287
2019-01-27 04:06:54 +08:00
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete \
// RUN: -analyzer-config c++-allocator-inlining=true
//
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -verify %s \
// RUN: -verify=expected,newdelete,leak \
[analyzer] Reimplement dependencies between checkers Unfortunately, up until now, the fact that certain checkers depended on one another was known, but how these actually unfolded was hidden deep within the implementation. For example, many checkers (like RetainCount, Malloc or CString) modelled a certain functionality, and exposed certain reportable bug types to the user. For example, while MallocChecker models many many different types of memory handling, the actual "unix.MallocChecker" checker the user was exposed to was merely and option to this modeling part. Other than this being an ugly mess, this issue made resolving the checker naming issue almost impossible. (The checker naming issue being that if a checker registered more than one checker within its registry function, both checker object recieved the same name) Also, if the user explicitly disabled a checker that was a dependency of another that _was_ explicitly enabled, it implicitly, without "telling" the user, reenabled it. Clearly, changing this to a well structured, declarative form, where the handling of dependencies are done on a higher level is very much preferred. This patch, among the detailed things later, makes checkers declare their dependencies within the TableGen file Checkers.td, and exposes the same functionality to plugins and statically linked non-generated checkers through CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies, makes sure that checkers are added to CheckerManager in the correct order, and makes sure that if a dependency is disabled, so will be every checker that depends on it. In detail: * Add a new field to the Checker class in CheckerBase.td called Dependencies, which is a list of Checkers. * Move unix checkers before cplusplus, as there is no forward declaration in tblgen :/ * Add the following new checkers: - StackAddrEscapeBase - StackAddrEscapeBase - CStringModeling - DynamicMemoryModeling (base of the MallocChecker family) - IteratorModeling (base of the IteratorChecker family) - ValistBase - SecuritySyntaxChecker (base of bcmp, bcopy, etc...) - NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker) - IvarInvalidationModeling (base of IvarInvalidation checker family) - RetainCountBase (base of RetainCount and OSObjectRetainCount) * Clear up and registry functions in MallocChecker, happily remove old FIXMEs. * Add a new addDependency function to CheckerRegistry. * Neatly format RUN lines in files I looked at while debugging. Big thanks to Artem Degrachev for all the guidance through this project! Differential Revision: https://reviews.llvm.org/D54438 llvm-svn: 352287
2019-01-27 04:06:54 +08:00
// RUN: -analyzer-checker=core \
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// RUN: -analyzer-checker=cplusplus.NewDelete \
[analyzer] Reimplement dependencies between checkers Unfortunately, up until now, the fact that certain checkers depended on one another was known, but how these actually unfolded was hidden deep within the implementation. For example, many checkers (like RetainCount, Malloc or CString) modelled a certain functionality, and exposed certain reportable bug types to the user. For example, while MallocChecker models many many different types of memory handling, the actual "unix.MallocChecker" checker the user was exposed to was merely and option to this modeling part. Other than this being an ugly mess, this issue made resolving the checker naming issue almost impossible. (The checker naming issue being that if a checker registered more than one checker within its registry function, both checker object recieved the same name) Also, if the user explicitly disabled a checker that was a dependency of another that _was_ explicitly enabled, it implicitly, without "telling" the user, reenabled it. Clearly, changing this to a well structured, declarative form, where the handling of dependencies are done on a higher level is very much preferred. This patch, among the detailed things later, makes checkers declare their dependencies within the TableGen file Checkers.td, and exposes the same functionality to plugins and statically linked non-generated checkers through CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies, makes sure that checkers are added to CheckerManager in the correct order, and makes sure that if a dependency is disabled, so will be every checker that depends on it. In detail: * Add a new field to the Checker class in CheckerBase.td called Dependencies, which is a list of Checkers. * Move unix checkers before cplusplus, as there is no forward declaration in tblgen :/ * Add the following new checkers: - StackAddrEscapeBase - StackAddrEscapeBase - CStringModeling - DynamicMemoryModeling (base of the MallocChecker family) - IteratorModeling (base of the IteratorChecker family) - ValistBase - SecuritySyntaxChecker (base of bcmp, bcopy, etc...) - NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker) - IvarInvalidationModeling (base of IvarInvalidation checker family) - RetainCountBase (base of RetainCount and OSObjectRetainCount) * Clear up and registry functions in MallocChecker, happily remove old FIXMEs. * Add a new addDependency function to CheckerRegistry. * Neatly format RUN lines in files I looked at while debugging. Big thanks to Artem Degrachev for all the guidance through this project! Differential Revision: https://reviews.llvm.org/D54438 llvm-svn: 352287
2019-01-27 04:06:54 +08:00
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \
// RUN: -analyzer-config c++-allocator-inlining=true
//
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -verify %s \
// RUN: -verify=expected,leak \
[analyzer] Reimplement dependencies between checkers Unfortunately, up until now, the fact that certain checkers depended on one another was known, but how these actually unfolded was hidden deep within the implementation. For example, many checkers (like RetainCount, Malloc or CString) modelled a certain functionality, and exposed certain reportable bug types to the user. For example, while MallocChecker models many many different types of memory handling, the actual "unix.MallocChecker" checker the user was exposed to was merely and option to this modeling part. Other than this being an ugly mess, this issue made resolving the checker naming issue almost impossible. (The checker naming issue being that if a checker registered more than one checker within its registry function, both checker object recieved the same name) Also, if the user explicitly disabled a checker that was a dependency of another that _was_ explicitly enabled, it implicitly, without "telling" the user, reenabled it. Clearly, changing this to a well structured, declarative form, where the handling of dependencies are done on a higher level is very much preferred. This patch, among the detailed things later, makes checkers declare their dependencies within the TableGen file Checkers.td, and exposes the same functionality to plugins and statically linked non-generated checkers through CheckerRegistry::addDependency. CheckerRegistry now resolves these dependencies, makes sure that checkers are added to CheckerManager in the correct order, and makes sure that if a dependency is disabled, so will be every checker that depends on it. In detail: * Add a new field to the Checker class in CheckerBase.td called Dependencies, which is a list of Checkers. * Move unix checkers before cplusplus, as there is no forward declaration in tblgen :/ * Add the following new checkers: - StackAddrEscapeBase - StackAddrEscapeBase - CStringModeling - DynamicMemoryModeling (base of the MallocChecker family) - IteratorModeling (base of the IteratorChecker family) - ValistBase - SecuritySyntaxChecker (base of bcmp, bcopy, etc...) - NSOrCFErrorDerefChecker (base of NSErrorChecker and CFErrorChecker) - IvarInvalidationModeling (base of IvarInvalidation checker family) - RetainCountBase (base of RetainCount and OSObjectRetainCount) * Clear up and registry functions in MallocChecker, happily remove old FIXMEs. * Add a new addDependency function to CheckerRegistry. * Neatly format RUN lines in files I looked at while debugging. Big thanks to Artem Degrachev for all the guidance through this project! Differential Revision: https://reviews.llvm.org/D54438 llvm-svn: 352287
2019-01-27 04:06:54 +08:00
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks
#include "Inputs/system-header-simulator-cxx.h"
typedef __typeof__(sizeof(int)) size_t;
extern "C" void *malloc(size_t);
extern "C" void free (void* ptr);
int *global;
//------------------
// check for leaks
//------------------
//----- Standard non-placement operators
void testGlobalOpNew() {
void *p = operator new(0);
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
} // leak-warning{{Potential leak of memory pointed to by 'p'}}
void testGlobalOpNewArray() {
void *p = operator new[](0);
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
} // leak-warning{{Potential leak of memory pointed to by 'p'}}
void testGlobalNewExpr() {
int *p = new int;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
} // leak-warning{{Potential leak of memory pointed to by 'p'}}
void testGlobalNewExprArray() {
int *p = new int[0];
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
} // leak-warning{{Potential leak of memory pointed to by 'p'}}
//----- Standard nothrow placement operators
void testGlobalNoThrowPlacementOpNewBeforeOverload() {
void *p = operator new(0, std::nothrow);
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
} // leak-warning{{Potential leak of memory pointed to by 'p'}}
void testGlobalNoThrowPlacementExprNewBeforeOverload() {
int *p = new(std::nothrow) int;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
} // leak-warning{{Potential leak of memory pointed to by 'p'}}
//----- Standard pointer placement operators
void testGlobalPointerPlacementNew() {
int i;
void *p1 = operator new(0, &i); // no warn
void *p2 = operator new[](0, &i); // no warn
int *p3 = new(&i) int; // no warn
int *p4 = new(&i) int[0]; // no warn
}
//----- Other cases
void testNewMemoryIsInHeap() {
int *p = new int;
if (global != p) // condition is always true as 'p' wraps a heap region that
// is different from a region wrapped by 'global'
global = p; // pointer escapes
}
struct PtrWrapper {
int *x;
PtrWrapper(int *input) : x(input) {}
};
void testNewInvalidationPlacement(PtrWrapper *w) {
// Ensure that we don't consider this a leak.
new (w) PtrWrapper(new int); // no warn
}
//-----------------------------------------
// check for usage of zero-allocated memory
//-----------------------------------------
void testUseZeroAlloc1() {
int *p = (int *)operator new(0);
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
*p = 1; // newdelete-warning {{Use of zero-allocated memory}}
delete p;
}
int testUseZeroAlloc2() {
int *p = (int *)operator new[](0);
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
return p[0]; // newdelete-warning {{Use of zero-allocated memory}}
delete[] p;
}
void f(int);
void testUseZeroAlloc3() {
int *p = new int[0];
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
f(*p); // newdelete-warning {{Use of zero-allocated memory}}
delete[] p;
}
//---------------
// other checks
//---------------
class SomeClass {
public:
void f(int *p);
};
void f(int *p1, int *p2 = 0, int *p3 = 0);
void g(SomeClass &c, ...);
void testUseFirstArgAfterDelete() {
int *p = new int;
delete p;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
f(p); // newdelete-warning{{Use of memory after it is freed}}
}
void testUseMiddleArgAfterDelete(int *p) {
delete p;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
f(0, p); // newdelete-warning{{Use of memory after it is freed}}
}
void testUseLastArgAfterDelete(int *p) {
delete p;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
f(0, 0, p); // newdelete-warning{{Use of memory after it is freed}}
}
void testUseSeveralArgsAfterDelete(int *p) {
delete p;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
f(p, p, p); // newdelete-warning{{Use of memory after it is freed}}
}
void testUseRefArgAfterDelete(SomeClass &c) {
delete &c;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
g(c); // newdelete-warning{{Use of memory after it is freed}}
}
void testVariadicArgAfterDelete() {
SomeClass c;
int *p = new int;
delete p;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
g(c, 0, p); // newdelete-warning{{Use of memory after it is freed}}
}
void testUseMethodArgAfterDelete(int *p) {
SomeClass *c = new SomeClass;
delete p;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
c->f(p); // newdelete-warning{{Use of memory after it is freed}}
}
void testUseThisAfterDelete() {
SomeClass *c = new SomeClass;
delete c;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
c->f(0); // newdelete-warning{{Use of memory after it is freed}}
}
void testDoubleDelete() {
int *p = new int;
delete p;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
delete p; // newdelete-warning{{Attempt to free released memory}}
}
void testExprDeleteArg() {
int i;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
delete &i; // newdelete-warning{{Argument to 'delete' is the address of the local variable 'i', which is not memory allocated by 'new'}}
}
void testExprDeleteArrArg() {
int i;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
delete[] & i; // newdelete-warning{{Argument to 'delete[]' is the address of the local variable 'i', which is not memory allocated by 'new[]'}}
}
void testAllocDeallocNames() {
int *p = new(std::nothrow) int[1];
delete[] (++p);
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
// newdelete-warning@-1{{Argument to 'delete[]' is offset by 4 bytes from the start of memory allocated by 'new[]'}}
}
//--------------------------------
// Test escape of newed const pointer. Note, a const pointer can be deleted.
//--------------------------------
struct StWithConstPtr {
const int *memp;
};
void escape(const int &x);
void escapeStruct(const StWithConstPtr &x);
void escapePtr(const StWithConstPtr *x);
void escapeVoidPtr(const void *x);
void testConstEscape() {
int *p = new int(1);
escape(*p);
} // no-warning
void testConstEscapeStruct() {
StWithConstPtr *St = new StWithConstPtr();
escapeStruct(*St);
} // no-warning
void testConstEscapeStructPtr() {
StWithConstPtr *St = new StWithConstPtr();
escapePtr(St);
} // no-warning
void testConstEscapeMember() {
StWithConstPtr St;
St.memp = new int(2);
escapeVoidPtr(St.memp);
} // no-warning
void testConstEscapePlacementNew() {
int *x = (int *)malloc(sizeof(int));
void *y = new (x) int;
escapeVoidPtr(y);
} // no-warning
//============== Test Uninitialized delete delete[]========================
void testUninitDelete() {
int *x;
int * y = new int;
delete y;
delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
}
void testUninitDeleteArray() {
int *x;
int * y = new int[5];
delete[] y;
delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
}
void testUninitFree() {
int *x;
free(x); // expected-warning{{1st function call argument is an uninitialized value}}
}
void testUninitDeleteSink() {
int *x;
delete x; // expected-warning{{Argument to 'delete' is uninitialized}}
(*(volatile int *)0 = 1); // no warn
}
void testUninitDeleteArraySink() {
int *x;
delete[] x; // expected-warning{{Argument to 'delete[]' is uninitialized}}
(*(volatile int *)0 = 1); // no warn
}
namespace reference_count {
class control_block {
unsigned count;
public:
control_block() : count(0) {}
void retain() { ++count; }
int release() { return --count; }
};
template <typename T>
class shared_ptr {
T *p;
control_block *control;
public:
shared_ptr() : p(0), control(0) {}
explicit shared_ptr(T *p) : p(p), control(new control_block) {
control->retain();
}
shared_ptr(shared_ptr &other) : p(other.p), control(other.control) {
if (control)
control->retain();
}
~shared_ptr() {
if (control && control->release() == 0) {
delete p;
delete control;
}
};
T &operator *() {
return *p;
};
void swap(shared_ptr &other) {
T *tmp = p;
p = other.p;
other.p = tmp;
control_block *ctrlTmp = control;
control = other.control;
other.control = ctrlTmp;
}
};
void testSingle() {
shared_ptr<int> a(new int);
*a = 1;
}
void testDouble() {
shared_ptr<int> a(new int);
shared_ptr<int> b = a;
*a = 1;
}
void testInvalidated() {
shared_ptr<int> a(new int);
shared_ptr<int> b = a;
*a = 1;
extern void use(shared_ptr<int> &);
use(b);
}
void testNestedScope() {
shared_ptr<int> a(new int);
{
shared_ptr<int> b = a;
}
*a = 1;
}
void testSwap() {
shared_ptr<int> a(new int);
shared_ptr<int> b;
shared_ptr<int> c = a;
shared_ptr<int>(c).swap(b);
}
void testUseAfterFree() {
int *p = new int;
{
shared_ptr<int> a(p);
shared_ptr<int> b = a;
}
// FIXME: We should get a warning here, but we don't because we've
// conservatively modeled ~shared_ptr.
*p = 1;
}
}
// Test double delete
class DerefClass{
public:
int *x;
DerefClass() {}
~DerefClass() {*x = 1;}
};
void testDoubleDeleteClassInstance() {
DerefClass *foo = new DerefClass();
delete foo;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
delete foo; // newdelete-warning {{Attempt to delete released memory}}
}
class EmptyClass{
public:
EmptyClass() {}
~EmptyClass() {}
};
void testDoubleDeleteEmptyClass() {
EmptyClass *foo = new EmptyClass();
delete foo;
[analyzer][MallocChecker] Make NewDeleteLeaks depend on DynamicMemoryModeling rather than NewDelete If you remember the mail [1] I sent out about how I envision the future of the already existing checkers to look dependencywise, one my main points was that no checker that emits diagnostics should be a dependency. This is more problematic for some checkers (ahem, RetainCount [2]) more than for others, like this one. The MallocChecker family is a mostly big monolithic modeling class some small reporting checkers that only come to action when we are constructing a warning message, after the actual bug was detected. The implication of this is that NewDeleteChecker doesn't really do anything to depend on, so this change was relatively simple. The only thing that complicates this change is that FreeMemAux (MallocCheckers method that models general memory deallocation) returns after calling a bug reporting method, regardless whether the report was ever emitted (which may not always happen, for instance, if the checker responsible for the report isn't enabled). This return unfortunately happens before cleaning up the maps in the GDM keeping track of the state of symbols (whether they are released, whether that release was successful, etc). What this means is that upon disabling some checkers, we would never clean up the map and that could've lead to false positives, e.g.: error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-intersections.mm Line 66: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 73: Potential leak of memory pointed to by 'p' File clang/test/Analysis/NewDelete-intersections.mm Line 77: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/NewDelete-checker-test.cpp Line 111: Undefined or garbage value returned to caller File clang/test/Analysis/NewDelete-checker-test.cpp Line 200: Potential leak of memory pointed to by 'p' error: 'warning' diagnostics seen but not expected: File clang/test/Analysis/new.cpp Line 137: Potential leak of memory pointed to by 'x' There two possible approaches I had in mind: Make bug reporting methods of MallocChecker returns whether they succeeded, and proceed with the rest of FreeMemAux if not, Halt execution with a sink node upon failure. I decided to go with this, as described in the code. As you can see from the removed/changed test files, before the big checker dependency effort landed, there were tests to check for all the weird configurations of enabled/disabled checkers and their messy interactions, I largely repurposed these. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063070.html [2] http://lists.llvm.org/pipermail/cfe-dev/2019-August/063205.html Differential Revision: https://reviews.llvm.org/D77474
2020-02-26 01:02:18 +08:00
delete foo; // newdelete-warning {{Attempt to delete released memory}}
}
struct Base {
virtual ~Base() {}
};
struct Derived : Base {
};
Base *allocate() {
return new Derived;
}
void shouldNotReportLeak() {
Derived *p = (Derived *)allocate();
delete p;
}