-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[FlowSensitive] Allow callback to initialize storagelocations #164675
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/fmayer/spr/main.flowsensitive-allow-callback-to-initialize-storagelocations
Are you sure you want to change the base?
Conversation
Created using spr 1.3.7
|
@llvm/pr-subscribers-clang-analysis @llvm/pr-subscribers-clang Author: Florian Mayer (fmayer) ChangesThis is useful to make sure that a newly created StorageLocation always Full diff: https://github.com/llvm/llvm-project/pull/164675.diff 2 Files Affected:
diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
index 11042e865c4e6..57dfabaa16212 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -111,6 +111,12 @@ class DataflowAnalysisContext {
SyntheticFieldCallback = CB;
}
+ void setInitializerCallback(
+ std::function<void(QualType, StorageLocation&)> CB) {
+ assert(!RecordStorageLocationCreated);
+ InitializerCallback = CB;
+ }
+
/// Returns a new storage location appropriate for `Type`.
///
/// A null `Type` is interpreted as the pointee type of `std::nullptr_t`.
@@ -332,6 +338,7 @@ class DataflowAnalysisContext {
std::unique_ptr<Logger> LogOwner; // If created via flags.
std::function<llvm::StringMap<QualType>(QualType)> SyntheticFieldCallback;
+ std::optional<std::function<void(QualType, StorageLocation&)>> InitializerCallback;
/// Has any `RecordStorageLocation` been created yet?
bool RecordStorageLocationCreated = false;
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
index 4196d6821c184..1b1b41f1f3160 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -59,6 +59,7 @@ void DataflowAnalysisContext::addModeledFields(const FieldSet &Fields) {
}
StorageLocation &DataflowAnalysisContext::createStorageLocation(QualType Type) {
+ StorageLocation *S;
if (!Type.isNull() && Type->isRecordType()) {
llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs;
for (const FieldDecl *Field : getModeledFields(Type))
@@ -74,10 +75,14 @@ StorageLocation &DataflowAnalysisContext::createStorageLocation(QualType Type) {
{Entry.getKey(),
&createStorageLocation(Entry.getValue().getNonReferenceType())});
- return createRecordStorageLocation(Type, std::move(FieldLocs),
+ S = &createRecordStorageLocation(Type, std::move(FieldLocs),
std::move(SyntheticFields));
+ } else {
+ S = &arena().create<ScalarStorageLocation>(Type);
}
- return arena().create<ScalarStorageLocation>(Type);
+ if (InitializerCallback)
+ (*InitializerCallback)(Type, *S);
+ return *S;
}
// Returns the keys for a given `StringMap`.
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions h,cpp -- clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
index 57dfabaa1..af9421060 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -111,8 +111,8 @@ public:
SyntheticFieldCallback = CB;
}
- void setInitializerCallback(
- std::function<void(QualType, StorageLocation&)> CB) {
+ void
+ setInitializerCallback(std::function<void(QualType, StorageLocation &)> CB) {
assert(!RecordStorageLocationCreated);
InitializerCallback = CB;
}
@@ -338,7 +338,8 @@ private:
std::unique_ptr<Logger> LogOwner; // If created via flags.
std::function<llvm::StringMap<QualType>(QualType)> SyntheticFieldCallback;
- std::optional<std::function<void(QualType, StorageLocation&)>> InitializerCallback;
+ std::optional<std::function<void(QualType, StorageLocation &)>>
+ InitializerCallback;
/// Has any `RecordStorageLocation` been created yet?
bool RecordStorageLocationCreated = false;
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
index 1b1b41f1f..e161f9689 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -76,7 +76,7 @@ StorageLocation &DataflowAnalysisContext::createStorageLocation(QualType Type) {
&createStorageLocation(Entry.getValue().getNonReferenceType())});
S = &createRecordStorageLocation(Type, std::move(FieldLocs),
- std::move(SyntheticFields));
+ std::move(SyntheticFields));
} else {
S = &arena().create<ScalarStorageLocation>(Type);
}
|
This is useful to make sure that a newly created StorageLocation always
has e.g. an uninitialized boolean.