Author: Yitzhak Mandelbaum Date: 2022-06-03T18:57:43Z New Revision: 6adfc64e709cc8b7b7a06b0e9afc60f6903f3cab
URL: https://github.com/llvm/llvm-project/commit/6adfc64e709cc8b7b7a06b0e9afc60f6903f3cab DIFF: https://github.com/llvm/llvm-project/commit/6adfc64e709cc8b7b7a06b0e9afc60f6903f3cab.diff LOG: [clang][dataflow] Modify `optional` model to handle type aliases. Previously, type aliases were not handled (and resulted in an assertion firing). This patch generalizes the model to consider aliases everywhere (a previous patch already considered aliases for optional-returning functions). Differential Revision: https://reviews.llvm.org/D126972 Added: Modified: clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp index 22a33c397a644..02cf2c75579ff 100644 --- a/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp +++ b/clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp @@ -43,13 +43,14 @@ DeclarationMatcher optionalClass() { 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 isValueOrNotEqX() { } 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 @@ auto buildTransferMatchSwitch( 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) diff --git a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp index a4ea2bf5e5abc..c83cf49567c1d 100644 --- a/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp @@ -2214,6 +2214,23 @@ TEST_P(UncheckedOptionalAccessTest, CallReturningOptional) { 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) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits