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.

llvm-svn: 157414
This commit is contained in:
Eli Friedman 2012-05-24 21:05:41 +00:00
parent d65dbd8e6a
commit f92f6454ef
2 changed files with 24 additions and 25 deletions

View File

@ -1883,30 +1883,20 @@ 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);
const CastExpr *CE = cast<CastExpr>(this);
if (CE->getCastKind() == CK_ToVoid) {
if (CE->getSubExpr()->isGLValue() &&
CE->getSubExpr()->getType().isVolatileQualified())
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;
}
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);
if (CE->getCastKind() == CK_ToVoid) {
if (CE->getSubExpr()->isGLValue() &&
CE->getSubExpr()->getType().isVolatileQualified())
return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc,
R1, R2, Ctx);
return false;
}
@ -1914,12 +1904,19 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
// 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);

View File

@ -30,5 +30,7 @@ namespace derefvolatile {
void f(volatile char* x) {
*x; // expected-warning {{expression result unused; assign into a variable to force a volatile load}}
(void)*x; // expected-warning {{expression result unused; assign into a variable to force a volatile load}}
volatile char y = 10;
(void)y; // don't warn here, because it's a common pattern.
}
}