[cfe-commits] r161388 - in /cfe/trunk: lib/AST/Expr.cpp lib/AST/ExprConstant.cpp test/CodeGenCXX/const-init-cxx11.cpp test/CodeGenCXX/debug-lambda-expressions.cpp test/CodeGenCXX/global-init.cpp test/CodeGenCXX/lambda-expressions.cpp test/CodeGen

Richard Smith richard at metafoo.co.uk
Mon Aug 6 21:59:47 PDT 2012


On Mon, Aug 6, 2012 at 9:46 PM, Eli Friedman <eli.friedman at gmail.com> wrote:

> On Mon, Aug 6, 2012 at 9:16 PM, Richard Smith
> <richard-llvm at metafoo.co.uk> wrote:
> > Author: rsmith
> > Date: Mon Aug  6 23:16:51 2012
> > New Revision: 161388
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=161388&view=rev
> > Log:
> > Teach Expr::HasSideEffects about all the Expr types, and fix a bug where
> it
> > was mistakenly classifying dynamic_casts which might throw as having no
> side
> > effects.
> >
> > Switch it from a visitor to a switch, so it is kept up-to-date as future
> Expr
> > nodes are added. Move it from ExprConstant.cpp to Expr.cpp, since it's
> not
> > really related to constant expression evaluation.
> >
> > Since we use HasSideEffect to determine whether to emit an unused global
> with
> > internal linkage, this has the effect of suppressing emission of globals
> in
> > some cases.
> >
> > I've left many of the Objective-C cases conservatively assuming that the
> > expression has side-effects. I'll leave it to someone with better
> knowledge
> > of Objective-C than mine to improve them.
> >
> > +  case DeclRefExprClass:
> > +  case ObjCIvarRefExprClass:
> > +    return getType().isVolatileQualified();
>
> Saying that a DeclRefExpr has a side-effect if it's volatile is weird
> and incomplete... an lvalue-to-rvalue conversion can have a
> side-effect, but the DeclRef itself doesn't.


I agree. This is inherited from the old HasSideEffects implementation. I
was intending to clean this up in a subsequent commit.


> > +  case CXXTypeidExprClass: {
> > +    // A typeid expression has side-effects if it can throw.
> > +    const CXXTypeidExpr *TE = cast<CXXTypeidExpr>(this);
> > +    if (TE->isTypeOperand())
> > +      return false;
> > +    const CXXRecordDecl *RD =
> > +        TE->getExprOperand()->getType()->getAsCXXRecordDecl();
> > +    if (!RD || !RD->isPolymorphic() ||
> > +        !TE->getExprOperand()->
> > +          Classify(const_cast<ASTContext&>(Ctx)).isGLValue())
> > +      // Not a glvalue of polymorphic class type: the expression is an
> > +      // unevaluated operand.
> > +      return false;
> > +    // Might throw.
> > +    return true;
> > +  }
>
> Do we really not have a helper routine for this?
>

I've not found one, but we clearly should. This is duplicated now at least
here, in Sema::BuildCXXTypeId and in CodeGenFunction::EmitCXXTypeidExpr.


> > +  case CXXConstructExprClass:
> > +  case CXXTemporaryObjectExprClass: {
> > +    const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
> > +    if (!CE->isElidable() && !CE->getConstructor()->isTrivial())
> > +      return true;
> > +    // An elidable or trivial constructor does not add any side-effects
> of its
> > +    // own. Just look at its arguments.
> > +    break;
> > +  }
>
> It's not obvious to me that an elidable constructor doesn't add
> side-effects; what exactly is HasSideEffects defined to return?


  /// HasSideEffects - This routine returns true for all those expressions
  /// which must be evaluated each time and must not be optimized away
  /// or evaluated at compile time. Example is a function call, volatile
  /// variable read.

... although some further investigation indicates that we have some callers
which want a stronger guarantee that evaluating the expression can't be
detected. I'll remove the elidable check and update the comment.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120806/9e1c5c07/attachment.html>


More information about the cfe-commits mailing list