Skip to content

Commit 39851e3

Browse files
authored
[clang][dataflow] Add a test demonstrating an issue in unchecked-optional-access-check (#110870)
createStorageLocation used in transferCallReturningOptional: https://github.com/llvm/llvm-project/blob/09ba83be0ac178851e3c9c9c8fefddbdd4d8353f/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp#L515 can stop recursively creating storage locations when it hits a field of reference type for a non-optional record: https://github.com/llvm/llvm-project/blob/3ca5d8082a0c6bd9520544ce3bca11bf3e02a5fa/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp#L67 If an optional is reached through that field then it may not have a storage location by the type we handle has_value in a transfer function.
1 parent 3a6b895 commit 39851e3

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2873,6 +2873,40 @@ TEST_P(UncheckedOptionalAccessTest, OptionalValueStruct) {
28732873
)");
28742874
}
28752875

2876+
// FIXME: A case that we should handle but currently don't.
2877+
// When there is a field of type reference to non-optional, we may
2878+
// stop recursively creating storage locations.
2879+
// E.g., the field `second` below in `pair` should eventually lead to
2880+
// the optional `x` in `A`.
2881+
TEST_P(UncheckedOptionalAccessTest, NestedOptionalThroughNonOptionalRefField) {
2882+
ExpectDiagnosticsFor(R"(
2883+
#include "unchecked_optional_access_test.h"
2884+
2885+
struct A {
2886+
$ns::$optional<int> x;
2887+
};
2888+
2889+
struct pair {
2890+
int first;
2891+
const A &second;
2892+
};
2893+
2894+
struct B {
2895+
$ns::$optional<pair>& nonConstGetRef();
2896+
};
2897+
2898+
void target(B b) {
2899+
const auto& maybe_pair = b.nonConstGetRef();
2900+
if (!maybe_pair.has_value())
2901+
return;
2902+
2903+
if(!maybe_pair->second.x.has_value())
2904+
return;
2905+
maybe_pair->second.x.value(); // [[unsafe]]
2906+
}
2907+
)");
2908+
}
2909+
28762910
TEST_P(UncheckedOptionalAccessTest, OptionalValueInitialization) {
28772911
ExpectDiagnosticsFor(
28782912
R"(

0 commit comments

Comments
 (0)