]> granicus.if.org Git - clang/commitdiff
Fix nodiscard for volatile references
authorErich Keane <erich.keane@intel.com>
Thu, 19 Oct 2017 15:58:58 +0000 (15:58 +0000)
committerErich Keane <erich.keane@intel.com>
Thu, 19 Oct 2017 15:58:58 +0000 (15:58 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316166 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Expr.cpp
test/CXX/dcl.dcl/dcl.attr/dcl.attr.nodiscard/p2.cpp

index e8aa8f3d33dc0a8efec67d26105d2699c27eacb6..6cda82b2b0cb0871b5ec5a1dba49b8bbc0288e36 100644 (file)
@@ -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);
         }
index 072f5e74aabbc6b2a063da23ddffd304b333a83a..49c418a687647519be0e9fb86df70dbf16e070b7 100644 (file)
@@ -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