diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp index 07ec16c9cc6ef..10b9866d5c23c 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ b/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 inPlaceClass() { } auto isOptionalNulloptConstructor() { - return cxxConstructExpr(hasOptionalType(), argumentCountIs(1), - hasArgument(0, hasNulloptType())); + return cxxConstructExpr( + hasOptionalType(), + hasDeclaration(cxxConstructorDecl(parameterCountIs(1), + hasParameter(0, hasNulloptType())))); } auto isOptionalInPlaceConstructor() { @@ -452,6 +455,7 @@ void assignOptionalValue(const Expr &E, Environment &Env, BoolValue &valueOrConversionHasValue(const FunctionDecl &F, const Expr &E, const MatchFinder::MatchResult &MatchRes, LatticeTransferState &State) { + assert(F.getTemplateSpecializationArgs() != nullptr); assert(F.getTemplateSpecializationArgs()->size() > 0); const int TemplateParamOptionalWrappersCount = countOptionalWrappers( diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp index 1fcede5d62865..2d108e8d24832 100644 --- a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp @@ -1498,6 +1498,23 @@ TEST_P(UncheckedOptionalAccessTest, NulloptConstructor) { )"); } +TEST_P(UncheckedOptionalAccessTest, NulloptConstructorWithSugaredType) { + ExpectDiagnosticsFor( + R"( + #include "unchecked_optional_access_test.h" + template + using wrapper = T; + + template + wrapper wrap(T); + + void target() { + $ns::$optional opt(wrap($ns::nullopt)); + opt.value(); // [[unsafe]] + } + )"); +} + TEST_P(UncheckedOptionalAccessTest, InPlaceConstructor) { ExpectDiagnosticsFor(R"( #include "unchecked_optional_access_test.h"