[cfe-dev] Unravelling i-c-e + the gnu mess

Eli Friedman eli.friedman at gmail.com
Wed Jul 9 16:03:14 PDT 2008


On Wed, Jul 9, 2008 at 11:05 AM, Chris Lattner <clattner at apple.com> wrote:
> Ok, I'm preparing to do battle with Expr::isIntegerConstantExpr and
> want to consult the guru's to see if this is a sane plan. :)
>
> Problem statement:
>   1) we want to support fully conformant C code with GNU extensions
> disabled.
>   2) We want to support GNU extensions, but emit ext-warns when they
> are used.
>   3) If a subexpr is a GNU ice, we don't want to emit warnings
> multiple times in the subexpr.  The canonical horrible example would
> be test/Sema/darwin-align-cast.c

I agree so far.

> 2. Change Expr::isIntegerConstantExpr to be something like this:
>
>   // See if this expr is a real i-c-e.
>   unsigned Diag = isIntegerConstExprHelper(this, ..., false)
>   if (Diag == 0) return true;
>
>   // See if it is a gnu one.
>   if (!LangOptions.NoExtensions) {
>     if (isIntegerConstExprHelper(this, ..., false) == 0) {
>       Emit Warning about using GNU i-c-e.
>       return true;
>     }
>   }
>   return false;

This is where it get really messy... the issue is that saying that
something is an integer constant expression has indirect effects in
some cases.  Non-ICE array bounds indicate a VLA, and the
compatibility rules for those are different from those for constant
arrays.  A conditional expression with a null pointer constant can
silently end up with a different type from an conditional with a
pointer that happens to evaluate to zero.  These are edge cases, but
-pedantic shouldn't affect semantics.

I think the right approach is what we're doing in
Sema::TryFixInvalidVariablyModifiedType: if we run into a situation
where we print a warning/error, but gcc accepts the code, try to
recover at the point where we would print the diagnostic.

If it's convenient, we could add a "RequireIntegerConstantExpr" method
which does roughly "if (Expr->ICE()) return val; if
(Expr->TryEvaluate()) {pedwarn(); return val;} error(); return
failure;".

Downsides to this approach: it's possible it will let stuff slip by
without a warning in non-pedantic mode that gcc wouldn't accept, and
this will leave constructs like the glibc tgmath.h broken.

On a related note, I'm considering rewriting
Expr::isIntegerConstantExpression() to delegate actual calculation to
Expr::TryEvaluate() at some point, to reduce code duplication.

> 3. Change Expr::isIntegerConstantExpr to return the diag reason up to
> its callers so they can emit more specific diags in some cases.

We should definitely do this eventually in any case.

-Eli



More information about the cfe-dev mailing list