diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -76,7 +76,7 @@ virtual ComparisonResult compare(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2) { - // FIXME: Consider adding QualType to StructValue and removing the Type + // FIXME: Consider adding QualType to RecordValue and removing the Type // argument here. return ComparisonResult::Unknown; } @@ -300,7 +300,7 @@ /// Returns the storage location assigned to the `this` pointee in the /// environment or null if the `this` pointee has no assigned storage location /// in the environment. - AggregateStorageLocation *getThisPointeeStorageLocation() const; + RecordStorageLocation *getThisPointeeStorageLocation() const; /// Returns the location of the result object for a record-type prvalue. /// @@ -325,7 +325,7 @@ /// /// Requirements: /// `E` must be a prvalue of record type. - AggregateStorageLocation &getResultObjectLocation(const Expr &RecordPRValue); + RecordStorageLocation &getResultObjectLocation(const Expr &RecordPRValue); /// Returns the return value of the current function. This can be null if: /// - The function has a void return type @@ -385,8 +385,8 @@ /// non-pointer/non-reference type. /// /// If `Type` is a class, struct, or union type, calls `setValue()` to - /// associate the `StructValue` with its storage location - /// (`StructValue::getAggregateLoc()`). + /// associate the `RecordValue` with its storage location + /// (`RecordValue::getLoc()`). /// /// If `Type` is one of the following types, this function will always return /// a non-null pointer: @@ -448,10 +448,10 @@ /// /// `E` must be a prvalue /// `Val` must not be a `ReferenceValue` - /// If `Val` is a `StructValue`, its `AggregateStorageLocation` must be the - /// same as that of any `StructValue` that has already been associated with + /// If `Val` is a `RecordValue`, its `RecordStorageLocation` must be the + /// same as that of any `RecordValue` that has already been associated with /// `E`. This is to guarantee that the result object initialized by a prvalue - /// `StructValue` has a durable storage location. + /// `RecordValue` has a durable storage location. void setValue(const Expr &E, Value &Val); /// Deprecated synonym for `setValue()`. @@ -662,7 +662,7 @@ StorageLocation *ReturnLoc = nullptr; // The storage location of the `this` pointee. Should only be null if the // function being analyzed is only a function and not a method. - AggregateStorageLocation *ThisPointeeLoc = nullptr; + RecordStorageLocation *ThisPointeeLoc = nullptr; // Maps from program declarations and statements to storage locations that are // assigned to them. Unlike the maps in `DataflowAnalysisContext`, these @@ -681,36 +681,44 @@ /// `CXXMemberCallExpr`, or null if none is defined in the environment. /// Dereferences the pointer if the member call expression was written using /// `->`. -AggregateStorageLocation * -getImplicitObjectLocation(const CXXMemberCallExpr &MCE, const Environment &Env); +RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE, + const Environment &Env); /// Returns the storage location for the base object of a `MemberExpr`, or null /// if none is defined in the environment. Dereferences the pointer if the /// member expression was written using `->`. -AggregateStorageLocation *getBaseObjectLocation(const MemberExpr &ME, - const Environment &Env); +RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, + const Environment &Env); /// Returns the fields of `RD` that are initialized by an `InitListExpr`, in the /// order in which they appear in `InitListExpr::inits()`. std::vector getFieldsForInitListExpr(const RecordDecl *RD); -/// Associates a new `StructValue` with `Loc` and returns the new value. +/// Associates a new `RecordValue` with `Loc` and returns the new value. /// It is not defined whether the field values remain the same or not. /// /// This function is primarily intended for use by checks that set custom -/// properties on `StructValue`s to model the state of these values. Such checks -/// should avoid modifying the properties of an existing `StructValue` because +/// properties on `RecordValue`s to model the state of these values. Such checks +/// should avoid modifying the properties of an existing `RecordValue` because /// these changes would be visible to other `Environment`s that share the same -/// `StructValue`. Instead, call `refreshStructValue()`, then set the properties -/// on the new `StructValue` that it returns. Typical usage: +/// `RecordValue`. Instead, call `refreshRecordValue()`, then set the properties +/// on the new `RecordValue` that it returns. Typical usage: /// -/// refreshStructValue(Loc, Env).setProperty("my_prop", MyPropValue); -StructValue &refreshStructValue(AggregateStorageLocation &Loc, - Environment &Env); +/// refreshRecordValue(Loc, Env).setProperty("my_prop", MyPropValue); +RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env); -/// Associates a new `StructValue` with `Expr` and returns the new value. +/// Associates a new `RecordValue` with `Expr` and returns the new value. /// See also documentation for the overload above. -StructValue &refreshStructValue(const Expr &Expr, Environment &Env); +RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env); + +/// Deprecated synonym for `refreshRecordValue()`. +inline RecordValue &refreshStructValue(RecordStorageLocation &Loc, + Environment &Env) { + return refreshRecordValue(Loc, Env); +} +inline RecordValue &refreshStructValue(const Expr &Expr, Environment &Env) { + return refreshRecordValue(Expr, Env); +} } // namespace dataflow } // namespace clang diff --git a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h --- a/clang/include/clang/Analysis/FlowSensitive/RecordOps.h +++ b/clang/include/clang/Analysis/FlowSensitive/RecordOps.h @@ -22,23 +22,23 @@ /// Copies a record (struct, class, or union) from `Src` to `Dst`. /// /// This performs a deep copy, i.e. it copies every field and recurses on -/// fields of record type. It also copies properties from the `StructValue` -/// associated with `Src` to the `StructValue` associated with `Dst` (if these -/// `StructValue`s exist). +/// fields of record type. It also copies properties from the `RecordValue` +/// associated with `Src` to the `RecordValue` associated with `Dst` (if these +/// `RecordValue`s exist). /// -/// If there is a `StructValue` associated with `Dst` in the environment, this -/// function creates a new `StructValue` and associates it with `Dst`; clients -/// need to be aware of this and must not assume that the `StructValue` +/// If there is a `RecordValue` associated with `Dst` in the environment, this +/// function creates a new `RecordValue` and associates it with `Dst`; clients +/// need to be aware of this and must not assume that the `RecordValue` /// associated with `Dst` remains the same after the call. /// -/// We create a new `StructValue` rather than modifying properties on the old -/// `StructValue` because the old `StructValue` may be shared with other +/// We create a new `RecordValue` rather than modifying properties on the old +/// `RecordValue` because the old `RecordValue` may be shared with other /// `Environment`s, and we don't want changes to properties to be visible there. /// /// Requirements: /// /// `Src` and `Dst` must have the same canonical unqualified type. -void copyRecord(AggregateStorageLocation &Src, AggregateStorageLocation &Dst, +void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst, Environment &Env); /// Returns whether the records `Loc1` and `Loc2` are equal. @@ -49,8 +49,8 @@ /// /// This performs a deep comparison, i.e. it compares every field and recurses /// on fields of record type. Fields of reference type compare equal if they -/// refer to the same storage location. If `StructValue`s are associated with -/// `Loc1` and `Loc2`, it also compares the properties on those `StructValue`s. +/// refer to the same storage location. If `RecordValue`s are associated with +/// `Loc1` and `Loc2`, it also compares the properties on those `RecordValue`s. /// /// Note on how to interpret the result: /// - If this returns true, the records are guaranteed to be equal at runtime. @@ -60,12 +60,11 @@ /// Requirements: /// /// `Src` and `Dst` must have the same canonical unqualified type. -bool recordsEqual(const AggregateStorageLocation &Loc1, const Environment &Env1, - const AggregateStorageLocation &Loc2, - const Environment &Env2); +bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1, + const RecordStorageLocation &Loc2, const Environment &Env2); -inline bool recordsEqual(const AggregateStorageLocation &Loc1, - const AggregateStorageLocation &Loc2, +inline bool recordsEqual(const RecordStorageLocation &Loc1, + const RecordStorageLocation &Loc2, const Environment &Env) { return recordsEqual(Loc1, Env, Loc2, Env); } diff --git a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h --- a/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h +++ b/clang/include/clang/Analysis/FlowSensitive/StorageLocation.h @@ -31,7 +31,12 @@ /// values is stored in the environment. class StorageLocation { public: - enum class Kind { Scalar, Aggregate }; + enum class Kind { + Scalar, + Record, + // Deprecated synonym for `Record` + Aggregate = Record, + }; StorageLocation(Kind LocKind, QualType Type) : LocKind(LocKind), Type(Type) { assert(Type.isNull() || !Type->isReferenceType()); @@ -66,11 +71,11 @@ } }; -/// A storage location which is subdivided into smaller storage locations that -/// can be traced independently by abstract interpretation. For example: a -/// struct with public members. The child map is flat, so when used for a struct -/// or class type, all accessible members of base struct and class types are -/// directly accesible as children of this location. +/// A storage location for a record (struct, class, or union). +/// +/// Contains storage locations for all modeled fields of the record (also +/// referred to as "children"). The child map is flat, so accessible members of +/// the base class are directly accesible as children of this location. /// /// The storage location for a field of reference type may be null. This /// typically occurs in one of two situations: @@ -82,16 +87,15 @@ /// FIXME: Currently, the storage location of unions is modelled the same way as /// that of structs or classes. Eventually, we need to change this modelling so /// that all of the members of a given union have the same storage location. -class AggregateStorageLocation final : public StorageLocation { +class RecordStorageLocation final : public StorageLocation { public: using FieldToLoc = llvm::DenseMap; - explicit AggregateStorageLocation(QualType Type) - : AggregateStorageLocation(Type, FieldToLoc()) {} + explicit RecordStorageLocation(QualType Type) + : RecordStorageLocation(Type, FieldToLoc()) {} - AggregateStorageLocation(QualType Type, FieldToLoc TheChildren) - : StorageLocation(Kind::Aggregate, Type), - Children(std::move(TheChildren)) { + RecordStorageLocation(QualType Type, FieldToLoc TheChildren) + : StorageLocation(Kind::Record, Type), Children(std::move(TheChildren)) { assert(!Type.isNull()); assert(Type->isRecordType()); assert([this] { @@ -104,7 +108,7 @@ } static bool classof(const StorageLocation *Loc) { - return Loc->getKind() == Kind::Aggregate; + return Loc->getKind() == Kind::Record; } /// Returns the child storage location for `D`. @@ -133,7 +137,7 @@ /// Changes the child storage location for a field `D` of reference type. /// All other fields cannot change their storage location and always retain - /// the storage location passed to the `AggregateStorageLocation` constructor. + /// the storage location passed to the `RecordStorageLocation` constructor. /// /// Requirements: /// @@ -151,6 +155,9 @@ FieldToLoc Children; }; +/// Deprecated synonym for `RecordStorageLocation`. +using AggregateStorageLocation = RecordStorageLocation; + } // namespace dataflow } // namespace clang diff --git a/clang/include/clang/Analysis/FlowSensitive/Value.h b/clang/include/clang/Analysis/FlowSensitive/Value.h --- a/clang/include/clang/Analysis/FlowSensitive/Value.h +++ b/clang/include/clang/Analysis/FlowSensitive/Value.h @@ -35,7 +35,9 @@ enum class Kind { Integer, Pointer, - Struct, + Record, + // Deprecated synonym for `Record` + Struct = Record, // TODO: Top values should not be need to be type-specific. TopBool, @@ -184,13 +186,13 @@ /// In C++, prvalues of class type serve only a limited purpose: They can only /// be used to initialize a result object. It is not possible to access member /// variables or call member functions on a prvalue of class type. -/// Correspondingly, `StructValue` also serves only two limited purposes: +/// Correspondingly, `RecordValue` also serves only two limited purposes: /// - It conveys a prvalue of class type from the place where the object is /// constructed to the result object that it initializes. /// /// When creating a prvalue of class type, we already need a storage location /// for `this`, even though prvalues are otherwise not associated with storage -/// locations. `StructValue` is therefore essentially a wrapper for a storage +/// locations. `RecordValue` is therefore essentially a wrapper for a storage /// location, which is then used to set the storage location for the result /// object when we process the AST node for that result object. /// @@ -198,43 +200,49 @@ /// MyStruct S = MyStruct(3); /// /// In this example, `MyStruct(3) is a prvalue, which is modeled as a -/// `StructValue` that wraps an `AbstractStorageLocation`. This -// `AbstractStorageLocation` is then used as the storage location for `S`. +/// `RecordValue` that wraps a `RecordStorageLocation`. This +// `RecordStorageLocation` is then used as the storage location for `S`. /// /// - It allows properties to be associated with an object of class type. /// Note that when doing so, you should avoid mutating the properties of an -/// existing `StructValue` in place, as these changes would be visible to -/// other `Environment`s that share the same `StructValue`. Instead, associate -/// a new `StructValue` with the `AggregateStorageLocation` and set the -/// properties on this new `StructValue`. (See also `refreshStructValue()` in +/// existing `RecordValue` in place, as these changes would be visible to +/// other `Environment`s that share the same `RecordValue`. Instead, associate +/// a new `RecordValue` with the `RecordStorageLocation` and set the +/// properties on this new `RecordValue`. (See also `refreshRecordValue()` in /// DataflowEnvironment.h, which makes this easy.) /// Note also that this implies that it is common for the same -/// `AggregateStorageLocation` to be associated with different `StructValue`s +/// `RecordStorageLocation` to be associated with different `RecordValue`s /// in different environments. -/// Over time, we may eliminate `StructValue` entirely. See also the discussion +/// Over time, we may eliminate `RecordValue` entirely. See also the discussion /// here: https://reviews.llvm.org/D155204#inline-1503204 -class StructValue final : public Value { +class RecordValue final : public Value { public: - explicit StructValue(AggregateStorageLocation &Loc) - : Value(Kind::Struct), Loc(Loc) {} + explicit RecordValue(RecordStorageLocation &Loc) + : Value(Kind::Record), Loc(Loc) {} static bool classof(const Value *Val) { - return Val->getKind() == Kind::Struct; + return Val->getKind() == Kind::Record; } - /// Returns the storage location that this `StructValue` is associated with. - AggregateStorageLocation &getAggregateLoc() const { return Loc; } + /// Returns the storage location that this `RecordValue` is associated with. + RecordStorageLocation &getLoc() const { return Loc; } + + /// Deprecated synonym for `getLoc()`. + RecordStorageLocation &getAggregateLoc() const { return Loc; } /// Convenience function that returns the child storage location for `Field`. - /// See also the documentation for `AggregateStorageLocation::getChild()`. + /// See also the documentation for `RecordStorageLocation::getChild()`. StorageLocation *getChild(const ValueDecl &Field) const { return Loc.getChild(Field); } private: - AggregateStorageLocation &Loc; + RecordStorageLocation &Loc; }; +/// Deprecated synonym for `RecordValue`. +using StructValue = RecordValue; + raw_ostream &operator<<(raw_ostream &OS, const Value &Val); } // namespace dataflow diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -67,7 +67,7 @@ else FieldLocs.insert({Field, &createStorageLocation( Field->getType().getNonReferenceType())}); - return arena().create(Type, std::move(FieldLocs)); + return arena().create(Type, std::move(FieldLocs)); } return arena().create(Type); } diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -69,7 +69,7 @@ switch (Val1.getKind()) { case Value::Kind::Integer: case Value::Kind::Pointer: - case Value::Kind::Struct: + case Value::Kind::Record: // FIXME: this choice intentionally introduces unsoundness to allow // for convergence. Once we have widening support for the // reference/pointer and struct built-in models, this should be @@ -120,19 +120,19 @@ } Value *MergedVal = nullptr; - if (auto *StructVal1 = dyn_cast(&Val1)) { - [[maybe_unused]] auto *StructVal2 = cast(&Val2); + if (auto *RecordVal1 = dyn_cast(&Val1)) { + [[maybe_unused]] auto *RecordVal2 = cast(&Val2); // Values to be merged are always associated with the same location in - // `LocToVal`. The location stored in `StructVal` should therefore also + // `LocToVal`. The location stored in `RecordVal` should therefore also // be the same. - assert(&StructVal1->getAggregateLoc() == &StructVal2->getAggregateLoc()); + assert(&RecordVal1->getLoc() == &RecordVal2->getLoc()); - // `StructVal1` and `StructVal2` may have different properties associated - // with them. Create a new `StructValue` without any properties so that we + // `RecordVal1` and `RecordVal2` may have different properties associated + // with them. Create a new `RecordValue` without any properties so that we // soundly approximate both values. If a particular analysis needs to merge // properties, it should do so in `DataflowAnalysis::merge()`. - MergedVal = &MergedEnv.create(StructVal1->getAggregateLoc()); + MergedVal = &MergedEnv.create(RecordVal1->getLoc()); } else { MergedVal = MergedEnv.createValue(Type); } @@ -320,7 +320,7 @@ if (MethodDecl && !MethodDecl->isStatic()) { QualType ThisPointeeType = MethodDecl->getThisObjectType(); ThisPointeeLoc = - &cast(createValue(ThisPointeeType))->getAggregateLoc(); + &cast(createValue(ThisPointeeType))->getLoc(); } } } @@ -337,7 +337,7 @@ if (const Expr *Arg = MethodCall->getImplicitObjectArgument()) { if (!isa(Arg)) Env.ThisPointeeLoc = - cast(getStorageLocation(*Arg)); + cast(getStorageLocation(*Arg)); // Otherwise (when the argument is `this`), retain the current // environment's `ThisPointeeLoc`. } @@ -634,18 +634,18 @@ return getStorageLocationInternal(E); } -AggregateStorageLocation *Environment::getThisPointeeStorageLocation() const { +RecordStorageLocation *Environment::getThisPointeeStorageLocation() const { return ThisPointeeLoc; } -AggregateStorageLocation & +RecordStorageLocation & Environment::getResultObjectLocation(const Expr &RecordPRValue) { assert(RecordPRValue.getType()->isRecordType()); assert(RecordPRValue.isPRValue()); if (StorageLocation *ExistingLoc = getStorageLocationInternal(RecordPRValue)) - return *cast(ExistingLoc); - auto &Loc = cast( + return *cast(ExistingLoc); + auto &Loc = cast( DACtx->getStableStorageLocation(RecordPRValue)); setStorageLocationInternal(RecordPRValue, Loc); return Loc; @@ -656,8 +656,7 @@ } void Environment::setValue(const StorageLocation &Loc, Value &Val) { - assert(!isa(&Val) || - &cast(&Val)->getAggregateLoc() == &Loc); + assert(!isa(&Val) || &cast(&Val)->getLoc() == &Loc); LocToVal[&Loc] = &Val; } @@ -665,16 +664,16 @@ void Environment::setValue(const Expr &E, Value &Val) { assert(E.isPRValue()); - if (auto *StructVal = dyn_cast(&Val)) { + if (auto *RecordVal = dyn_cast(&Val)) { if ([[maybe_unused]] auto *ExistingVal = - cast_or_null(getValue(E))) - assert(&ExistingVal->getAggregateLoc() == &StructVal->getAggregateLoc()); + cast_or_null(getValue(E))) + assert(&ExistingVal->getLoc() == &RecordVal->getLoc()); if ([[maybe_unused]] StorageLocation *ExistingLoc = getStorageLocationInternal(E)) - assert(ExistingLoc == &StructVal->getAggregateLoc()); + assert(ExistingLoc == &RecordVal->getLoc()); else - setStorageLocationInternal(E, StructVal->getAggregateLoc()); - setValue(StructVal->getAggregateLoc(), Val); + setStorageLocationInternal(E, RecordVal->getLoc()); + setValue(RecordVal->getLoc(), Val); return; } @@ -774,15 +773,15 @@ CreatedValuesCount)}); } - AggregateStorageLocation &Loc = - arena().create(Type, std::move(FieldLocs)); - StructValue &StructVal = create(Loc); + RecordStorageLocation &Loc = + arena().create(Type, std::move(FieldLocs)); + RecordValue &RecordVal = create(Loc); - // As we already have a storage location for the `StructValue`, we can and + // As we already have a storage location for the `RecordValue`, we can and // should associate them in the environment. - setValue(Loc, StructVal); + setValue(Loc, RecordVal); - return &StructVal; + return &RecordVal; } return nullptr; @@ -804,7 +803,7 @@ return createStorageLocation(Ty); if (Ty->isRecordType()) - return cast(Val)->getAggregateLoc(); + return cast(Val)->getLoc(); StorageLocation &Loc = createStorageLocation(Ty); setValue(Loc, *Val); @@ -850,7 +849,7 @@ Val = createValue(Ty); if (Ty->isRecordType()) - return cast(Val)->getAggregateLoc(); + return cast(Val)->getLoc(); StorageLocation &Loc = D ? createStorageLocation(*D) : createStorageLocation(Ty); @@ -893,32 +892,31 @@ dump(llvm::dbgs()); } -AggregateStorageLocation * -getImplicitObjectLocation(const CXXMemberCallExpr &MCE, - const Environment &Env) { +RecordStorageLocation *getImplicitObjectLocation(const CXXMemberCallExpr &MCE, + const Environment &Env) { Expr *ImplicitObject = MCE.getImplicitObjectArgument(); if (ImplicitObject == nullptr) return nullptr; if (ImplicitObject->getType()->isPointerType()) { if (auto *Val = cast_or_null(Env.getValue(*ImplicitObject))) - return &cast(Val->getPointeeLoc()); + return &cast(Val->getPointeeLoc()); return nullptr; } - return cast_or_null( + return cast_or_null( Env.getStorageLocation(*ImplicitObject)); } -AggregateStorageLocation *getBaseObjectLocation(const MemberExpr &ME, - const Environment &Env) { +RecordStorageLocation *getBaseObjectLocation(const MemberExpr &ME, + const Environment &Env) { Expr *Base = ME.getBase(); if (Base == nullptr) return nullptr; if (ME.isArrow()) { if (auto *Val = cast_or_null(Env.getValue(*Base))) - return &cast(Val->getPointeeLoc()); + return &cast(Val->getPointeeLoc()); return nullptr; } - return cast_or_null(Env.getStorageLocation(*Base)); + return cast_or_null(Env.getStorageLocation(*Base)); } std::vector getFieldsForInitListExpr(const RecordDecl *RD) { @@ -933,37 +931,36 @@ return Fields; } -StructValue &refreshStructValue(AggregateStorageLocation &Loc, - Environment &Env) { - auto &NewVal = Env.create(Loc); +RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env) { + auto &NewVal = Env.create(Loc); Env.setValue(Loc, NewVal); return NewVal; } -StructValue &refreshStructValue(const Expr &Expr, Environment &Env) { +RecordValue &refreshRecordValue(const Expr &Expr, Environment &Env) { assert(Expr.getType()->isRecordType()); if (Expr.isPRValue()) { - if (auto *ExistingVal = cast_or_null(Env.getValue(Expr))) { - auto &NewVal = Env.create(ExistingVal->getAggregateLoc()); + if (auto *ExistingVal = cast_or_null(Env.getValue(Expr))) { + auto &NewVal = Env.create(ExistingVal->getLoc()); Env.setValue(Expr, NewVal); return NewVal; } - auto &NewVal = *cast(Env.createValue(Expr.getType())); + auto &NewVal = *cast(Env.createValue(Expr.getType())); Env.setValue(Expr, NewVal); return NewVal; } - if (auto *Loc = cast_or_null( - Env.getStorageLocation(Expr))) { - auto &NewVal = Env.create(*Loc); + if (auto *Loc = + cast_or_null(Env.getStorageLocation(Expr))) { + auto &NewVal = Env.create(*Loc); Env.setValue(*Loc, NewVal); return NewVal; } - auto &NewVal = *cast(Env.createValue(Expr.getType())); - Env.setStorageLocation(Expr, NewVal.getAggregateLoc()); + auto &NewVal = *cast(Env.createValue(Expr.getType())); + Env.setStorageLocation(Expr, NewVal.getLoc()); return NewVal; } diff --git a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp --- a/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp +++ b/clang/lib/Analysis/FlowSensitive/DebugSupport.cpp @@ -28,8 +28,8 @@ return "Integer"; case Value::Kind::Pointer: return "Pointer"; - case Value::Kind::Struct: - return "Struct"; + case Value::Kind::Record: + return "Record"; case Value::Kind::AtomicBool: return "AtomicBool"; case Value::Kind::TopBool: diff --git a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp --- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp +++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp @@ -103,9 +103,8 @@ JOS.attributeObject( "pointee", [&] { dump(cast(V).getPointeeLoc()); }); break; - case Value::Kind::Struct: - for (const auto &Child : - cast(V).getAggregateLoc().children()) + case Value::Kind::Record: + for (const auto &Child : cast(V).getLoc().children()) JOS.attributeObject("f:" + Child.first->getNameAsString(), [&] { if (Child.second) if (Value *Val = Env.getValue(*Child.second)) diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -256,9 +256,9 @@ /// Creates a symbolic value for an `optional` value at an existing storage /// location. Uses `HasValueVal` as the symbolic value of the "has_value" /// property. -StructValue &createOptionalValue(AggregateStorageLocation &Loc, +RecordValue &createOptionalValue(RecordStorageLocation &Loc, BoolValue &HasValueVal, Environment &Env) { - auto &OptionalVal = Env.create(Loc); + auto &OptionalVal = Env.create(Loc); Env.setValue(Loc, OptionalVal); setHasValue(OptionalVal, HasValueVal); return OptionalVal; @@ -335,7 +335,7 @@ // the check, like another optional or a boolean that influences control // flow. if (ValueLoc.getType()->isRecordType()) { - refreshStructValue(cast(ValueLoc), Env); + refreshRecordValue(cast(ValueLoc), Env); return &ValueLoc; } else { auto *ValueVal = Env.createValue(ValueLoc.getType()); @@ -356,7 +356,7 @@ // example: // // void target(optional oo, bool b) { - // // `oo` is associated with a `StructValue` here, which we will call + // // `oo` is associated with a `RecordValue` here, which we will call // // `OptionalVal`. // // // The `has_value` property is set on `OptionalVal` (but not the @@ -532,15 +532,13 @@ if (State.Env.getValue(*E) != nullptr) return; - AggregateStorageLocation *Loc = nullptr; + RecordStorageLocation *Loc = nullptr; if (E->isPRValue()) { Loc = &State.Env.getResultObjectLocation(*E); } else { - Loc = cast_or_null( - State.Env.getStorageLocation(*E)); + Loc = cast_or_null(State.Env.getStorageLocation(*E)); if (Loc == nullptr) { - Loc = - &cast(State.Env.createStorageLocation(*E)); + Loc = &cast(State.Env.createStorageLocation(*E)); State.Env.setStorageLocation(*E, *Loc); } } @@ -550,7 +548,7 @@ void constructOptionalValue(const Expr &E, Environment &Env, BoolValue &HasValueVal) { - AggregateStorageLocation &Loc = Env.getResultObjectLocation(E); + RecordStorageLocation &Loc = Env.getResultObjectLocation(E); Env.setValue(E, createOptionalValue(Loc, HasValueVal, Env)); } @@ -598,7 +596,7 @@ LatticeTransferState &State) { assert(E->getNumArgs() > 0); - if (auto *Loc = cast( + if (auto *Loc = cast( State.Env.getStorageLocation(*E->getArg(0)))) { createOptionalValue(*Loc, HasValueVal, State.Env); @@ -623,8 +621,8 @@ transferAssignment(E, State.Env.getBoolLiteralValue(false), State); } -void transferSwap(AggregateStorageLocation *Loc1, - AggregateStorageLocation *Loc2, Environment &Env) { +void transferSwap(RecordStorageLocation *Loc1, RecordStorageLocation *Loc2, + Environment &Env) { // We account for cases where one or both of the optionals are not modeled, // either lacking associated storage locations, or lacking values associated // to such storage locations. @@ -661,7 +659,7 @@ const MatchFinder::MatchResult &, LatticeTransferState &State) { assert(E->getNumArgs() == 1); - auto *OtherLoc = cast_or_null( + auto *OtherLoc = cast_or_null( State.Env.getStorageLocation(*E->getArg(0))); transferSwap(getImplicitObjectLocation(*E, State.Env), OtherLoc, State.Env); } @@ -669,9 +667,9 @@ void transferStdSwapCall(const CallExpr *E, const MatchFinder::MatchResult &, LatticeTransferState &State) { assert(E->getNumArgs() == 2); - auto *Arg0Loc = cast_or_null( + auto *Arg0Loc = cast_or_null( State.Env.getStorageLocation(*E->getArg(0))); - auto *Arg1Loc = cast_or_null( + auto *Arg1Loc = cast_or_null( State.Env.getStorageLocation(*E->getArg(1))); transferSwap(Arg0Loc, Arg1Loc, State.Env); } @@ -848,7 +846,7 @@ isOptionalMemberCallWithNameMatcher(hasName("emplace")), [](const CXXMemberCallExpr *E, const MatchFinder::MatchResult &, LatticeTransferState &State) { - if (AggregateStorageLocation *Loc = + if (RecordStorageLocation *Loc = getImplicitObjectLocation(*E, State.Env)) { createOptionalValue(*Loc, State.Env.getBoolLiteralValue(true), State.Env); @@ -860,7 +858,7 @@ isOptionalMemberCallWithNameMatcher(hasName("reset")), [](const CXXMemberCallExpr *E, const MatchFinder::MatchResult &, LatticeTransferState &State) { - if (AggregateStorageLocation *Loc = + if (RecordStorageLocation *Loc = getImplicitObjectLocation(*E, State.Env)) { createOptionalValue(*Loc, State.Env.getBoolLiteralValue(false), State.Env); @@ -1032,7 +1030,7 @@ if (isa(CurrentHasVal)) return &Current; } - return &createOptionalValue(cast(Current).getAggregateLoc(), + return &createOptionalValue(cast(Current).getLoc(), CurrentEnv.makeTopBoolValue(), CurrentEnv); case ComparisonResult::Unknown: return nullptr; diff --git a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp --- a/clang/lib/Analysis/FlowSensitive/RecordOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/RecordOps.cpp @@ -14,9 +14,8 @@ #define DEBUG_TYPE "dataflow" -void clang::dataflow::copyRecord(AggregateStorageLocation &Src, - AggregateStorageLocation &Dst, - Environment &Env) { +void clang::dataflow::copyRecord(RecordStorageLocation &Src, + RecordStorageLocation &Dst, Environment &Env) { auto SrcType = Src.getType().getCanonicalType().getUnqualifiedType(); auto DstType = Dst.getType().getCanonicalType().getUnqualifiedType(); @@ -43,8 +42,8 @@ (SrcFieldLoc != nullptr && DstFieldLoc != nullptr)); if (Field->getType()->isRecordType()) { - copyRecord(cast(*SrcFieldLoc), - cast(*DstFieldLoc), Env); + copyRecord(cast(*SrcFieldLoc), + cast(*DstFieldLoc), Env); } else if (Field->getType()->isReferenceType()) { Dst.setChild(*Field, SrcFieldLoc); } else { @@ -55,10 +54,10 @@ } } - StructValue *SrcVal = cast_or_null(Env.getValue(Src)); - StructValue *DstVal = cast_or_null(Env.getValue(Dst)); + RecordValue *SrcVal = cast_or_null(Env.getValue(Src)); + RecordValue *DstVal = cast_or_null(Env.getValue(Dst)); - DstVal = &Env.create(Dst); + DstVal = &Env.create(Dst); Env.setValue(Dst, *DstVal); if (SrcVal == nullptr) @@ -70,9 +69,9 @@ } } -bool clang::dataflow::recordsEqual(const AggregateStorageLocation &Loc1, +bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1, - const AggregateStorageLocation &Loc2, + const RecordStorageLocation &Loc2, const Environment &Env2) { LLVM_DEBUG({ if (Loc2.getType().getCanonicalType().getUnqualifiedType() != @@ -91,8 +90,8 @@ (FieldLoc1 != nullptr && FieldLoc2 != nullptr)); if (Field->getType()->isRecordType()) { - if (!recordsEqual(cast(*FieldLoc1), Env1, - cast(*FieldLoc2), Env2)) + if (!recordsEqual(cast(*FieldLoc1), Env1, + cast(*FieldLoc2), Env2)) return false; } else if (Field->getType()->isReferenceType()) { if (FieldLoc1 != FieldLoc2) @@ -104,10 +103,10 @@ llvm::StringMap Props1, Props2; - if (StructValue *Val1 = cast_or_null(Env1.getValue(Loc1))) + if (RecordValue *Val1 = cast_or_null(Env1.getValue(Loc1))) for (const auto &[Name, Value] : Val1->properties()) Props1[Name] = Value; - if (StructValue *Val2 = cast_or_null(Env2.getValue(Loc2))) + if (RecordValue *Val2 = cast_or_null(Env2.getValue(Loc2))) for (const auto &[Name, Value] : Val2->properties()) Props2[Name] = Value; diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -435,7 +435,7 @@ } } - AggregateStorageLocation *BaseLoc = getBaseObjectLocation(*S, Env); + RecordStorageLocation *BaseLoc = getBaseObjectLocation(*S, Env); if (BaseLoc == nullptr) return; @@ -464,7 +464,7 @@ assert(Arg != nullptr); auto *ArgLoc = - cast_or_null(Env.getStorageLocation(*Arg)); + cast_or_null(Env.getStorageLocation(*Arg)); if (ArgLoc == nullptr) return; @@ -472,9 +472,9 @@ if (Value *Val = Env.getValue(*ArgLoc)) Env.setValue(*S, *Val); } else { - auto &Val = *cast(Env.createValue(S->getType())); + auto &Val = *cast(Env.createValue(S->getType())); Env.setValue(*S, Val); - copyRecord(*ArgLoc, Val.getAggregateLoc(), Env); + copyRecord(*ArgLoc, Val.getLoc(), Env); } return; } @@ -483,9 +483,8 @@ // of records, and we currently can't create values for arrays. So check if // we've got a record type. if (S->getType()->isRecordType()) { - auto &InitialVal = *cast(Env.createValue(S->getType())); - copyRecord(InitialVal.getAggregateLoc(), Env.getResultObjectLocation(*S), - Env); + auto &InitialVal = *cast(Env.createValue(S->getType())); + copyRecord(InitialVal.getLoc(), Env.getResultObjectLocation(*S), Env); } transferInlineCall(S, ConstructorDecl); @@ -511,9 +510,9 @@ return; auto *LocSrc = - cast_or_null(Env.getStorageLocation(*Arg1)); + cast_or_null(Env.getStorageLocation(*Arg1)); auto *LocDst = - cast_or_null(Env.getStorageLocation(*Arg0)); + cast_or_null(Env.getStorageLocation(*Arg0)); if (LocSrc != nullptr && LocDst != nullptr) { copyRecord(*LocSrc, *LocDst, Env); @@ -573,8 +572,8 @@ if (SubExprVal == nullptr) return; - if (StructValue *StructVal = dyn_cast(SubExprVal)) { - Env.setStorageLocation(*S, StructVal->getAggregateLoc()); + if (RecordValue *RecordVal = dyn_cast(SubExprVal)) { + Env.setStorageLocation(*S, RecordVal->getLoc()); return; } @@ -638,14 +637,13 @@ } auto &Loc = - Env.getDataflowAnalysisContext() - .arena() - .create(Type, std::move(FieldLocs)); - StructValue &StructVal = Env.create(Loc); + Env.getDataflowAnalysisContext().arena().create( + Type, std::move(FieldLocs)); + RecordValue &RecordVal = Env.create(Loc); - Env.setValue(Loc, StructVal); + Env.setValue(Loc, RecordVal); - Env.setValue(*S, StructVal); + Env.setValue(*S, RecordVal); // FIXME: Implement array initialization. } diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -376,7 +376,7 @@ assert(InitExpr != nullptr); const FieldDecl *Member = nullptr; - AggregateStorageLocation *ParentLoc = &ThisLoc; + RecordStorageLocation *ParentLoc = &ThisLoc; StorageLocation *MemberLoc = nullptr; if (Init->isMemberInitializer()) { Member = Init->getMember(); @@ -387,7 +387,7 @@ MemberLoc = &ThisLoc; for (const auto *I : IndirectField->chain()) { Member = cast(I); - ParentLoc = cast(MemberLoc); + ParentLoc = cast(MemberLoc); MemberLoc = ParentLoc->getChild(*Member); } } @@ -398,8 +398,8 @@ // to simply use `Environment::createObject()` here, the same way that we do // this in `TransferVisitor::VisitInitListExpr()`. However, this would require // us to be able to build a list of fields that we then use to initialize an - // `AggregateStorageLocation` -- and the problem is that, when we get here, - // the `AggregateStorageLocation` already exists. We should explore if there's + // `RecordStorageLocation` -- and the problem is that, when we get here, + // the `RecordStorageLocation` already exists. We should explore if there's // anything that we can do to change this. if (Member->getType()->isReferenceType()) { auto *InitExprLoc = Env.getStorageLocation(*InitExpr); @@ -409,13 +409,13 @@ ParentLoc->setChild(*Member, InitExprLoc); } else if (auto *InitExprVal = Env.getValue(*InitExpr)) { if (Member->getType()->isRecordType()) { - auto *InitValStruct = cast(InitExprVal); + auto *InitValStruct = cast(InitExprVal); // FIXME: Rather than performing a copy here, we should really be // initializing the field in place. This would require us to propagate the // storage location of the field to the AST node that creates the - // `StructValue`. - copyRecord(InitValStruct->getAggregateLoc(), - *cast(MemberLoc), Env); + // `RecordValue`. + copyRecord(InitValStruct->getLoc(), + *cast(MemberLoc), Env); } else { Env.setValue(*MemberLoc, *InitExprVal); } diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp --- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp @@ -91,7 +91,7 @@ // Verify that the struct and the field (`R`) with first appearance of the // type is created successfully. Environment Env(DAContext, *Fun); - StructValue *SVal = cast(Env.createValue(Ty)); + RecordValue *SVal = cast(Env.createValue(Ty)); PointerValue *PV = cast_or_null(getFieldValue(SVal, *R, Env)); EXPECT_THAT(PV, NotNull()); } @@ -171,7 +171,7 @@ // Verify that the `X` field of `S` is populated when analyzing the // constructor, even though it is not referenced directly in the constructor. Environment Env(DAContext, *Constructor); - auto *Val = cast(Env.createValue(QTy)); + auto *Val = cast(Env.createValue(QTy)); EXPECT_THAT(getFieldValue(Val, *XDecl, Env), NotNull()); } @@ -215,8 +215,8 @@ // Verify the global variable is populated when we analyze `Target`. Environment Env(DAContext, *Fun); const auto *GlobalLoc = - cast(Env.getStorageLocation(*GlobalDecl)); - const auto *GlobalVal = cast(Env.getValue(*GlobalLoc)); + cast(Env.getStorageLocation(*GlobalDecl)); + const auto *GlobalVal = cast(Env.getValue(*GlobalLoc)); auto *BarVal = getFieldValue(GlobalVal, *BarDecl, Env); EXPECT_TRUE(isa(BarVal)); } @@ -253,7 +253,7 @@ EXPECT_THAT(Env.getValue(*Var), NotNull()); } -TEST_F(EnvironmentTest, RefreshStructValue) { +TEST_F(EnvironmentTest, RefreshRecordValue) { using namespace ast_matchers; std::string Code = R"cc( @@ -280,7 +280,7 @@ Environment Env(DAContext, *Target); EXPECT_THAT(Env.getStorageLocation(*DRE), IsNull()); - refreshStructValue(*DRE, Env); + refreshRecordValue(*DRE, Env); EXPECT_THAT(Env.getStorageLocation(*DRE), NotNull()); } diff --git a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp --- a/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp @@ -58,10 +58,10 @@ const ValueDecl *InnerDecl = findValueDecl(ASTCtx, "inner"); const ValueDecl *InnerIntDecl = findValueDecl(ASTCtx, "inner_int"); - auto &S1 = getLocForDecl(ASTCtx, Env, "s1"); - auto &S2 = getLocForDecl(ASTCtx, Env, "s2"); - auto &Inner1 = *cast(S1.getChild(*InnerDecl)); - auto &Inner2 = *cast(S2.getChild(*InnerDecl)); + auto &S1 = getLocForDecl(ASTCtx, Env, "s1"); + auto &S2 = getLocForDecl(ASTCtx, Env, "s2"); + auto &Inner1 = *cast(S1.getChild(*InnerDecl)); + auto &Inner2 = *cast(S2.getChild(*InnerDecl)); EXPECT_NE(getFieldValue(&S1, *OuterIntDecl, Env), getFieldValue(&S2, *OuterIntDecl, Env)); @@ -69,8 +69,8 @@ EXPECT_NE(getFieldValue(&Inner1, *InnerIntDecl, Env), getFieldValue(&Inner2, *InnerIntDecl, Env)); - auto *S1Val = cast(Env.getValue(S1)); - auto *S2Val = cast(Env.getValue(S2)); + auto *S1Val = cast(Env.getValue(S1)); + auto *S2Val = cast(Env.getValue(S2)); EXPECT_NE(S1Val, S2Val); S1Val->setProperty("prop", Env.getBoolLiteralValue(true)); @@ -83,8 +83,8 @@ EXPECT_EQ(getFieldValue(&Inner1, *InnerIntDecl, Env), getFieldValue(&Inner2, *InnerIntDecl, Env)); - S1Val = cast(Env.getValue(S1)); - S2Val = cast(Env.getValue(S2)); + S1Val = cast(Env.getValue(S1)); + S2Val = cast(Env.getValue(S2)); EXPECT_NE(S1Val, S2Val); EXPECT_EQ(S2Val->getProperty("prop"), &Env.getBoolLiteralValue(true)); @@ -118,11 +118,11 @@ const ValueDecl *InnerDecl = findValueDecl(ASTCtx, "inner"); const ValueDecl *InnerIntDecl = findValueDecl(ASTCtx, "inner_int"); - auto &S1 = getLocForDecl(ASTCtx, Env, "s1"); - auto &S2 = getLocForDecl(ASTCtx, Env, "s2"); - auto &Inner2 = *cast(S2.getChild(*InnerDecl)); + auto &S1 = getLocForDecl(ASTCtx, Env, "s1"); + auto &S2 = getLocForDecl(ASTCtx, Env, "s2"); + auto &Inner2 = *cast(S2.getChild(*InnerDecl)); - cast(Env.getValue(S1)) + cast(Env.getValue(S1)) ->setProperty("prop", Env.getBoolLiteralValue(true)); // Strategy: Create two equal records, then verify each of the various @@ -163,14 +163,14 @@ EXPECT_TRUE(recordsEqual(S1, S2, Env)); // S1 and S2 have the same property with different values. - cast(Env.getValue(S2)) + cast(Env.getValue(S2)) ->setProperty("prop", Env.getBoolLiteralValue(false)); EXPECT_FALSE(recordsEqual(S1, S2, Env)); copyRecord(S1, S2, Env); EXPECT_TRUE(recordsEqual(S1, S2, Env)); // S1 has a property that S2 doesn't have. - cast(Env.getValue(S1)) + cast(Env.getValue(S1)) ->setProperty("other_prop", Env.getBoolLiteralValue(false)); EXPECT_FALSE(recordsEqual(S1, S2, Env)); // We modified S1 this time, so need to copy back the other way. @@ -178,7 +178,7 @@ EXPECT_TRUE(recordsEqual(S1, S2, Env)); // S2 has a property that S1 doesn't have. - cast(Env.getValue(S2)) + cast(Env.getValue(S2)) ->setProperty("other_prop", Env.getBoolLiteralValue(false)); EXPECT_FALSE(recordsEqual(S1, S2, Env)); copyRecord(S1, S2, Env); @@ -186,9 +186,9 @@ // S1 and S2 have the same number of properties, but with different // names. - cast(Env.getValue(S1)) + cast(Env.getValue(S1)) ->setProperty("prop1", Env.getBoolLiteralValue(false)); - cast(Env.getValue(S2)) + cast(Env.getValue(S2)) ->setProperty("prop2", Env.getBoolLiteralValue(false)); EXPECT_FALSE(recordsEqual(S1, S2, Env)); }); @@ -215,8 +215,8 @@ Environment Env = getEnvironmentAtAnnotation(Results, "p").fork(); const ValueDecl *IDecl = findValueDecl(ASTCtx, "i"); - auto &A = getLocForDecl(ASTCtx, Env, "a"); - auto &B = getLocForDecl(ASTCtx, Env, "b"); + auto &A = getLocForDecl(ASTCtx, Env, "a"); + auto &B = getLocForDecl(ASTCtx, Env, "b"); EXPECT_NE(Env.getValue(*A.getChild(*IDecl)), Env.getValue(*B.getChild(*IDecl))); diff --git a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h --- a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h +++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h @@ -453,7 +453,7 @@ /// Returns the value of a `Field` on the record referenced by `Loc.` /// Returns null if `Loc` is null. -inline Value *getFieldValue(const AggregateStorageLocation *Loc, +inline Value *getFieldValue(const RecordStorageLocation *Loc, const ValueDecl &Field, const Environment &Env) { if (Loc == nullptr) return nullptr; @@ -469,7 +469,7 @@ /// Note: This function currently does not use the `Env` parameter, but it will /// soon be needed to look up the `Value` when `setChild()` changes to return a /// `StorageLocation *`. -inline Value *getFieldValue(const StructValue *Struct, const ValueDecl &Field, +inline Value *getFieldValue(const RecordValue *Struct, const ValueDecl &Field, const Environment &Env) { if (Struct == nullptr) return nullptr; diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -164,10 +164,10 @@ auto *FooValue = dyn_cast_or_null(Env.getValue(*FooDecl)); ASSERT_THAT(FooValue, NotNull()); - EXPECT_TRUE(isa(FooValue->getPointeeLoc())); + EXPECT_TRUE(isa(FooValue->getPointeeLoc())); auto *FooPointeeValue = Env.getValue(FooValue->getPointeeLoc()); ASSERT_THAT(FooPointeeValue, NotNull()); - EXPECT_TRUE(isa(FooPointeeValue)); + EXPECT_TRUE(isa(FooPointeeValue)); }); } @@ -215,9 +215,9 @@ ASSERT_THAT(UnmodeledDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *UnmodeledLoc = FooLoc->getChild(*UnmodeledDecl); - ASSERT_TRUE(isa(UnmodeledLoc)); + ASSERT_TRUE(isa(UnmodeledLoc)); EXPECT_THAT(Env.getValue(*UnmodeledLoc), IsNull()); const ValueDecl *ZabDecl = findValueDecl(ASTCtx, "Zab"); @@ -262,7 +262,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); EXPECT_TRUE(isa(getFieldValue(FooLoc, *BarDecl, Env))); }); } @@ -305,7 +305,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); EXPECT_TRUE(isa(getFieldValue(FooLoc, *BarDecl, Env))); }); } @@ -369,7 +369,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); EXPECT_TRUE(isa(getFieldValue(FooLoc, *BarDecl, Env))); }); } @@ -396,10 +396,10 @@ ASSERT_THAT(FooDecl, NotNull()); const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); - ASSERT_TRUE(isa_and_nonnull(FooLoc)); + ASSERT_TRUE(isa_and_nonnull(FooLoc)); const Value *FooReferentVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull(FooReferentVal)); + EXPECT_TRUE(isa_and_nonnull(FooReferentVal)); }); } @@ -483,20 +483,20 @@ ASSERT_THAT(BazPtrDecl, NotNull()); const auto &FooLoc = - *cast(Env.getStorageLocation(*FooDecl)); + *cast(Env.getStorageLocation(*FooDecl)); const auto &BarLoc = - *cast(FooLoc.getChild(*BarDecl)); + *cast(FooLoc.getChild(*BarDecl)); const auto &FooReferentLoc = - *cast(BarLoc.getChild(*FooRefDecl)); + *cast(BarLoc.getChild(*FooRefDecl)); EXPECT_THAT(Env.getValue(FooReferentLoc), NotNull()); EXPECT_THAT(getFieldValue(&FooReferentLoc, *BarDecl, Env), IsNull()); const auto &FooPtrVal = *cast(getFieldValue(&BarLoc, *FooPtrDecl, Env)); const auto &FooPtrPointeeLoc = - cast(FooPtrVal.getPointeeLoc()); + cast(FooPtrVal.getPointeeLoc()); EXPECT_THAT(Env.getValue(FooPtrPointeeLoc), NotNull()); EXPECT_THAT(getFieldValue(&FooPtrPointeeLoc, *BarDecl, Env), IsNull()); @@ -535,10 +535,10 @@ const PointerValue *FooVal = cast(Env.getValue(*FooLoc)); const StorageLocation &FooPointeeLoc = FooVal->getPointeeLoc(); - EXPECT_TRUE(isa(&FooPointeeLoc)); + EXPECT_TRUE(isa(&FooPointeeLoc)); const Value *FooPointeeVal = Env.getValue(FooPointeeLoc); - EXPECT_TRUE(isa_and_nonnull(FooPointeeVal)); + EXPECT_TRUE(isa_and_nonnull(FooPointeeVal)); }); } @@ -638,19 +638,19 @@ *cast(Env.getStorageLocation(*FooDecl)); const auto &FooVal = *cast(Env.getValue(FooLoc)); const auto &FooPointeeVal = - *cast(Env.getValue(FooVal.getPointeeLoc())); + *cast(Env.getValue(FooVal.getPointeeLoc())); const auto &BarVal = *cast(getFieldValue(&FooPointeeVal, *BarDecl, Env)); const auto &BarPointeeVal = - *cast(Env.getValue(BarVal.getPointeeLoc())); + *cast(Env.getValue(BarVal.getPointeeLoc())); EXPECT_THAT(getFieldValue(&BarPointeeVal, *FooRefDecl, Env), NotNull()); const auto &FooPtrVal = *cast( getFieldValue(&BarPointeeVal, *FooPtrDecl, Env)); const auto &FooPtrPointeeLoc = - cast(FooPtrVal.getPointeeLoc()); + cast(FooPtrVal.getPointeeLoc()); EXPECT_THAT(Env.getValue(FooPtrPointeeLoc), IsNull()); EXPECT_THAT(getFieldValue(&BarPointeeVal, *BazRefDecl, Env), NotNull()); @@ -1044,7 +1044,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); EXPECT_TRUE(isa(getFieldValue(FooLoc, *BarDecl, Env))); }); } @@ -1069,10 +1069,10 @@ ASSERT_THAT(FooDecl, NotNull()); const StorageLocation *FooLoc = Env.getStorageLocation(*FooDecl); - ASSERT_TRUE(isa_and_nonnull(FooLoc)); + ASSERT_TRUE(isa_and_nonnull(FooLoc)); const Value *FooReferentVal = Env.getValue(*FooLoc); - EXPECT_TRUE(isa_and_nonnull(FooReferentVal)); + EXPECT_TRUE(isa_and_nonnull(FooReferentVal)); }); } @@ -1100,10 +1100,10 @@ const PointerValue *FooVal = cast(Env.getValue(*FooLoc)); const StorageLocation &FooPointeeLoc = FooVal->getPointeeLoc(); - EXPECT_TRUE(isa(&FooPointeeLoc)); + EXPECT_TRUE(isa(&FooPointeeLoc)); const Value *FooPointeeVal = Env.getValue(FooPointeeLoc); - EXPECT_TRUE(isa_and_nonnull(FooPointeeVal)); + EXPECT_TRUE(isa_and_nonnull(FooPointeeVal)); }); } @@ -1142,7 +1142,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *BarVal = cast(getFieldValue(FooLoc, *BarDecl, Env)); @@ -1273,7 +1273,7 @@ ASSERT_THAT(APublicDecl, NotNull()); ASSERT_TRUE( - isa(Env.getStorageLocation(*FooDecl))); + isa(Env.getStorageLocation(*FooDecl))); }); } @@ -1304,9 +1304,9 @@ ASSERT_THAT(BarDecl, NotNull()); const auto &FooLoc = - *cast(Env.getStorageLocation(*FooDecl)); - const auto &FooVal = *cast(Env.getValue(FooLoc)); - EXPECT_EQ(&FooVal.getAggregateLoc(), &FooLoc); + *cast(Env.getStorageLocation(*FooDecl)); + const auto &FooVal = *cast(Env.getValue(FooLoc)); + EXPECT_EQ(&FooVal.getLoc(), &FooLoc); } TEST(TransferTest, DerivedBaseMemberStructDefault) { @@ -1383,7 +1383,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *BarVal = cast(getFieldValue(FooLoc, *BarDecl, Env)); @@ -1473,7 +1473,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *BarReferentVal = cast(getFieldValue(FooLoc, *BarDecl, Env)); @@ -1543,8 +1543,8 @@ ASSERT_THAT(BazDecl, NotNull()); const auto *QuxLoc = - cast(ThisLoc->getChild(*QuxDecl)); - EXPECT_THAT(dyn_cast(Env.getValue(*QuxLoc)), NotNull()); + cast(ThisLoc->getChild(*QuxDecl)); + EXPECT_THAT(dyn_cast(Env.getValue(*QuxLoc)), NotNull()); const auto *BazVal = cast(getFieldValue(QuxLoc, *BazDecl, Env)); @@ -1614,8 +1614,8 @@ ASSERT_THAT(BazDecl, NotNull()); const auto *QuxLoc = - cast(ThisLoc->getChild(*QuxDecl)); - EXPECT_THAT(dyn_cast(Env.getValue(*QuxLoc)), NotNull()); + cast(ThisLoc->getChild(*QuxDecl)); + EXPECT_THAT(dyn_cast(Env.getValue(*QuxLoc)), NotNull()); const auto *BazVal = cast(getFieldValue(QuxLoc, *BazDecl, Env)); @@ -1897,7 +1897,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); EXPECT_TRUE(isa(getFieldValue(FooLoc, *BarDecl, Env))); }); } @@ -1930,7 +1930,7 @@ ASSERT_THAT(BarDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); EXPECT_TRUE(isa(getFieldValue(FooLoc, *BarDecl, Env))); }, LangStandard::lang_cxx14); @@ -1970,9 +1970,9 @@ const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1"); const auto *FooLoc1 = - cast(Env1.getStorageLocation(*FooDecl)); + cast(Env1.getStorageLocation(*FooDecl)); const auto *BarLoc1 = - cast(Env1.getStorageLocation(*BarDecl)); + cast(Env1.getStorageLocation(*BarDecl)); EXPECT_FALSE(recordsEqual(*FooLoc1, *BarLoc1, Env1)); const auto *FooBazVal1 = @@ -1987,12 +1987,12 @@ const Environment &Env2 = getEnvironmentAtAnnotation(Results, "p2"); const auto *FooLoc2 = - cast(Env2.getStorageLocation(*FooDecl)); + cast(Env2.getStorageLocation(*FooDecl)); const auto *BarLoc2 = - cast(Env2.getStorageLocation(*BarDecl)); + cast(Env2.getStorageLocation(*BarDecl)); - const auto *FooVal2 = cast(Env2.getValue(*FooLoc2)); - const auto *BarVal2 = cast(Env2.getValue(*BarLoc2)); + const auto *FooVal2 = cast(Env2.getValue(*FooLoc2)); + const auto *BarVal2 = cast(Env2.getValue(*BarLoc2)); EXPECT_NE(FooVal2, BarVal2); EXPECT_TRUE(recordsEqual(*FooLoc2, *BarLoc2, Env2)); @@ -2009,9 +2009,9 @@ const Environment &Env3 = getEnvironmentAtAnnotation(Results, "p3"); const auto *FooLoc3 = - cast(Env3.getStorageLocation(*FooDecl)); + cast(Env3.getStorageLocation(*FooDecl)); const auto *BarLoc3 = - cast(Env3.getStorageLocation(*BarDecl)); + cast(Env3.getStorageLocation(*BarDecl)); EXPECT_FALSE(recordsEqual(*FooLoc3, *BarLoc3, Env3)); const auto *FooBazVal3 = @@ -2076,13 +2076,13 @@ getEnvironmentAtAnnotation(Results, "after_copy"); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *BarLoc = - cast(Env.getStorageLocation(*BarDecl)); + cast(Env.getStorageLocation(*BarDecl)); - // `Foo` and `Bar` have different `StructValue`s associated with them. - const auto *FooVal = cast(Env.getValue(*FooLoc)); - const auto *BarVal = cast(Env.getValue(*BarLoc)); + // `Foo` and `Bar` have different `RecordValue`s associated with them. + const auto *FooVal = cast(Env.getValue(*FooLoc)); + const auto *BarVal = cast(Env.getValue(*BarLoc)); EXPECT_NE(FooVal, BarVal); // But the records compare equal. @@ -2102,9 +2102,9 @@ getEnvironmentAtAnnotation(Results, "after_update"); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *BarLoc = - cast(Env.getStorageLocation(*BarDecl)); + cast(Env.getStorageLocation(*BarDecl)); EXPECT_FALSE(recordsEqual(*FooLoc, *BarLoc, Env)); @@ -2149,9 +2149,9 @@ ASSERT_THAT(BazDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *BarLoc = - cast(Env.getStorageLocation(*BarDecl)); + cast(Env.getStorageLocation(*BarDecl)); EXPECT_TRUE(recordsEqual(*FooLoc, *BarLoc, Env)); const auto *FooBazVal = @@ -2192,9 +2192,9 @@ ASSERT_THAT(BazDecl, NotNull()); const auto *FooLoc = - cast(Env.getStorageLocation(*FooDecl)); + cast(Env.getStorageLocation(*FooDecl)); const auto *BarLoc = - cast(Env.getStorageLocation(*BarDecl)); + cast(Env.getStorageLocation(*BarDecl)); EXPECT_TRUE(recordsEqual(*FooLoc, *BarLoc, Env)); const auto *FooBazVal = @@ -2226,9 +2226,9 @@ const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); const auto &FooLoc = - getLocForDecl(ASTCtx, Env, "Foo"); + getLocForDecl(ASTCtx, Env, "Foo"); const auto &BarLoc = - getLocForDecl(ASTCtx, Env, "Bar"); + getLocForDecl(ASTCtx, Env, "Bar"); const auto *FooBazVal = cast(getFieldValue(&FooLoc, *BazDecl, Env)); @@ -2300,14 +2300,14 @@ ASSERT_THAT(BazDecl, NotNull()); const auto *FooLoc1 = - cast(Env1.getStorageLocation(*FooDecl)); + cast(Env1.getStorageLocation(*FooDecl)); const auto *BarLoc1 = - cast(Env1.getStorageLocation(*BarDecl)); + cast(Env1.getStorageLocation(*BarDecl)); EXPECT_FALSE(recordsEqual(*FooLoc1, *BarLoc1, Env1)); - const auto *FooVal1 = cast(Env1.getValue(*FooLoc1)); - const auto *BarVal1 = cast(Env1.getValue(*BarLoc1)); + const auto *FooVal1 = cast(Env1.getValue(*FooLoc1)); + const auto *BarVal1 = cast(Env1.getValue(*BarLoc1)); EXPECT_NE(FooVal1, BarVal1); const auto *FooBazVal1 = @@ -2317,8 +2317,8 @@ EXPECT_NE(FooBazVal1, BarBazVal1); const auto *FooLoc2 = - cast(Env2.getStorageLocation(*FooDecl)); - const auto *FooVal2 = cast(Env2.getValue(*FooLoc2)); + cast(Env2.getStorageLocation(*FooDecl)); + const auto *FooVal2 = cast(Env2.getValue(*FooLoc2)); EXPECT_NE(FooVal2, BarVal1); EXPECT_TRUE(recordsEqual(*FooLoc2, Env2, *BarLoc1, Env1)); @@ -2357,7 +2357,7 @@ const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); ASSERT_THAT(BazDecl, NotNull()); - const auto &FooVal = *cast(Env.getValue(*FooDecl)); + const auto &FooVal = *cast(Env.getValue(*FooDecl)); const auto *BarVal = cast(Env.getValue(*BarDecl)); EXPECT_EQ(BarVal, getFieldValue(&FooVal, *BazDecl, Env)); }); @@ -2530,7 +2530,7 @@ EXPECT_THAT(Env.getValue(BarPointeeLoc), IsNull()); const StorageLocation &BazPointeeLoc = BazVal->getPointeeLoc(); - EXPECT_TRUE(isa(BazPointeeLoc)); + EXPECT_TRUE(isa(BazPointeeLoc)); EXPECT_THAT(Env.getValue(BazPointeeLoc), IsNull()); const StorageLocation &NullPointeeLoc = NullVal->getPointeeLoc(); @@ -2716,10 +2716,10 @@ const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); ASSERT_THAT(BazDecl, NotNull()); - const auto *FooVal = cast(Env.getValue(*FooDecl)); - const auto *BarVal = cast(Env.getValue(*BarDecl)); + const auto *FooVal = cast(Env.getValue(*FooDecl)); + const auto *BarVal = cast(Env.getValue(*BarDecl)); - const auto *BazVal = dyn_cast(Env.getValue(*BazDecl)); + const auto *BazVal = dyn_cast(Env.getValue(*BazDecl)); ASSERT_THAT(BazVal, NotNull()); EXPECT_NE(BazVal, FooVal); @@ -2857,11 +2857,11 @@ const auto *BarArgVal = cast(Env.getValue(*BarArgDecl)); const auto *QuxArgVal = cast(Env.getValue(*QuxArgDecl)); - const auto *QuuxVal = cast(Env.getValue(*QuuxDecl)); + const auto *QuuxVal = cast(Env.getValue(*QuuxDecl)); ASSERT_THAT(QuuxVal, NotNull()); const auto *BazVal = - cast(getFieldValue(QuuxVal, *BazDecl, Env)); + cast(getFieldValue(QuuxVal, *BazDecl, Env)); ASSERT_THAT(BazVal, NotNull()); EXPECT_EQ(getFieldValue(QuuxVal, *BarDecl, Env), BarArgVal); @@ -2871,7 +2871,7 @@ // Check that fields initialized in an initializer list are always // modeled in other instances of the same type. const auto &OtherBVal = - getValueForDecl(ASTCtx, Env, "OtherB"); + getValueForDecl(ASTCtx, Env, "OtherB"); EXPECT_THAT(OtherBVal.getChild(*BarDecl), NotNull()); EXPECT_THAT(OtherBVal.getChild(*BazDecl), NotNull()); EXPECT_THAT(OtherBVal.getChild(*QuxDecl), NotNull()); @@ -2899,7 +2899,7 @@ const ValueDecl *RefFieldDecl = findValueDecl(ASTCtx, "RefField"); auto &ILoc = getLocForDecl(ASTCtx, Env, "i"); - auto &SLoc = getLocForDecl(ASTCtx, Env, "s"); + auto &SLoc = getLocForDecl(ASTCtx, Env, "s"); EXPECT_EQ(SLoc.getChild(*RefFieldDecl), &ILoc); }); @@ -2926,7 +2926,7 @@ const ValueDecl *I1FieldDecl = findValueDecl(ASTCtx, "i1"); const ValueDecl *I2FieldDecl = findValueDecl(ASTCtx, "i2"); - auto &SLoc = getLocForDecl(ASTCtx, Env, "s"); + auto &SLoc = getLocForDecl(ASTCtx, Env, "s"); auto &IValue = getValueForDecl(ASTCtx, Env, "i"); auto &I1Value = @@ -2972,7 +2972,7 @@ } ASSERT_THAT(FooDecl, NotNull()); - const auto *BazLoc = dyn_cast_or_null( + const auto *BazLoc = dyn_cast_or_null( Env.getStorageLocation(*BazDecl)); ASSERT_THAT(BazLoc, NotNull()); ASSERT_THAT(Env.getValue(*BazLoc), NotNull()); @@ -3540,7 +3540,7 @@ const auto *BarVal = cast(Env.getValue(*BarDecl)); - const auto *A2Val = cast(Env.getValue(*A2Decl)); + const auto *A2Val = cast(Env.getValue(*A2Decl)); EXPECT_EQ(getFieldValue(A2Val, *FooDecl, Env), BarVal); }); } @@ -5449,7 +5449,7 @@ void target() { Outer *p = new Outer; // Access the fields to make sure the analysis actually generates children - // for them in the `AggregateStorageLoc` and `StructValue`. + // for them in the `RecordStorageLocation` and `RecordValue`. p->OuterField.InnerField; // [[after_new]] } @@ -5466,9 +5466,9 @@ auto &P = getValueForDecl(ASTCtx, Env, "p"); - auto &OuterLoc = cast(P.getPointeeLoc()); + auto &OuterLoc = cast(P.getPointeeLoc()); auto &OuterFieldLoc = - *cast(OuterLoc.getChild(*OuterField)); + *cast(OuterLoc.getChild(*OuterField)); auto &InnerFieldLoc = *OuterFieldLoc.getChild(*InnerField); // Values for the struct and all fields exist after the new. @@ -5574,9 +5574,8 @@ const IndirectFieldDecl *IndirectField = findIndirectFieldDecl(ASTCtx, "b"); - auto *S = - cast(Env.getStorageLocation(*SDecl)); - auto &AnonStruct = *cast( + auto *S = cast(Env.getStorageLocation(*SDecl)); + auto &AnonStruct = *cast( S->getChild(*cast(IndirectField->chain().front()))); auto *B = cast(getFieldValue(&AnonStruct, *BDecl, Env)); @@ -5606,8 +5605,8 @@ findIndirectFieldDecl(ASTCtx, "b"); auto *ThisLoc = - cast(Env.getThisPointeeStorageLocation()); - auto &AnonStruct = *cast(ThisLoc->getChild( + cast(Env.getThisPointeeStorageLocation()); + auto &AnonStruct = *cast(ThisLoc->getChild( *cast(IndirectField->chain().front()))); auto *B = cast(getFieldValue(&AnonStruct, *BDecl, Env)); @@ -5639,8 +5638,8 @@ findIndirectFieldDecl(ASTCtx, "i"); auto *ThisLoc = - cast(Env.getThisPointeeStorageLocation()); - auto &AnonStruct = *cast(ThisLoc->getChild( + cast(Env.getThisPointeeStorageLocation()); + auto &AnonStruct = *cast(ThisLoc->getChild( *cast(IndirectField->chain().front()))); ASSERT_EQ(AnonStruct.getChild(*IDecl), diff --git a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp --- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp @@ -415,7 +415,7 @@ if (const auto *E = selectFirst( "call", match(cxxConstructExpr(HasSpecialBoolType).bind("call"), *S, getASTContext()))) { - cast(Env.getValue(*E)) + cast(Env.getValue(*E)) ->setProperty("is_set", Env.getBoolLiteralValue(false)); } else if (const auto *E = selectFirst( "call", match(cxxMemberCallExpr(callee(cxxMethodDecl(ofClass( @@ -423,9 +423,9 @@ .bind("call"), *S, getASTContext()))) { auto &ObjectLoc = - *cast(getImplicitObjectLocation(*E, Env)); + *cast(getImplicitObjectLocation(*E, Env)); - refreshStructValue(ObjectLoc, Env) + refreshRecordValue(ObjectLoc, Env) .setProperty("is_set", Env.getBoolLiteralValue(true)); } } @@ -572,7 +572,7 @@ *S, getASTContext()); if (const auto *E = selectFirst( "construct", Matches)) { - cast(Env.getValue(*E)) + cast(Env.getValue(*E)) ->setProperty("has_value", Env.getBoolLiteralValue(false)); } else if (const auto *E = selectFirst("operator", Matches)) { @@ -580,7 +580,7 @@ auto *Object = E->getArg(0); assert(Object != nullptr); - refreshStructValue(*Object, Env) + refreshRecordValue(*Object, Env) .setProperty("has_value", Env.getBoolLiteralValue(true)); } }