[cfe-commits] r157362 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Expr.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaStmt.cpp test/Sema/unused-expr.c test/SemaCXX/reinterpret-cast.cpp test/SemaCXX/unused.
Nico Weber
thakis at chromium.org
Thu May 24 09:57:27 PDT 2012
Hi Eli,
someone on IRC reported that this breaks the compiler-rt build. Log at
http://paste.ubuntu.com/1004855/ , excerpt below:
In file included from
/home/lockal/bin/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_clock.h:16:
/home/lockal/bin/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_defs.h:144:9:
error: expression result unused; assign into a variable to force a
volatile load [-Werror,-Wunused-volatile-lvalue]
(void)cfg;
^~~
/home/lockal/bin/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_defs.h:145:9:
error: expression result unused; assign into a variable to force a
volatile load [-Werror,-Wunused-volatile-lvalue]
(void)stats;
^~~~~
/home/lockal/bin/llvm/projects/compiler-rt/lib/tsan/rtl/tsan_defs.h:146:9:
error: expression result unused; assign into a variable to force a
volatile load [-Werror,-Wunused-volatile-lvalue]
(void)shadow;
^~~~~~
This fires also in the chrome build, for example here:
../../third_party/WebKit/Source/WTF/wtf/DynamicAnnotations.cpp:48:5:
error: expression result unused; assign into a variable to force a
volatile load [-Werror,-Wunused-volatile-lvalue]
DYNAMIC_ANNOTATIONS_IMPL
^~~~~~~~~~~~~~~~~~~~~~~~
../../third_party/WebKit/Source/WTF/wtf/DynamicAnnotations.cpp:39:11:
note: expanded from macro 'DYNAMIC_ANNOTATIONS_IMPL'
(void)lineno;
^~~~~~
Nico
On Wed, May 23, 2012 at 5:47 PM, Eli Friedman <eli.friedman at gmail.com> wrote:
> Author: efriedma
> Date: Wed May 23 19:47:05 2012
> New Revision: 157362
>
> URL: http://llvm.org/viewvc/llvm-project?rev=157362&view=rev
> Log:
> Add a warning to diagnose statements in C++ like "*(volatile int*)x;". Conceptually, this is part of -Wunused-value, but I added a separate flag -Wunused-volatile-lvalue so it doesn't get turned off by accident with -Wno-unused-value. I also made a few minor improvements to existing unused value warnings in the process. <rdar://problem/11516811>.
>
>
> Modified:
> cfe/trunk/include/clang/AST/Expr.h
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/lib/AST/Expr.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/lib/Sema/SemaStmt.cpp
> cfe/trunk/test/Sema/unused-expr.c
> cfe/trunk/test/SemaCXX/reinterpret-cast.cpp
> cfe/trunk/test/SemaCXX/unused.cpp
> cfe/trunk/test/SemaCXX/warn-unused-value.cpp
>
> Modified: cfe/trunk/include/clang/AST/Expr.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Expr.h (original)
> +++ cfe/trunk/include/clang/AST/Expr.h Wed May 23 19:47:05 2012
> @@ -179,11 +179,12 @@
> SourceLocation getExprLoc() const LLVM_READONLY;
>
> /// isUnusedResultAWarning - Return true if this immediate expression should
> - /// be warned about if the result is unused. If so, fill in Loc and Ranges
> - /// with location to warn on and the source range[s] to report with the
> - /// warning.
> - bool isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
> - SourceRange &R2, ASTContext &Ctx) const;
> + /// be warned about if the result is unused. If so, fill in expr, location,
> + /// and ranges with expr to warn on and source locations/ranges appropriate
> + /// for a warning.
> + bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc,
> + SourceRange &R1, SourceRange &R2,
> + ASTContext &Ctx) const;
>
> /// isLValue - True if this expression is an "l-value" according to
> /// the rules of the current language. C and C++ give somewhat
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed May 23 19:47:05 2012
> @@ -4728,6 +4728,10 @@
> def warn_unused_result : Warning<
> "ignoring return value of function declared with warn_unused_result "
> "attribute">, InGroup<DiagGroup<"unused-result">>;
> +def warn_unused_volatile : Warning<
> + "expression result unused; assign into a variable to force a volatile load">,
> + InGroup<DiagGroup<"unused-volatile-lvalue">>;
> +
> def warn_unused_comparison : Warning<
> "%select{equality|inequality}0 comparison result unused">,
> InGroup<UnusedComparison>;
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Wed May 23 19:47:05 2012
> @@ -1654,8 +1654,9 @@
> /// be warned about if the result is unused. If so, fill in Loc and Ranges
> /// with location to warn on and the source range[s] to report with the
> /// warning.
> -bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
> - SourceRange &R2, ASTContext &Ctx) const {
> +bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
> + SourceRange &R1, SourceRange &R2,
> + ASTContext &Ctx) const {
> // Don't warn if the expr is type dependent. The type could end up
> // instantiating to void.
> if (isTypeDependent())
> @@ -1665,30 +1666,32 @@
> default:
> if (getType()->isVoidType())
> return false;
> + WarnE = this;
> Loc = getExprLoc();
> R1 = getSourceRange();
> return true;
> case ParenExprClass:
> return cast<ParenExpr>(this)->getSubExpr()->
> - isUnusedResultAWarning(Loc, R1, R2, Ctx);
> + isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> case GenericSelectionExprClass:
> return cast<GenericSelectionExpr>(this)->getResultExpr()->
> - isUnusedResultAWarning(Loc, R1, R2, Ctx);
> + isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> case UnaryOperatorClass: {
> const UnaryOperator *UO = cast<UnaryOperator>(this);
>
> switch (UO->getOpcode()) {
> - default: break;
> + case UO_Plus:
> + case UO_Minus:
> + case UO_AddrOf:
> + case UO_Not:
> + case UO_LNot:
> + case UO_Deref:
> + break;
> case UO_PostInc:
> case UO_PostDec:
> case UO_PreInc:
> case UO_PreDec: // ++/--
> return false; // Not a warning.
> - case UO_Deref:
> - // Dereferencing a volatile pointer is a side-effect.
> - if (Ctx.getCanonicalType(getType()).isVolatileQualified())
> - return false;
> - break;
> case UO_Real:
> case UO_Imag:
> // accessing a piece of a volatile complex is a side-effect.
> @@ -1697,8 +1700,9 @@
> return false;
> break;
> case UO_Extension:
> - return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
> + return UO->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> }
> + WarnE = this;
> Loc = UO->getOperatorLoc();
> R1 = UO->getSubExpr()->getSourceRange();
> return true;
> @@ -1717,17 +1721,18 @@
> dyn_cast<IntegerLiteral>(BO->getRHS()->IgnoreParens()))
> if (IE->getValue() == 0)
> return false;
> - return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
> + return BO->getRHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> // Consider '||', '&&' to have side effects if the LHS or RHS does.
> case BO_LAnd:
> case BO_LOr:
> - if (!BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx) ||
> - !BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx))
> + if (!BO->getLHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx) ||
> + !BO->getRHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx))
> return false;
> break;
> }
> if (BO->isAssignmentOp())
> return false;
> + WarnE = this;
> Loc = BO->getOperatorLoc();
> R1 = BO->getLHS()->getSourceRange();
> R2 = BO->getRHS()->getSourceRange();
> @@ -1743,28 +1748,22 @@
> // be being used for control flow. Only warn if both the LHS and
> // RHS are warnings.
> const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
> - if (!Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx))
> + if (!Exp->getRHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx))
> return false;
> if (!Exp->getLHS())
> return true;
> - return Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Ctx);
> + return Exp->getLHS()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> }
>
> case MemberExprClass:
> - // If the base pointer or element is to a volatile pointer/field, accessing
> - // it is a side effect.
> - if (Ctx.getCanonicalType(getType()).isVolatileQualified())
> - return false;
> + WarnE = this;
> Loc = cast<MemberExpr>(this)->getMemberLoc();
> R1 = SourceRange(Loc, Loc);
> R2 = cast<MemberExpr>(this)->getBase()->getSourceRange();
> return true;
>
> case ArraySubscriptExprClass:
> - // If the base pointer or element is to a volatile pointer/field, accessing
> - // it is a side effect.
> - if (Ctx.getCanonicalType(getType()).isVolatileQualified())
> - return false;
> + WarnE = this;
> Loc = cast<ArraySubscriptExpr>(this)->getRBracketLoc();
> R1 = cast<ArraySubscriptExpr>(this)->getLHS()->getSourceRange();
> R2 = cast<ArraySubscriptExpr>(this)->getRHS()->getSourceRange();
> @@ -1780,6 +1779,7 @@
> const CXXOperatorCallExpr *Op = cast<CXXOperatorCallExpr>(this);
> if (Op->getOperator() == OO_EqualEqual ||
> Op->getOperator() == OO_ExclaimEqual) {
> + WarnE = this;
> Loc = Op->getOperatorLoc();
> R1 = Op->getSourceRange();
> return true;
> @@ -1800,6 +1800,7 @@
> // updated to match for QoI.
> if (FD->getAttr<WarnUnusedResultAttr>() ||
> FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
> + WarnE = this;
> Loc = CE->getCallee()->getLocStart();
> R1 = CE->getCallee()->getSourceRange();
>
> @@ -1824,6 +1825,7 @@
> ME->getSelector().getIdentifierInfoForSlot(0) &&
> ME->getSelector().getIdentifierInfoForSlot(0)
> ->getName().startswith("init")) {
> + WarnE = this;
> Loc = getExprLoc();
> R1 = ME->getSourceRange();
> return true;
> @@ -1831,6 +1833,7 @@
>
> const ObjCMethodDecl *MD = ME->getMethodDecl();
> if (MD && MD->getAttr<WarnUnusedResultAttr>()) {
> + WarnE = this;
> Loc = getExprLoc();
> return true;
> }
> @@ -1838,6 +1841,7 @@
> }
>
> case ObjCPropertyRefExprClass:
> + WarnE = this;
> Loc = getExprLoc();
> R1 = getSourceRange();
> return true;
> @@ -1850,6 +1854,7 @@
> isa<BinaryOperator>(PO->getSyntacticForm()))
> return false;
>
> + WarnE = this;
> Loc = getExprLoc();
> R1 = getSourceRange();
> return true;
> @@ -1864,50 +1869,70 @@
> const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
> if (!CS->body_empty()) {
> if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
> - return E->isUnusedResultAWarning(Loc, R1, R2, Ctx);
> + return E->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> if (const LabelStmt *Label = dyn_cast<LabelStmt>(CS->body_back()))
> if (const Expr *E = dyn_cast<Expr>(Label->getSubStmt()))
> - return E->isUnusedResultAWarning(Loc, R1, R2, Ctx);
> + return E->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> }
>
> if (getType()->isVoidType())
> return false;
> + WarnE = this;
> Loc = cast<StmtExpr>(this)->getLParenLoc();
> R1 = getSourceRange();
> return true;
> }
> - case CStyleCastExprClass:
> - // If this is an explicit cast to void, allow it. People do this when they
> - // think they know what they're doing :).
> - if (getType()->isVoidType())
> + case CStyleCastExprClass: {
> + // Ignore an explicit cast to void, as long as the operand isn't a
> + // 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;
> - Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
> - R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
> + }
> + WarnE = this;
> + Loc = CE->getLParenLoc();
> + R1 = CE->getSubExpr()->getSourceRange();
> return true;
> + }
> case CXXFunctionalCastExprClass: {
> - if (getType()->isVoidType())
> + // 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;
> - const CastExpr *CE = cast<CastExpr>(this);
> + }
>
> - // If this is a cast to void or a constructor conversion, check the operand.
> + // If this is a cast to a constructor conversion, check the operand.
> // Otherwise, the result of the cast is unused.
> - if (CE->getCastKind() == CK_ToVoid ||
> - CE->getCastKind() == CK_ConstructorConversion)
> - return (cast<CastExpr>(this)->getSubExpr()
> - ->isUnusedResultAWarning(Loc, R1, R2, Ctx));
> - Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
> - R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
> + if (CE->getCastKind() == CK_ConstructorConversion)
> + return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> + WarnE = this;
> + Loc = CE->getTypeBeginLoc();
> + R1 = CE->getSubExpr()->getSourceRange();
> return true;
> }
>
> - case ImplicitCastExprClass:
> - // Check the operand, since implicit casts are inserted by Sema
> - return (cast<ImplicitCastExpr>(this)
> - ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
> + case ImplicitCastExprClass: {
> + const CastExpr *ICE = cast<ImplicitCastExpr>(this);
>
> + // lvalue-to-rvalue conversion on a volatile lvalue is a side-effect.
> + if (ICE->getCastKind() == CK_LValueToRValue &&
> + ICE->getSubExpr()->getType().isVolatileQualified())
> + return false;
> +
> + return ICE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
> + }
> case CXXDefaultArgExprClass:
> return (cast<CXXDefaultArgExpr>(this)
> - ->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
> + ->getExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
>
> case CXXNewExprClass:
> // FIXME: In theory, there might be new expressions that don't have side
> @@ -1916,10 +1941,10 @@
> return false;
> case CXXBindTemporaryExprClass:
> return (cast<CXXBindTemporaryExpr>(this)
> - ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
> + ->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
> case ExprWithCleanupsClass:
> return (cast<ExprWithCleanups>(this)
> - ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Ctx));
> + ->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
> }
> }
>
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed May 23 19:47:05 2012
> @@ -7412,8 +7412,6 @@
> // C99 6.5.17
> static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS,
> SourceLocation Loc) {
> - S.DiagnoseUnusedExprResult(LHS.get());
> -
> LHS = S.CheckPlaceholderExpr(LHS.take());
> RHS = S.CheckPlaceholderExpr(RHS.take());
> if (LHS.isInvalid() || RHS.isInvalid())
> @@ -7429,6 +7427,8 @@
> if (LHS.isInvalid())
> return QualType();
>
> + S.DiagnoseUnusedExprResult(LHS.get());
> +
> if (!S.getLangOpts().CPlusPlus) {
> RHS = S.DefaultFunctionArrayLvalueConversion(RHS.take());
> if (RHS.isInvalid())
>
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed May 23 19:47:05 2012
> @@ -153,10 +153,11 @@
> if (!E)
> return;
>
> + const Expr *WarnExpr;
> SourceLocation Loc;
> SourceRange R1, R2;
> if (SourceMgr.isInSystemMacro(E->getExprLoc()) ||
> - !E->isUnusedResultAWarning(Loc, R1, R2, Context))
> + !E->isUnusedResultAWarning(WarnExpr, Loc, R1, R2, Context))
> return;
>
> // Okay, we have an unused result. Depending on what the base expression is,
> @@ -171,7 +172,7 @@
> if (DiagnoseUnusedComparison(*this, E))
> return;
>
> - E = E->IgnoreParenImpCasts();
> + E = WarnExpr;
> if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
> if (E->getType()->isVoidType())
> return;
> @@ -229,6 +230,11 @@
> }
> }
>
> + if (E->isGLValue() && E->getType().isVolatileQualified()) {
> + Diag(Loc, diag::warn_unused_volatile) << R1 << R2;
> + return;
> + }
> +
> DiagRuntimeBehavior(Loc, 0, PDiag(DiagID) << R1 << R2);
> }
>
>
> Modified: cfe/trunk/test/Sema/unused-expr.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/unused-expr.c?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/test/Sema/unused-expr.c (original)
> +++ cfe/trunk/test/Sema/unused-expr.c Wed May 23 19:47:05 2012
> @@ -92,6 +92,7 @@
> fn2(92, 21); // expected-warning {{ignoring return value of function declared with pure attribute}}
> fn3(42); // expected-warning {{ignoring return value of function declared with const attribute}}
> __builtin_fabsf(0); // expected-warning {{ignoring return value of function declared with const attribute}}
> + (void)0, fn1(); // expected-warning {{ignoring return value of function declared with warn_unused_result attribute}}
> return 0;
> }
>
>
> Modified: cfe/trunk/test/SemaCXX/reinterpret-cast.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/reinterpret-cast.cpp?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/reinterpret-cast.cpp (original)
> +++ cfe/trunk/test/SemaCXX/reinterpret-cast.cpp Wed May 23 19:47:05 2012
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast %s
> +// RUN: %clang_cc1 -fsyntax-only -verify -ffreestanding -Wundefined-reinterpret-cast -Wno-unused-volatile-lvalue %s
>
> #include <stdint.h>
>
>
> Modified: cfe/trunk/test/SemaCXX/unused.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/unused.cpp?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/unused.cpp (original)
> +++ cfe/trunk/test/SemaCXX/unused.cpp Wed May 23 19:47:05 2012
> @@ -1,24 +1,34 @@
> // RUN: %clang_cc1 -fsyntax-only -verify %s
> +
> // PR4103 : Make sure we don't get a bogus unused expression warning
> -class APInt {
> - char foo;
> -};
> -class APSInt : public APInt {
> - char bar;
> -public:
> - APSInt &operator=(const APSInt &RHS);
> -};
> +namespace PR4103 {
> + class APInt {
> + char foo;
> + };
> + class APSInt : public APInt {
> + char bar;
> + public:
> + APSInt &operator=(const APSInt &RHS);
> + };
>
> -APSInt& APSInt::operator=(const APSInt &RHS) {
> - APInt::operator=(RHS);
> - return *this;
> -}
> + APSInt& APSInt::operator=(const APSInt &RHS) {
> + APInt::operator=(RHS);
> + return *this;
> + }
>
> -template<typename T>
> -struct X {
> - X();
> -};
> + template<typename T>
> + struct X {
> + X();
> + };
> +
> + void test() {
> + X<int>();
> + }
> +}
>
> -void test() {
> - X<int>();
> +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}}
> + }
> }
>
> Modified: cfe/trunk/test/SemaCXX/warn-unused-value.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unused-value.cpp?rev=157362&r1=157361&r2=157362&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/warn-unused-value.cpp (original)
> +++ cfe/trunk/test/SemaCXX/warn-unused-value.cpp Wed May 23 19:47:05 2012
> @@ -12,7 +12,7 @@
> // pointer to volatile has side effect (thus no warning)
> Box* box = new Box;
> box->i; // expected-warning {{expression result unused}}
> - box->j;
> + box->j; // expected-warning {{expression result unused}}
> }
> }
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list