[cfe-commits] r147026 - in /cfe/trunk: lib/AST/Expr.cpp test/Sema/static-init.c

Richard Smith richard at metafoo.co.uk
Tue Dec 20 18:39:21 PST 2011


Hi Eli,

On Wed, December 21, 2011 00:43, Eli Friedman wrote:
> Author: efriedma
> Date: Tue Dec 20 18:43:02 2011
> New Revision: 147026
>
> URL: http://llvm.org/viewvc/llvm-project?rev=147026&view=rev
> Log:
> Fix a case where Expr::isConstantInitializer would return true for an
> expression we can't support.  In a slightly amusing twist, the case in
> question was already in the clang regression tests marked as a valid
> construct.  <rdar://problem/10020074>
>
>
> Modified:
> cfe/trunk/lib/AST/Expr.cpp cfe/trunk/test/Sema/static-init.c
>
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=147026&r1=
> 147025&r2=147026&view=diff
> ==============================================================================
>  --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Tue Dec 20 18:43:02 2011
> @@ -2550,17 +2550,30 @@
> if (getType()->isVectorType() && CE->getCastKind() == CK_BitCast) return
> CE->getSubExpr()->isConstantInitializer(Ctx, false);
>
>
> -    // Handle casts with a destination that's a struct or union; this
> -    // deals with both the gcc no-op struct cast extension and the
> -    // cast-to-union extension.
> -    if (getType()->isRecordType())
> +    // Handle misc casts we want to ignore.
> +    // FIXME: Is it really safe to ignore all these?
> +    if (CE->getCastKind() == CK_NoOp ||
> +        CE->getCastKind() == CK_LValueToRValue ||
> +        CE->getCastKind() == CK_ToUnion ||
> +        CE->getCastKind() == CK_ConstructorConversion)
> return CE->getSubExpr()->isConstantInitializer(Ctx, false);
>
> -    // Integer->integer casts can be handled here, which is important for
> -    // things like (int)(&&x-&&y).  Scary but true.
> -    if (getType()->isIntegerType() &&
> -        CE->getSubExpr()->getType()->isIntegerType())
> -      return CE->getSubExpr()->isConstantInitializer(Ctx, false);
> +    // Handle things like (int)(&&x-&&y). It's a bit nasty, but we support
> it. +    if (CE->getCastKind() == CK_IntegralCast) {
> +      const Expr *E = CE->getSubExpr()->IgnoreParenNoopCasts(Ctx);
> +      while (const CastExpr *InnerCE = dyn_cast<CastExpr>(E)) {
> +        if (InnerCE->getCastKind() != CK_IntegralCast)
> +          break;
> +        E = InnerCE->getSubExpr()->IgnoreParenNoopCasts(Ctx);
> +      }
> +
> +      if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
> +        if (BO->getOpcode() == BO_Sub &&
> +            isa<AddrLabelExpr>(BO->getLHS()->IgnoreParenNoopCasts(Ctx)) &&
> +            isa<AddrLabelExpr>(BO->getRHS()->IgnoreParenNoopCasts(Ctx)))
> +          return true;
> +      }
> +    }
>
>
> break; }
>
>
> Modified: cfe/trunk/test/Sema/static-init.c
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/static-init.c?rev=147
> 026&r1=147025&r2=147026&view=diff
> ==============================================================================
>  --- cfe/trunk/test/Sema/static-init.c (original)
> +++ cfe/trunk/test/Sema/static-init.c Tue Dec 20 18:43:02 2011
> @@ -19,5 +19,6 @@
> };
>
>
> union bar u[1]; -struct foo x = {(intptr_t) u}; // no-error
> +struct foo x = {(intptr_t) u}; // expected-error {{initializer element is not
> a compile-time constant}}

A matching change to CGExprConstant is required, or we'll still emit IR which
can't be lowered in some cases (for instance, when building the same test case
in C++ mode).

- Richard




More information about the cfe-commits mailing list