[cfe-commits] r63242 - in /cfe/trunk: Driver/RewriteObjC.cpp include/clang/AST/Decl.h include/clang/AST/Expr.h include/clang/AST/ExprCXX.h include/clang/Basic/DiagnosticSemaKinds.def lib/AST/Expr.cpp lib/AST/StmtPrinter.cpp lib/CodeGen/CGExprAgg.

Eli Friedman eli.friedman at gmail.com
Wed Jan 28 14:55:08 PST 2009


On Wed, Jan 28, 2009 at 1:54 PM, Douglas Gregor <dgregor at apple.com> wrote:
> +      // Implicitly-generated value initializations are okay.
> +      if (isa<CXXZeroInitValueExpr>(Exp->getInit(i)) &&
> +          cast<CXXZeroInitValueExpr>(Exp->getInit(i))->isImplicit())
> +        continue;
> +
>       if (CheckForConstantInitializer(Exp->getInit(i),
>                                       Exp->getInit(i)->getType()))
>         return true;

This doesn't look quite right... I'm pretty sure a
CXXZeroInitValueExpr should be a valid constant initializer even if it
isn't in an init list.

In any case, this seems like a massive abuse of CXXZeroInitValueExpr,
and I'm not completely sure that the C++ rules match what you want
here.  I'd suggest a new expression type to represent the holes.

> +      SemaRef->Diag(D->getStartLocation(),
> +                    diag::warn_designator_into_union_broken_init)
> +        << SourceRange(D->getStartLocation(), DIE->getSourceRange().getEnd());

If we're going to do the wrong thing, this should be an error.

> +    SemaRef->Diag(D->getEllipsisLoc(),
> +                  diag::warn_gnu_array_range_designator_unsupported)
> +      << SourceRange(D->getLBracketLoc(), D->getRBracketLoc());

If we're going to do the wrong thing, this should be an error.

> +    // Here, xs[0].a == 0 and xs[0].b == 3, since the second,
> +    // designated initializer re-initializes the whole
> +    // subobject [0], overwriting previous initializers.
> +    SemaRef->Diag(InitRange.getBegin(), diag::warn_subobject_initializer_overrides)
> +      << InitRange;
> +    SemaRef->Diag(ExistingInit->getSourceRange().getBegin(),
> +                  diag::note_previous_initializer)
> +      << ExistingInit->hasSideEffects(SemaRef->Context)
> +      << ExistingInit->getSourceRange();

There's one somewhat dangerous case here; take the following example
at file scope:

struct X { int a, b; };
struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };

In gnu89 mode in gcc, the init list is actually equivalent to "{1,
3}".  clang, on the other hand, will give different results (although
it will also warn, so it might not be so bad).

> +bool Expr::hasSideEffects(ASTContext &Ctx) const {
> +  EvalResult Result;
> +  Evaluate(Result, Ctx);
> +  return Result.HasSideEffects;
> +}

I don't think this will work quite correctly; you probably want
something like "return !Evaluate(Result, Ctx) ||
Result.HasSideEffects"

In general, though, this does seem like a good approach.

-Eli



More information about the cfe-commits mailing list