[clang] 6adfc64 - [clang][dataflow] Modify `optional` model to handle type aliases.
Yitzhak Mandelbaum via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 3 12:01:12 PDT 2022
Author: Yitzhak Mandelbaum
Date: 2022-06-03T18:57:43Z
New Revision: 6adfc64e709cc8b7b7a06b0e9afc60f6903f3cab
URL: https://github.com/llvm/llvm-project/commit/6adfc64e709cc8b7b7a06b0e9afc60f6903f3cab
DIFF: https://github.com/llvm/llvm-project/commit/6adfc64e709cc8b7b7a06b0e9afc60f6903f3cab.diff
LOG: [clang][dataflow] Modify `optional` model to handle type aliases.
Previously, type aliases were not handled (and resulted in an assertion
firing). This patch generalizes the model to consider aliases everywhere (a
previous patch already considered aliases for optional-returning functions).
Differential Revision: https://reviews.llvm.org/D126972
Added:
Modified:
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
index 22a33c397a644..02cf2c75579ff 100644
--- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
@@ -43,13 +43,14 @@ DeclarationMatcher optionalClass() {
hasTemplateArgument(0, refersToType(type().bind("T"))));
}
-auto hasOptionalType() { return hasType(optionalClass()); }
-
-auto hasOptionalOrAliasType() {
+auto optionalOrAliasType() {
return hasUnqualifiedDesugaredType(
recordType(hasDeclaration(optionalClass())));
}
+/// Matches any of the spellings of the optional types and sugar, aliases, etc.
+auto hasOptionalType() { return hasType(optionalOrAliasType()); }
+
auto isOptionalMemberCallWithName(
llvm::StringRef MemberName,
llvm::Optional<StatementMatcher> Ignorable = llvm::None) {
@@ -164,9 +165,8 @@ auto isValueOrNotEqX() {
}
auto isCallReturningOptional() {
- return callExpr(callee(functionDecl(
- returns(anyOf(hasOptionalOrAliasType(),
- referenceType(pointee(hasOptionalOrAliasType())))))));
+ return callExpr(callee(functionDecl(returns(anyOf(
+ optionalOrAliasType(), referenceType(pointee(optionalOrAliasType())))))));
}
/// Creates a symbolic value for an `optional` value using `HasValueVal` as the
@@ -485,8 +485,9 @@ auto buildTransferMatchSwitch(
return MatchSwitchBuilder<LatticeTransferState>()
// Attach a symbolic "has_value" state to optional values that we see for
// the first time.
- .CaseOf<Expr>(expr(anyOf(declRefExpr(), memberExpr()), hasOptionalType()),
- initializeOptionalReference)
+ .CaseOf<Expr>(
+ expr(anyOf(declRefExpr(), memberExpr()), hasOptionalType()),
+ initializeOptionalReference)
// make_optional
.CaseOf<CallExpr>(isMakeOptionalCall(), transferMakeOptionalCall)
diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp
index a4ea2bf5e5abc..c83cf49567c1d 100644
--- a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp
@@ -2214,6 +2214,23 @@ TEST_P(UncheckedOptionalAccessTest, CallReturningOptional) {
UnorderedElementsAre(Pair("check-4", "unsafe: input.cc:10:7")));
}
+// Verifies that the model sees through aliases.
+TEST_P(UncheckedOptionalAccessTest, WithAlias) {
+ ExpectLatticeChecksFor(
+ R"(
+ #include "unchecked_optional_access_test.h"
+
+ template <typename T>
+ using MyOptional = $ns::$optional<T>;
+
+ void target(MyOptional<int> opt) {
+ opt.value();
+ /*[[check]]*/
+ }
+ )",
+ UnorderedElementsAre(Pair("check", "unsafe: input.cc:8:7")));
+}
+
// FIXME: Add support for:
// - constructors (copy, move)
// - assignment operators (default, copy, move)
More information about the cfe-commits
mailing list