[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / SemaCXX / warn-unused-value.cpp
blobd964684069155e0ae0cc6e1d86cef62a11428c9f
1 // RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++11 %s
4 // RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -std=c++17 %s
6 // PR4806
7 namespace test0 {
8 class Box {
9 public:
10 int i;
11 volatile int j;
14 void doit() {
15 // pointer to volatile has side effect (thus no warning)
16 Box* box = new Box;
17 box->i; // expected-warning {{expression result unused}}
18 box->j;
19 #if __cplusplus <= 199711L
20 // expected-warning@-2 {{expression result unused}}
21 #endif
25 namespace test1 {
26 struct Foo {
27 int i;
28 bool operator==(const Foo& rhs) {
29 return i == rhs.i;
33 #define NOP(x) (x)
34 void b(Foo f1, Foo f2) {
35 NOP(f1 == f2); // expected-warning {{expression result unused}}
37 #undef NOP
40 namespace test2 {
41 extern "C++" {
42 namespace std {
43 template<typename T> struct basic_string {
44 struct X {};
45 void method() const {
46 X* x;
47 &x[0]; // expected-warning {{expression result unused}}
50 typedef basic_string<char> string;
51 void func(const std::string& str) {
52 str.method(); // expected-note {{in instantiation of member function}}
58 namespace test3 {
59 struct Used {
60 Used();
61 Used(int);
62 Used(int, int);
63 ~Used() {}
65 struct __attribute__((warn_unused)) Unused {
66 Unused();
67 Unused(int);
68 Unused(int, int);
69 ~Unused() {}
71 void f() {
72 Used();
73 Used(1);
74 Used(1, 1);
75 Unused(); // expected-warning {{expression result unused}}
76 Unused(1); // expected-warning {{expression result unused}}
77 Unused(1, 1); // expected-warning {{expression result unused}}
78 #if __cplusplus >= 201103L // C++11 or later
79 Used({});
80 Unused({}); // expected-warning {{expression result unused}}
81 #endif
85 namespace std {
86 struct type_info {};
89 namespace test4 {
90 struct Good { Good &f(); };
91 struct Bad { virtual Bad& f(); };
93 void f() {
94 int i = 0;
95 (void)typeid(++i); // expected-warning {{expression with side effects has no effect in an unevaluated context}}
97 Good g;
98 (void)typeid(g.f()); // Ok; not a polymorphic use of a glvalue.
100 // This is a polymorphic use of a glvalue, which results in the typeid being
101 // evaluated instead of unevaluated.
102 Bad b;
103 (void)typeid(b.f()); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
105 // A dereference of a volatile pointer is a side effecting operation, however
106 // since it is idiomatic code, and the alternatives induce higher maintenance
107 // costs, it is allowed.
108 int * volatile x;
109 (void)sizeof(*x); // Ok
113 static volatile char var1 = 'a';
114 volatile char var2 = 'a';
115 static volatile char arr1[] = "hello";
116 volatile char arr2[] = "hello";
117 void volatile_array() {
118 static volatile char var3 = 'a';
119 volatile char var4 = 'a';
120 static volatile char arr3[] = "hello";
121 volatile char arr4[] = "hello";
123 // These all result in volatile loads in C and C++11. In C++98, they don't,
124 // but we suppress the warning in the case where '(void)var;' might be
125 // idiomatically suppressing an 'unused variable' warning.
126 (void)var1;
127 (void)var2;
128 #if __cplusplus < 201103L
129 // expected-warning@-2 {{expression result unused; assign into a variable to force a volatile load}}
130 #endif
131 (void)var3;
132 (void)var4;
134 // None of these result in volatile loads in any language mode, and it's not
135 // really reasonable to assume that they would, since volatile array loads
136 // don't really exist anywhere.
137 (void)arr1;
138 (void)arr2;
139 (void)arr3;
140 (void)arr4;
143 #if __cplusplus >= 201103L // C++11 or later
144 namespace test5 {
145 int v[(5, 6)]; // expected-warning {{left operand of comma operator has no effect}}
146 void foo() {
147 new double[false ? (1, 2) : 3]
148 // FIXME: We shouldn't diagnose the unreachable constant expression
149 // here.
150 [false ? (1, 2) : 3]; // expected-warning {{left operand of comma operator has no effect}}
152 } // namespace test5
154 // comma operator diagnostics should be suppressed in a SFINAE context.
155 template <typename T, int = (T{},0)> int c(int) { return 0; }
156 template <typename T, int> int c(double) { return 1; }
157 int foo() { return c<int>(0); }
159 #endif
161 #if __cplusplus >= 201703L // C++17 or later
162 namespace test6 {
163 auto b() {
164 if constexpr (false)
165 return (1,0);
166 else
167 return (1.0,0.0); // expected-warning {{left operand of comma operator has no effect}}
169 } // namespace test6
170 #endif