diff options
author | Hans Wennborg <hans@hanshq.net> | 2011-12-10 13:20:11 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2011-12-10 13:20:11 +0000 |
commit | 6fcd932dfd6835f70cc00d6f7c6789793f6d7b66 (patch) | |
tree | 2ee0188182bc788b5a2ad7707914e8850c36ac83 /include/clang/Analysis/Analyses | |
parent | e7edf30143e565574c9bed0f1dbeaa47bb9a0891 (diff) |
Check that arguments to a scanf call match the format specifier,
and offer fixits when there is a mismatch.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146326 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Analysis/Analyses')
-rw-r--r-- | include/clang/Analysis/Analyses/FormatString.h | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h index 2edbc8c296..f84ca988ec 100644 --- a/include/clang/Analysis/Analyses/FormatString.h +++ b/include/clang/Analysis/Analyses/FormatString.h @@ -185,6 +185,7 @@ public: return EndScanList ? EndScanList - Position : 1; } + bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } const char *toString() const; bool isPrintfKind() const { return IsPrintf; } @@ -364,7 +365,6 @@ public: bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; } bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; } - bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgBeg; } unsigned getLength() const { @@ -506,10 +506,35 @@ public: } }; +using analyze_format_string::ArgTypeResult; using analyze_format_string::LengthModifier; using analyze_format_string::OptionalAmount; using analyze_format_string::OptionalFlag; +class ScanfArgTypeResult : public ArgTypeResult { +public: + enum Kind { UnknownTy, InvalidTy, CStrTy, WCStrTy, PtrToArgTypeResultTy }; +private: + Kind K; + ArgTypeResult A; + const char *Name; + QualType getRepresentativeType(ASTContext &C) const; +public: + ScanfArgTypeResult(Kind k = UnknownTy, const char* n = 0) : K(k), Name(n) {} + ScanfArgTypeResult(ArgTypeResult a, const char *n = 0) + : K(PtrToArgTypeResultTy), A(a), Name(n) { + assert(A.isValid()); + } + + static ScanfArgTypeResult Invalid() { return ScanfArgTypeResult(InvalidTy); } + + bool isValid() const { return K != InvalidTy; } + + bool matchesType(ASTContext& C, QualType argTy) const; + + std::string getRepresentativeTypeName(ASTContext& C) const; +}; + class ScanfSpecifier : public analyze_format_string::FormatSpecifier { OptionalFlag SuppressAssignment; // '*' public: @@ -538,6 +563,12 @@ public: return CS.consumesDataArgument() && !SuppressAssignment; } + ScanfArgTypeResult getArgType(ASTContext &Ctx) const; + + bool fixType(QualType QT, const LangOptions &LangOpt); + + void toString(raw_ostream &os) const; + static ScanfSpecifier Parse(const char *beg, const char *end); }; |