case CXXReinterpretCastExprClass:
case CXXConstCastExprClass:
case CXXFunctionalCastExprClass: {
+ // While volatile reads are side-effecting in both C and C++, we treat them
+ // as having possible (not definite) side-effects. This allows idiomatic
+ // code to behave without warning, such as sizeof(*v) for a volatile-
+ // qualified pointer.
+ if (!IncludePossibleEffects)
+ break;
+
const CastExpr *CE = cast<CastExpr>(this);
if (CE->getCastKind() == CK_LValueToRValue &&
CE->getSubExpr()->getType().isVolatileQualified())
Bad b;
(void)typeid(b.f()); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
- // A dereference of a volatile pointer is a side effecting operation, despite
- // it being a reasonable operation.
+ // A dereference of a volatile pointer is a side effecting operation, however
+ // since it is idiomatic code, and the alternatives induce higher maintenance
+ // costs, it is allowed.
int * volatile x;
- (void)sizeof(*x); // expected-warning {{expression with side effects has no effect in an unevaluated context}}
+ (void)sizeof(*x); // Ok
}
}