| 1 | // RUN: %clang_cc1 -fsyntax-only -verify -Wunused %s |
| 2 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -Wunused %s |
| 3 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wunused %s |
| 4 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++17 -Wunused %s |
| 5 | |
| 6 | // PR4103 : Make sure we don't get a bogus unused expression warning |
| 7 | namespace PR4103 { |
| 8 | class APInt { |
| 9 | char foo; // expected-warning {{private field 'foo' is not used}} |
| 10 | }; |
| 11 | class APSInt : public APInt { |
| 12 | char bar; // expected-warning {{private field 'bar' is not used}} |
| 13 | public: |
| 14 | APSInt &operator=(const APSInt &RHS); |
| 15 | }; |
| 16 | |
| 17 | APSInt& APSInt::operator=(const APSInt &RHS) { |
| 18 | APInt::operator=(RHS); |
| 19 | return *this; |
| 20 | } |
| 21 | |
| 22 | template<typename T> |
| 23 | struct X { |
| 24 | X(); |
| 25 | }; |
| 26 | |
| 27 | void test() { |
| 28 | X<int>(); |
| 29 | } |
| 30 | } |
| 31 | |
| 32 | namespace derefvolatile { |
| 33 | void f(volatile char* x) { |
| 34 | *x; |
| 35 | #if __cplusplus <= 199711L |
| 36 | // expected-warning@-2 {{expression result unused; assign into a variable to force a volatile load}} |
| 37 | #endif |
| 38 | (void)*x; |
| 39 | #if __cplusplus <= 199711L |
| 40 | // expected-warning@-2 {{expression result unused; assign into a variable to force a volatile load}} |
| 41 | #endif |
| 42 | volatile char y = 10; |
| 43 | (void)y; // don't warn here, because it's a common pattern. |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | // <rdar://problem/12359208> |
| 48 | namespace AnonObject { |
| 49 | struct Foo { |
| 50 | Foo(const char* const message); |
| 51 | ~Foo(); |
| 52 | }; |
| 53 | void f() { |
| 54 | Foo("Hello World!"); // don't warn |
| 55 | int(1); // expected-warning {{expression result unused}} |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | // Test that constructing an object (which may have side effects) with |
| 60 | // constructor arguments which are dependent doesn't produce an unused value |
| 61 | // warning. |
| 62 | namespace UnresolvedLookup { |
| 63 | struct Foo { |
| 64 | Foo(int i, int j); |
| 65 | }; |
| 66 | template <typename T> |
| 67 | struct Bar { |
| 68 | void f(T t) { |
| 69 | Foo(t, 0); // no warning |
| 70 | } |
| 71 | }; |
| 72 | } |
| 73 | |
| 74 | #if __cplusplus >= 201703L |
| 75 | namespace PR33839 { |
| 76 | void a() { |
| 77 | struct X { int a, b; } x; |
| 78 | auto [a, b] = x; // expected-warning {{unused variable '[a, b]'}} |
| 79 | auto [c, d] = x; |
| 80 | (void)d; |
| 81 | } |
| 82 | |
| 83 | template<typename T> void f() { |
| 84 | struct A { int n; } a[1]; |
| 85 | for (auto [x] : a) { |
| 86 | (void)x; |
| 87 | } |
| 88 | auto [y] = a[0]; // expected-warning {{unused}} |
| 89 | } |
| 90 | template<bool b> void g() { |
| 91 | struct A { int n; } a[1]; |
| 92 | for (auto [x] : a) { |
| 93 | if constexpr (b) |
| 94 | (void)x; |
| 95 | } |
| 96 | |
| 97 | auto [y] = a[0]; |
| 98 | if constexpr (b) |
| 99 | (void)y; // ok, even when b == false |
| 100 | } |
| 101 | template<typename T> void h() { |
| 102 | struct A { int n; } a[1]; |
| 103 | for (auto [x] : a) { // expected-warning {{unused variable '[x]'}} |
| 104 | } |
| 105 | } |
| 106 | void use() { |
| 107 | f<int>(); // expected-note {{instantiation of}} |
| 108 | g<true>(); |
| 109 | g<false>(); |
| 110 | h<int>(); // expected-note {{instantiation of}} |
| 111 | } |
| 112 | } |
| 113 | #endif |
| 114 | |