summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/Decl.h5
-rw-r--r--clang/lib/AST/Decl.cpp4
-rw-r--r--clang/test/SemaCXX/warn-unused-result.cpp46
3 files changed, 48 insertions, 7 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index ad723a3e2b8..573ea55de1f 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -2082,10 +2082,7 @@ public:
const Attr *getUnusedResultAttr() const;
/// \brief Returns true if this function or its return type has the
- /// warn_unused_result attribute. If the return type has the attribute and
- /// this function is a method of the return type's class, then false will be
- /// returned to avoid spurious warnings on member methods such as assignment
- /// operators.
+ /// warn_unused_result attribute.
bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; }
/// \brief Returns the storage class as written in the source. For the
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 2b22e5bb50a..094e8dcff08 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3003,9 +3003,7 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
const Attr *FunctionDecl::getUnusedResultAttr() const {
QualType RetType = getReturnType();
if (RetType->isRecordType()) {
- const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl();
- const auto *MD = dyn_cast<CXXMethodDecl>(this);
- if (Ret && !(MD && MD->getCorrespondingMethodInClass(Ret, true))) {
+ if (const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl()) {
if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>())
return R;
}
diff --git a/clang/test/SemaCXX/warn-unused-result.cpp b/clang/test/SemaCXX/warn-unused-result.cpp
index 01bc457ec20..88f5ab1e85c 100644
--- a/clang/test/SemaCXX/warn-unused-result.cpp
+++ b/clang/test/SemaCXX/warn-unused-result.cpp
@@ -160,3 +160,49 @@ void g() {
(void)noexcept(f(), false); // Should not warn.
}
}
+
+namespace {
+// C++ Methods should warn even in their own class.
+struct [[clang::warn_unused_result]] S {
+ S DoThing() { return {}; };
+ S operator++(int) { return {}; };
+ S operator--(int) { return {}; };
+ // Improperly written prefix.
+ S operator++() { return {}; };
+ S operator--() { return {}; };
+};
+
+struct [[clang::warn_unused_result]] P {
+ P DoThing() { return {}; };
+};
+
+P operator++(const P &, int) { return {}; };
+P operator--(const P &, int) { return {}; };
+// Improperly written prefix.
+P operator++(const P &) { return {}; };
+P operator--(const P &) { return {}; };
+
+void f() {
+ S s;
+ P p;
+ s.DoThing(); // expected-warning {{ignoring return value}}
+ p.DoThing(); // expected-warning {{ignoring return value}}
+ // Only postfix is expected to warn when written correctly.
+ s++; // expected-warning {{ignoring return value}}
+ s--; // expected-warning {{ignoring return value}}
+ p++; // expected-warning {{ignoring return value}}
+ p--; // expected-warning {{ignoring return value}}
+ // Improperly written prefix operators should still warn.
+ ++s; // expected-warning {{ignoring return value}}
+ --s; // expected-warning {{ignoring return value}}
+ ++p; // expected-warning {{ignoring return value}}
+ --p; // expected-warning {{ignoring return value}}
+
+ // Silencing the warning by cast to void still works.
+ (void)s.DoThing();
+ (void)s++;
+ (void)p++;
+ (void)++s;
+ (void)++p;
+}
+} // namespace
OpenPOWER on IntegriCloud