1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify -Wc++20-extensions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify -Wc++17-extensions %s
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -DEXT -Wc++17-extensions -Wc++20-extensions %s
struct [[nodiscard]] S {};
S get_s();
S& get_s_ref();
enum [[nodiscard]] E {};
E get_e();
[[nodiscard]] int get_i();
[[nodiscard]] volatile int &get_vi();
void f() {
get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
get_vi(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
// Okay, warnings are not encouraged
get_s_ref();
(void)get_s();
(void)get_i();
(void)get_vi();
(void)get_e();
}
[[nodiscard]] volatile char &(*fp)(); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}
void g() {
fp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
// OK, warning suppressed.
(void)fp();
}
namespace PR31526 {
typedef E (*fp1)();
typedef S (*fp2)();
typedef S S_alias;
typedef S_alias (*fp3)();
typedef fp2 fp2_alias;
void f() {
fp1 one;
fp2 two;
fp3 three;
fp2_alias four;
one(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
two(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
three(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
four(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
// These are all okay because of the explicit cast to void.
(void)one();
(void)two();
(void)three();
(void)four();
}
} // namespace PR31526
struct [[nodiscard("reason")]] ReasonStruct {};
struct LaterReason;
struct [[nodiscard("later reason")]] LaterReason {};
ReasonStruct get_reason();
LaterReason get_later_reason();
[[nodiscard("another reason")]] int another_reason();
[[nodiscard("conflicting reason")]] int conflicting_reason();
[[nodiscard("special reason")]] int conflicting_reason();
void cxx20_use() {
get_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: reason}}
get_later_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: later reason}}
another_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: another reason}}
conflicting_reason(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: special reason}}
}
namespace p1771 {
struct[[nodiscard("Don't throw me away!")]] ConvertTo{};
struct S {
[[nodiscard]] S();
[[nodiscard("Don't let that S-Char go!")]] S(char);
S(int);
[[gnu::warn_unused_result]] S(double);
operator ConvertTo();
[[nodiscard]] operator int();
[[nodiscard("Don't throw away as a double")]] operator double();
};
struct[[nodiscard("Don't throw me away either!")]] Y{};
void usage() {
S(); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}
S('A'); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't let that S-Char go!}}
S(1);
S(2.2);
Y(); // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away either!}}
S s;
ConvertTo{}; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}}
// AST is different in C++20 mode, pre-2017 a move ctor for ConvertTo is there
// as well, hense the constructor warning.
#if __cplusplus >= 201703L
// expected-warning@+4 {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}}
#else
// expected-warning@+2 {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away!}}
#endif
(ConvertTo) s;
(int)s; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
(S)'c'; // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't let that S-Char go!}}
#if __cplusplus >= 201703L
// expected-warning@+4 {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw me away!}}
#else
// expected-warning@+2 {{ignoring temporary created by a constructor declared with 'nodiscard' attribute: Don't throw me away!}}
#endif
static_cast<ConvertTo>(s);
static_cast<int>(s); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
static_cast<double>(s); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute: Don't throw away as a double}}
}
}; // namespace p1771
#ifdef EXT
// expected-warning@5 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@9 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@12 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@13 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@29 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@65 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@67 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@71 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@73 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@74 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@84 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@86 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@87 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@91 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@92 {{use of the 'nodiscard' attribute is a C++20 extension}}
// expected-warning@95 {{use of the 'nodiscard' attribute is a C++20 extension}}
#endif
|