[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

Eli Friedman eli.friedman at gmail.com
Mon Aug 6 21:46:07 PDT 2012


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.  "&x" for any normal
variable x doesn't have a side-effect whether or not the type is
volatile-qualified, and "*(volatile int*)0x1234" has a side-effect
even though I think the current HasSideEffects will conclude it
doesn't.

> +  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?

> +  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?

-Eli



More information about the cfe-commits mailing list