brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.9 KiB · 0988177 Raw
495 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s2 3int f() __attribute__((warn_unused_result));4 5struct S {6  void t() const;7};8S g1() __attribute__((warn_unused_result));9S *g2() __attribute__((warn_unused_result));10S &g3() __attribute__((warn_unused_result));11 12void test() {13  f(); // expected-warning {{ignoring return value}}14  g1(); // expected-warning {{ignoring return value}}15  g2(); // expected-warning {{ignoring return value}}16  g3(); // expected-warning {{ignoring return value}}17 18  (void)f();19  (void)g1();20  (void)g2();21  (void)g3();22 23  if (f() == 0) return;24 25  g1().t();26  g2()->t();27  g3().t();28 29  int i = f();30  S s1 = g1();31  S *s2 = g2();32  S &s3 = g3();33  const S &s4 = g1();34}35 36void testSubstmts(int i) {37  switch (i) {38  case 0:39    f(); // expected-warning {{ignoring return value}}40  default:41    f(); // expected-warning {{ignoring return value}}42  }43 44  if (i)45    f(); // expected-warning {{ignoring return value}}46  else47    f(); // expected-warning {{ignoring return value}}48 49  while (i)50    f(); // expected-warning {{ignoring return value}}51 52  do53    f(); // expected-warning {{ignoring return value}}54  while (i);55 56  for (f(); // expected-warning {{ignoring return value}}57       ;58       f() // expected-warning {{ignoring return value}}59      )60    f(); // expected-warning {{ignoring return value}}61 62  f(),  // expected-warning {{ignoring return value}}63  (void)f();64}65 66struct X {67 int foo() __attribute__((warn_unused_result));68};69 70void bah() {71  X x, *x2;72  x.foo(); // expected-warning {{ignoring return value}}73  x2->foo(); // expected-warning {{ignoring return value}}74}75 76namespace warn_unused_CXX11 {77class Status;78class Foo {79 public:80  Status doStuff();81};82 83struct [[clang::warn_unused_result]] Status {84  bool ok() const;85  Status& operator=(const Status& x);86  inline void Update(const Status& new_status) {87    if (ok()) {88      *this = new_status; //no-warning89    }90  }91};92Status DoSomething();93Status& DoSomethingElse();94Status* DoAnotherThing();95Status** DoYetAnotherThing();96void lazy() {97  Status s = DoSomething();98  if (!s.ok()) return;99  Status &rs = DoSomethingElse();100  if (!rs.ok()) return;101  Status *ps = DoAnotherThing();102  if (!ps->ok()) return;103  Status **pps = DoYetAnotherThing();104  if (!(*pps)->ok()) return;105 106  (void)DoSomething();107  (void)DoSomethingElse();108  (void)DoAnotherThing();109  (void)DoYetAnotherThing();110 111  DoSomething(); // expected-warning {{ignoring return value of type 'Status' declared with 'clang::warn_unused_result'}}112  DoSomethingElse();113  DoAnotherThing();114  DoYetAnotherThing();115}116 117template <typename T>118class [[clang::warn_unused_result]] StatusOr {119};120StatusOr<int> doit();121void test() {122  Foo f;123  f.doStuff(); // expected-warning {{ignoring return value of type 'Status' declared with 'clang::warn_unused_result'}}124  doit(); // expected-warning {{ignoring return value of type 'StatusOr<int>' declared with 'clang::warn_unused_result'}}125 126  auto func = []() { return Status(); };127  func(); // expected-warning {{ignoring return value of type 'Status' declared with 'clang::warn_unused_result'}}128}129}130 131namespace PR17587 {132struct [[clang::warn_unused_result]] Status;133 134struct Foo {135  Status Bar();136};137 138struct Status {};139 140void Bar() {141  Foo f;142  f.Bar(); // expected-warning {{ignoring return value of type 'Status' declared with 'clang::warn_unused_result'}}143};144 145}146 147namespace PR18571 {148// Unevaluated contexts should not trigger unused result warnings.149template <typename T>150auto foo(T) -> decltype(f(), bool()) { // Should not warn.151  return true;152}153 154void g() {155  foo(1);156}157}158 159namespace std {160class type_info { };161}162 163namespace {164// The typeid expression operand is evaluated only when the expression type is165// a glvalue of polymorphic class type.166 167struct B {168  virtual void f() {}169};170 171struct D : B {172  void f() override {}173};174 175struct C {};176 177void g() {178  // The typeid expression operand is evaluated only when the expression type is179  // a glvalue of polymorphic class type; otherwise the expression operand is not180  // evaluated and should not trigger a diagnostic.181  D d;182  C c;183  (void)typeid(f(), c); // Should not warn.184  (void)typeid(f(), d); // expected-warning {{ignoring return value}} expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}185 186  // The sizeof expression operand is never evaluated.187  (void)sizeof(f(), c); // Should not warn.188 189   // The noexcept expression operand is never evaluated.190  (void)noexcept(f(), false); // Should not warn.191}192}193 194namespace {195// C++ Methods should warn even in their own class.196struct [[clang::warn_unused_result]] S {197  S DoThing() { return {}; };198  S operator++(int) { return {}; };199  S operator--(int) { return {}; };200  // Improperly written prefix.201  S operator++() { return {}; };202  S operator--() { return {}; };203};204 205struct [[clang::warn_unused_result]] P {206  P DoThing() { return {}; };207};208 209P operator++(const P &, int) { return {}; };210P operator--(const P &, int) { return {}; };211// Improperly written prefix.212P operator++(const P &) { return {}; };213P operator--(const P &) { return {}; };214 215void f() {216  S s;217  P p;218  s.DoThing(); // expected-warning {{ignoring return value of type 'S' declared with 'clang::warn_unused_result'}}219  p.DoThing(); // expected-warning {{ignoring return value of type 'P' declared with 'clang::warn_unused_result'}}220  // Only postfix is expected to warn when written correctly.221  s++; // expected-warning {{ignoring return value of type 'S' declared with 'clang::warn_unused_result'}}222  s--; // expected-warning {{ignoring return value of type 'S' declared with 'clang::warn_unused_result'}}223  p++; // expected-warning {{ignoring return value of type 'P' declared with 'clang::warn_unused_result'}}224  p--; // expected-warning {{ignoring return value of type 'P' declared with 'clang::warn_unused_result'}}225  // Improperly written prefix operators should still warn.226  ++s; // expected-warning {{ignoring return value of type 'S' declared with 'clang::warn_unused_result'}}227  --s; // expected-warning {{ignoring return value of type 'S' declared with 'clang::warn_unused_result'}}228  ++p; // expected-warning {{ignoring return value of type 'P' declared with 'clang::warn_unused_result'}}229  --p; // expected-warning {{ignoring return value of type 'P' declared with 'clang::warn_unused_result'}}230 231  // Silencing the warning by cast to void still works.232  (void)s.DoThing();233  (void)s++;234  (void)p++;235  (void)++s;236  (void)++p;237}238} // namespace239 240namespace PR39837 {241[[clang::warn_unused_result]] int f(int);242 243void g() {244  int a[2];245  for (int b : a)246    f(b); // expected-warning {{ignoring return value of function declared with 'clang::warn_unused_result'}}247}248} // namespace PR39837249 250namespace PR45520 {251[[nodiscard]] bool (*f)(); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}252[[clang::warn_unused_result]] bool (*g)();253__attribute__((warn_unused_result)) bool (*h)();254 255void i([[nodiscard]] bool (*fp)()); // expected-warning {{'nodiscard' attribute only applies to functions, classes, or enumerations}}256}257 258namespace unused_typedef_result {259[[clang::warn_unused_result]] typedef void *a;260typedef a indirect;261a af1();262indirect indirectf1();263void af2() {264  af1(); // expected-warning {{ignoring return value of type 'a' declared with 'clang::warn_unused_result'}}265  void *(*a1)();266  a1(); // no warning267  a (*a2)();268  a2(); // expected-warning {{ignoring return value of type 'a' declared with 'clang::warn_unused_result'}}269  indirectf1(); // expected-warning {{ignoring return value of type 'a' declared with 'clang::warn_unused_result'}}270}271[[nodiscard]] typedef void *b1; // expected-warning {{'[[nodiscard]]' attribute ignored when applied to a typedef; consider using '__attribute__((warn_unused_result))' or '[[clang::warn_unused_result]]' instead}}272[[gnu::warn_unused_result]] typedef void *b2; // expected-warning {{'[[gnu::warn_unused_result]]' attribute ignored when applied to a typedef; consider using '__attribute__((warn_unused_result))' or '[[clang::warn_unused_result]]' instead}}273b1 b1f1();274b2 b2f1();275void bf2() {276  b1f1(); // no warning277  b2f1(); // no warning278}279__attribute__((warn_unused_result)) typedef void *c;280c cf1();281void cf2() {282  cf1(); // expected-warning {{ignoring return value of type 'c' declared with 'warn_unused_result'}}283  void *(*c1)();284  c1();285  c (*c2)();286  c2(); // expected-warning {{ignoring return value of type 'c' declared with 'warn_unused_result'}}287}288}289 290namespace nodiscard_specialization {291// Test to only mark a specialization of class template as nodiscard292template<typename T> struct S { S(int) {} };293template<> struct [[nodiscard]] S<int> { S(int) {} };294template<typename T> struct [[clang::warn_unused_result]] S<const T> { S(int) {} };295 296template<typename T>297S<T> obtain(const T&) { return {2}; }298 299template<typename T>300[[nodiscard]] S<T> obtain2(const T&) { return {2}; }301 302template<typename T>303__attribute__((warn_unused_result)) S<T> obtain3(const T&) { return {2}; }304 305void use() {306  obtain(1.0);             // no warning307  obtain(1);               // expected-warning {{ignoring return value of type 'S<int>' declared with 'nodiscard'}}308  obtain<const double>(1); // expected-warning {{ignoring return value of type 'S<const double>' declared with 'clang::warn_unused_result'}}309 310  S<double>(2);     // no warning311  S<int>(2);        // expected-warning {{ignoring temporary of type 'S<int>' declared with 'nodiscard'}}312  S<const char>(2); // expected-warning {{ignoring temporary of type 'S<const char>' declared with 'clang::warn_unused_result' attribute}}313 314  // function should take precedence over type315  obtain2(1.0);             // expected-warning {{ignoring return value of function declared with 'nodiscard'}}316  obtain2(1);               // expected-warning {{ignoring return value of function declared with 'nodiscard'}}317  obtain2<const double>(1); // expected-warning {{ignoring return value of function declared with 'nodiscard'}}318  obtain3(1.0);             // expected-warning {{ignoring return value of function declared with 'warn_unused_result'}}319  obtain3(1);               // expected-warning {{ignoring return value of function declared with 'warn_unused_result'}}320  obtain3<const double>(1); // expected-warning {{ignoring return value of function declared with 'warn_unused_result'}}321}322 323// Test on constructor nodiscard324struct H {325  explicit H(int) {}326  [[nodiscard]] explicit H(double) {}327  __attribute__((warn_unused_result)) H(const char*) {}328};329 330struct [[nodiscard]] G {331  explicit G(int) {}332  [[nodiscard]] explicit G(double) {}333  [[clang::warn_unused_result]] G(const char*) {}334};335 336void use2() {337  H{2};       // no warning338  H(2.0);     // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard'}}339  H("Hello"); // expected-warning {{ignoring temporary created by a constructor declared with 'warn_unused_result' attribute}}340 341  // no warning for explicit cast to void342  (void)H(2);343  (void)H{2.0};344  (void)H{"Hello"};345 346  // warns for all these invocations347  // here, constructor/function should take precedence over type348  G{2};       // expected-warning {{ignoring temporary of type 'G' declared with 'nodiscard'}}349  G(2.0);     // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard'}}350  G("Hello"); // expected-warning {{ignoring temporary created by a constructor declared with 'clang::warn_unused_result'}}351 352  // no warning for explicit cast to void353  (void)G(2);354  (void)G{2.0};355  (void)G{"Hello"};356}357} // namespace nodiscard_specialization358 359namespace GH117975 {360// Test for a regression for ICE in CallExpr::getUnusedResultAttr361int f() { return 0; }362void id_print_name() {363  (int) // expected-warning {{expression result unused}}364    ((int(*)())f)();365}366} // namespace GH117975367 368namespace inheritance {369// Test that [[nodiscard]] is not inherited by derived class types,370// but is inherited by member functions371struct [[nodiscard]] E {372  [[nodiscard]] explicit E(int);373  explicit E(const char*);374  [[nodiscard]] int f();375};376struct F : E {377  using E::E;378};379E e();380F f();381void test() {382  e();     // expected-warning {{ignoring return value of type 'E' declared with 'nodiscard' attribute}}383  f();     // no warning: derived class type does not inherit the attribute384  E(1);    // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}385  E("x");  // expected-warning {{ignoring temporary of type 'E' declared with 'nodiscard' attribute}}386  F(1);    // no warning: inherited constructor does not inherit the attribute either387  F("x");  // no warning388  e().f(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}389  f().f(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}390}391} // namespace inheritance392 393namespace BuildStringOnClangScope {394 395[[clang::warn_unused_result("Discarded result")]]396bool makeClangTrue() { return true; }397 398[[gnu::warn_unused_result("Discarded result")]]399bool makeGccTrue() { return true; }400 401void doClangThings() {402  makeClangTrue(); // expected-warning {{ignoring return value of function declared with 'clang::warn_unused_result' attribute: Discarded result}}403}404 405void doGccThings() {406  makeGccTrue(); // expected-warning {{ignoring return value of function declared with 'gnu::warn_unused_result' attribute}}407}408 409} // namespace BuildStringOnClangScope410 411namespace candiscard {412 413struct [[nodiscard]] NoDiscard {414  [[nodiscard]] NoDiscard(int);415  NoDiscard(const char *);416};417 418struct [[gnu::warn_unused]] WarnUnused {419  [[gnu::warn_unused]] WarnUnused(int); // expected-warning {{'gnu::warn_unused' attribute only applies to structs, unions, and classes}}420  WarnUnused(const char*);421};422 423struct [[gnu::warn_unused_result]] WarnUnusedResult {424  [[gnu::warn_unused_result]] WarnUnusedResult(int);425  WarnUnusedResult(const char*);426};427 428NoDiscard return_nodiscard();429WarnUnused return_warnunused();430WarnUnusedResult return_warnunusedresult();431 432NoDiscard (*p_return_nodiscard)();433WarnUnused (*p_return_warnunused)();434WarnUnusedResult (*p_return_warnunusedresult)();435 436NoDiscard (*(*pp_return_nodiscard)())();437WarnUnused (*(*pp_return_warnunused)())();438WarnUnusedResult (*(*pp_return_warnunusedresult)())();439 440template <class T> T from_a_template();441 442void test() {443  // Unused but named variables444  NoDiscard unused_variable1(1);         // no warning445  NoDiscard unused_variable2("");        // no warning446  WarnUnused unused_variable3(1);        // no warning447  WarnUnused unused_variable4("");       // no warning448  WarnUnusedResult unused_variable5(1);  // no warning449  WarnUnusedResult unused_variable6(""); // no warning450 451  // Constructor return values452  NoDiscard(1);         // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}453  NoDiscard("");        // expected-warning {{ignoring temporary of type 'NoDiscard' declared with 'nodiscard' attribute}}454  WarnUnused(1);        // expected-warning {{expression result unused}}455  WarnUnused("");       // expected-warning {{expression result unused}}456  WarnUnusedResult(1);  // expected-warning {{ignoring temporary created by a constructor declared with 'gnu::warn_unused_result' attribute}}457  WarnUnusedResult(""); // expected-warning {{ignoring temporary of type 'WarnUnusedResult' declared with 'gnu::warn_unused_result' attribute}}458 459  NoDiscard{1};         // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}460  NoDiscard{""};        // expected-warning {{ignoring temporary of type 'NoDiscard' declared with 'nodiscard' attribute}}461  WarnUnused{1};        // expected-warning {{expression result unused}}462  WarnUnused{""};       // expected-warning {{expression result unused}}463  WarnUnusedResult{1};  // expected-warning {{ignoring temporary created by a constructor declared with 'gnu::warn_unused_result' attribute}}464  WarnUnusedResult{""}; // expected-warning {{ignoring temporary of type 'WarnUnusedResult' declared with 'gnu::warn_unused_result' attribute}}465 466  static_cast<NoDiscard>(1);         // expected-warning {{ignoring temporary created by a constructor declared with 'nodiscard' attribute}}467  static_cast<NoDiscard>("");        // expected-warning {{ignoring temporary of type 'NoDiscard' declared with 'nodiscard' attribute}}468  static_cast<WarnUnused>(1);        // expected-warning {{expression result unused}}469  static_cast<WarnUnused>("");       // expected-warning {{expression result unused}}470  static_cast<WarnUnusedResult>(1);  // expected-warning {{ignoring temporary created by a constructor declared with 'gnu::warn_unused_result' attribute}}471  static_cast<WarnUnusedResult>(""); // expected-warning {{ignoring temporary of type 'WarnUnusedResult' declared with 'gnu::warn_unused_result' attribute}}472 473  // Function return values474  return_nodiscard(); // expected-warning {{ignoring return value of type 'NoDiscard' declared with 'nodiscard' attribute}}475  return_warnunused(); // no warning476  return_warnunusedresult(); // expected-warning {{ignoring return value of type 'WarnUnusedResult' declared with 'gnu::warn_unused_result' attribute}}477 478  // Function pointer return values479  p_return_nodiscard(); // expected-warning {{ignoring return value of type 'NoDiscard' declared with 'nodiscard' attribute}}480  p_return_warnunused(); // no warning481  p_return_warnunusedresult(); // expected-warning {{ignoring return value of type 'WarnUnusedResult' declared with 'gnu::warn_unused_result' attribute}}482 483  // Function pointer expression return values484  pp_return_nodiscard()(); // expected-warning {{ignoring return value of type 'NoDiscard' declared with 'nodiscard' attribute}}485  pp_return_warnunused()(); // no warning486  pp_return_warnunusedresult()(); // expected-warning {{ignoring return value of type 'WarnUnusedResult' declared with 'gnu::warn_unused_result' attribute}}487 488  // From a template489  from_a_template<NoDiscard>(); // expected-warning {{ignoring return value of type 'NoDiscard' declared with 'nodiscard' attribute}}490  from_a_template<WarnUnused>(); // no warning491  from_a_template<WarnUnusedResult>(); // expected-warning {{ignoring return value of type 'WarnUnusedResult' declared with 'gnu::warn_unused_result' attribute}}492}493 494} // namespace candiscard495