r224465 - Adding a -Wunused-value warning for expressions with side effects used in an unevaluated expression context, such as sizeof(), or decltype(). Also adds a similar warning when the expression passed to typeid() *is* evaluated, since it is equally likely that the user would expect the expression operand to be unevaluated in that case.
Timur Iskhodzhanov
timurrrr at google.com
Fri Dec 19 05:20:03 PST 2014
I believe this is a false positive:
-----------------------------------------
#include <typeinfo>
#include <vector>
struct A {
virtual ~A();
};
const char *foo(const std::vector<A*> &v) {
const std::type_info &t = typeid(*v[0]);
return t.name();
}
-----------------------------------------
This warning seems to be pretty annoying as it's on by default.
Is it possible to revert/disable and reland it gradually, making sure we
don't get false positives along the way?
or at least put it under a separate flag for the time being?
On Thu Dec 18 2014 at 9:01:03 PM Aaron Ballman <aaron at aaronballman.com>
wrote:
> Author: aaronballman
> Date: Wed Dec 17 15:57:17 2014
> New Revision: 224465
>
> URL: http://llvm.org/viewvc/llvm-project?rev=224465&view=rev
> Log:
> Adding a -Wunused-value warning for expressions with side effects used in
> an unevaluated expression context, such as sizeof(), or decltype(). Also
> adds a similar warning when the expression passed to typeid() *is*
> evaluated, since it is equally likely that the user would expect the
> expression operand to be unevaluated in that case.
>
> Modified:
> cfe/trunk/include/clang/AST/Expr.h
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/AST/Expr.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/lib/Sema/SemaExprCXX.cpp
> cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
> cfe/trunk/lib/Sema/SemaType.cpp
> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generi
> c-lambda-1y.cpp
> cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp
> cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
> cfe/trunk/test/Sema/bitfield.c
> cfe/trunk/test/Sema/expr-comma-c99.c
> cfe/trunk/test/Sema/expr-comma.c
> cfe/trunk/test/Sema/warn-unused-value.c
> cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
> cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp
> cfe/trunk/test/SemaCXX/undefined-internal.cpp
> cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
> cfe/trunk/test/SemaCXX/warn-unused-result.cpp
> cfe/trunk/test/SemaCXX/warn-unused-value-cxx11.cpp
> cfe/trunk/test/SemaCXX/warn-unused-value.cpp
> cfe/trunk/test/SemaObjCXX/arc-ppe.mm
>
> Modified: cfe/trunk/include/clang/AST/Expr.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
> AST/Expr.h?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/AST/Expr.h (original)
> +++ cfe/trunk/include/clang/AST/Expr.h Wed Dec 17 15:57:17 2014
> @@ -586,8 +586,13 @@ public:
>
> /// HasSideEffects - This routine returns true for all those expressions
> /// which have any effect other than producing a value. Example is a
> function
> - /// call, volatile variable read, or throwing an exception.
> - bool HasSideEffects(const ASTContext &Ctx) const;
> + /// call, volatile variable read, or throwing an exception. If
> + /// IncludePossibleEffects is false, this call treats certain
> expressions with
> + /// potential side effects (such as function call-like expressions,
> + /// instantiation-dependent expressions, or invocations from a macro)
> as not
> + /// having side effects.
> + bool HasSideEffects(const ASTContext &Ctx,
> + bool IncludePossibleEffects = true) const;
>
> /// \brief Determine whether this expression involves a call to any
> function
> /// that is not trivial.
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
> DiagnosticSemaKinds.td?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Dec 17
> 15:57:17 2014
> @@ -6107,6 +6107,12 @@ def warn_unused_container_subscript_expr
> def warn_unused_call : Warning<
> "ignoring return value of function declared with %0 attribute">,
> InGroup<UnusedValue>;
> +def warn_side_effects_unevaluated_context : Warning<
> + "expression with side effects has no effect in an unevaluated context">,
> + InGroup<UnusedValue>;
> +def warn_side_effects_typeid : Warning<
> + "expression with side effects will be evaluated despite being used as
> an "
> + "operand to 'typeid'">, InGroup<UnusedValue>;
> def warn_unused_result : Warning<
> "ignoring return value of function declared with warn_unused_result "
> "attribute">, InGroup<DiagGroup<"unused-result">>;
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
> Sema/Sema.h?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Wed Dec 17 15:57:17 2014
> @@ -1399,7 +1399,10 @@ public:
> const CXXScopeSpec &SS, QualType T);
>
> QualType BuildTypeofExprType(Expr *E, SourceLocation Loc);
> - QualType BuildDecltypeType(Expr *E, SourceLocation Loc);
> + /// If AsUnevaluated is false, E is treated as though it were an
> evaluated
> + /// context, such as when building a type for decltype(auto).
> + QualType BuildDecltypeType(Expr *E, SourceLocation Loc,
> + bool AsUnevaluated = true);
> QualType BuildUnaryTransformType(QualType BaseType,
> UnaryTransformType::UTTKind UKind,
> SourceLocation Loc);
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.
> cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Wed Dec 17 15:57:17 2014
> @@ -2866,9 +2866,16 @@ bool Expr::isConstantInitializer(ASTCont
> return false;
> }
>
> -bool Expr::HasSideEffects(const ASTContext &Ctx) const {
> +bool Expr::HasSideEffects(const ASTContext &Ctx,
> + bool IncludePossibleEffects) const {
> + // In circumstances where we care about definite side effects instead of
> + // potential side effects, we want to ignore expressions that are part
> of a
> + // macro expansion as a potential side effect.
> + if (!IncludePossibleEffects && getExprLoc().isMacroID())
> + return false;
> +
> if (isInstantiationDependent())
> - return true;
> + return IncludePossibleEffects;
>
> switch (getStmtClass()) {
> case NoStmtClass:
> @@ -2921,21 +2928,27 @@ bool Expr::HasSideEffects(const ASTConte
> return false;
>
> case CallExprClass:
> + case CXXOperatorCallExprClass:
> + case CXXMemberCallExprClass:
> + case CUDAKernelCallExprClass:
> + case BlockExprClass:
> + case CXXBindTemporaryExprClass:
> + case UserDefinedLiteralClass:
> + // We don't know a call definitely has side effects, but we can check
> the
> + // call's operands.
> + if (!IncludePossibleEffects)
> + break;
> + return true;
> +
> case MSPropertyRefExprClass:
> case CompoundAssignOperatorClass:
> case VAArgExprClass:
> case AtomicExprClass:
> case StmtExprClass:
> - case CXXOperatorCallExprClass:
> - case CXXMemberCallExprClass:
> - case UserDefinedLiteralClass:
> case CXXThrowExprClass:
> case CXXNewExprClass:
> case CXXDeleteExprClass:
> case ExprWithCleanupsClass:
> - case CXXBindTemporaryExprClass:
> - case BlockExprClass:
> - case CUDAKernelCallExprClass:
> // These always have a side-effect.
> return true;
>
> @@ -2971,24 +2984,26 @@ bool Expr::HasSideEffects(const ASTConte
> case InitListExprClass:
> // FIXME: The children for an InitListExpr doesn't include the array
> filler.
> if (const Expr *E = cast<InitListExpr>(this)->getArrayFiller())
> - if (E->HasSideEffects(Ctx))
> + if (E->HasSideEffects(Ctx, IncludePossibleEffects))
> return true;
> break;
>
> case GenericSelectionExprClass:
> return cast<GenericSelectionExpr>(this)->getResultExpr()->
> - HasSideEffects(Ctx);
> + HasSideEffects(Ctx, IncludePossibleEffects);
>
> case ChooseExprClass:
> - return cast<ChooseExpr>(this)->getChosenSubExpr()->HasSideEffects(
> Ctx);
> + return cast<ChooseExpr>(this)->getChosenSubExpr()->HasSideEffects(
> + Ctx, IncludePossibleEffects);
>
> case CXXDefaultArgExprClass:
> - return cast<CXXDefaultArgExpr>(this)->getExpr()->HasSideEffects(Ctx);
> + return cast<CXXDefaultArgExpr>(this)->getExpr()->HasSideEffects(
> + Ctx, IncludePossibleEffects);
>
> case CXXDefaultInitExprClass: {
> const FieldDecl *FD = cast<CXXDefaultInitExpr>(this)->getField();
> if (const Expr *E = FD->getInClassInitializer())
> - return E->HasSideEffects(Ctx);
> + return E->HasSideEffects(Ctx, IncludePossibleEffects);
> // If we've not yet parsed the initializer, assume it has
> side-effects.
> return true;
> }
> @@ -3021,7 +3036,7 @@ bool Expr::HasSideEffects(const ASTConte
> case CXXConstructExprClass:
> case CXXTemporaryObjectExprClass: {
> const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
> - if (!CE->getConstructor()->isTrivial())
> + if (!CE->getConstructor()->isTrivial() && IncludePossibleEffects)
> return true;
> // A trivial constructor does not add any side-effects of its own.
> Just look
> // at its arguments.
> @@ -3049,7 +3064,7 @@ bool Expr::HasSideEffects(const ASTConte
> const Expr *Subexpr = *I;
> if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Sube
> xpr))
> Subexpr = OVE->getSourceExpr();
> - if (Subexpr->HasSideEffects(Ctx))
> + if (Subexpr->HasSideEffects(Ctx, IncludePossibleEffects))
> return true;
> }
> return false;
> @@ -3058,22 +3073,24 @@ bool Expr::HasSideEffects(const ASTConte
> case ObjCBoxedExprClass:
> case ObjCArrayLiteralClass:
> case ObjCDictionaryLiteralClass:
> - case ObjCMessageExprClass:
> case ObjCSelectorExprClass:
> case ObjCProtocolExprClass:
> - case ObjCPropertyRefExprClass:
> case ObjCIsaExprClass:
> case ObjCIndirectCopyRestoreExprClass:
> case ObjCSubscriptRefExprClass:
> case ObjCBridgedCastExprClass:
> - // FIXME: Classify these cases better.
> - return true;
> + case ObjCMessageExprClass:
> + case ObjCPropertyRefExprClass:
> + // FIXME: Classify these cases better.
> + if (IncludePossibleEffects)
> + return true;
> + break;
> }
>
> // Recurse to children.
> for (const_child_range SubStmts = children(); SubStmts; ++SubStmts)
> if (const Stmt *S = *SubStmts)
> - if (cast<Expr>(S)->HasSideEffects(Ctx))
> + if (cast<Expr>(S)->HasSideEffects(Ctx, IncludePossibleEffects))
> return true;
>
> return false;
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaE
> xpr.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Dec 17 15:57:17 2014
> @@ -1290,6 +1290,13 @@ Sema::CreateGenericSelectionExpr(SourceL
> ControllingExpr = result.get();
> }
>
> + // The controlling expression is an unevaluated operand, so side
> effects are
> + // likely unintended.
> + if (ActiveTemplateInstantiations.empty() &&
> + ControllingExpr->HasSideEffects(Context, false))
> + Diag(ControllingExpr->getExprLoc(),
> + diag::warn_side_effects_unevaluated_context);
> +
> bool TypeErrorFound = false,
> IsResultDependent = ControllingExpr->isTypeDependent(),
> ContainsUnexpandedParameterPack
> @@ -3525,6 +3532,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOper
> return true;
> }
>
> + // The operand for sizeof and alignof is in an unevaluated expression
> context,
> + // so side effects could result in unintended consequences.
> + if ((ExprKind == UETT_SizeOf || ExprKind == UETT_AlignOf) &&
> + ActiveTemplateInstantiations.empty() && E->HasSideEffects(Context,
> false))
> + Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context);
> +
> if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(),
> E->getSourceRange(), ExprKind))
> return true;
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaE
> xprCXX.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Dec 17 15:57:17 2014
> @@ -396,6 +396,7 @@ ExprResult Sema::BuildCXXTypeId(QualType
> SourceLocation TypeidLoc,
> Expr *E,
> SourceLocation RParenLoc) {
> + bool WasEvaluated = false;
> if (E && !E->isTypeDependent()) {
> if (E->getType()->isPlaceholderType()) {
> ExprResult result = CheckPlaceholderExpr(E);
> @@ -425,6 +426,7 @@ ExprResult Sema::BuildCXXTypeId(QualType
>
> // We require a vtable to query the type at run time.
> MarkVTableUsed(TypeidLoc, RecordD);
> + WasEvaluated = true;
> }
> }
>
> @@ -444,6 +446,14 @@ ExprResult Sema::BuildCXXTypeId(QualType
> if (E->getType()->isVariablyModifiedType())
> return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid)
> << E->getType());
> + else if (ActiveTemplateInstantiations.empty() &&
> + E->HasSideEffects(Context, WasEvaluated)) {
> + // The expression operand for typeid is in an unevaluated expression
> + // context, so side effects could result in unintended consequences.
> + Diag(E->getExprLoc(), WasEvaluated
> + ? diag::warn_side_effects_typeid
> + : diag::warn_side_effects_uneval
> uated_context);
> + }
>
> return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
> SourceRange(TypeidLoc, RParenLoc));
> @@ -5622,7 +5632,8 @@ ExprResult Sema::ActOnPseudoDestructorEx
> if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
> return ExprError();
>
> - QualType T = BuildDecltypeType(DS.getRepAsExpr(),
> DS.getTypeSpecTypeLoc());
> + QualType T = BuildDecltypeType(DS.getRepAsExpr(),
> DS.getTypeSpecTypeLoc(),
> + false);
>
> TypeLocBuilder TLB;
> DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T);
> @@ -5690,6 +5701,13 @@ ExprResult Sema::BuildCXXMemberCallExpr(
>
> ExprResult Sema::BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr
> *Operand,
> SourceLocation RParen) {
> + if (ActiveTemplateInstantiations.empty() &&
> + Operand->HasSideEffects(Context, false)) {
> + // The expression operand for noexcept is in an unevaluated expression
> + // context, so side effects could result in unintended consequences.
> + Diag(Operand->getExprLoc(), diag::warn_side_effects_uneval
> uated_context);
> + }
> +
> CanThrowResult CanThrow = canThrow(Operand);
> return new (Context)
> CXXNoexceptExpr(Context.BoolTy, Operand, CanThrow, KeyLoc, RParen);
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaT
> emplateDeduction.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Wed Dec 17 15:57:17 2014
> @@ -3989,7 +3989,7 @@ Sema::DeduceAutoType(TypeLoc Type, Expr
> return DAR_FailedAlreadyDiagnosed;
> }
>
> - QualType Deduced = BuildDecltypeType(Init, Init->getLocStart());
> + QualType Deduced = BuildDecltypeType(Init, Init->getLocStart(),
> false);
> // FIXME: Support a non-canonical deduced type for 'auto'.
> Deduced = Context.getCanonicalType(Deduced);
> Result = SubstituteAutoTransform(*this, Deduced).Apply(Type);
>
> Modified: cfe/trunk/lib/Sema/SemaType.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaT
> ype.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Dec 17 15:57:17 2014
> @@ -5518,11 +5518,19 @@ static QualType getDecltypeForExpr(Sema
> return T;
> }
>
> -QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) {
> +QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc,
> + bool AsUnevaluated) {
> ExprResult ER = CheckPlaceholderExpr(E);
> if (ER.isInvalid()) return QualType();
> E = ER.get();
>
> + if (AsUnevaluated && ActiveTemplateInstantiations.empty() &&
> + E->HasSideEffects(Context, false)) {
> + // The expression operand for decltype is in an unevaluated expression
> + // context, so side effects could result in unintended consequences.
> + Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context);
> + }
> +
> return Context.getDecltypeType(E, getDecltypeForExpr(*this, E));
> }
>
>
> Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generi
> c-lambda-1y.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/
> expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp?rev=
> 224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
> (original)
> +++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2-generic-lambda-1y.cpp
> Wed Dec 17 15:57:17 2014
> @@ -18,7 +18,7 @@ void unevaluated_operand(P &p, int i) {
> // FIXME: this should only emit one error.
> int i2 = sizeof([](auto a, auto b)->void{}(3, '4')); //
> expected-error{{lambda expression in an unevaluated operand}} \
> //
> expected-error{{invalid application of 'sizeof'}}
> - const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p;
> return p; }(i));
> + const std::type_info &ti1 = typeid([](auto &a) -> P& { static P p;
> return p; }(i)); // expected-warning {{expression with side effects will be
> evaluated despite being used as an operand to 'typeid'}}
> const std::type_info &ti2 = typeid([](auto) -> int { return i; }(i));
> // expected-error{{lambda expression in an unevaluated operand}}\
>
> // expected-error{{cannot be implicitly captured}}\
>
> // expected-note{{begins here}}
>
> Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/
> expr.prim/expr.prim.lambda/p2.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp (original)
> +++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p2.cpp Wed Dec 17
> 15:57:17 2014
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
> +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-unused-value %s -verify
>
> // prvalue
> void prvalue() {
>
> Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/
> expr.unary/expr.unary.noexcept/sema.cpp?rev=224465&r1=
> 224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
> (original)
> +++ cfe/trunk/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp Wed
> Dec 17 15:57:17 2014
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify
> -std=c++11 -fms-extensions -Wno-delete-incomplete %s
> +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify
> -std=c++11 -fms-extensions -Wno-delete-incomplete -Wno-unused-value %s
> // expected-no-diagnostics
>
> #define P(e) static_assert(noexcept(e), "expected nothrow")
>
> Modified: cfe/trunk/test/Sema/bitfield.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/bitf
> ield.c?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/bitfield.c (original)
> +++ cfe/trunk/test/Sema/bitfield.c Wed Dec 17 15:57:17 2014
> @@ -1,4 +1,5 @@
> -// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c11
> +// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c11 -Wno-unused-value
> +
> enum e0; // expected-note{{forward declaration of 'enum e0'}}
>
> struct a {
>
> Modified: cfe/trunk/test/Sema/expr-comma-c99.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/expr
> -comma-c99.c?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/expr-comma-c99.c (original)
> +++ cfe/trunk/test/Sema/expr-comma-c99.c Wed Dec 17 15:57:17 2014
> @@ -1,5 +1,4 @@
> // RUN: %clang_cc1 %s -fsyntax-only -verify -std=c99
> -Wno-sizeof-array-decay
> -// expected-no-diagnostics
> // rdar://6095180
>
> struct s { char c[17]; };
> @@ -14,5 +13,5 @@ int B[sizeof((a.c)) == 17 ? 1 : -1];
> // comma does array/function promotion in c99.
> int X[sizeof(0, (foo().c)) == sizeof(char*) ? 1 : -1];
> int Y[sizeof(0, (a,b).c) == sizeof(char*) ? 1 : -1];
> -int Z[sizeof(0, (a=b).c) == sizeof(char*) ? 1 : -1];
> +int Z[sizeof(0, (a=b).c) == sizeof(char*) ? 1 : -1]; // expected-warning
> {{expression with side effects has no effect in an unevaluated context}}
>
>
> Modified: cfe/trunk/test/Sema/expr-comma.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/expr
> -comma.c?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/expr-comma.c (original)
> +++ cfe/trunk/test/Sema/expr-comma.c Wed Dec 17 15:57:17 2014
> @@ -1,5 +1,4 @@
> // RUN: %clang_cc1 %s -fsyntax-only -verify -std=c89
> -Wno-sizeof-array-decay
> -// expected-no-diagnostics
> // rdar://6095180
>
> struct s { char c[17]; };
> @@ -15,4 +14,4 @@ int B[sizeof((a.c)) == 17 ? 1 : -1];
> int W[sizeof(0, a.c) == sizeof(char*) ? 1 : -1];
> int X[sizeof(0, (foo().c)) == 17 ? 1 : -1];
> int Y[sizeof(0, (a,b).c) == 17 ? 1 : -1];
> -int Z[sizeof(0, (a=b).c) == 17 ? 1 : -1];
> +int Z[sizeof(0, (a=b).c) == 17 ? 1 : -1]; // expected-warning
> {{expression with side effects has no effect in an unevaluated context}}
>
> Modified: cfe/trunk/test/Sema/warn-unused-value.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn
> -unused-value.c?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/warn-unused-value.c (original)
> +++ cfe/trunk/test/Sema/warn-unused-value.c Wed Dec 17 15:57:17 2014
> @@ -1,6 +1,6 @@
> -// RUN: %clang_cc1 -fsyntax-only -verify -Wunused-value -Wunused-label %s
> -// RUN: %clang_cc1 -fsyntax-only -verify -Wunused %s
> -// RUN: %clang_cc1 -fsyntax-only -verify -Wall %s
> +// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wunused-value
> -Wunused-label %s
> +// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wunused %s
> +// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wall %s
>
> int i = 0;
> int j = 0;
> @@ -88,3 +88,22 @@ void f1(struct s0 *a) {
> // rdar://8139785
> f0((int)(a->f0 + 1, 10)); // expected-warning {{expression result
> unused}}
> }
> +
> +void blah(int a);
> +#define GenTest(x) _Generic(x, default : blah)(x)
> +
> +void unevaluated_operands(void) {
> + int val = 0;
> +
> + (void)sizeof(++val); // expected-warning {{expression with side effects
> has no effect in an unevaluated context}}
> + (void)_Generic(val++, default : 0); // expected-warning {{expression
> with side effects has no effect in an unevaluated context}}
> + (void)_Alignof(val++); // expected-warning {{expression with side
> effects has no effect in an unevaluated context}} expected-warning
> {{'_Alignof' applied to an expression is a GNU extension}}
> +
> + // VLAs can have side effects so long as it's part of the type and not
> + // an expression.
> + (void)sizeof(int[++val]); // Ok
> + (void)_Alignof(int[++val]); // Ok
> +
> + // Side effects as part of macro expansion are ok.
> + GenTest(val++);
> +}
>
> Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
> constant-expression-cxx11.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
> +++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Wed Dec 17
> 15:57:17 2014
> @@ -1613,7 +1613,8 @@ namespace TypeId {
> A &g();
> constexpr auto &x = typeid(f());
> constexpr auto &y = typeid(g()); // expected-error{{constant
> expression}} \
> - // expected-note{{typeid applied to expression of polymorphic type
> 'TypeId::A' is not allowed in a constant expression}}
> + // expected-note{{typeid applied to expression of polymorphic type
> 'TypeId::A' is not allowed in a constant expression}} \
> + // expected-warning {{expression with side effects will be evaluated
> despite being used as an operand to 'typeid'}}
> }
>
> namespace PR14203 {
>
> Modified: cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
> runtimediag-ppe.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp (original)
> +++ cfe/trunk/test/SemaCXX/runtimediag-ppe.cpp Wed Dec 17 15:57:17 2014
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -fsyntax-only -verify %s
> +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-value %s
>
> // Make sure diagnostics that we don't print based on runtime control
> // flow are delayed correctly in cases where we can't immediately tell
> whether
>
> Modified: cfe/trunk/test/SemaCXX/undefined-internal.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
> undefined-internal.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/undefined-internal.cpp (original)
> +++ cfe/trunk/test/SemaCXX/undefined-internal.cpp Wed Dec 17 15:57:17 2014
> @@ -163,7 +163,7 @@ namespace cxx11_odr_rules {
>
> // Check that the checks work with unevaluated contexts
> (void)sizeof(p(A::used1));
> - (void)typeid(p(A::used1)); // xpected-note {{used here}}
> + (void)typeid(p(A::used1)); // expected-warning {{expression with side
> effects will be evaluated despite being used as an operand to 'typeid'}}
> xpected-note {{used here}}
>
> // Misc other testing
> a(A::unused, 1 ? A::used2 : A::used2); // xpected-note {{used here}}
>
> Modified: cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
> vararg-non-pod.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/vararg-non-pod.cpp (original)
> +++ cfe/trunk/test/SemaCXX/vararg-non-pod.cpp Wed Dec 17 15:57:17 2014
> @@ -103,7 +103,7 @@ Base &get_base(...);
> int eat_base(...);
>
> void test_typeid(Base &base) {
> - (void)typeid(get_base(base)); // expected-warning{{cannot pass object
> of non-POD type 'Base' through variadic function; call will abort at
> runtime}}
> + (void)typeid(get_base(base)); // expected-warning{{cannot pass object
> of non-POD type 'Base' through variadic function; call will abort at
> runtime}} expected-warning{{expression with side effects will be evaluated
> despite being used as an operand to 'typeid'}}
> (void)typeid(eat_base(base)); // okay
> }
>
>
> Modified: cfe/trunk/test/SemaCXX/warn-unused-result.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
> warn-unused-result.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/warn-unused-result.cpp (original)
> +++ cfe/trunk/test/SemaCXX/warn-unused-result.cpp Wed Dec 17 15:57:17 2014
> @@ -132,7 +132,7 @@ void g() {
> D d;
> C c;
> (void)typeid(f(), c); // Should not warn.
> - (void)typeid(f(), d); // expected-warning {{ignoring return value}}
> + (void)typeid(f(), d); // expected-warning {{ignoring return value}}
> expected-warning {{expression with side effects will be evaluated despite
> being used as an operand to 'typeid'}}
>
> // The sizeof expression operand is never evaluated.
> (void)sizeof(f(), c); // Should not warn.
>
> Modified: cfe/trunk/test/SemaCXX/warn-unused-value-cxx11.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
> warn-unused-value-cxx11.cpp?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/warn-unused-value-cxx11.cpp (original)
> +++ cfe/trunk/test/SemaCXX/warn-unused-value-cxx11.cpp Wed Dec 17
> 15:57:17 2014
> @@ -1,5 +1,4 @@
> // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -Wunused-value %s
> -// expected-no-diagnostics
>
> void f() __attribute__((const));
>
> @@ -13,4 +12,33 @@ auto foo(T) -> decltype(f(), bool()) { /
> void g() {
> foo(1);
> }
> +
> +void h() {
> + int i = 0;
> + (void)noexcept(++i); // expected-warning {{expression with side effects
> has no effect in an unevaluated context}}
> + decltype(i++) j = 0; // expected-warning {{expression with side effects
> has no effect in an unevaluated context}}
> }
> +
> +struct S {
> + S operator++(int);
> + S(int i);
> + S();
> +
> + int& f();
> + S g();
> +};
> +
> +void j() {
> + S s;
> + int i = 0;
> + (void)noexcept(s++); // Ok
> + (void)noexcept(i++); // expected-warning {{expression with side effects
> has no effect in an unevaluated context}}
> + (void)noexcept(i = 5); // expected-warning {{expression with side
> effects has no effect in an unevaluated context}}
> + (void)noexcept(s = 5); // Ok
> +
> + (void)sizeof(s.f()); // Ok
> + (void)sizeof(s.f() = 5); // expected-warning {{expression with side
> effects has no effect in an unevaluated context}}
> + (void)noexcept(s.g() = 5); // Ok
> +}
> +
> +}
> \ No newline at end of file
>
> 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=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/warn-unused-value.cpp (original)
> +++ cfe/trunk/test/SemaCXX/warn-unused-value.cpp Wed Dec 17 15:57:17 2014
> @@ -39,13 +39,13 @@ namespace test2 {
> void method() const {
> X* x;
> &x[0]; // expected-warning {{expression result unused}}
> - }
> + }
> };
> typedef basic_string<char> string;
> - void func(const std::string& str) {
> + void func(const std::string& str) {
> str.method(); // expected-note {{in instantiation of member
> function}}
> }
> - }
> + }
> }
> }
>
> @@ -69,3 +69,30 @@ void f() {
> Unused(1, 1); // expected-warning {{expression result unused}}
> }
> }
> +
> +namespace std {
> + struct type_info {};
> +}
> +
> +namespace test4 {
> +struct Good { Good &f(); };
> +struct Bad { virtual Bad& f(); };
> +
> +void f() {
> + int i = 0;
> + (void)typeid(++i); // expected-warning {{expression with side effects
> has no effect in an unevaluated context}}
> +
> + Good g;
> + (void)typeid(g.f()); // Ok; not a polymorphic use of a glvalue.
> +
> + // This is a polymorphic use of a glvalue, which results in the typeid
> being
> + // evaluated instead of unevaluated.
> + 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.
> + int * volatile x;
> + (void)sizeof(*x); // expected-warning {{expression with side effects
> has no effect in an unevaluated context}}
> +}
> +}
>
> Modified: cfe/trunk/test/SemaObjCXX/arc-ppe.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCX
> X/arc-ppe.mm?rev=224465&r1=224464&r2=224465&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaObjCXX/arc-ppe.mm (original)
> +++ cfe/trunk/test/SemaObjCXX/arc-ppe.mm Wed Dec 17 15:57:17 2014
> @@ -13,4 +13,4 @@ void test1() { (void)typeid(NP((void*)(i
>
> class Poly { virtual ~Poly(); };
> Poly& P(void*);
> -void test2() { (void)typeid(P((void*)(id*)0)); } // expected-error
> {{pointer to non-const type 'id'}}
> +void test2() { (void)typeid(P((void*)(id*)0)); } // expected-error
> {{pointer to non-const type 'id'}} expected-warning {{expression with side
> effects will be evaluated despite being used as an operand to 'typeid'}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141219/50e9e71f/attachment.html>
More information about the cfe-commits
mailing list