ymandel created this revision. ymandel added reviewers: xazax.hun, gribozavr2. Herald added subscribers: martong, rnkovacs. Herald added a reviewer: NoQ. Herald added a project: All. ymandel requested review of this revision. Herald added a project: clang.
Currently, the checker only recognizes the nullopt constructor when it is called without sugar, resulting in a crash in the (rare) case where it has been wrapped in sugar. This relaxes the constraint by checking the constructor decl directly (which always contains the same, desugared form) rather than the construct expression (where the spelling depends on the context). Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D140921 Files: clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp Index: clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp +++ clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp @@ -1498,6 +1498,23 @@ )"); } +TEST_P(UncheckedOptionalAccessTest, NulloptConstructorWithSugaredType) { + ExpectDiagnosticsFor( + R"( + #include "unchecked_optional_access_test.h" + template <typename T> + using wrapper = T; + + template <typename T> + wrapper<T> wrap(T); + + void target() { + $ns::$optional<int> opt(wrap($ns::nullopt)); + opt.value(); // [[unsafe]] + } + )"); +} + TEST_P(UncheckedOptionalAccessTest, InPlaceConstructor) { ExpectDiagnosticsFor(R"( #include "unchecked_optional_access_test.h" Index: clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -22,6 +22,7 @@ #include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/NoopLattice.h" +#include "clang/Analysis/FlowSensitive/StorageLocation.h" #include "clang/Analysis/FlowSensitive/Value.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/StringRef.h" @@ -100,8 +101,10 @@ } auto isOptionalNulloptConstructor() { - return cxxConstructExpr(hasOptionalType(), argumentCountIs(1), - hasArgument(0, hasNulloptType())); + return cxxConstructExpr( + hasOptionalType(), + hasDeclaration(cxxConstructorDecl(parameterCountIs(1), + hasParameter(0, hasNulloptType())))); } auto isOptionalInPlaceConstructor() {
Index: clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp +++ clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp @@ -1498,6 +1498,23 @@ )"); } +TEST_P(UncheckedOptionalAccessTest, NulloptConstructorWithSugaredType) { + ExpectDiagnosticsFor( + R"( + #include "unchecked_optional_access_test.h" + template <typename T> + using wrapper = T; + + template <typename T> + wrapper<T> wrap(T); + + void target() { + $ns::$optional<int> opt(wrap($ns::nullopt)); + opt.value(); // [[unsafe]] + } + )"); +} + TEST_P(UncheckedOptionalAccessTest, InPlaceConstructor) { ExpectDiagnosticsFor(R"( #include "unchecked_optional_access_test.h" Index: clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -22,6 +22,7 @@ #include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/NoopLattice.h" +#include "clang/Analysis/FlowSensitive/StorageLocation.h" #include "clang/Analysis/FlowSensitive/Value.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/StringRef.h" @@ -100,8 +101,10 @@ } auto isOptionalNulloptConstructor() { - return cxxConstructExpr(hasOptionalType(), argumentCountIs(1), - hasArgument(0, hasNulloptType())); + return cxxConstructExpr( + hasOptionalType(), + hasDeclaration(cxxConstructorDecl(parameterCountIs(1), + hasParameter(0, hasNulloptType())))); } auto isOptionalInPlaceConstructor() {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits