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

Eli Friedman eli.friedman at gmail.com
Tue Dec 20 18:55:12 PST 2011


On Tue, Dec 20, 2011 at 6:39 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> 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).

Err, great.  That will be a bit annoying to write.  It would make all
the constant stuff a bit less complicated if Evaluate could handle all
scalar expressions...

-Eli




More information about the cfe-commits mailing list