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:
parent
d65dbd8e6a
commit
f92f6454ef
|
@ -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);
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue