diff options
Diffstat (limited to 'clang/test')
32 files changed, 336 insertions, 123 deletions
diff --git a/clang/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist b/clang/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist index 957988b..e4adeca 100644 --- a/clang/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist +++ b/clang/test/Analysis/Inputs/expected-plists/NewDelete-path-notes.cpp.plist @@ -33,9 +33,9 @@ </array> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Attempt to free released memory</string> + <string>Attempt to release already released memory</string> <key>message</key> - <string>Attempt to free released memory</string> + <string>Attempt to release already released memory</string> </dict> <dict> <key>kind</key><string>control</string> @@ -232,7 +232,7 @@ </array> </dict> </array> - <key>description</key><string>Attempt to free released memory</string> + <key>description</key><string>Attempt to release already released memory</string> <key>category</key><string>Memory error</string> <key>type</key><string>Double free</string> <key>check_name</key><string>cplusplus.NewDelete</string> @@ -456,12 +456,12 @@ </array> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Attempt to free released memory</string> + <string>Attempt to release already released memory</string> <key>message</key> - <string>Attempt to free released memory</string> + <string>Attempt to release already released memory</string> </dict> </array> - <key>description</key><string>Attempt to free released memory</string> + <key>description</key><string>Attempt to release already released memory</string> <key>category</key><string>Memory error</string> <key>type</key><string>Double free</string> <key>check_name</key><string>cplusplus.NewDelete</string> diff --git a/clang/test/Analysis/Inputs/expected-plists/malloc-plist.c.plist b/clang/test/Analysis/Inputs/expected-plists/malloc-plist.c.plist index 8ae5850..3fdf5da4 100644 --- a/clang/test/Analysis/Inputs/expected-plists/malloc-plist.c.plist +++ b/clang/test/Analysis/Inputs/expected-plists/malloc-plist.c.plist @@ -1725,12 +1725,12 @@ </array> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Use of memory after it is freed</string> + <string>Use of memory after it is released</string> <key>message</key> - <string>Use of memory after it is freed</string> + <string>Use of memory after it is released</string> </dict> </array> - <key>description</key><string>Use of memory after it is freed</string> + <key>description</key><string>Use of memory after it is released</string> <key>category</key><string>Memory error</string> <key>type</key><string>Use-after-free</string> <key>check_name</key><string>unix.Malloc</string> @@ -2985,12 +2985,12 @@ </array> <key>depth</key><integer>0</integer> <key>extended_message</key> - <string>Use of memory after it is freed</string> + <string>Use of memory after it is released</string> <key>message</key> - <string>Use of memory after it is freed</string> + <string>Use of memory after it is released</string> </dict> </array> - <key>description</key><string>Use of memory after it is freed</string> + <key>description</key><string>Use of memory after it is released</string> <key>category</key><string>Memory error</string> <key>type</key><string>Use-after-free</string> <key>check_name</key><string>unix.Malloc</string> diff --git a/clang/test/Analysis/Inputs/overloaded-delete-in-header.h b/clang/test/Analysis/Inputs/overloaded-delete-in-header.h index 8243961..96aa4af 100644 --- a/clang/test/Analysis/Inputs/overloaded-delete-in-header.h +++ b/clang/test/Analysis/Inputs/overloaded-delete-in-header.h @@ -12,7 +12,7 @@ void DeleteInHeader::operator delete(void *ptr) { ::operator delete(ptr); - self->data = 2; // expected-warning {{Use of memory after it is freed [cplusplus.NewDelete]}} + self->data = 2; // expected-warning {{Use of memory after it is released [cplusplus.NewDelete]}} } #endif // OVERLOADED_DELETE_IN_SYSTEM_HEADER diff --git a/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp index 6c20b4b..b9eb85d 100644 --- a/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp +++ b/clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp @@ -9,7 +9,7 @@ void testMallocDoubleFree() { int *p = (int *)malloc(sizeof(int)); free(p); - free(p); // expected-warning{{Attempt to free released memory}} + free(p); // expected-warning{{Attempt to release already released memory}} } void testMallocLeak() { @@ -19,7 +19,7 @@ void testMallocLeak() { void testMallocUseAfterFree() { int *p = (int *)malloc(sizeof(int)); free(p); - int j = *p; // expected-warning{{Use of memory after it is freed}} + int j = *p; // expected-warning{{Use of memory after it is released}} } void testMallocBadFree() { @@ -46,7 +46,7 @@ void testMismatchedDeallocator() { void testNewDoubleFree() { int *p = new int; delete p; - delete p; // expected-warning{{Attempt to free released memory}} + delete p; // expected-warning{{Attempt to release already released memory}} } void testNewLeak() { @@ -59,7 +59,7 @@ void testNewLeak() { void testNewUseAfterFree() { int *p = (int *)operator new(0); delete p; - int j = *p; // expected-warning{{Use of memory after it is freed}} + int j = *p; // expected-warning{{Use of memory after it is released}} } void testNewBadFree() { @@ -95,7 +95,7 @@ void testShouldReportDoubleFreeNotMismatched() { int *p = (int*)malloc(sizeof(int)*4); globalPtr = p; free(p); - delete globalPtr; // expected-warning {{Attempt to free released memory}} + delete globalPtr; // expected-warning {{Attempt to release already released memory}} } int *allocIntArray(unsigned c) { return new int[c]; diff --git a/clang/test/Analysis/NewDelete-checker-test.cpp b/clang/test/Analysis/NewDelete-checker-test.cpp index 7c3e142..c417b9c 100644 --- a/clang/test/Analysis/NewDelete-checker-test.cpp +++ b/clang/test/Analysis/NewDelete-checker-test.cpp @@ -155,52 +155,52 @@ void g(SomeClass &c, ...); void testUseFirstArgAfterDelete() { int *p = new int; delete p; - f(p); // newdelete-warning{{Use of memory after it is freed}} + f(p); // newdelete-warning{{Use of memory after it is released}} } void testUseMiddleArgAfterDelete(int *p) { delete p; - f(0, p); // newdelete-warning{{Use of memory after it is freed}} + f(0, p); // newdelete-warning{{Use of memory after it is released}} } void testUseLastArgAfterDelete(int *p) { delete p; - f(0, 0, p); // newdelete-warning{{Use of memory after it is freed}} + f(0, 0, p); // newdelete-warning{{Use of memory after it is released}} } void testUseSeveralArgsAfterDelete(int *p) { delete p; - f(p, p, p); // newdelete-warning{{Use of memory after it is freed}} + f(p, p, p); // newdelete-warning{{Use of memory after it is released}} } void testUseRefArgAfterDelete(SomeClass &c) { delete &c; - g(c); // newdelete-warning{{Use of memory after it is freed}} + g(c); // newdelete-warning{{Use of memory after it is released}} } void testVariadicArgAfterDelete() { SomeClass c; int *p = new int; delete p; - g(c, 0, p); // newdelete-warning{{Use of memory after it is freed}} + g(c, 0, p); // newdelete-warning{{Use of memory after it is released}} } void testUseMethodArgAfterDelete(int *p) { SomeClass *c = new SomeClass; delete p; - c->f(p); // newdelete-warning{{Use of memory after it is freed}} + c->f(p); // newdelete-warning{{Use of memory after it is released}} } void testUseThisAfterDelete() { SomeClass *c = new SomeClass; delete c; - c->f(0); // newdelete-warning{{Use of memory after it is freed}} + c->f(0); // newdelete-warning{{Use of memory after it is released}} } void testDoubleDelete() { int *p = new int; delete p; - delete p; // newdelete-warning{{Attempt to free released memory}} + delete p; // newdelete-warning{{Attempt to release already released memory}} } void testExprDeleteArg() { @@ -412,7 +412,7 @@ public: void testDoubleDeleteClassInstance() { DerefClass *foo = new DerefClass(); delete foo; - delete foo; // newdelete-warning {{Attempt to free released memory}} + delete foo; // newdelete-warning {{Attempt to release already released memory}} } class EmptyClass{ @@ -424,7 +424,7 @@ public: void testDoubleDeleteEmptyClass() { EmptyClass *foo = new EmptyClass(); delete foo; - delete foo; // newdelete-warning {{Attempt to free released memory}} + delete foo; // newdelete-warning {{Attempt to release already released memory}} } struct Base { diff --git a/clang/test/Analysis/NewDelete-intersections.mm b/clang/test/Analysis/NewDelete-intersections.mm index e897f48..eddfb32 100644 --- a/clang/test/Analysis/NewDelete-intersections.mm +++ b/clang/test/Analysis/NewDelete-intersections.mm @@ -78,11 +78,11 @@ void testObjcFreeNewed() { void testFreeAfterDelete() { int *p = new int; delete p; - free(p); // newdelete-warning{{Use of memory after it is freed}} + free(p); // newdelete-warning{{Use of memory after it is released}} } void testStandardPlacementNewAfterDelete() { int *p = new int; delete p; - p = new (p) int; // newdelete-warning{{Use of memory after it is freed}} + p = new (p) int; // newdelete-warning{{Use of memory after it is released}} } diff --git a/clang/test/Analysis/NewDelete-path-notes.cpp b/clang/test/Analysis/NewDelete-path-notes.cpp index 2837fd1..852632f 100644 --- a/clang/test/Analysis/NewDelete-path-notes.cpp +++ b/clang/test/Analysis/NewDelete-path-notes.cpp @@ -16,8 +16,8 @@ void test() { delete p; // expected-note@-1 {{Memory is released}} - delete p; // expected-warning {{Attempt to free released memory}} - // expected-note@-1 {{Attempt to free released memory}} + delete p; // expected-warning {{Attempt to release already released memory}} + // expected-note@-1 {{Attempt to release already released memory}} } struct Odd { @@ -29,7 +29,7 @@ struct Odd { void test(Odd *odd) { odd->kill(); // expected-note{{Calling 'Odd::kill'}} // expected-note@-1 {{Returning; memory was released}} - delete odd; // expected-warning {{Attempt to free released memory}} - // expected-note@-1 {{Attempt to free released memory}} + delete odd; // expected-warning {{Attempt to release already released memory}} + // expected-note@-1 {{Attempt to release already released memory}} } diff --git a/clang/test/Analysis/analyzer-enabled-checkers.c b/clang/test/Analysis/analyzer-enabled-checkers.c index 78ee00de..a632b70 100644 --- a/clang/test/Analysis/analyzer-enabled-checkers.c +++ b/clang/test/Analysis/analyzer-enabled-checkers.c @@ -14,7 +14,6 @@ // CHECK-NEXT: core.BitwiseShift // CHECK-NEXT: core.CallAndMessageModeling // CHECK-NEXT: core.CallAndMessage -// CHECK-NEXT: core.DereferenceModeling // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation // CHECK-NEXT: core.FixedAddressDereference diff --git a/clang/test/Analysis/diagnostics/dtors.cpp b/clang/test/Analysis/diagnostics/dtors.cpp index 6a8349d..61e71fd 100644 --- a/clang/test/Analysis/diagnostics/dtors.cpp +++ b/clang/test/Analysis/diagnostics/dtors.cpp @@ -19,8 +19,8 @@ struct smart_ptr { return (x || 0) ? nullptr : s; // expected-note{{Field 'x' is 0}} // expected-note@-1{{Left side of '||' is false}} // expected-note@-2{{'?' condition is false}} - // expected-warning@-3{{Use of memory after it is freed}} - // expected-note@-4{{Use of memory after it is freed}} + // expected-warning@-3{{Use of memory after it is released}} + // expected-note@-4{{Use of memory after it is released}} } }; diff --git a/clang/test/Analysis/dtor.cpp b/clang/test/Analysis/dtor.cpp index c17c886..9e00e93 100644 --- a/clang/test/Analysis/dtor.cpp +++ b/clang/test/Analysis/dtor.cpp @@ -35,7 +35,7 @@ void testSmartPointer() { SmartPointer Deleter(mem); // destructor called here } - *mem = 0; // expected-warning{{Use of memory after it is freed}} + *mem = 0; // expected-warning{{Use of memory after it is released}} } @@ -48,7 +48,7 @@ void testSmartPointer2() { doSomething(); // destructor called here } - *mem = 0; // expected-warning{{Use of memory after it is freed}} + *mem = 0; // expected-warning{{Use of memory after it is released}} } @@ -65,7 +65,7 @@ void testSubclassSmartPointer() { doSomething(); // destructor called here } - *mem = 0; // expected-warning{{Use of memory after it is freed}} + *mem = 0; // expected-warning{{Use of memory after it is released}} } @@ -82,7 +82,7 @@ void testMultipleInheritance1() { doSomething(); // destructor called here } - *mem = 0; // expected-warning{{Use of memory after it is freed}} + *mem = 0; // expected-warning{{Use of memory after it is released}} } void testMultipleInheritance2() { @@ -93,7 +93,7 @@ void testMultipleInheritance2() { doSomething(); // destructor called here } - *mem = 0; // expected-warning{{Use of memory after it is freed}} + *mem = 0; // expected-warning{{Use of memory after it is released}} } void testMultipleInheritance3() { @@ -103,7 +103,7 @@ void testMultipleInheritance3() { // Remove dead bindings... doSomething(); // destructor called here - // expected-warning@28 {{Attempt to free released memory}} + // expected-warning@28 {{Attempt to release already released memory}} } } @@ -122,7 +122,7 @@ void testSmartPointerMember() { doSomething(); // destructor called here } - *mem = 0; // expected-warning{{Use of memory after it is freed}} + *mem = 0; // expected-warning{{Use of memory after it is release}} } @@ -524,7 +524,7 @@ struct NonTrivial { return *this; } ~NonTrivial() { - delete[] p; // expected-warning {{free released memory}} + delete[] p; // expected-warning {{release already released memory}} } }; @@ -593,5 +593,5 @@ void overrideLeak() { void overrideDoubleDelete() { auto *a = new CustomOperators(); delete a; - delete a; // expected-warning@577 {{Attempt to free released memory}} + delete a; // expected-warning@577 {{Attempt to release already released memory}} } diff --git a/clang/test/Analysis/getline-alloc.c b/clang/test/Analysis/getline-alloc.c index 74a40a1..43d0a2d 100644 --- a/clang/test/Analysis/getline-alloc.c +++ b/clang/test/Analysis/getline-alloc.c @@ -29,7 +29,7 @@ void test_getline_malloc_buffer() { ssize_t r = getdelim(&buffer, &n, '\r', F1); // ptr may be dangling - free(ptr); // expected-warning {{Attempt to free released memory}} + free(ptr); // expected-warning {{Attempt to release already released memory}} free(buffer); // ok fclose(F1); } diff --git a/clang/test/Analysis/gmalloc.c b/clang/test/Analysis/gmalloc.c index dae28eb..a94e5db 100644 --- a/clang/test/Analysis/gmalloc.c +++ b/clang/test/Analysis/gmalloc.c @@ -41,7 +41,7 @@ void f1(void) { g_free(g1); g_free(g2); - g_free(g2); // expected-warning{{Attempt to free released memory}} + g_free(g2); // expected-warning{{Attempt to release already released memory}} } void f2(void) { @@ -61,7 +61,7 @@ void f2(void) { g_free(g1); g_free(g2); g_free(g3); - g3 = g_memdup(g3, n_bytes); // expected-warning{{Use of memory after it is freed}} + g3 = g_memdup(g3, n_bytes); // expected-warning{{Use of memory after it is released}} } void f3(void) { diff --git a/clang/test/Analysis/malloc-annotations.c b/clang/test/Analysis/malloc-annotations.c index 3a8b1b2..68ac71d 100644 --- a/clang/test/Analysis/malloc-annotations.c +++ b/clang/test/Analysis/malloc-annotations.c @@ -45,13 +45,13 @@ void f1(void) { void f2(void) { int *p = malloc(12); free(p); - free(p); // expected-warning{{Attempt to free released memory}} + free(p); // expected-warning{{Attempt to release already released memory}} } void f2_realloc_0(void) { int *p = malloc(12); realloc(p,0); - realloc(p,0); // expected-warning{{Attempt to free released memory}} + realloc(p,0); // expected-warning{{Attempt to release already released memory}} } void f2_realloc_1(void) { @@ -106,25 +106,25 @@ void af1_g(struct stuff **pps) { void af2(void) { int *p = my_malloc(12); my_free(p); - free(p); // expected-warning{{Attempt to free released memory}} + free(p); // expected-warning{{Attempt to release already released memory}} } void af2b(void) { int *p = my_malloc(12); free(p); - my_free(p); // expected-warning{{Attempt to free released memory}} + my_free(p); // expected-warning{{Attempt to release already released memory}} } void af2c(void) { int *p = my_malloc(12); free(p); - my_hold(p); // expected-warning{{Attempt to free released memory}} + my_hold(p); // expected-warning{{Attempt to release already released memory}} } void af2d(void) { int *p = my_malloc(12); free(p); - my_hold2(0, 0, p); // expected-warning{{Attempt to free released memory}} + my_hold2(0, 0, p); // expected-warning{{Attempt to release already released memory}} } // No leak if malloc returns null. @@ -139,13 +139,13 @@ void af2e(void) { void af3(void) { int *p = my_malloc(12); my_hold(p); - free(p); // expected-warning{{Attempt to free non-owned memory}} + free(p); // expected-warning{{Attempt to release non-owned memory}} } int * af4(void) { int *p = my_malloc(12); my_free(p); - return p; // expected-warning{{Use of memory after it is freed}} + return p; // expected-warning{{Use of memory after it is released}} } // This case is (possibly) ok, be conservative @@ -211,13 +211,13 @@ void pr6293(void) { void f7(void) { char *x = (char*) malloc(4); free(x); - x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} + x[0] = 'a'; // expected-warning{{Use of memory after it is released}} } void f7_realloc(void) { char *x = (char*) malloc(4); realloc(x,0); - x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} + x[0] = 'a'; // expected-warning{{Use of memory after it is released}} } void PR6123(void) { diff --git a/clang/test/Analysis/malloc-annotations.cpp b/clang/test/Analysis/malloc-annotations.cpp index d75683f..67a069d 100644 --- a/clang/test/Analysis/malloc-annotations.cpp +++ b/clang/test/Analysis/malloc-annotations.cpp @@ -54,19 +54,19 @@ void af1_g(MemoryAllocator &Alloc, struct stuff **pps) { void af2(MemoryAllocator &Alloc) { void *p = Alloc.my_malloc(12); Alloc.my_free(p); - free(p); // expected-warning{{Attempt to free released memory}} + free(p); // expected-warning{{Attempt to release already released memory}} } void af2b(MemoryAllocator &Alloc) { void *p = Alloc.my_malloc(12); free(p); - Alloc.my_free(p); // expected-warning{{Attempt to free released memory}} + Alloc.my_free(p); // expected-warning{{Attempt to release already released memory}} } void af2c(MemoryAllocator &Alloc) { void *p = Alloc.my_malloc(12); free(p); - Alloc.my_hold(p); // expected-warning{{Attempt to free released memory}} + Alloc.my_hold(p); // expected-warning{{Attempt to release already released memory}} } // No leak if malloc returns null. @@ -81,13 +81,13 @@ void af2e(MemoryAllocator &Alloc) { void af3(MemoryAllocator &Alloc) { void *p = Alloc.my_malloc(12); Alloc.my_hold(p); - free(p); // expected-warning{{Attempt to free non-owned memory}} + free(p); // expected-warning{{Attempt to release non-owned memory}} } void * af4(MemoryAllocator &Alloc) { void *p = Alloc.my_malloc(12); Alloc.my_free(p); - return p; // expected-warning{{Use of memory after it is freed}} + return p; // expected-warning{{Use of memory after it is released}} } // This case is (possibly) ok, be conservative diff --git a/clang/test/Analysis/malloc-free-after-return.cpp b/clang/test/Analysis/malloc-free-after-return.cpp index cebd79a..5174e30 100644 --- a/clang/test/Analysis/malloc-free-after-return.cpp +++ b/clang/test/Analysis/malloc-free-after-return.cpp @@ -12,10 +12,10 @@ private: }; int *freeAfterReturnTemp() { - return S().getData(); // expected-warning {{Use of memory after it is freed}} + return S().getData(); // expected-warning {{Use of memory after it is released}} } int *freeAfterReturnLocal() { S X; - return X.getData(); // expected-warning {{Use of memory after it is freed}} + return X.getData(); // expected-warning {{Use of memory after it is released}} } diff --git a/clang/test/Analysis/malloc-interprocedural.c b/clang/test/Analysis/malloc-interprocedural.c index 5e5232a..e1569cf 100644 --- a/clang/test/Analysis/malloc-interprocedural.c +++ b/clang/test/Analysis/malloc-interprocedural.c @@ -59,13 +59,13 @@ int test4(void) { my_free1(data); data = (int *)my_malloc2(1, 4); my_free1(data); - return *data; // expected-warning {{Use of memory after it is freed}} + return *data; // expected-warning {{Use of memory after it is released}} } void test6(void) { int *data = (int *)my_malloc2(1, 4); my_free1((int*)data); - my_free1((int*)data); // expected-warning{{Use of memory after it is freed}} + my_free1((int*)data); // expected-warning{{Use of memory after it is released}} } // TODO: We should warn here. @@ -96,5 +96,5 @@ int uafAndCallsFooWithEmptyReturn(void) { int *x = (int*)malloc(12); free(x); fooWithEmptyReturn(12); - return *x; // expected-warning {{Use of memory after it is freed}} + return *x; // expected-warning {{Use of memory after it is released}} } diff --git a/clang/test/Analysis/malloc-plist.c b/clang/test/Analysis/malloc-plist.c index 6a3ba5b..caceaaf6 100644 --- a/clang/test/Analysis/malloc-plist.c +++ b/clang/test/Analysis/malloc-plist.c @@ -46,7 +46,7 @@ void test_wrapper(void) { (void) buf; }//expected-warning{{Potential leak}} -// Test what happens when the same call frees and allocated memory. +// Test what happens when the same call releases and allocated memory. // Also tests the stack hint for parameters, when they are passed directly or via pointer. void my_free(void *x) { free(x); @@ -60,7 +60,7 @@ void my_malloc_and_free(void **x) { void *test_double_action_call(void) { void *buf; my_malloc_and_free(&buf); - return buf; //expected-warning{{Use of memory after it is freed}} + return buf; //expected-warning{{Use of memory after it is released}} } // Test stack hint for 'reallocation failed'. @@ -98,7 +98,7 @@ void call_myfree_takingblock(void) { int *p = malloc(sizeof(int)); myfree_takingblock(some_block, p); - *p = 3;//expected-warning{{Use of memory after it is freed}} + *p = 3;//expected-warning{{Use of memory after it is released}} } // Test that we refer to the last symbol used in the leak diagnostic. diff --git a/clang/test/Analysis/malloc-refcounted.c b/clang/test/Analysis/malloc-refcounted.c index bfbe91d..224b60f 100644 --- a/clang/test/Analysis/malloc-refcounted.c +++ b/clang/test/Analysis/malloc-refcounted.c @@ -69,12 +69,12 @@ void test_uaf(void) { struct SomeData *data = alloc_data(); put_data_uncond(data); - data->i += 1; // expected-warning{{Use of memory after it is freed}} + data->i += 1; // expected-warning{{Use of memory after it is released}} } void test_no_uaf_atomic_after(void) { struct SomeData *data = alloc_data(); put_data_unrelated_atomic(data); - data->i += 1; // expected-warning{{Use of memory after it is freed}} + data->i += 1; // expected-warning{{Use of memory after it is released}} } diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index a9828cf..82eb364 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -97,13 +97,13 @@ void f1(void) { void f2(void) { int *p = malloc(12); free(p); - free(p); // expected-warning{{Attempt to free released memory}} + free(p); // expected-warning{{Attempt to release already released memory}} } void f2_realloc_0(void) { int *p = malloc(12); realloc(p,0); - realloc(p,0); // expected-warning{{Attempt to free released memory}} + realloc(p,0); // expected-warning{{Attempt to release already released memory}} } void f2_realloc_1(void) { @@ -153,7 +153,7 @@ void reallocSizeZero1(void) { char *p = malloc(12); char *r = realloc(p, 0); if (!r) { - free(p); // expected-warning {{Attempt to free released memory}} + free(p); // expected-warning {{Attempt to release already released memory}} } else { free(r); } @@ -163,11 +163,11 @@ void reallocSizeZero2(void) { char *p = malloc(12); char *r = realloc(p, 0); if (!r) { - free(p); // expected-warning {{Attempt to free released memory}} + free(p); // expected-warning {{Attempt to release already released memory}} } else { free(r); } - free(p); // expected-warning {{Attempt to free released memory}} + free(p); // expected-warning {{Attempt to release already released memory}} } void reallocSizeZero3(void) { @@ -262,7 +262,7 @@ void reallocfRadar6337483_3(void) { char * tmp; tmp = (char*)reallocf(buf, 0x1000000); if (!tmp) { - free(buf); // expected-warning {{Attempt to free released memory}} + free(buf); // expected-warning {{Attempt to release already released memory}} return; } buf = tmp; @@ -480,19 +480,19 @@ void pr6293(void) { void f7(void) { char *x = (char*) malloc(4); free(x); - x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} + x[0] = 'a'; // expected-warning{{Use of memory after it is released}} } void f8(void) { char *x = (char*) malloc(4); free(x); - char *y = strndup(x, 4); // expected-warning{{Use of memory after it is freed}} + char *y = strndup(x, 4); // expected-warning{{Use of memory after it is released}} } void f7_realloc(void) { char *x = (char*) malloc(4); realloc(x,0); - x[0] = 'a'; // expected-warning{{Use of memory after it is freed}} + x[0] = 'a'; // expected-warning{{Use of memory after it is released}} } void PR6123(void) { @@ -773,7 +773,7 @@ void nullFree(void) { void paramFree(int *p) { myfoo(p); free(p); // no warning - myfoo(p); // expected-warning {{Use of memory after it is freed}} + myfoo(p); // expected-warning {{Use of memory after it is released}} } void allocaFree(void) { @@ -813,14 +813,14 @@ void mallocEscapeFreeFree(void) { int *p = malloc(12); myfoo(p); free(p); - free(p); // expected-warning{{Attempt to free released memory}} + free(p); // expected-warning{{Attempt to release already released memory}} } void mallocEscapeFreeUse(void) { int *p = malloc(12); myfoo(p); free(p); - myfoo(p); // expected-warning{{Use of memory after it is freed}} + myfoo(p); // expected-warning{{Use of memory after it is released}} } int *myalloc(void); @@ -846,7 +846,7 @@ void mallocBindFreeUse(void) { int *x = malloc(12); int *y = x; free(y); - myfoo(x); // expected-warning{{Use of memory after it is freed}} + myfoo(x); // expected-warning{{Use of memory after it is released}} } void mallocEscapeMalloc(void) { @@ -871,13 +871,13 @@ void mallocFreeMalloc(void) { void mallocFreeUse_params(void) { int *p = malloc(12); free(p); - myfoo(p); //expected-warning{{Use of memory after it is freed}} + myfoo(p); //expected-warning{{Use of memory after it is released}} } void mallocFreeUse_params2(void) { int *p = malloc(12); free(p); - myfooint(*p); //expected-warning{{Use of memory after it is freed}} + myfooint(*p); //expected-warning{{Use of memory after it is released}} } void mallocFailedOrNot(void) { @@ -895,14 +895,14 @@ struct StructWithInt { int *mallocReturnFreed(void) { int *p = malloc(12); free(p); - return p; // expected-warning {{Use of memory after it is freed}} + return p; // expected-warning {{Use of memory after it is released}} } int useAfterFreeStruct(void) { struct StructWithInt *px= malloc(sizeof(struct StructWithInt)); px->g = 5; free(px); - return px->g; // expected-warning {{Use of memory after it is freed}} + return px->g; // expected-warning {{Use of memory after it is released}} } void nonSymbolAsFirstArg(int *pp, struct StructWithInt *p); @@ -935,7 +935,7 @@ void vallocEscapeFreeUse(void) { int *p = valloc(12); myfoo(p); free(p); - myfoo(p); // expected-warning{{Use of memory after it is freed}} + myfoo(p); // expected-warning{{Use of memory after it is released}} } int *Gl; @@ -1543,7 +1543,7 @@ void freeButNoMalloc(int *p, int x){ free(p); //user forgot a return here. } - free(p); // expected-warning {{Attempt to free released memory}} + free(p); // expected-warning {{Attempt to release already released memory}} } struct HasPtr { @@ -1553,7 +1553,7 @@ struct HasPtr { char* reallocButNoMalloc(struct HasPtr *a, int c, int size) { int *s; char *b = realloc(a->p, size); - char *m = realloc(a->p, size); // expected-warning {{Attempt to free released memory}} + char *m = realloc(a->p, size); // expected-warning {{Attempt to release already released memory}} // We don't expect a use-after-free for a->P here because the warning above // is a sink. return a->p; // no-warning @@ -1722,7 +1722,7 @@ void testOffsetZeroDoubleFree(void) { int *array = malloc(sizeof(int)*2); int *p = &array[0]; free(p); - free(&array[0]); // expected-warning{{Attempt to free released memory}} + free(&array[0]); // expected-warning{{Attempt to release already released memory}} } void testOffsetPassedToStrlen(void) { @@ -1835,7 +1835,7 @@ int testNoCheckerDataPropagationFromLogicalOpOperandToOpResult(void) { int ok = (param && value); free(param); free(value); - // Previously we ended up with 'Use of memory after it is freed' on return. + // Previously we ended up with 'Use of memory after it is released' on return. return ok; // no warning } @@ -1970,7 +1970,7 @@ void gh149754(void *p) { // was since then removed for the codebase. if (!realloc(p, 8)) { realloc(p, 8); - free(p); // expected-warning {{Attempt to free released memory}} + free(p); // expected-warning {{Attempt to release already released memory}} } // expected-warning@+1 {{Potential memory leak}} } diff --git a/clang/test/Analysis/malloc.mm b/clang/test/Analysis/malloc.mm index 5b816a1..8b4de9a 100644 --- a/clang/test/Analysis/malloc.mm +++ b/clang/test/Analysis/malloc.mm @@ -35,7 +35,7 @@ void testNSStringFreeWhenDoneYES3(NSUInteger dataLength) { void testNSStringFreeWhenDoneYES4(NSUInteger dataLength) { unichar *data = (unichar*)malloc(42); NSString *nsstr = [[NSString alloc] initWithCharactersNoCopy:data length:dataLength freeWhenDone:1]; - free(data); //expected-warning {{Attempt to free non-owned memory}} + free(data); //expected-warning {{Attempt to release non-owned memory}} } void testNSStringFreeWhenDoneYES(NSUInteger dataLength) { @@ -95,14 +95,14 @@ void testOffsetFree() { void testRelinquished1() { void *data = malloc(42); NSData *nsdata = [NSData dataWithBytesNoCopy:data length:42 freeWhenDone:1]; - free(data); // expected-warning {{Attempt to free non-owned memory}} + free(data); // expected-warning {{Attempt to release non-owned memory}} } void testRelinquished2() { void *data = malloc(42); NSData *nsdata; free(data); - [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Use of memory after it is freed}} + [NSData dataWithBytesNoCopy:data length:42]; // expected-warning {{Use of memory after it is released}} } @interface My @@ -112,7 +112,7 @@ void testRelinquished2() { void testUseAfterFree() { int *p = (int *)malloc(sizeof(int)); free(p); - [My param:p]; // expected-warning{{Use of memory after it is freed}} + [My param:p]; // expected-warning{{Use of memory after it is released}} } void testNoCopy() { @@ -318,7 +318,7 @@ NSString *test12365078_no_malloc_returnValue(unichar *characters) { void test12365078_nocheck_nomalloc(unichar *characters) { NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; - free(characters); // expected-warning {{Attempt to free non-owned memory}} + free(characters); // expected-warning {{Attempt to release non-owned memory}} } void test12365078_nested(unichar *characters) { @@ -339,7 +339,7 @@ void test12365078_nested(unichar *characters) { void test12365078_check_positive() { unichar *characters = (unichar*)malloc(12); NSString *string = [[NSString alloc] initWithCharactersNoCopy:characters length:12 freeWhenDone:1]; - if (string) free(characters); // expected-warning{{Attempt to free non-owned memory}} + if (string) free(characters); // expected-warning{{Attempt to release non-owned memory}} } void *test_reinterpret_cast_to_block() { diff --git a/clang/test/Analysis/new.cpp b/clang/test/Analysis/new.cpp index 15c27e7..8e5c6c4 100644 --- a/clang/test/Analysis/new.cpp +++ b/clang/test/Analysis/new.cpp @@ -112,7 +112,7 @@ void testCacheOut(PtrWrapper w) { void testUseAfter(int *p) { SomeClass *c = new SomeClass; free(p); - c->f(p); // expected-warning{{Use of memory after it is freed}} + c->f(p); // expected-warning{{Use of memory after it is released}} delete c; } @@ -140,25 +140,25 @@ void testDeleteMallocked() { void testDeleteOpAfterFree() { int *p = (int *)malloc(sizeof(int)); free(p); - operator delete(p); // expected-warning{{Use of memory after it is freed}} + operator delete(p); // expected-warning{{Use of memory after it is released}} } void testDeleteAfterFree() { int *p = (int *)malloc(sizeof(int)); free(p); - delete p; // expected-warning{{Use of memory after it is freed}} + delete p; // expected-warning{{Use of memory after it is released}} } void testStandardPlacementNewAfterFree() { int *p = (int *)malloc(sizeof(int)); free(p); - p = new(p) int; // expected-warning{{Use of memory after it is freed}} + p = new(p) int; // expected-warning{{Use of memory after it is released}} } void testCustomPlacementNewAfterFree() { int *p = (int *)malloc(sizeof(int)); free(p); - p = new(0, p) int; // expected-warning{{Use of memory after it is freed}} + p = new(0, p) int; // expected-warning{{Use of memory after it is released}} } void testUsingThisAfterDelete() { diff --git a/clang/test/Analysis/retain-count-alloc.cpp b/clang/test/Analysis/retain-count-alloc.cpp index 472cbbf..4b023a7 100644 --- a/clang/test/Analysis/retain-count-alloc.cpp +++ b/clang/test/Analysis/retain-count-alloc.cpp @@ -33,5 +33,5 @@ void useAfterFree(__isl_take Object *A) { freeObj(B); A->Ref = 13; - // no-warning: 'Use of memory after it is freed' was here. + // no-warning: 'Use of memory after it is released' was here. } diff --git a/clang/test/Analysis/self-assign.cpp b/clang/test/Analysis/self-assign.cpp index 7d3ea99b..d5c75c4 100644 --- a/clang/test/Analysis/self-assign.cpp +++ b/clang/test/Analysis/self-assign.cpp @@ -42,8 +42,8 @@ StringUsed &StringUsed::operator=(const StringUsed &rhs) { // expected-note@-2{{TRUE}} // expected-note@-3{{UNKNOWN}} free(str); // expected-note{{Memory is released}} - str = strdup(rhs.str); // expected-warning{{Use of memory after it is freed}} - // expected-note@-1{{Use of memory after it is freed}} + str = strdup(rhs.str); // expected-warning{{Use of memory after it is released}} + // expected-note@-1{{Use of memory after it is released}} // expected-note@-2{{Memory is allocated}} return *this; } @@ -90,8 +90,8 @@ StringUnused &StringUnused::operator=(const StringUnused &rhs) { // expected-note@-2{{TRUE}} // expected-note@-3{{UNKNOWN}} free(str); // expected-note{{Memory is released}} - str = strdup(rhs.str); // expected-warning{{Use of memory after it is freed}} - // expected-note@-1{{Use of memory after it is freed}} + str = strdup(rhs.str); // expected-warning{{Use of memory after it is released}} + // expected-note@-1{{Use of memory after it is released}} return *this; } diff --git a/clang/test/Analysis/stack-frame-context-revision.cpp b/clang/test/Analysis/stack-frame-context-revision.cpp index 51f86de..bd2f046 100644 --- a/clang/test/Analysis/stack-frame-context-revision.cpp +++ b/clang/test/Analysis/stack-frame-context-revision.cpp @@ -31,7 +31,7 @@ void test(Node *N) { delete N; N = Next.getPointer(); - // no-warning: 'Use of memory after it is freed' was here as the same + // no-warning: 'Use of memory after it is released' was here as the same // 'StackArgumentsSpaceRegion' purged out twice as 'P'. } } diff --git a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c index 7f9c9ff..b388c31 100644 --- a/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c +++ b/clang/test/Analysis/std-c-library-functions-arg-enabled-checkers.c @@ -22,7 +22,6 @@ // CHECK-NEXT: core.BitwiseShift // CHECK-NEXT: core.CallAndMessageModeling // CHECK-NEXT: core.CallAndMessage -// CHECK-NEXT: core.DereferenceModeling // CHECK-NEXT: core.DivideZero // CHECK-NEXT: core.DynamicTypePropagation // CHECK-NEXT: core.FixedAddressDereference diff --git a/clang/test/Analysis/std-string.cpp b/clang/test/Analysis/std-string.cpp index ee6dc02..150f557 100644 --- a/clang/test/Analysis/std-string.cpp +++ b/clang/test/Analysis/std-string.cpp @@ -57,8 +57,8 @@ void ctor_notetag_on_constraining_symbol(const char *p) { free((void *)p); // expected-note {{Memory is released}} free((void *)p); - // expected-warning@-1 {{Attempt to free released memory}} - // expected-note@-2 {{Attempt to free released memory}} + // expected-warning@-1 {{Attempt to release already released memory}} + // expected-note@-2 {{Attempt to release already released memory}} } void ctor_no_notetag_symbol_already_constrained(const char *p) { @@ -73,8 +73,8 @@ void ctor_no_notetag_symbol_already_constrained(const char *p) { free((void *)p); // expected-note {{Memory is released}} free((void *)p); - // expected-warning@-1 {{Attempt to free released memory}} - // expected-note@-2 {{Attempt to free released memory}} + // expected-warning@-1 {{Attempt to release already released memory}} + // expected-note@-2 {{Attempt to release already released memory}} } void ctor_no_notetag_if_not_interesting(const char *p1, const char *p2) { @@ -83,6 +83,6 @@ void ctor_no_notetag_if_not_interesting(const char *p1, const char *p2) { free((void *)p1); // expected-note {{Memory is released}} free((void *)p1); - // expected-warning@-1 {{Attempt to free released memory}} - // expected-note@-2 {{Attempt to free released memory}} + // expected-warning@-1 {{Attempt to release already released memory}} + // expected-note@-2 {{Attempt to release already released memory}} } diff --git a/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp new file mode 100644 index 0000000..bd07ada --- /dev/null +++ b/clang/test/Modules/specializations-lazy-load-parentmap-crash.cpp @@ -0,0 +1,99 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file --leading-lines %s %t +// +// Prepare the BMIs. +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a-part1.pcm %t/mod_a-part1.cppm +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a-part2.pcm %t/mod_a-part2.cppm +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_a.pcm %t/mod_a.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-module-interface -o %t/mod_b.pcm %t/mod_b.cppm -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm + +// Below are two examples to trigger the construction of the parent map (which is necessary to trigger the bug this regression test is for). +// Using ArrayBoundV2 checker: +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -analyze -analyzer-checker=security,alpha.security -analyzer-output=text %t/test-array-bound-v2.cpp -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm -fmodule-file=mod_b=%t/mod_b.pcm +// Using a sanitized build: +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fsanitize=unsigned-integer-overflow -fsanitize-undefined-ignore-overflow-pattern=all -emit-llvm -o %t/ignored %t/test-sanitized-build.cpp -fmodule-file=mod_a:part2=%t/mod_a-part2.pcm -fmodule-file=mod_a=%t/mod_a.pcm -fmodule-file=mod_a:part1=%t/mod_a-part1.pcm -fmodule-file=mod_b=%t/mod_b.pcm + +//--- mod_a-part1.cppm +module; +namespace mod_a { +template <int> struct Important; +} + +namespace mod_a { +Important<0>& instantiate1(); +} // namespace mod_a +export module mod_a:part1; + +export namespace mod_a { +using ::mod_a::instantiate1; +} + +//--- mod_a-part2.cppm +module; +namespace mod_a { +template <int> struct Important; +} + +namespace mod_a { +template <int N> Important<N>& instantiate2(); +namespace part2InternalInstantiations { +// During the construction of the parent map, we iterate over ClassTemplateDecl::specializations() for 'Important'. +// After GH119333, the following instantiations get loaded between the call to spec_begin() and spec_end(). +// This used to invalidate the begin iterator returned by spec_begin() by the time the end iterator is returned. +// This is a regression test for that. +Important<1> fn1(); +Important<2> fn2(); +Important<3> fn3(); +Important<4> fn4(); +Important<5> fn5(); +Important<6> fn6(); +Important<7> fn7(); +Important<8> fn8(); +Important<9> fn9(); +Important<10> fn10(); +Important<11> fn11(); +} +} // namespace mod_a +export module mod_a:part2; + +export namespace mod_a { +using ::mod_a::instantiate2; +} + +//--- mod_a.cppm +export module mod_a; +export import :part1; +export import :part2; + +//--- mod_b.cppm +export module mod_b; +import mod_a; + +void a() { + mod_a::instantiate1(); + mod_a::instantiate2<42>(); +} + +//--- test-array-bound-v2.cpp +import mod_b; + +extern void someFunc(char* first, char* last); +void triggerParentMapContextCreationThroughArrayBoundV2() { + // This code currently causes the ArrayBoundV2 checker to create the ParentMapContext. + // Once it detects an access to buf[100], the checker looks through the parents to find '&' operator. + // (this is needed since taking the address of past-the-end pointer is allowed by the checker) + char buf[100]; + someFunc(&buf[0], &buf[100]); +} + +//--- test-sanitized-build.cpp +import mod_b; + +extern void some(); +void triggerParentMapContextCreationThroughSanitizedBuild(unsigned i) { + // This code currently causes UBSan to create the ParentMapContext. + // UBSan currently excludes the pattern below to avoid noise, and it relies on ParentMapContext to detect it. + while (i--) + some(); +} diff --git a/clang/test/Sema/attr-nonstring.c b/clang/test/Sema/attr-nonstring.c index 3838aa3..fe7b6d2 100644 --- a/clang/test/Sema/attr-nonstring.c +++ b/clang/test/Sema/attr-nonstring.c @@ -229,3 +229,11 @@ struct Outer o2[] = { } } }; + +// The attribute also works with a pointer type, not just an array type. +__attribute__((nonstring)) char *ptr1; +__attribute__((nonstring)) const unsigned char *ptr2; +struct GH150951 { + __attribute__((nonstring)) char *ptr1; + __attribute__((nonstring)) const unsigned char *ptr2; +}; diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp index 2253cbb..fcbe0f6 100644 --- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp +++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp @@ -1357,3 +1357,35 @@ void Bar(this int) { // expected-note {{candidate function}} } } + +namespace GH147046_regression { + +template <typename z> struct ai { + ai(z::ah); +}; + +template <typename z> struct ak { + template <typename am> void an(am, z); + template <typename am> static void an(am, ai<z>); +}; +template <typename> struct ao {}; + +template <typename ap> +auto ar(ao<ap> at) -> decltype(ak<ap>::an(at, 0)); +// expected-note@-1 {{candidate template ignored: substitution failure [with ap = GH147046_regression::ay]: no matching function for call to 'an'}} + +class aw; +struct ax { + typedef int ah; +}; +struct ay { + typedef aw ah; +}; + +ao<ay> az ; +ai<ax> bd(0); +void f() { + ar(az); // expected-error {{no matching function for call to 'ar'}} +} + +} diff --git a/clang/test/SemaCXX/warn-unused-result.cpp b/clang/test/SemaCXX/warn-unused-result.cpp index fe7d5ea..447654e 100644 --- a/clang/test/SemaCXX/warn-unused-result.cpp +++ b/clang/test/SemaCXX/warn-unused-result.cpp @@ -365,6 +365,31 @@ void id_print_name() { } } // namespace GH117975 +namespace inheritance { +// Test that [[nodiscard]] is not inherited by derived class types, +// but is inherited by member functions +struct [[nodiscard]] E { + [[nodiscard]] explicit E(int); + explicit E(const char*); + [[nodiscard]] int f(); +}; +struct F : E { + using E::E; +}; +E e(); +F f(); +void test() { + e(); // expected-warning {{ignoring return value of type 'E' declared with 'nodiscard' attribute}} + f(); // no warning: derived class type does not inherit the attribute + E(1); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}} + E("x"); // expected-warning {{ignoring temporary of type 'E' declared with 'nodiscard' attribute}} + F(1); // no warning: inherited constructor does not inherit the attribute either + F("x"); // no warning + e().f(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + f().f(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} +} // namespace inheritance + namespace BuildStringOnClangScope { [[clang::warn_unused_result("Discarded result")]] @@ -381,4 +406,4 @@ void doGccThings() { makeGccTrue(); // expected-warning {{ignoring return value of function declared with 'gnu::warn_unused_result' attribute}} } -} +} // namespace BuildStringOnClangScope diff --git a/clang/test/SemaObjC/attr-nodiscard.m b/clang/test/SemaObjC/attr-nodiscard.m new file mode 100644 index 0000000..6d04665 --- /dev/null +++ b/clang/test/SemaObjC/attr-nodiscard.m @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct [[nodiscard]] expected {}; + +typedef struct expected E; + +@interface INTF +- (int) a [[nodiscard]]; ++ (int) b [[nodiscard]]; +- (struct expected) c; ++ (struct expected) d; +- (E) e; ++ (E) f; +- (void) g [[nodiscard]]; // expected-warning {{attribute 'nodiscard' cannot be applied to Objective-C method without return value}} +@end + +void foo(INTF *a) { + [a a]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + [INTF b]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + [a c]; // expected-warning {{ignoring return value of type 'expected' declared with 'nodiscard' attribute}} + [INTF d]; // expected-warning {{ignoring return value of type 'expected' declared with 'nodiscard' attribute}} + [a e]; // expected-warning {{ignoring return value of type 'expected' declared with 'nodiscard' attribute}} + [INTF f]; // expected-warning {{ignoring return value of type 'expected' declared with 'nodiscard' attribute}} + [a g]; +} diff --git a/clang/test/SemaObjCXX/attr-nodiscard.mm b/clang/test/SemaObjCXX/attr-nodiscard.mm new file mode 100644 index 0000000..e1eefb7 --- /dev/null +++ b/clang/test/SemaObjCXX/attr-nodiscard.mm @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template<class T> +struct [[nodiscard]] expected {}; + +using E = expected<int>; + +@interface INTF +- (int) a [[nodiscard]]; ++ (int) b [[nodiscard]]; +- (expected<int>) c; ++ (expected<int>) d; +- (E) e; ++ (E) f; +- (void) g [[nodiscard]]; // expected-warning {{attribute 'nodiscard' cannot be applied to Objective-C method without return value}} +@end + +void foo(INTF *a) { + [a a]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + [INTF b]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + [a c]; // expected-warning {{ignoring return value of type 'expected<int>' declared with 'nodiscard' attribute}} + [INTF d]; // expected-warning {{ignoring return value of type 'expected<int>' declared with 'nodiscard' attribute}} + [a e]; // expected-warning {{ignoring return value of type 'expected<int>' declared with 'nodiscard' attribute}} + [INTF f]; // expected-warning {{ignoring return value of type 'expected<int>' declared with 'nodiscard' attribute}} + [a g]; +} |