summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2017-10-19 15:58:58 +0000
committerErich Keane <erich.keane@intel.com>2017-10-19 15:58:58 +0000
commit80b0fb04a6e9ec51e0bd7e021d49a3fa21eaa1cc (patch)
treee2c39f8be347e3b702e7d01a489ffdc78b00fceb
parentf2127d172835149b309eb4f949d2edf6764965a3 (diff)
downloadbcm5719-llvm-80b0fb04a6e9ec51e0bd7e021d49a3fa21eaa1cc.tar.gz
bcm5719-llvm-80b0fb04a6e9ec51e0bd7e021d49a3fa21eaa1cc.zip
Fix nodiscard for volatile references
As reported here https://bugs.llvm.org/show_bug.cgi?id=34988 [[nodiscard]] warnings were not being suppressed for volatile-ref return values. Differential Revision: https://reviews.llvm.org/D39075 llvm-svn: 316166
-rw-r--r--clang/lib/AST/Expr.cpp3
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp12
2 files changed, 14 insertions, 1 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index e8aa8f3d33d..6cda82b2b0c 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2298,7 +2298,8 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
const DeclRefExpr *DRE =
dyn_cast<DeclRefExpr>(CE->getSubExpr()->IgnoreParens());
if (!(DRE && isa<VarDecl>(DRE->getDecl()) &&
- cast<VarDecl>(DRE->getDecl())->hasLocalStorage())) {
+ cast<VarDecl>(DRE->getDecl())->hasLocalStorage()) &&
+ !isa<CallExpr>(CE->getSubExpr()->IgnoreParens())) {
return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc,
R1, R2, Ctx);
}
diff --git a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
index 072f5e74aab..49c418a6876 100644
--- a/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp
@@ -9,21 +9,33 @@ 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)();
+void g() {
+ fp(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}}
+
+ // OK, warning suppressed.
+ (void)fp();
+}
#ifdef EXT
// expected-warning@4 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@8 {{use of the 'nodiscard' attribute is a C++17 extension}}
// expected-warning@11 {{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@28 {{use of the 'nodiscard' attribute is a C++17 extension}}
#endif
OpenPOWER on IntegriCloud