mirror of https://github.com/microsoft/clang.git
some StmtExprs do not have side-effects
Differential Revision: http://reviews.llvm.org/D10211 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239476 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b26f2993b7
commit
0485743836
|
@ -28,6 +28,7 @@ class ASTContext;
|
|||
/// of its potentially-evaluated subexpressions, recursively.
|
||||
template<template <typename> class Ptr, typename ImplClass>
|
||||
class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
|
||||
protected:
|
||||
const ASTContext &Context;
|
||||
|
||||
public:
|
||||
|
|
|
@ -2887,6 +2887,28 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
|
|||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// \brief Look for any side effects within a Stmt.
|
||||
class SideEffectFinder : public ConstEvaluatedExprVisitor<SideEffectFinder> {
|
||||
typedef ConstEvaluatedExprVisitor<SideEffectFinder> Inherited;
|
||||
const bool IncludePossibleEffects;
|
||||
bool HasSideEffects;
|
||||
|
||||
public:
|
||||
explicit SideEffectFinder(const ASTContext &Context, bool IncludePossible)
|
||||
: Inherited(Context),
|
||||
IncludePossibleEffects(IncludePossible), HasSideEffects(false) { }
|
||||
|
||||
bool hasSideEffects() const { return HasSideEffects; }
|
||||
|
||||
void VisitExpr(const Expr *E) {
|
||||
if (!HasSideEffects &&
|
||||
E->HasSideEffects(Context, IncludePossibleEffects))
|
||||
HasSideEffects = true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
bool Expr::HasSideEffects(const ASTContext &Ctx,
|
||||
bool IncludePossibleEffects) const {
|
||||
// In circumstances where we care about definite side effects instead of
|
||||
|
@ -2974,7 +2996,6 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
|
|||
case CompoundAssignOperatorClass:
|
||||
case VAArgExprClass:
|
||||
case AtomicExprClass:
|
||||
case StmtExprClass:
|
||||
case CXXThrowExprClass:
|
||||
case CXXNewExprClass:
|
||||
case CXXDeleteExprClass:
|
||||
|
@ -2982,6 +3003,13 @@ bool Expr::HasSideEffects(const ASTContext &Ctx,
|
|||
// These always have a side-effect.
|
||||
return true;
|
||||
|
||||
case StmtExprClass: {
|
||||
// StmtExprs have a side-effect if any substatement does.
|
||||
SideEffectFinder Finder(Ctx, IncludePossibleEffects);
|
||||
Finder.Visit(cast<StmtExpr>(this)->getSubStmt());
|
||||
return Finder.hasSideEffects();
|
||||
}
|
||||
|
||||
case ParenExprClass:
|
||||
case ArraySubscriptExprClass:
|
||||
case MemberExprClass:
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -Wno-gnu-statement-expression
|
||||
|
||||
int stmtexpr_fn();
|
||||
void stmtexprs(int i) {
|
||||
__builtin_assume( ({ 1; }) ); // no warning about "side effects"
|
||||
__builtin_assume( ({ if (i) { (void)0; }; 42; }) ); // no warning about "side effects"
|
||||
// expected-warning@+1 {{the argument to '__builtin_assume' has side effects that will be discarded}}
|
||||
__builtin_assume( ({ if (i) ({ stmtexpr_fn(); }); 1; }) );
|
||||
}
|
Loading…
Reference in New Issue