diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-05-24 21:05:41 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-05-24 21:05:41 +0000 |
commit | 4059da87fa2fe9f415c9656dc63e75d5d4a489ef (patch) | |
tree | c94199701fa44c782aa5abc54057c1df6291fd8c /lib/AST/Expr.cpp | |
parent | a1bfcbda748b66bc7d6a436f54ef04680fa4aebd (diff) |
A minor tweak to the new volatile lvalue warning: don't warn on "(void)x", where "x" refers to a local variable. This should silence a useless warning in compiler-rt and other places.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157414 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 729030b7ad..111f3384a8 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1883,43 +1883,40 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc, return true; } case CStyleCastExprClass: { - // Ignore an explicit cast to void, as long as the operand isn't a + // Ignore an explicit cast to void unless the operand is a non-trivial // volatile lvalue. - const CStyleCastExpr *CE = cast<CStyleCastExpr>(this); - if (CE->getCastKind() == CK_ToVoid) { - if (CE->getSubExpr()->isGLValue() && - CE->getSubExpr()->getType().isVolatileQualified()) - return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, - R1, R2, Ctx); - return false; - } - WarnE = this; - Loc = CE->getLParenLoc(); - R1 = CE->getSubExpr()->getSourceRange(); - return true; - } - case CXXFunctionalCastExprClass: { - // Ignore an explicit cast to void, as long as the operand isn't a - // volatile lvalue. - const CXXFunctionalCastExpr *CE = cast<CXXFunctionalCastExpr>(this); + const CastExpr *CE = cast<CastExpr>(this); if (CE->getCastKind() == CK_ToVoid) { if (CE->getSubExpr()->isGLValue() && - CE->getSubExpr()->getType().isVolatileQualified()) - return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, - R1, R2, Ctx); + CE->getSubExpr()->getType().isVolatileQualified()) { + const DeclRefExpr *DRE = + dyn_cast<DeclRefExpr>(CE->getSubExpr()->IgnoreParens()); + if (!(DRE && isa<VarDecl>(DRE->getDecl()) && + cast<VarDecl>(DRE->getDecl())->hasLocalStorage())) { + return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, + R1, R2, Ctx); + } + } return false; } - + // If this is a cast to a constructor conversion, check the operand. // Otherwise, the result of the cast is unused. if (CE->getCastKind() == CK_ConstructorConversion) return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx); + WarnE = this; - Loc = CE->getTypeBeginLoc(); - R1 = CE->getSubExpr()->getSourceRange(); + if (const CXXFunctionalCastExpr *CXXCE = + dyn_cast<CXXFunctionalCastExpr>(this)) { + Loc = CXXCE->getTypeBeginLoc(); + R1 = CXXCE->getSubExpr()->getSourceRange(); + } else { + const CStyleCastExpr *CStyleCE = cast<CStyleCastExpr>(this); + Loc = CStyleCE->getLParenLoc(); + R1 = CStyleCE->getSubExpr()->getSourceRange(); + } return true; } - case ImplicitCastExprClass: { const CastExpr *ICE = cast<ImplicitCastExpr>(this); |