aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Analysis/Analyses
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2011-12-10 13:20:11 +0000
committerHans Wennborg <hans@hanshq.net>2011-12-10 13:20:11 +0000
commit6fcd932dfd6835f70cc00d6f7c6789793f6d7b66 (patch)
tree2ee0188182bc788b5a2ad7707914e8850c36ac83 /include/clang/Analysis/Analyses
parente7edf30143e565574c9bed0f1dbeaa47bb9a0891 (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.h33
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);
};