[PATCH] Catch more cases when diagnosing integer-constant-expression overflows.

Richard Smith richard at metafoo.co.uk
Tue Jul 30 15:45:24 PDT 2013


On Tue, Jul 30, 2013 at 12:38 PM, Josh Magee <
Joshua_Magee at playstation.sony.com> wrote:

> jmagee added you to the CC list for the revision "Catch more cases when
> diagnosing integer-constant-expression overflows.".
>
> Hi,
>
> This patch improves integer-constant-expression overflow diagnostics.
>
> Currently clang catches overflow in some cases:
>
> int i;
> ...
> switch (i) {
>   case 4096 * 1024 * 1024:  // Generates overflow warning
>   ...
> }
>
> if (4096 * 1024 * 1024) { // Generates overflow warning
> }
>
> But it misses other cases:
>
> uint64_t x = 4096 * 1024 * 1024; // no warning
>
> if ((x = 4096 * 1024 * 1024)) { // no warning
> }
>
> switch (i) {
>   case (uint64_t)(4096 * 1024 * 1024): // no warning
> ...
> }
>
> void f1(int);
> ...
> f1(4096 * 1024 * 1024); // no warning
>
>
> The patch introduces the following changes:
>  1) In Sema::CheckForIntOverflow, when checking for a BinaryOperator ignore
>     any casts in addition to parentheses.
>

The BinaryOperator check is highly dubious. It would be interesting to
measure the performance cost of running the check on all expressions, not
just binary operators.


>    Ignoring only parentheses was not enough because it missed cases like:
>    x = 4608 * 1024 * 1024, which has an implicit cast:
>     ImplicitCastExpr 0x5145858 'uint64_t':'unsigned long' <IntegralCast>
>     `-BinaryOperator 0x5145830 'int' '*'
>       |-BinaryOperator 0x51457e8 'int' '*'
>       | |-IntegerLiteral 0x51457a8 'int' 4608
>       | `-IntegerLiteral 0x51457c8 'int' 1024
>       `-IntegerLiteral 0x5145810 'int' 1024
>
>  2) In Sema::CheckForIntOverflow, check for CallExprs and recursively
> check for
>     overflow on each argument.
>

It would be better to just pass the whole expression to the checker; that
was the original intent.


>   This handles cases like f1(4096 * 1024 * 1024).
>
>  3) In IntExprEvaluator::VisitBinaryOperator(), bail out on AssignmentOps
>    _after_ running the DataRecursiveIntBinOpEvaluator. In fact, I am not
> sure
>    if check here for AssignmentOps is really necessary.  It seems like it
> is an
>    early-exit optimization.


Please only do this if Info.keepEvaluatingAfterFailure() is true.
Otherwise, we want to bail out as early as we can once we find that an
expression cannot be evaluated.


>  Presumably it was thought that assignment
>    operators would not have any integer expression operands that need
>    evaluating here, however this is not the case in "x = y = 4096 * 1024 *
> 1024"
>    or "if ((y = 4096 * 1024 *1024))".  Running the
> DataRecursiveIntBinOpEvaluator
>    on AssignmentOps catches these cases.  Note, this change was only
> needed to
>    catch these cases in C mode.  In C++ mode an implicit LValueToRValue
> cast was
>    added which changed the path taken through semantic analysis.
>
>
> Thanks,
> Josh
>
> http://llvm-reviews.chandlerc.com/D1238
>
> Files:
>   lib/AST/ExprConstant.cpp
>   lib/Sema/SemaChecking.cpp
>   test/Sema/integer-overflow.c
>   test/SemaCXX/integer-overflow.cpp
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130730/bfd975c4/attachment.html>


More information about the cfe-commits mailing list