This revision was automatically updated to reflect the committed changes. Closed by commit rL371256: [analyzer] pr43179: Make CallDescription defensive against C variadic functions. (authored by dergachev, committed by ). Herald added a project: LLVM. Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D67019?vs=218160&id=219169#toc Repository: rL LLVM CHANGES SINCE LAST ACTION https://reviews.llvm.org/D67019/new/ https://reviews.llvm.org/D67019 Files: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp cfe/trunk/test/Analysis/cast-value-weird.cpp Index: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -368,7 +368,8 @@ if (CD.Flags & CDF_MaybeBuiltin) { return CheckerContext::isCLibraryFunction(FD, CD.getFunctionName()) && - (!CD.RequiredArgs || CD.RequiredArgs <= getNumArgs()); + (!CD.RequiredArgs || CD.RequiredArgs <= getNumArgs()) && + (!CD.RequiredParams || CD.RequiredParams <= parameters().size()); } if (!CD.IsLookupDone) { @@ -407,7 +408,8 @@ return false; } - return (!CD.RequiredArgs || CD.RequiredArgs == getNumArgs()); + return (!CD.RequiredArgs || CD.RequiredArgs == getNumArgs()) && + (!CD.RequiredParams || CD.RequiredParams == parameters().size()); } SVal CallEvent::getArgSVal(unsigned Index) const { Index: cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -116,7 +116,9 @@ // vswprintf is the wide version of vsnprintf, // vsprintf has no wide version {{"vswscanf", 3}, 2}}; -const CallDescription ValistChecker::VaStart("__builtin_va_start", 2), + +const CallDescription + ValistChecker::VaStart("__builtin_va_start", /*Args=*/2, /*Params=*/1), ValistChecker::VaCopy("__builtin_va_copy", 2), ValistChecker::VaEnd("__builtin_va_end", 1); } // end anonymous namespace Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -1064,8 +1064,19 @@ // e.g. "{a, b}" represent the qualified names, like "a::b". std::vector<const char *> QualifiedName; Optional<unsigned> RequiredArgs; + Optional<size_t> RequiredParams; int Flags; + // A constructor helper. + static Optional<size_t> readRequiredParams(Optional<unsigned> RequiredArgs, + Optional<size_t> RequiredParams) { + if (RequiredParams) + return RequiredParams; + if (RequiredArgs) + return static_cast<size_t>(*RequiredArgs); + return None; + } + public: /// Constructs a CallDescription object. /// @@ -1078,14 +1089,17 @@ /// call. Omit this parameter to match every occurrence of call with a given /// name regardless the number of arguments. CallDescription(int Flags, ArrayRef<const char *> QualifiedName, - Optional<unsigned> RequiredArgs = None) + Optional<unsigned> RequiredArgs = None, + Optional<size_t> RequiredParams = None) : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs), + RequiredParams(readRequiredParams(RequiredArgs, RequiredParams)), Flags(Flags) {} /// Construct a CallDescription with default flags. CallDescription(ArrayRef<const char *> QualifiedName, - Optional<unsigned> RequiredArgs = None) - : CallDescription(0, QualifiedName, RequiredArgs) {} + Optional<unsigned> RequiredArgs = None, + Optional<size_t> RequiredParams = None) + : CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {} /// Get the name of the function that this object matches. StringRef getFunctionName() const { return QualifiedName.back(); } Index: cfe/trunk/test/Analysis/cast-value-weird.cpp =================================================================== --- cfe/trunk/test/Analysis/cast-value-weird.cpp +++ cfe/trunk/test/Analysis/cast-value-weird.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,apiModeling -verify %s + +// expected-no-diagnostics + +namespace llvm { +template <typename> +void cast(...); +void a() { cast<int>(int()); } // no-crash +} // namespace llvm
Index: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -368,7 +368,8 @@ if (CD.Flags & CDF_MaybeBuiltin) { return CheckerContext::isCLibraryFunction(FD, CD.getFunctionName()) && - (!CD.RequiredArgs || CD.RequiredArgs <= getNumArgs()); + (!CD.RequiredArgs || CD.RequiredArgs <= getNumArgs()) && + (!CD.RequiredParams || CD.RequiredParams <= parameters().size()); } if (!CD.IsLookupDone) { @@ -407,7 +408,8 @@ return false; } - return (!CD.RequiredArgs || CD.RequiredArgs == getNumArgs()); + return (!CD.RequiredArgs || CD.RequiredArgs == getNumArgs()) && + (!CD.RequiredParams || CD.RequiredParams == parameters().size()); } SVal CallEvent::getArgSVal(unsigned Index) const { Index: cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/ValistChecker.cpp @@ -116,7 +116,9 @@ // vswprintf is the wide version of vsnprintf, // vsprintf has no wide version {{"vswscanf", 3}, 2}}; -const CallDescription ValistChecker::VaStart("__builtin_va_start", 2), + +const CallDescription + ValistChecker::VaStart("__builtin_va_start", /*Args=*/2, /*Params=*/1), ValistChecker::VaCopy("__builtin_va_copy", 2), ValistChecker::VaEnd("__builtin_va_end", 1); } // end anonymous namespace Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -1064,8 +1064,19 @@ // e.g. "{a, b}" represent the qualified names, like "a::b". std::vector<const char *> QualifiedName; Optional<unsigned> RequiredArgs; + Optional<size_t> RequiredParams; int Flags; + // A constructor helper. + static Optional<size_t> readRequiredParams(Optional<unsigned> RequiredArgs, + Optional<size_t> RequiredParams) { + if (RequiredParams) + return RequiredParams; + if (RequiredArgs) + return static_cast<size_t>(*RequiredArgs); + return None; + } + public: /// Constructs a CallDescription object. /// @@ -1078,14 +1089,17 @@ /// call. Omit this parameter to match every occurrence of call with a given /// name regardless the number of arguments. CallDescription(int Flags, ArrayRef<const char *> QualifiedName, - Optional<unsigned> RequiredArgs = None) + Optional<unsigned> RequiredArgs = None, + Optional<size_t> RequiredParams = None) : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs), + RequiredParams(readRequiredParams(RequiredArgs, RequiredParams)), Flags(Flags) {} /// Construct a CallDescription with default flags. CallDescription(ArrayRef<const char *> QualifiedName, - Optional<unsigned> RequiredArgs = None) - : CallDescription(0, QualifiedName, RequiredArgs) {} + Optional<unsigned> RequiredArgs = None, + Optional<size_t> RequiredParams = None) + : CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {} /// Get the name of the function that this object matches. StringRef getFunctionName() const { return QualifiedName.back(); } Index: cfe/trunk/test/Analysis/cast-value-weird.cpp =================================================================== --- cfe/trunk/test/Analysis/cast-value-weird.cpp +++ cfe/trunk/test/Analysis/cast-value-weird.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,apiModeling -verify %s + +// expected-no-diagnostics + +namespace llvm { +template <typename> +void cast(...); +void a() { cast<int>(int()); } // no-crash +} // namespace llvm
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits