Skip to content

Commit 1b334a2

Browse files
committed
[clang][dataflow] Eliminate ReferenceValue.
There are no remaining uses of this class in the framework. This patch is part of the ongoing migration to strict handling of value categories (see https://discourse.llvm.org/t/70086 for details). Reviewed By: ymandel, xazax.hun, gribozavr2 Differential Revision: https://reviews.llvm.org/D155922
1 parent 771d7d7 commit 1b334a2

File tree

7 files changed

+16
-100
lines changed

7 files changed

+16
-100
lines changed

clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum class SkipPast {
4747
/// No indirections should be skipped past.
4848
None,
4949
/// An optional reference should be skipped past.
50+
/// This is deprecated; it is equivalent to `None` and will be removed.
5051
Reference,
5152
};
5253

@@ -304,9 +305,10 @@ class Environment {
304305
/// `E` must be a glvalue or a `BuiltinType::BuiltinFn`
305306
void setStorageLocationStrict(const Expr &E, StorageLocation &Loc);
306307

307-
/// Returns the storage location assigned to `E` in the environment, applying
308-
/// the `SP` policy for skipping past indirections, or null if `E` isn't
309-
/// assigned a storage location in the environment.
308+
/// Returns the storage location assigned to `E` in the environment, or null
309+
/// if `E` isn't assigned a storage location in the environment.
310+
///
311+
/// The `SP` parameter has no effect.
310312
///
311313
/// This function is deprecated; prefer `getStorageLocationStrict()`.
312314
/// For details, see https://discourse.llvm.org/t/70086.
@@ -490,12 +492,14 @@ class Environment {
490492
/// isn't assigned a value in the environment.
491493
Value *getValue(const StorageLocation &Loc) const;
492494

493-
/// Equivalent to `getValue(getStorageLocation(D, SP), SkipPast::None)` if `D`
494-
/// is assigned a storage location in the environment, otherwise returns null.
495+
/// Equivalent to `getValue(getStorageLocation(D))` if `D` is assigned a
496+
/// storage location in the environment, otherwise returns null.
495497
Value *getValue(const ValueDecl &D) const;
496498

497-
/// Equivalent to `getValue(getStorageLocation(E, SP), SkipPast::None)` if `E`
498-
/// is assigned a storage location in the environment, otherwise returns null.
499+
/// Equivalent to `getValue(getStorageLocation(E, SP))` if `E` is assigned a
500+
/// storage location in the environment, otherwise returns null.
501+
///
502+
/// The `SP` parameter has no effect.
499503
///
500504
/// This function is deprecated; prefer `getValueStrict()`. For details, see
501505
/// https://discourse.llvm.org/t/70086.
@@ -672,9 +676,6 @@ class Environment {
672676
StorageLocation &createObjectInternal(const VarDecl *D, QualType Ty,
673677
const Expr *InitExpr);
674678

675-
StorageLocation &skip(StorageLocation &Loc, SkipPast SP) const;
676-
const StorageLocation &skip(const StorageLocation &Loc, SkipPast SP) const;
677-
678679
/// Shared implementation of `pushCall` overloads. Note that unlike
679680
/// `pushCall`, this member is invoked on the environment of the callee, not
680681
/// of the caller.

clang/include/clang/Analysis/FlowSensitive/Value.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ class Value {
3434
public:
3535
enum class Kind {
3636
Integer,
37-
Reference,
3837
Pointer,
3938
Struct,
4039

@@ -165,23 +164,6 @@ class IntegerValue : public Value {
165164
}
166165
};
167166

168-
/// Models a dereferenced pointer. For example, a reference in C++ or an lvalue
169-
/// in C.
170-
class ReferenceValue final : public Value {
171-
public:
172-
explicit ReferenceValue(StorageLocation &ReferentLoc)
173-
: Value(Kind::Reference), ReferentLoc(ReferentLoc) {}
174-
175-
static bool classof(const Value *Val) {
176-
return Val->getKind() == Kind::Reference;
177-
}
178-
179-
StorageLocation &getReferentLoc() const { return ReferentLoc; }
180-
181-
private:
182-
StorageLocation &ReferentLoc;
183-
};
184-
185167
/// Models a symbolic pointer. Specifically, any value of type `T*`.
186168
class PointerValue final : public Value {
187169
public:

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ static bool compareDistinctValues(QualType Type, Value &Val1,
6868
case ComparisonResult::Unknown:
6969
switch (Val1.getKind()) {
7070
case Value::Kind::Integer:
71-
case Value::Kind::Reference:
7271
case Value::Kind::Pointer:
7372
case Value::Kind::Struct:
7473
// FIXME: this choice intentionally introduces unsoundness to allow
@@ -140,11 +139,6 @@ static Value *mergeDistinctValues(QualType Type, Value &Val1,
140139

141140
// FIXME: Consider destroying `MergedValue` immediately if `ValueModel::merge`
142141
// returns false to avoid storing unneeded values in `DACtx`.
143-
// FIXME: Creating the value based on the type alone creates misshapen values
144-
// for lvalues, since the type does not reflect the need for `ReferenceValue`.
145-
// This issue will be resolved when `ReferenceValue` is eliminated as part
146-
// of the ongoing migration to strict handling of value categories (see
147-
// https://discourse.llvm.org/t/70086 for details).
148142
if (MergedVal)
149143
if (Model.merge(Type, Val1, Env1, Val2, Env2, *MergedVal, MergedEnv))
150144
return MergedVal;
@@ -611,7 +605,6 @@ StorageLocation &Environment::createStorageLocation(const Expr &E) {
611605

612606
void Environment::setStorageLocation(const ValueDecl &D, StorageLocation &Loc) {
613607
assert(!DeclToLoc.contains(&D));
614-
assert(!isa_and_nonnull<ReferenceValue>(getValue(Loc)));
615608
DeclToLoc[&D] = &Loc;
616609
}
617610

@@ -622,8 +615,6 @@ StorageLocation *Environment::getStorageLocation(const ValueDecl &D) const {
622615

623616
StorageLocation *Loc = It->second;
624617

625-
assert(!isa_and_nonnull<ReferenceValue>(getValue(*Loc)));
626-
627618
return Loc;
628619
}
629620

@@ -647,7 +638,7 @@ StorageLocation *Environment::getStorageLocation(const Expr &E,
647638
SkipPast SP) const {
648639
// FIXME: Add a test with parens.
649640
auto It = ExprToLoc.find(&ignoreCFGOmittedNodes(E));
650-
return It == ExprToLoc.end() ? nullptr : &skip(*It->second, SP);
641+
return It == ExprToLoc.end() ? nullptr : &*It->second;
651642
}
652643

653644
StorageLocation *Environment::getStorageLocationStrict(const Expr &E) const {
@@ -659,9 +650,6 @@ StorageLocation *Environment::getStorageLocationStrict(const Expr &E) const {
659650
if (Loc == nullptr)
660651
return nullptr;
661652

662-
if (auto *RefVal = dyn_cast_or_null<ReferenceValue>(getValue(*Loc)))
663-
return &RefVal->getReferentLoc();
664-
665653
return Loc;
666654
}
667655

@@ -696,7 +684,6 @@ void Environment::setValue(const StorageLocation &Loc, Value &Val) {
696684

697685
void Environment::setValueStrict(const Expr &E, Value &Val) {
698686
assert(E.isPRValue());
699-
assert(!isa<ReferenceValue>(Val));
700687

701688
if (auto *StructVal = dyn_cast<StructValue>(&Val)) {
702689
if (auto *ExistingVal = cast_or_null<StructValue>(getValueStrict(E)))
@@ -739,8 +726,6 @@ Value *Environment::getValueStrict(const Expr &E) const {
739726
assert(E.isPRValue());
740727
Value *Val = getValue(E, SkipPast::None);
741728

742-
assert(Val == nullptr || !isa<ReferenceValue>(Val));
743-
744729
return Val;
745730
}
746731

@@ -760,6 +745,7 @@ Value *Environment::createValueUnlessSelfReferential(
760745
QualType Type, llvm::DenseSet<QualType> &Visited, int Depth,
761746
int &CreatedValuesCount) {
762747
assert(!Type.isNull());
748+
assert(!Type->isReferenceType());
763749

764750
// Allow unlimited fields at depth 1; only cap at deeper nesting levels.
765751
if ((Depth > 1 && CreatedValuesCount > MaxCompositeValueSize) ||
@@ -779,16 +765,13 @@ Value *Environment::createValueUnlessSelfReferential(
779765
return &arena().create<IntegerValue>();
780766
}
781767

782-
if (Type->isReferenceType() || Type->isPointerType()) {
768+
if (Type->isPointerType()) {
783769
CreatedValuesCount++;
784770
QualType PointeeType = Type->getPointeeType();
785771
StorageLocation &PointeeLoc =
786772
createLocAndMaybeValue(PointeeType, Visited, Depth, CreatedValuesCount);
787773

788-
if (Type->isReferenceType())
789-
return &arena().create<ReferenceValue>(PointeeLoc);
790-
else
791-
return &arena().create<PointerValue>(PointeeLoc);
774+
return &arena().create<PointerValue>(PointeeLoc);
792775
}
793776

794777
if (Type->isRecordType()) {
@@ -892,25 +875,6 @@ StorageLocation &Environment::createObjectInternal(const VarDecl *D,
892875
return Loc;
893876
}
894877

895-
StorageLocation &Environment::skip(StorageLocation &Loc, SkipPast SP) const {
896-
switch (SP) {
897-
case SkipPast::None:
898-
return Loc;
899-
case SkipPast::Reference:
900-
// References cannot be chained so we only need to skip past one level of
901-
// indirection.
902-
if (auto *Val = dyn_cast_or_null<ReferenceValue>(getValue(Loc)))
903-
return Val->getReferentLoc();
904-
return Loc;
905-
}
906-
llvm_unreachable("bad SkipPast kind");
907-
}
908-
909-
const StorageLocation &Environment::skip(const StorageLocation &Loc,
910-
SkipPast SP) const {
911-
return skip(*const_cast<StorageLocation *>(&Loc), SP);
912-
}
913-
914878
void Environment::addToFlowCondition(const Formula &Val) {
915879
DACtx->addFlowConditionConstraint(FlowConditionToken, Val);
916880
}

clang/lib/Analysis/FlowSensitive/DebugSupport.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ llvm::StringRef debugString(Value::Kind Kind) {
2626
switch (Kind) {
2727
case Value::Kind::Integer:
2828
return "Integer";
29-
case Value::Kind::Reference:
30-
return "Reference";
3129
case Value::Kind::Pointer:
3230
return "Pointer";
3331
case Value::Kind::Struct:

clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ class ModelDumper {
9999
case Value::Kind::AtomicBool:
100100
case Value::Kind::FormulaBool:
101101
break;
102-
case Value::Kind::Reference:
103-
JOS.attributeObject(
104-
"referent", [&] { dump(cast<ReferenceValue>(V).getReferentLoc()); });
105-
break;
106102
case Value::Kind::Pointer:
107103
JOS.attributeObject(
108104
"pointee", [&] { dump(cast<PointerValue>(V).getPointeeLoc()); });

clang/lib/Analysis/FlowSensitive/Value.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,6 @@ namespace dataflow {
1919

2020
static bool areEquivalentIndirectionValues(const Value &Val1,
2121
const Value &Val2) {
22-
if (auto *IndVal1 = dyn_cast<ReferenceValue>(&Val1)) {
23-
auto *IndVal2 = cast<ReferenceValue>(&Val2);
24-
return &IndVal1->getReferentLoc() == &IndVal2->getReferentLoc();
25-
}
2622
if (auto *IndVal1 = dyn_cast<PointerValue>(&Val1)) {
2723
auto *IndVal2 = cast<PointerValue>(&Val2);
2824
return &IndVal1->getPointeeLoc() == &IndVal2->getPointeeLoc();
@@ -38,10 +34,6 @@ bool areEquivalentValues(const Value &Val1, const Value &Val2) {
3834

3935
raw_ostream &operator<<(raw_ostream &OS, const Value &Val) {
4036
switch (Val.getKind()) {
41-
case Value::Kind::Reference: {
42-
const auto *RV = cast<ReferenceValue>(&Val);
43-
return OS << "Reference(" << &RV->getReferentLoc() << ")";
44-
}
4537
case Value::Kind::Pointer: {
4638
const auto *PV = dyn_cast<PointerValue>(&Val);
4739
return OS << "Pointer(" << &PV->getPointeeLoc() << ")";

clang/unittests/Analysis/FlowSensitive/ValueTest.cpp

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,6 @@ TEST(ValueTest, DifferentIntegerValuesNotEquivalent) {
2929
EXPECT_FALSE(areEquivalentValues(V1, V2));
3030
}
3131

32-
TEST(ValueTest, AliasedReferencesEquivalent) {
33-
auto L = ScalarStorageLocation(QualType());
34-
ReferenceValue V1(L);
35-
ReferenceValue V2(L);
36-
EXPECT_TRUE(areEquivalentValues(V1, V2));
37-
EXPECT_TRUE(areEquivalentValues(V2, V1));
38-
}
39-
4032
TEST(ValueTest, AliasedPointersEquivalent) {
4133
auto L = ScalarStorageLocation(QualType());
4234
PointerValue V1(L);
@@ -68,21 +60,12 @@ TEST(ValueTest, EquivalentValuesWithDifferentPropsEquivalent) {
6860
TEST(ValueTest, DifferentKindsNotEquivalent) {
6961
Arena A;
7062
auto L = ScalarStorageLocation(QualType());
71-
ReferenceValue V1(L);
63+
PointerValue V1(L);
7264
TopBoolValue V2(A.makeAtomRef(Atom(0)));
7365
EXPECT_FALSE(areEquivalentValues(V1, V2));
7466
EXPECT_FALSE(areEquivalentValues(V2, V1));
7567
}
7668

77-
TEST(ValueTest, NotAliasedReferencesNotEquivalent) {
78-
auto L1 = ScalarStorageLocation(QualType());
79-
ReferenceValue V1(L1);
80-
auto L2 = ScalarStorageLocation(QualType());
81-
ReferenceValue V2(L2);
82-
EXPECT_FALSE(areEquivalentValues(V1, V2));
83-
EXPECT_FALSE(areEquivalentValues(V2, V1));
84-
}
85-
8669
TEST(ValueTest, NotAliasedPointersNotEquivalent) {
8770
auto L1 = ScalarStorageLocation(QualType());
8871
PointerValue V1(L1);

0 commit comments

Comments
 (0)