-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[analyzer] Revert incorrect LazyCoumpoundVal changes #163461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
1775b58
b7eb40d
6421727
dbd3caa
904f919
8df969f
8f840c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,13 +3,13 @@ | |
| // RUN: -analyzer-checker=core \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDelete | ||
| // | ||
| // RUN: %clang_analyze_cc1 -DLEAKS -std=c++11 -fblocks %s \ | ||
| // RUN: %clang_analyze_cc1 -std=c++11 -fblocks %s \ | ||
| // RUN: -verify=expected,newdelete,leak \ | ||
| // RUN: -analyzer-checker=core \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDelete \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDeleteLeaks | ||
| // | ||
| // RUN: %clang_analyze_cc1 -std=c++11 -fblocks -verify %s \ | ||
| // RUN: %clang_analyze_cc1 -std=c++11 -fblocks %s \ | ||
| // RUN: -verify=expected,leak \ | ||
| // RUN: -analyzer-checker=core \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDeleteLeaks | ||
|
|
@@ -19,13 +19,13 @@ | |
| // RUN: -analyzer-checker=core \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDelete | ||
| // | ||
| // RUN: %clang_analyze_cc1 -DLEAKS -std=c++17 -fblocks %s \ | ||
| // RUN: %clang_analyze_cc1 -std=c++17 -fblocks %s \ | ||
| // RUN: -verify=expected,newdelete,leak \ | ||
| // RUN: -analyzer-checker=core \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDelete \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDeleteLeaks | ||
| // | ||
| // RUN: %clang_analyze_cc1 -std=c++17 -fblocks -verify %s \ | ||
| // RUN: %clang_analyze_cc1 -std=c++17 -fblocks %s \ | ||
| // RUN: -verify=expected,leak,inspection \ | ||
| // RUN: -analyzer-checker=core \ | ||
| // RUN: -analyzer-checker=cplusplus.NewDeleteLeaks \ | ||
|
|
@@ -503,3 +503,75 @@ namespace optional_union { | |
| custom_union_t a; | ||
| } // leak-warning{{Potential leak of memory pointed to by 'a.present.q'}} | ||
| } | ||
|
|
||
| namespace gh153782 { | ||
|
|
||
| // Ensure we do not regress on the following use case. | ||
|
|
||
| namespace mutually_exclusive_test_case_1 { | ||
| struct StorageWrapper { | ||
| // Imagine those two call a reset() function (among other things) | ||
|
||
| ~StorageWrapper() { delete parts; } | ||
| StorageWrapper(StorageWrapper const&) = default; | ||
|
|
||
| // Mind that there is no assignment here -- this is the bug we would like to find. | ||
|
||
| void operator=(StorageWrapper&&) { delete parts; } // newdelete-warning{{Attempt to release already released memory}} | ||
|
|
||
| // Not provided, typically would do `parts = new long`. | ||
| StorageWrapper(); | ||
|
|
||
| long* parts; | ||
| }; | ||
|
|
||
| void test_non_trivial_struct_assignment() { | ||
| StorageWrapper* object = new StorageWrapper[]{StorageWrapper()}; | ||
| object[0] = StorageWrapper(); // This assignment leads to the double-free. | ||
| } | ||
| } // mutually_exclusive_test_case_1 | ||
|
|
||
| namespace mutually_exclusive_test_case_2 { | ||
| struct StorageWrapper { | ||
| // Imagine those two call a reset() function (among other things) | ||
| ~StorageWrapper() { delete parts; } | ||
| StorageWrapper(StorageWrapper const&) = default; | ||
|
|
||
| // Mind that there is no assignment here -- this is the bug we would like to find. | ||
| void operator=(StorageWrapper&&) { delete parts; } | ||
|
|
||
| // Not provided, typically would do `parts = new long`. | ||
| StorageWrapper(); | ||
|
|
||
| long* parts; | ||
| }; | ||
|
|
||
| void test_non_trivial_struct_assignment() { | ||
| StorageWrapper* object = new StorageWrapper[]{StorageWrapper()}; | ||
| // object[0] = StorageWrapper(); // Remove the source of double free to make the potential leak appear. | ||
| } // leak-warning{{Potential leak of memory pointed to by 'object'}} | ||
| } // mutually_exclusive_test_case_2 | ||
|
|
||
| namespace mutually_exclusive_test_case_3 { | ||
| struct StorageWrapper { | ||
| // Imagine those two call a reset() function (among other things) | ||
| ~StorageWrapper() { delete parts; } | ||
| StorageWrapper(StorageWrapper const&) = default; | ||
|
|
||
| // Mind that there is no assignment here -- this is the bug we would like to find. | ||
| void operator=(StorageWrapper&&) { delete parts; } // newdelete-warning{{Attempt to release already released memory}} | ||
|
|
||
| // Not provided, typically would do `parts = new long`. | ||
| StorageWrapper(); | ||
|
|
||
| long* parts; | ||
| }; | ||
|
|
||
| struct TestDoubleFreeWithInitializerList { | ||
| StorageWrapper* Object; | ||
| TestDoubleFreeWithInitializerList() | ||
| : Object(new StorageWrapper[]{StorageWrapper()}) { | ||
| Object[0] = StorageWrapper(); // This assignment leads to the double-free. | ||
| } | ||
| }; | ||
| } // mutually_exclusive_test_case_3 | ||
|
|
||
| } // namespace gh153782 | ||
Uh oh!
There was an error while loading. Please reload this page.