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