On Fri Dec 19 2014 at 5:54:36 PM Aaron Ballman <[email protected]> wrote:
> On Fri, Dec 19, 2014 at 8:20 AM, Timur Iskhodzhanov <[email protected]> > 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 <[email protected]> > > 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 > >> [email protected] > >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
