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 06:58:11 PST 2014


On Fri Dec 19 2014 at 5:54:36 PM Aaron Ballman <aaron at aaronballman.com>
wrote:

> On Fri, Dec 19, 2014 at 8:20 AM, Timur Iskhodzhanov <timurrrr at google.com>
> wrote:
> > 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();
> >   }
> > -----------------------------------------
>
> That's not actually a false-positive because the result is a
> polymorphic glvalue, which means operator[] is truly being called,
> which can lead to some pretty unexpected results if you are not
> anticipating it.
>

Can you clarify what unexpected results do you mean?


> > This warning seems to be pretty annoying as it's on by default.
>
> I will be making a small change this morning to put this under its own
> warning flag so that it can be turned off. I'm also exploring ways to
> tweak the algorithm because there are some cases where this is
> reasonable behavior. That being said, your code does have UB if
> v.empty() == true, so it can catch bugs. ;-)
>

(oh yeah, I was assuming the vector is not empty.  the warning is still
there if I push_back a new object)


> > 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?
>
> Separate flag is incoming.
>

Great!
Will it be off by default?


> ~Aaron
>
> >
> > 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-
> generic-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>(Subexpr))
> >>          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/
> SemaExpr.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/
> SemaExprCXX.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_unevaluated_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_unevaluated_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/
> SemaTemplateDeduction.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/
> SemaType.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-
> generic-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/
> bitfield.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/
> SemaObjCXX/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/257e3168/attachment.html>


More information about the cfe-commits mailing list