Make various ObjectRepository methods return pointers.
PiperOrigin-RevId: 458449285
diff --git a/lifetime_analysis/analyze.cc b/lifetime_analysis/analyze.cc
index b98b068..7392dcc 100644
--- a/lifetime_analysis/analyze.cc
+++ b/lifetime_analysis/analyze.cc
@@ -168,11 +168,11 @@
}
if (object_repository.GetThisObject().has_value()) {
- var_objects.insert(*object_repository.GetThisObject());
+ var_objects.insert(**object_repository.GetThisObject());
lines.push_back(absl::StrFormat(
"\"%s%s\"[label=%s]", name_prefix,
- object_repository.GetThisObject()->DebugString(),
- VariableLabel("this", *object_repository.GetThisObject())));
+ (*object_repository.GetThisObject())->DebugString(),
+ VariableLabel("this", **object_repository.GetThisObject())));
}
for (auto [decl, object] : object_repository) {
@@ -182,11 +182,11 @@
VariableLabel(decl->getNameAsString(), *object)));
}
- var_objects.insert(object_repository.GetReturnObject());
+ var_objects.insert(*object_repository.GetReturnObject());
lines.push_back(absl::StrFormat(
"\"%s%s\"[label=%s]", name_prefix,
- object_repository.GetReturnObject().DebugString(),
- VariableLabel("return", object_repository.GetReturnObject())));
+ object_repository.GetReturnObject()->DebugString(),
+ VariableLabel("return", *object_repository.GetReturnObject())));
for (Object object : all_objects) {
if (!var_objects.contains(object)) {
@@ -486,7 +486,7 @@
}
if (!IsInitExprInitializingARecordObject(init_expr)) {
TransferInitializer(
- *object_repository.GetFieldObject(this_object.value(), field),
+ *object_repository.GetFieldObject(*this_object.value(), field),
field->getType(), object_repository, init_expr, points_to_map);
}
}
@@ -714,11 +714,12 @@
ObjectRepository& object_repository, PointsToMap& points_to_map) {
assert(ctor->isDefaulted() && ctor->isDefaultConstructor());
- std::optional<Object> this_object_maybe = object_repository.GetThisObject();
+ std::optional<const Object*> this_object_maybe =
+ object_repository.GetThisObject();
if (!this_object_maybe.has_value()) {
llvm::report_fatal_error("didn't find `this` object for constructor");
}
- Object this_object = *this_object_maybe;
+ const Object* this_object = *this_object_maybe;
const clang::CXXRecordDecl* record = ctor->getParent();
for (const CXXBaseSpecifier& base : record->bases()) {
@@ -727,7 +728,7 @@
if (const clang::CXXConstructorDecl* base_ctor =
GetDefaultConstructor(base_record)) {
const Object* base_this_object =
- object_repository.GetBaseClassObject(this_object, base.getType());
+ object_repository.GetBaseClassObject(*this_object, base.getType());
if (llvm::Error err = TransferDefaultConstructor(
base_ctor, *base_this_object, object_repository, points_to_map,
callee_lifetimes)) {
@@ -742,7 +743,7 @@
if (const clang::CXXConstructorDecl* field_ctor =
GetDefaultConstructor(field_record)) {
const Object* field_this_object =
- object_repository.GetFieldObject(this_object, field);
+ object_repository.GetFieldObject(*this_object, field);
if (llvm::Error err = TransferDefaultConstructor(
field_ctor, *field_this_object, object_repository,
points_to_map, callee_lifetimes)) {
@@ -983,7 +984,7 @@
for (unsigned i = 0; i < func->getNumParams(); ++i) {
const clang::ParmVarDecl* param = func->getParamDecl(i);
FindLifetimeSubstitutions(
- object_repository.GetOriginalParameterValue(param), param->getType(),
+ *object_repository.GetOriginalParameterValue(param), param->getType(),
points_to_map, object_repository, result.GetParamLifetimes(i), subst);
}
@@ -1009,8 +1010,8 @@
}
FindLifetimeSubstitutions(
- object_repository.GetReturnObject(), func->getReturnType(), points_to_map,
- object_repository, result.GetReturnLifetimes(), subst);
+ *object_repository.GetReturnObject(), func->getReturnType(),
+ points_to_map, object_repository, result.GetReturnLifetimes(), subst);
result.SubstituteLifetimes(subst);
diff --git a/lifetime_analysis/lifetime_analysis.cc b/lifetime_analysis/lifetime_analysis.cc
index d572c0f..ff654cf 100644
--- a/lifetime_analysis/lifetime_analysis.cc
+++ b/lifetime_analysis/lifetime_analysis.cc
@@ -405,7 +405,7 @@
if (auto iter = lifetime_to_object_set.find(Lifetime::Static());
iter != lifetime_to_object_set.end()) {
for (const Object& object : iter->second) {
- Object pointer = object_repository.CreateStaticObject(
+ const Object* pointer = object_repository.CreateStaticObject(
ast_context.getPointerType(object.Type()));
points_to_map.ExtendPointerPointsToSet(pointer, {object});
}
@@ -421,9 +421,9 @@
// Step 3: Determine points-to set for the return value.
if (return_lifetimes.HasLifetimes()) {
if (IsInitExprInitializingARecordObject(call)) {
- Object init_object = object_repository.GetInitializedObject(call);
+ const Object* init_object = object_repository.GetInitializedObject(call);
PropagateLifetimesToPointees(
- {init_object}, call->getType(), return_lifetimes, points_to_map,
+ *init_object, call->getType(), return_lifetimes, points_to_map,
object_repository, lifetime_to_object_set, ast_context);
} else {
ObjectSet rval_points_to;
@@ -511,7 +511,7 @@
std::optional<std::string> TransferStmtVisitor::VisitStringLiteral(
const clang::StringLiteral* strlit) {
- Object obj = object_repository_.CreateStaticObject(strlit->getType());
+ const Object* obj = object_repository_.CreateStaticObject(strlit->getType());
points_to_map_.SetExprObjectSet(strlit, {obj});
return std::nullopt;
}
@@ -797,8 +797,9 @@
return std::nullopt;
}
// The object set for each field should be pointing to the initializers.
- Object init_object = object_repository_.GetInitializedObject(init_list);
- TransferInitializer(init_object, init_list->getType(), object_repository_,
+ const Object* init_object =
+ object_repository_.GetInitializedObject(init_list);
+ TransferInitializer(*init_object, init_list->getType(), object_repository_,
init_list, points_to_map_);
} else {
// If the InitListExpr is not initializing a record object, we assume it's
@@ -822,7 +823,8 @@
std::optional<std::string> TransferStmtVisitor::VisitMaterializeTemporaryExpr(
const clang::MaterializeTemporaryExpr* temporary_expr) {
- Object temp_object = object_repository_.GetTemporaryObject(temporary_expr);
+ const Object* temp_object =
+ object_repository_.GetTemporaryObject(temporary_expr);
points_to_map_.SetExprObjectSet(temporary_expr, {temp_object});
return std::nullopt;
}
@@ -862,7 +864,7 @@
std::optional<std::string> TransferStmtVisitor::VisitCXXThisExpr(
const clang::CXXThisExpr* this_expr) {
- std::optional<Object> this_object = object_repository_.GetThisObject();
+ std::optional<const Object*> this_object = object_repository_.GetThisObject();
assert(this_object.has_value());
points_to_map_.SetExprObjectSet(this_expr, ObjectSet{this_object.value()});
return std::nullopt;
@@ -887,7 +889,7 @@
fn_params.push_back(FunctionParameter{
clang::dyn_cast<clang::CXXMethodDecl>(callee)->getThisType(),
callee_lifetimes.GetThisLifetimes(),
- object_repository.GetCallExprThisPointer(call)});
+ *object_repository.GetCallExprThisPointer(call)});
}
// Handle all other arguments.
@@ -895,7 +897,7 @@
fn_params.push_back(FunctionParameter{
callee->getParamDecl(i - 1)->getType().getCanonicalType(),
callee_lifetimes.GetParamLifetimes(i - 1),
- object_repository.GetCallExprArgumentObject(call, i)});
+ *object_repository.GetCallExprArgumentObject(call, i)});
}
} else {
// We check <= instead of == because of default arguments.
@@ -905,7 +907,7 @@
fn_params.push_back(FunctionParameter{
callee->getParamDecl(i)->getType().getCanonicalType(),
callee_lifetimes.GetParamLifetimes(i),
- object_repository.GetCallExprArgumentObject(call, i)});
+ *object_repository.GetCallExprArgumentObject(call, i)});
}
if (const auto* member_call =
clang::dyn_cast<clang::CXXMemberCallExpr>(call)) {
@@ -925,7 +927,7 @@
fn_params.push_back(
FunctionParameter{member_call->getMethodDecl()->getThisType(),
callee_lifetimes.GetThisLifetimes(),
- object_repository.GetCallExprThisPointer(call)});
+ *object_repository.GetCallExprThisPointer(call)});
}
}
return fn_params;
@@ -1021,7 +1023,7 @@
// PointsToSet more than needed, as dataflow analysis relies on points-to
// sets never shrinking.
TransferInitializer(
- object_repository_.GetCallExprArgumentObject(call, i),
+ *object_repository_.GetCallExprArgumentObject(call, i),
callee->getParamDecl(is_member_operator ? i - 1 : i)->getType(),
object_repository_, call->getArg(i), points_to_map_);
}
@@ -1078,10 +1080,11 @@
assert(construct_expr->getNumArgs() <= constructor->getNumParams());
for (size_t i = 0; i < construct_expr->getNumArgs(); i++) {
- TransferInitializer(
- object_repository_.GetCXXConstructExprArgumentObject(construct_expr, i),
- construct_expr->getArg(i)->getType(), object_repository_,
- construct_expr->getArg(i), points_to_map_);
+ TransferInitializer(*object_repository_.GetCXXConstructExprArgumentObject(
+ construct_expr, i),
+ construct_expr->getArg(i)->getType(),
+ object_repository_, construct_expr->getArg(i),
+ points_to_map_);
}
// Handle the `this` parameter, which should point to the object getting
@@ -1098,14 +1101,14 @@
constructor->getParamDecl(i)->getType().getCanonicalType();
fn_params.push_back(
FunctionParameter{arg_type, callee_lifetimes.GetParamLifetimes(i),
- object_repository_.GetCXXConstructExprArgumentObject(
+ *object_repository_.GetCXXConstructExprArgumentObject(
construct_expr, i)});
}
clang::QualType type = constructor->getThisType();
fn_params.push_back(FunctionParameter{
type, callee_lifetimes.GetThisLifetimes(),
- object_repository_.GetCXXConstructExprThisPointer(construct_expr)});
+ *object_repository_.GetCXXConstructExprThisPointer(construct_expr)});
TransferLifetimesForCall(
construct_expr, fn_params,
diff --git a/lifetime_analysis/object_repository.cc b/lifetime_analysis/object_repository.cc
index 80221d6..5f9b0ea 100644
--- a/lifetime_analysis/object_repository.cc
+++ b/lifetime_analysis/object_repository.cc
@@ -426,18 +426,20 @@
}
if (init->getMember() && init->getMember()->getType()->isRecordType()) {
- std::optional<Object> this_object = object_repository_.GetThisObject();
+ std::optional<const Object*> this_object =
+ object_repository_.GetThisObject();
assert(this_object.has_value());
const Object* field_object =
- object_repository_.GetFieldObject(*this_object, init->getMember());
+ object_repository_.GetFieldObject(**this_object, init->getMember());
PropagateInitializedObject(init_expr, field_object);
} else if (init->getBaseClass()) {
- std::optional<Object> this_object = object_repository_.GetThisObject();
+ std::optional<const Object*> this_object =
+ object_repository_.GetThisObject();
assert(this_object.has_value());
const Object* base_object = object_repository_.GetBaseClassObject(
- *this_object, init->getBaseClass());
+ **this_object, init->getBaseClass());
PropagateInitializedObject(init_expr, base_object);
}
@@ -537,7 +539,7 @@
return iter->second;
}
-Object ObjectRepository::GetTemporaryObject(
+const Object* ObjectRepository::GetTemporaryObject(
const clang::MaterializeTemporaryExpr* expr) const {
auto iter = temporary_objects_.find(expr);
if (iter == temporary_objects_.end()) {
@@ -546,10 +548,10 @@
llvm::errs() << "\n" << DebugString();
llvm::report_fatal_error("Didn't find object for temporary expression");
}
- return *iter->second;
+ return iter->second;
}
-Object ObjectRepository::GetOriginalParameterValue(
+const Object* ObjectRepository::GetOriginalParameterValue(
const clang::ParmVarDecl* var_decl) const {
auto iter = initial_parameter_object_.find(var_decl);
if (iter == initial_parameter_object_.end()) {
@@ -558,11 +560,11 @@
llvm::errs() << "\n" << DebugString();
llvm::report_fatal_error("Didn't find caller object for parameter");
}
- return *iter->second;
+ return iter->second;
}
-Object ObjectRepository::GetCallExprArgumentObject(const clang::CallExpr* expr,
- size_t arg_index) const {
+const Object* ObjectRepository::GetCallExprArgumentObject(
+ const clang::CallExpr* expr, size_t arg_index) const {
auto iter = call_expr_args_objects_.find(std::make_pair(expr, arg_index));
if (iter == call_expr_args_objects_.end()) {
llvm::errs() << "Didn't find object for argument " << arg_index
@@ -571,10 +573,10 @@
llvm::errs() << "\n" << DebugString();
llvm::report_fatal_error("Didn't find object for argument");
}
- return *iter->second;
+ return iter->second;
}
-Object ObjectRepository::GetCallExprThisPointer(
+const Object* ObjectRepository::GetCallExprThisPointer(
const clang::CallExpr* expr) const {
auto iter = call_expr_this_pointers_.find(expr);
if (iter == call_expr_this_pointers_.end()) {
@@ -583,10 +585,10 @@
llvm::errs() << "\n" << DebugString();
llvm::report_fatal_error("Didn't find `this` object for call");
}
- return *iter->second;
+ return iter->second;
}
-Object ObjectRepository::GetCXXConstructExprArgumentObject(
+const Object* ObjectRepository::GetCXXConstructExprArgumentObject(
const clang::CXXConstructExpr* expr, size_t arg_index) const {
auto iter = call_expr_args_objects_.find(std::make_pair(expr, arg_index));
if (iter == call_expr_args_objects_.end()) {
@@ -597,10 +599,10 @@
llvm::report_fatal_error(
"Didn't find object for argument of constructor call");
}
- return *iter->second;
+ return iter->second;
}
-Object ObjectRepository::GetCXXConstructExprThisPointer(
+const Object* ObjectRepository::GetCXXConstructExprThisPointer(
const clang::CXXConstructExpr* expr) const {
auto iter = call_expr_this_pointers_.find(expr);
if (iter == call_expr_this_pointers_.end()) {
@@ -609,10 +611,10 @@
llvm::errs() << "\n" << DebugString();
llvm::report_fatal_error("Didn't find `this` object for constructor");
}
- return *iter->second;
+ return iter->second;
}
-Object ObjectRepository::GetInitializedObject(
+const Object* ObjectRepository::GetInitializedObject(
const clang::Expr* initializer_expr) const {
assert(clang::isa<clang::CXXConstructExpr>(initializer_expr) ||
clang::isa<clang::InitListExpr>(initializer_expr) ||
@@ -625,7 +627,7 @@
llvm::errs() << "\n" << DebugString();
llvm::report_fatal_error("Didn't find object for initializer");
}
- return *iter->second;
+ return iter->second;
}
ObjectRepository::ObjectValueType ObjectRepository::GetObjectValueType(
@@ -686,10 +688,10 @@
return ret;
}
-Object ObjectRepository::CreateStaticObject(clang::QualType type) {
+const Object* ObjectRepository::CreateStaticObject(clang::QualType type) {
auto iter = static_objects_.find(type);
if (iter != static_objects_.end()) {
- return *iter->second;
+ return iter->second;
}
const Object* object = CreateObject(Lifetime::Static(), type);
@@ -699,7 +701,7 @@
*object, type, [](const clang::Expr*) { return Lifetime::Static(); },
true);
- return *object;
+ return object;
}
void ObjectRepository::CreateObjects(Object root_object, clang::QualType type,
diff --git a/lifetime_analysis/object_repository.h b/lifetime_analysis/object_repository.h
index ec3d7bf..159503a 100644
--- a/lifetime_analysis/object_repository.h
+++ b/lifetime_analysis/object_repository.h
@@ -100,7 +100,8 @@
const Object* GetDeclObject(const clang::ValueDecl* decl) const;
// Returns the object associated with a materialize temporary expression.
- Object GetTemporaryObject(const clang::MaterializeTemporaryExpr* expr) const;
+ const Object* GetTemporaryObject(
+ const clang::MaterializeTemporaryExpr* expr) const;
// Returns the object representing the value of a function parameter at
// function entry.
@@ -110,26 +111,27 @@
// use this object's identity in any way; i.e. no other `Object` in the
// points-to map should ever point to the object returned by this
// function.
- Object GetOriginalParameterValue(const clang::ParmVarDecl* var_decl) const;
+ const Object* GetOriginalParameterValue(
+ const clang::ParmVarDecl* var_decl) const;
// Returns the object associated with an argument to a CallExpr.
- Object GetCallExprArgumentObject(const clang::CallExpr* expr,
- size_t arg_index) const;
+ const Object* GetCallExprArgumentObject(const clang::CallExpr* expr,
+ size_t arg_index) const;
// Returns the object associated with the `this` argument to a CallExpr that
// represents a method call. Note that this object represents the `this`
// pointer, not the object that the method is being called on.
- Object GetCallExprThisPointer(const clang::CallExpr* expr) const;
+ const Object* GetCallExprThisPointer(const clang::CallExpr* expr) const;
// Returns the object associated with an argument to a CXXConstructExpr.
- Object GetCXXConstructExprArgumentObject(const clang::CXXConstructExpr* expr,
- size_t arg_index) const;
+ const Object* GetCXXConstructExprArgumentObject(
+ const clang::CXXConstructExpr* expr, size_t arg_index) const;
// Returns the object associated with the `this` argument to a
// CXXConstructExpr. Note that this object represents the `this` pointer, not
// the object that the method is being called on (which is represnted by the
// object from GetInitializedObject()).
- Object GetCXXConstructExprThisPointer(
+ const Object* GetCXXConstructExprThisPointer(
const clang::CXXConstructExpr* expr) const;
// Returns the object associated with, and initialized by, a constructor call
@@ -137,19 +139,13 @@
// represents the actual class object being initialized, not the `this`
// pointer to it that is passed to methods of the class, and which is
// represented by the object from GetCXXConstructExprThisPointer().
- Object GetInitializedObject(const clang::Expr* initializer_expr) const;
+ const Object* GetInitializedObject(const clang::Expr* initializer_expr) const;
// Returns what kind of values the given object represents.
ObjectValueType GetObjectValueType(Object object) const;
// Returns the object that represents `*this`, if in a member function.
- std::optional<Object> GetThisObject() const {
- if (this_object_) {
- return **this_object_;
- } else {
- return std::nullopt;
- }
- }
+ std::optional<const Object*> GetThisObject() const { return this_object_; }
// Returns the `Object` associated with the return value of the function.
// Unlike the `Object`s for variables, the "return value object" is a fiction
@@ -157,7 +153,7 @@
// the return value, and it will not, in general, be possible to take the
// address of the return value object. It's still a useful fiction, however,
// because it allows us to treat return values the same way as other values.
- Object GetReturnObject() const { return *return_object_; }
+ const Object* GetReturnObject() const { return return_object_; }
// Returns the object associated with a given field in the struct
// represented by `struct_object`.
@@ -201,7 +197,7 @@
// returns the same object. This is to guarantee that the number of objects
// used in the analysis is bounded and that therefore the lattice is finite
// and the analysis terminates.
- Object CreateStaticObject(clang::QualType type);
+ const Object* CreateStaticObject(clang::QualType type);
private:
void CreateObjects(Object root_object, clang::QualType type,