| 1 | // RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify -Wc++17-extensions %s |
| 2 | // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -DEXT -Wc++17-extensions %s |
| 3 | |
| 4 | struct [[nodiscard]] S {}; |
| 5 | S get_s(); |
| 6 | S& get_s_ref(); |
| 7 | |
| 8 | enum [[nodiscard]] E {}; |
| 9 | E get_e(); |
| 10 | |
| 11 | [[nodiscard]] int get_i(); |
| 12 | [[nodiscard]] volatile int &get_vi(); |
| 13 | |
| 14 | void f() { |
| 15 | get_s(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 16 | get_i(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 17 | get_vi(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 18 | get_e(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 19 | |
| 20 | // Okay, warnings are not encouraged |
| 21 | get_s_ref(); |
| 22 | (void)get_s(); |
| 23 | (void)get_i(); |
| 24 | (void)get_vi(); |
| 25 | (void)get_e(); |
| 26 | } |
| 27 | |
| 28 | [[nodiscard]] volatile char &(*fp)(); |
| 29 | void g() { |
| 30 | fp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 31 | |
| 32 | // OK, warning suppressed. |
| 33 | (void)fp(); |
| 34 | } |
| 35 | |
| 36 | namespace PR31526 { |
| 37 | typedef E (*fp1)(); |
| 38 | typedef S (*fp2)(); |
| 39 | |
| 40 | typedef S S_alias; |
| 41 | typedef S_alias (*fp3)(); |
| 42 | |
| 43 | typedef fp2 fp2_alias; |
| 44 | |
| 45 | void f() { |
| 46 | fp1 one; |
| 47 | fp2 two; |
| 48 | fp3 three; |
| 49 | fp2_alias four; |
| 50 | |
| 51 | one(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 52 | two(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 53 | three(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 54 | four(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} |
| 55 | |
| 56 | // These are all okay because of the explicit cast to void. |
| 57 | (void)one(); |
| 58 | (void)two(); |
| 59 | (void)three(); |
| 60 | (void)four(); |
| 61 | } |
| 62 | } // namespace PR31526 |
| 63 | |
| 64 | #ifdef EXT |
| 65 | // expected-warning@4 {{use of the 'nodiscard' attribute is a C++17 extension}} |
| 66 | // expected-warning@8 {{use of the 'nodiscard' attribute is a C++17 extension}} |
| 67 | // expected-warning@11 {{use of the 'nodiscard' attribute is a C++17 extension}} |
| 68 | // expected-warning@12 {{use of the 'nodiscard' attribute is a C++17 extension}} |
| 69 | // expected-warning@28 {{use of the 'nodiscard' attribute is a C++17 extension}} |
| 70 | #endif |
| 71 | |