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