Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ template <typename Base> class CachedConstAccessorsLattice : public Base {
///
/// - `Callee` should return a location (return type is a reference type or a
/// record type).
StorageLocation &getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
Environment &Env,
llvm::function_ref<void(QualType, StorageLocation &)> Initialize);
StorageLocation &getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize);
Expand Down Expand Up @@ -196,7 +200,8 @@ template <typename Base>
StorageLocation &
CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize) {
Environment &Env,
llvm::function_ref<void(QualType, StorageLocation &)> Initialize) {
assert(Callee != nullptr);
QualType Type = Callee->getReturnType();
assert(!Type.isNull());
Expand All @@ -206,13 +211,24 @@ CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
if (it != ObjMap.end())
return *it->second;

auto T = Type.getNonReferenceType();
StorageLocation &Loc = Env.createStorageLocation(Type.getNonReferenceType());
Initialize(Loc);
Initialize(T, Loc);

ObjMap.insert({Callee, &Loc});
return Loc;
}

template <typename Base>
StorageLocation &
CachedConstAccessorsLattice<Base>::getOrCreateConstMethodReturnStorageLocation(
const RecordStorageLocation &RecordLoc, const FunctionDecl *Callee,
Environment &Env, llvm::function_ref<void(StorageLocation &)> Initialize) {
return getOrCreateConstMethodReturnStorageLocation(
RecordLoc, Callee, Env,
[Initialize](QualType T, StorageLocation &Loc) { Initialize(Loc); });
}

} // namespace dataflow
} // namespace clang

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,18 @@ template <typename LatticeT>
void transferSmartPointerLikeCachedDeref(
const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc);
llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc);
template <typename LatticeT>
void transferSmartPointerLikeCachedDeref(
const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
transferSmartPointerLikeCachedDeref<LatticeT>(
DerefExpr, SmartPointerLoc, State,
[InitializeLoc](QualType T, StorageLocation &Loc) {
InitializeLoc(Loc);
});
}

/// A transfer function for `operator->` (and `get`) calls that can be cached.
/// Runs the `InitializeLoc` callback to initialize any new StorageLocations.
Expand All @@ -103,13 +114,24 @@ template <typename LatticeT>
void transferSmartPointerLikeCachedGet(
const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc);
llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc);
template <typename LatticeT>
void transferSmartPointerLikeCachedGet(
const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
transferSmartPointerLikeCachedGet<LatticeT>(
GetExpr, SmartPointerLoc, State,
[InitializeLoc](QualType T, StorageLocation &Loc) {
InitializeLoc(Loc);
});
}

template <typename LatticeT>
void transferSmartPointerLikeCachedDeref(
const CallExpr *DerefExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc) {
if (State.Env.getStorageLocation(*DerefExpr) != nullptr)
return;
if (SmartPointerLoc == nullptr)
Expand Down Expand Up @@ -145,7 +167,7 @@ template <typename LatticeT>
void transferSmartPointerLikeCachedGet(
const CallExpr *GetExpr, RecordStorageLocation *SmartPointerLoc,
TransferState<LatticeT> &State,
llvm::function_ref<void(StorageLocation &)> InitializeLoc) {
llvm::function_ref<void(QualType, StorageLocation &)> InitializeLoc) {
if (SmartPointerLoc == nullptr)
return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,5 +307,23 @@ TEST_F(CachedConstAccessorsLatticeTest, ProducesNewValueAfterJoinDistinct) {
EXPECT_NE(ValAfterJoin2, Val3);
}

TEST_F(CachedConstAccessorsLatticeTest, TypePassed) {
CommonTestInputs Inputs;
auto *CE = Inputs.CallRef;
RecordStorageLocation Loc(Inputs.SType, RecordStorageLocation::FieldToLoc(),
{});

LatticeT Lattice;

const FunctionDecl *Callee = CE->getDirectCallee();
auto RetType = Callee->getReturnType().getNonReferenceType();
auto CheckedInit = [RetType](QualType T, StorageLocation &) {
ASSERT_EQ(T, RetType);
};
ASSERT_NE(Callee, nullptr);
Lattice.getOrCreateConstMethodReturnStorageLocation(Loc, Callee, Env,
CheckedInit);
}

} // namespace
} // namespace clang::dataflow