Skip to content

Introduce temporary bindings to BoundsCastExprs #694

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Oct 19, 2019

Conversation

kkjeer
Copy link
Contributor

@kkjeer kkjeer commented Oct 11, 2019

This PR adds a temporary binding expression when building a BoundsCastExpr. This helps enable dynamic and assume bounds casts expressions to be treated as non-value-preserving in CanonBounds::CompareExpr (see issue #691).

Changes

  • Introduce temporary binding expression to bounds casts.
  • Adjust bounds inference and visiting cast expressions to reflect the temporary bindings.
  • Account for BoundsCastExprs when getting the temporary binding of an expression.
  • Account for whether the expression is in a checked scope or not in PruneTemporaryBindings. (A follow-up issue Differentiate between Memory and Bounds checked scopes in SemaBounds #698 is opened to use the CheckedScopeSpecifier enum rather than a boolean here.)
  • Consider BoundsCastExprs to be value-preserving in CheckBoundsDeclarations::EqualValue. Note: this assumes that the expressions E1 and E2 have been successfully evaluated. This change has been removed. This affects the Checked C static_check_bounds_cast.c test (modified in Add tests for bounds cast expression temporary bindings checkedc#385 - opened Improve memory access detection for bounds casts #695 to track remaining work).
  • Treat bounds cast expressions as non-value-preserving.
  • Consider an expression e to be lexicographically equal to the usage of a temporary binding of e.
  • Remove the llvm_unreachable call if a dynamic cast fails in CanonBounds::Compare. Since bounds casts are no longer considered value-preserving, it is possible to compare, e.g. a BoundsCastExpr and an ImplicitCastExpr. An ImplicitCastExpr cannot be dynamically cast to a BoundsCastExpr.
  • Account for the cast kind when profiling a BoundsCastExpr.

Tests

  • Remove the function call test from bounds-decl-challenges. With the introduction of temporaries to bounds cast expressions, this test no longer produces an error.
  • Add AST tests to verify that bounds cast expressions include a temporary binding expression.
  • Other tests are added to checked-c (Add tests for bounds cast expression temporary bindings checkedc#385).

Copy link
Member

@dtarditi dtarditi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a few formatting suggestions. I think that the check in EqualValue needs to be pushed into the lexicographic comparison class.

if (BoundsValueExpr *BV1 = dyn_cast<BoundsValueExpr>(E1))
if (BV1->getTemporaryBinding() == E2)
if (BoundsValueExpr *BV1 = dyn_cast<BoundsValueExpr>(E1)) {
CHKCBindTemporaryExpr *Binding = BV1->getTemporaryBinding();
Copy link
Member

@dtarditi dtarditi Oct 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stylisitc issues: I believe the indentation of the declaration of Binding is off by one-space.

Clang/LLVM developers don't put single statements in blocks. So:

if (Binding == E2) {
 return Result::Equal;
}

should be

if (Binding == E2) 
  return Result::Equal
 #Resolved

return Result::Equal;
}
if (Binding) {
Copy link
Member

@dtarditi dtarditi Oct 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation seems off here.
#Resolved

@@ -2471,6 +2470,12 @@ namespace {
}

CHKCBindTemporaryExpr *GetTempBinding(Expr *E) {
// Bounds casts should always have a temporary binding.
if (BoundsCastExpr *BCE = dyn_cast<BoundsCastExpr>(E)) {
CHKCBindTemporaryExpr *Result = dyn_cast<CHKCBindTemporaryExpr>(BCE->getSubExpr());
Copy link
Member

@dtarditi dtarditi Oct 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation should be 2 characters.
#Resolved

@@ -2234,7 +2222,18 @@ namespace {
}

static bool EqualValue(ASTContext &Ctx, Expr *E1, Expr *E2, EquivExprSets *EquivExprs) {
Lexicographic::Result R = Lexicographic(Ctx, EquivExprs).CompareExpr(E1, E2);
// It is assumed that E1 and E2 have been successfully evaluated, so that dynamic and assume bounds casts can be treated as value preserving here.
Copy link
Member

@dtarditi dtarditi Oct 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to push this check into Lexicographic expression comparison. There should be a special mode that answer the questions: if e1 and e2 evaluate to values, are the values guaranteed to be equal? We can assume there that any evaluations of dynamic_bounds_cast in subexpressions of e1 (or 32) will succeed and any bounds checks that depend on bounds changed by *_cast operation will also succeed.

#Resolved

Copy link
Member

@dtarditi dtarditi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great - nice to see code be deleted and become simpler! I have one suggested comment update. Please run automated testing before committing this,.

Cmp = CompareTypeIgnoreCheckedness(E1ChildExpr->getType(),
E2ChildExpr->getType());

if (!isa<BoundsExpr>(E1ChildExpr))
Copy link
Member

@dtarditi dtarditi Oct 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be helpful to add a comment "Bounds expressions don't have types".
#Resolved

@kkjeer
Copy link
Contributor Author

kkjeer commented Oct 18, 2019

Looks great - nice to see code be deleted and become simpler! I have one suggested comment update. Please run automated testing before committing this,.

The automated testing has passed.

Copy link
Member

@dtarditi dtarditi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the methods in the BoundsInference class, can you make InCheckedScope a field, instead of passing it as an additional argument? An expression is always in the same checked scope, I believe.

@dtarditi
Copy link
Member

If we were to add support for statement expressions in GCC (https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html) , an expression might not always be in the same checked scope.

@kkjeer kkjeer merged commit 82f665e into master Oct 19, 2019
@kkjeer kkjeer deleted the issue691-bounds-casts-temp-binding branch October 19, 2019 00:16
mgrang pushed a commit that referenced this pull request Oct 25, 2019
Cherry-picked from commit 82f665e
Author: Katherine Kjeer <[email protected]>
Commit: GitHub <[email protected]>

    Introduce temporary bindings to BoundsCastExprs (#694)

    * Account for cast kind in StmtProfiler::VisitBoundsCastExpr and CanonBounds::CompareImpl

    * Don't treat dynamic and assume bounds casts as value preserving; don't compare types on bounds expressions

    * Introduce a temporary binding expression for all bounds cast expressions

    * Use the temporary bindings introduced in bounds cast expressions to infer bounds

    * Remove unused PruneTemporaryBindings

    * Treat e and the usage of a temporary binding of e as equal

    * Remove llvm_unreachable from CanonBounds::Compare

    * Account for bounds cast expressions in GetTempBinding

    * Treat bounds casts as value preserving in CheckBoundsDelarations::EqualValue (introducing the assumption that E1 and E2 have been evaluated)

    * Remove function call test from bounds-decl-challenges

    * Add AST dump tests for bounds cast expression temporaries

    * Fix indentation

    * More formatting fixes

    * Revert treating bounds casts as value preserving in EqualValue

    * Add comment about lack of bounds expression types

    * Prune temporary bindings from member expression bounds

    * Account for checked scope information in PruneTemporaryBindings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants