Skip to content

Commit 14bc11a

Browse files
jcsxkyhuqizhi
and
huqizhi
authored
[clang][dataflow]Use cast_or_null instead of cast to prevent crash (#68510)
`getStorageLocation` may return `nullptr` and this will produce crash when use `cast`, use `dyn_cast_or_null` instead. I test it locally using [FTXUI](https://github.com/ArthurSonzogni/FTXUI) and it may be the cause of issue [issue](#68412), but I am not sure. Co-authored-by: huqizhi <huqizhi@[email protected]>
1 parent bdc3e6c commit 14bc11a

File tree

5 files changed

+45
-1
lines changed

5 files changed

+45
-1
lines changed

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ Changes in existing checks
219219
<clang-tidy/checks/bugprone/reserved-identifier>` check, so that it does not
220220
warn on macros starting with underscore and lowercase letter.
221221

222+
- Improved :doc:`bugprone-unchecked-optional-access
223+
<clang-tidy/checks/bugprone/unchecked-optional-access>` check, so that it does
224+
not crash during handling of optional values.
225+
222226
- Improved :doc:`bugprone-undefined-memory-manipulation
223227
<clang-tidy/checks/bugprone/undefined-memory-manipulation>` check to support
224228
fixed-size arrays of non-trivial types.

clang-tools-extra/test/clang-tidy/checkers/bugprone/Inputs/unchecked-optional-access/absl/types/optional.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class optional {
6666
void reset() noexcept;
6767

6868
void swap(optional &rhs) noexcept;
69+
70+
template <typename U> optional &operator=(const U &u);
6971
};
7072

7173
} // namespace absl

clang-tools-extra/test/clang-tidy/checkers/bugprone/unchecked-optional-access.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,23 @@ void std_forward_rvalue_ref_safe(absl::optional<int>&& opt) {
180180

181181
std::forward<absl::optional<int>>(opt).value();
182182
}
183+
184+
namespace std {
185+
186+
template <typename T> class vector {
187+
public:
188+
T &operator[](unsigned long index);
189+
bool empty();
190+
};
191+
192+
} // namespace std
193+
194+
struct S {
195+
absl::optional<float> x;
196+
};
197+
std::vector<S> vec;
198+
199+
void foo() {
200+
if (!vec.empty())
201+
vec[0].x = 0;
202+
}

clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ void transferAssignment(const CXXOperatorCallExpr *E, BoolValue &HasValueVal,
599599
LatticeTransferState &State) {
600600
assert(E->getNumArgs() > 0);
601601

602-
if (auto *Loc = cast<RecordStorageLocation>(
602+
if (auto *Loc = cast_or_null<RecordStorageLocation>(
603603
State.Env.getStorageLocation(*E->getArg(0)))) {
604604
createOptionalValue(*Loc, HasValueVal, State.Env);
605605

clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,24 @@ TEST_P(UncheckedOptionalAccessTest, OptionalSwap) {
21312131
)");
21322132
}
21332133

2134+
TEST_P(UncheckedOptionalAccessTest, OptionalReturnedFromFuntionCall) {
2135+
ExpectDiagnosticsFor(
2136+
R"(
2137+
#include "unchecked_optional_access_test.h"
2138+
2139+
struct S {
2140+
$ns::$optional<float> x;
2141+
} s;
2142+
S getOptional() {
2143+
return s;
2144+
}
2145+
2146+
void target() {
2147+
getOptional().x = 0;
2148+
}
2149+
)");
2150+
}
2151+
21342152
TEST_P(UncheckedOptionalAccessTest, StdSwap) {
21352153
ExpectDiagnosticsFor(
21362154
R"(

0 commit comments

Comments
 (0)