This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG6adfc64e709c: [clang][dataflow] Modify `optional` model to handle type aliases. (authored by ymandel).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D126972/new/ https://reviews.llvm.org/D126972 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 @@ -2214,6 +2214,23 @@ 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) Index: clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -43,13 +43,14 @@ 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 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 @@ 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)
Index: clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp =================================================================== --- clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp +++ clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp @@ -2214,6 +2214,23 @@ 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) Index: clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp =================================================================== --- clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -43,13 +43,14 @@ 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 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 @@ 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)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits