Skip to content

Commit 2dba020

Browse files
author
kakje
committed
Allow equality with NullToPointer casts and add type compatibility check to GetOriginalValue
1 parent a2eca86 commit 2dba020

2 files changed

Lines changed: 250 additions & 93 deletions

File tree

clang/lib/Sema/SemaBounds.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3672,20 +3672,6 @@ namespace {
36723672
// State.G is assumed to contain expressions that produce the same value
36733673
// as the source of the assignment.
36743674
void RecordEqualityWithTarget(Expr *Target, CheckingState &State) {
3675-
// Do not record equality between the target and source if the source
3676-
// produces the same value as a NullToPointer cast. This avoids
3677-
// recording equality between non-assignment-compatible variables
3678-
// with pointer types. For example, for the assignments int *p = 0;
3679-
// array_ptr<int> a = 0; UEQ should not contain { 0, p, a }. UEQ
3680-
// also should not contain { 0, p } and { 0, a } so that UEQ does not
3681-
// grow too large.
3682-
for (auto I = State.G.begin(); I != State.G.end(); ++I) {
3683-
if (CastExpr *CE = dyn_cast<CastExpr>(*I)) {
3684-
if (CE->getCastKind() == CastKind::CK_NullToPointer)
3685-
return;
3686-
}
3687-
}
3688-
36893675
// If UEQ contains a set F of expressions that produce the same value
36903676
// as the source, add the target to F. This prevents UEQ from growing
36913677
// too large and containing redundant equality information. For example,
@@ -3821,8 +3807,17 @@ namespace {
38213807
Lexicographic Lex(S.Context, nullptr);
38223808
Expr *E = Lex.IgnoreValuePreservingOperations(S.Context, *I);
38233809
DeclRefExpr *W = GetRValueVariable(E);
3824-
if (W != nullptr && !EqualValue(S.Context, V, W, nullptr))
3825-
return *I;
3810+
if (W != nullptr && !EqualValue(S.Context, V, W, nullptr)) {
3811+
// Any variable used as the orginal value of v must have a type that
3812+
// is compatible with the type of v. Expression equality recorded in
3813+
// UEQ does not take types into account, so expressions in the same
3814+
// set in UEQ may have incompatible types.
3815+
Sema::AssignConvertType Conv =
3816+
S.CheckAssignmentConstraints(SourceLocation(), V->getType(), W->getType());
3817+
if (Conv == Sema::AssignConvertType::Compatible ||
3818+
Conv == Sema::AssignConvertType::CompatiblePointerDiscardsQualifiers)
3819+
return *I;
3820+
}
38263821
}
38273822

38283823
return nullptr;

0 commit comments

Comments
 (0)