24
24
#include " llvm/ADT/DenseSet.h"
25
25
#include " llvm/ADT/MapVector.h"
26
26
#include " llvm/ADT/STLExtras.h"
27
+ #include " llvm/ADT/ScopeExit.h"
27
28
#include " llvm/Support/ErrorHandling.h"
28
29
#include < cassert>
29
30
#include < utility>
@@ -80,7 +81,6 @@ static bool equateUnknownValues(Value::Kind K) {
80
81
switch (K) {
81
82
case Value::Kind::Integer:
82
83
case Value::Kind::Pointer:
83
- case Value::Kind::Record:
84
84
return true ;
85
85
default :
86
86
return false ;
@@ -145,25 +145,7 @@ static Value *joinDistinctValues(QualType Type, Value &Val1,
145
145
return &A.makeBoolValue (JoinedVal);
146
146
}
147
147
148
- Value *JoinedVal = nullptr ;
149
- if (auto *RecordVal1 = dyn_cast<RecordValue>(&Val1)) {
150
- auto *RecordVal2 = cast<RecordValue>(&Val2);
151
-
152
- if (&RecordVal1->getLoc () == &RecordVal2->getLoc ())
153
- // `RecordVal1` and `RecordVal2` may have different properties associated
154
- // with them. Create a new `RecordValue` with the same location but
155
- // without any properties so that we soundly approximate both values. If a
156
- // particular analysis needs to join properties, it should do so in
157
- // `DataflowAnalysis::join()`.
158
- JoinedVal = &JoinedEnv.create <RecordValue>(RecordVal1->getLoc ());
159
- else
160
- // If the locations for the two records are different, need to create a
161
- // completely new value.
162
- JoinedVal = JoinedEnv.createValue (Type);
163
- } else {
164
- JoinedVal = JoinedEnv.createValue (Type);
165
- }
166
-
148
+ Value *JoinedVal = JoinedEnv.createValue (Type);
167
149
if (JoinedVal)
168
150
Model.join (Type, Val1, Env1, Val2, Env2, *JoinedVal, JoinedEnv);
169
151
@@ -565,7 +547,6 @@ void Environment::initialize() {
565
547
auto &ThisLoc =
566
548
cast<RecordStorageLocation>(createStorageLocation (ThisPointeeType));
567
549
setThisPointeeStorageLocation (ThisLoc);
568
- refreshRecordValue (ThisLoc, *this );
569
550
// Initialize fields of `*this` with values, but only if we're not
570
551
// analyzing a constructor; after all, it's the constructor's job to do
571
552
// this (and we want to be able to test that).
@@ -709,10 +690,6 @@ void Environment::popCall(const CXXConstructExpr *Call,
709
690
// See also comment in `popCall(const CallExpr *, const Environment &)` above.
710
691
this ->LocToVal = std::move (CalleeEnv.LocToVal );
711
692
this ->FlowConditionToken = std::move (CalleeEnv.FlowConditionToken );
712
-
713
- if (Value *Val = CalleeEnv.getValue (*CalleeEnv.ThisPointeeLoc )) {
714
- setValue (*Call, *Val);
715
- }
716
693
}
717
694
718
695
bool Environment::equivalentTo (const Environment &Other,
@@ -936,24 +913,23 @@ void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc,
936
913
}
937
914
938
915
void Environment::setValue (const StorageLocation &Loc, Value &Val) {
939
- assert (!isa<RecordValue>(&Val) || &cast<RecordValue>(&Val)-> getLoc () == &Loc);
940
-
916
+ // Records should not be associated with values.
917
+ assert (!isa<RecordStorageLocation>(Loc));
941
918
LocToVal[&Loc] = &Val;
942
919
}
943
920
944
921
void Environment::setValue (const Expr &E, Value &Val) {
945
922
const Expr &CanonE = ignoreCFGOmittedNodes (E);
946
923
947
- if (auto *RecordVal = dyn_cast<RecordValue>(&Val)) {
948
- assert (&RecordVal->getLoc () == &getResultObjectLocation (CanonE));
949
- (void )RecordVal;
950
- }
951
-
952
924
assert (CanonE.isPRValue ());
925
+ // Records should not be associated with values.
926
+ assert (!CanonE.getType ()->isRecordType ());
953
927
ExprToVal[&CanonE] = &Val;
954
928
}
955
929
956
930
Value *Environment::getValue (const StorageLocation &Loc) const {
931
+ // Records should not be associated with values.
932
+ assert (!isa<RecordStorageLocation>(Loc));
957
933
return LocToVal.lookup (&Loc);
958
934
}
959
935
@@ -965,6 +941,9 @@ Value *Environment::getValue(const ValueDecl &D) const {
965
941
}
966
942
967
943
Value *Environment::getValue (const Expr &E) const {
944
+ // Records should not be associated with values.
945
+ assert (!E.getType ()->isRecordType ());
946
+
968
947
if (E.isPRValue ()) {
969
948
auto It = ExprToVal.find (&ignoreCFGOmittedNodes (E));
970
949
return It == ExprToVal.end () ? nullptr : It->second ;
@@ -993,6 +972,7 @@ Value *Environment::createValueUnlessSelfReferential(
993
972
int &CreatedValuesCount) {
994
973
assert (!Type.isNull ());
995
974
assert (!Type->isReferenceType ());
975
+ assert (!Type->isRecordType ());
996
976
997
977
// Allow unlimited fields at depth 1; only cap at deeper nesting levels.
998
978
if ((Depth > 1 && CreatedValuesCount > MaxCompositeValueSize) ||
@@ -1021,15 +1001,6 @@ Value *Environment::createValueUnlessSelfReferential(
1021
1001
return &arena ().create <PointerValue>(PointeeLoc);
1022
1002
}
1023
1003
1024
- if (Type->isRecordType ()) {
1025
- CreatedValuesCount++;
1026
- auto &Loc = cast<RecordStorageLocation>(createStorageLocation (Type));
1027
- initializeFieldsWithValues (Loc, Loc.getType (), Visited, Depth,
1028
- CreatedValuesCount);
1029
-
1030
- return &refreshRecordValue (Loc, *this );
1031
- }
1032
-
1033
1004
return nullptr ;
1034
1005
}
1035
1006
@@ -1039,20 +1010,23 @@ Environment::createLocAndMaybeValue(QualType Ty,
1039
1010
int Depth, int &CreatedValuesCount) {
1040
1011
if (!Visited.insert (Ty.getCanonicalType ()).second )
1041
1012
return createStorageLocation (Ty.getNonReferenceType ());
1042
- Value *Val = createValueUnlessSelfReferential (
1043
- Ty.getNonReferenceType (), Visited, Depth, CreatedValuesCount);
1044
- Visited.erase (Ty.getCanonicalType ());
1013
+ auto EraseVisited = llvm::make_scope_exit (
1014
+ [&Visited, Ty] { Visited.erase (Ty.getCanonicalType ()); });
1045
1015
1046
1016
Ty = Ty.getNonReferenceType ();
1047
1017
1048
- if (Val == nullptr )
1049
- return createStorageLocation (Ty);
1050
-
1051
- if (Ty-> isRecordType ())
1052
- return cast<RecordValue>(Val)-> getLoc ();
1018
+ if (Ty-> isRecordType ()) {
1019
+ auto &Loc = cast<RecordStorageLocation>( createStorageLocation (Ty) );
1020
+ initializeFieldsWithValues (Loc, Ty, Visited, Depth, CreatedValuesCount);
1021
+ return Loc;
1022
+ }
1053
1023
1054
1024
StorageLocation &Loc = createStorageLocation (Ty);
1055
- setValue (Loc, *Val);
1025
+
1026
+ if (Value *Val = createValueUnlessSelfReferential (Ty, Visited, Depth,
1027
+ CreatedValuesCount))
1028
+ setValue (Loc, *Val);
1029
+
1056
1030
return Loc;
1057
1031
}
1058
1032
@@ -1064,10 +1038,11 @@ void Environment::initializeFieldsWithValues(RecordStorageLocation &Loc,
1064
1038
auto initField = [&](QualType FieldType, StorageLocation &FieldLoc) {
1065
1039
if (FieldType->isRecordType ()) {
1066
1040
auto &FieldRecordLoc = cast<RecordStorageLocation>(FieldLoc);
1067
- setValue (FieldRecordLoc, create<RecordValue>(FieldRecordLoc));
1068
1041
initializeFieldsWithValues (FieldRecordLoc, FieldRecordLoc.getType (),
1069
1042
Visited, Depth + 1 , CreatedValuesCount);
1070
1043
} else {
1044
+ if (getValue (FieldLoc) != nullptr )
1045
+ return ;
1071
1046
if (!Visited.insert (FieldType.getCanonicalType ()).second )
1072
1047
return ;
1073
1048
if (Value *Val = createValueUnlessSelfReferential (
@@ -1125,7 +1100,6 @@ StorageLocation &Environment::createObjectInternal(const ValueDecl *D,
1125
1100
auto &RecordLoc = cast<RecordStorageLocation>(Loc);
1126
1101
if (!InitExpr)
1127
1102
initializeFieldsWithValues (RecordLoc);
1128
- refreshRecordValue (RecordLoc, *this );
1129
1103
} else {
1130
1104
Value *Val = nullptr ;
1131
1105
if (InitExpr)
@@ -1264,25 +1238,5 @@ RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME,
1264
1238
return Env.get <RecordStorageLocation>(*Base);
1265
1239
}
1266
1240
1267
- RecordValue &refreshRecordValue (RecordStorageLocation &Loc, Environment &Env) {
1268
- auto &NewVal = Env.create <RecordValue>(Loc);
1269
- Env.setValue (Loc, NewVal);
1270
- return NewVal;
1271
- }
1272
-
1273
- RecordValue &refreshRecordValue (const Expr &Expr, Environment &Env) {
1274
- assert (Expr.getType ()->isRecordType ());
1275
-
1276
- if (Expr.isPRValue ())
1277
- refreshRecordValue (Env.getResultObjectLocation (Expr), Env);
1278
-
1279
- if (auto *Loc = Env.get <RecordStorageLocation>(Expr))
1280
- refreshRecordValue (*Loc, Env);
1281
-
1282
- auto &NewVal = *cast<RecordValue>(Env.createValue (Expr.getType ()));
1283
- Env.setStorageLocation (Expr, NewVal.getLoc ());
1284
- return NewVal;
1285
- }
1286
-
1287
1241
} // namespace dataflow
1288
1242
} // namespace clang
0 commit comments