[cfe-commits] r94851 - in /cfe/trunk: include/clang/Analysis/Analyses/PrintfFormatString.h lib/Analysis/PrintfFormatString.cpp
Ted Kremenek
kremenek at apple.com
Fri Jan 29 14:59:33 PST 2010
Author: kremenek
Date: Fri Jan 29 16:59:32 2010
New Revision: 94851
URL: http://llvm.org/viewvc/llvm-project?rev=94851&view=rev
Log:
Per a suggestion from Cristian Draghici, add a method to FormatSpecifier that returns the expected type of the matching data argument. It isn't complete, but should handle several of the important cases.
Modified:
cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h
cfe/trunk/lib/Analysis/PrintfFormatString.cpp
Modified: cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h?rev=94851&r1=94850&r2=94851&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h Fri Jan 29 16:59:32 2010
@@ -15,9 +15,12 @@
#ifndef LLVM_CLANG_FPRINTF_FORMAT_H
#define LLVM_CLANG_FPRINTF_FORMAT_H
-#include <cassert>
+#include "clang/AST/CanonicalType.h"
namespace clang {
+
+class ASTContext;
+
namespace analyze_printf {
class ConversionSpecifier {
@@ -147,24 +150,45 @@
HowSpecified hs;
unsigned amt;
};
+
+class ArgTypeResult {
+ enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy };
+ const Kind K;
+ QualType T;
+ ArgTypeResult(bool) : K(InvalidTy) {}
+public:
+ ArgTypeResult() : K(UnknownTy) {}
+ ArgTypeResult(QualType t) : K(SpecificTy), T(t) {}
+ ArgTypeResult(CanQualType t) : K(SpecificTy), T(t) {}
+
+ static ArgTypeResult Invalid() { return ArgTypeResult(true); }
+
+ bool isValid() const { return K != InvalidTy; }
+
+ const QualType *getSpecificType() const {
+ return K == SpecificTy ? &T : 0;
+ }
+
+ bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; };
+};
class FormatSpecifier {
- unsigned lengthModifier : 5;
+ LengthModifier LM;
unsigned flags : 5;
- ConversionSpecifier conversionSpecifier;
+ ConversionSpecifier CS;
OptionalAmount FieldWidth;
OptionalAmount Precision;
public:
- FormatSpecifier() : lengthModifier(0), flags(0) {}
+ FormatSpecifier() : LM(None), flags(0) {}
static FormatSpecifier Parse(const char *beg, const char *end);
// Methods for incrementally constructing the FormatSpecifier.
- void setConversionSpecifier(const ConversionSpecifier &CS) {
- conversionSpecifier = CS;
+ void setConversionSpecifier(const ConversionSpecifier &cs) {
+ CS = cs;
}
void setLengthModifier(LengthModifier lm) {
- lengthModifier = (unsigned) lm;
+ LM = lm;
}
void setIsLeftJustified() { flags |= LeftJustified; }
void setHasPlusPrefix() { flags |= PlusPrefix; }
@@ -175,11 +199,11 @@
// Methods for querying the format specifier.
const ConversionSpecifier &getConversionSpecifier() const {
- return conversionSpecifier;
+ return CS;
}
LengthModifier getLengthModifier() const {
- return (LengthModifier) lengthModifier;
+ return LM;
}
const OptionalAmount &getFieldWidth() const {
@@ -197,6 +221,13 @@
const OptionalAmount &getPrecision() const {
return Precision;
}
+
+ /// \brief Returns the builtin type that a data argument
+ /// paired with this format specifier should have. This method
+ /// will return null if the format specifier does not have
+ /// a matching data argument or the matching argument matches
+ /// more than one type.
+ ArgTypeResult getArgType(ASTContext &Ctx) const;
bool isLeftJustified() const { return flags & LeftJustified; }
bool hasPlusPrefix() const { return flags & PlusPrefix; }
Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=94851&r1=94850&r2=94851&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Fri Jan 29 16:59:32 2010
@@ -13,9 +13,11 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Analyses/PrintfFormatString.h"
+#include "clang/AST/ASTContext.h"
using clang::analyze_printf::FormatSpecifier;
using clang::analyze_printf::OptionalAmount;
+using clang::analyze_printf::ArgTypeResult;
using namespace clang;
namespace {
@@ -261,3 +263,54 @@
}
FormatStringHandler::~FormatStringHandler() {}
+
+//===----------------------------------------------------------------------===//
+// Methods on FormatSpecifier.
+//===----------------------------------------------------------------------===//
+
+ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const {
+ if (!CS.consumesDataArgument())
+ return ArgTypeResult::Invalid();
+
+ if (CS.isIntArg())
+ switch (LM) {
+ case AsLongDouble:
+ return ArgTypeResult::Invalid();
+ case None: return Ctx.IntTy;
+ case AsChar: return Ctx.SignedCharTy;
+ case AsShort: return Ctx.ShortTy;
+ case AsLong: return Ctx.LongTy;
+ case AsLongLong: return Ctx.LongLongTy;
+ case AsIntMax:
+ // FIXME: Return unknown for now.
+ return ArgTypeResult();
+ case AsSizeT: return Ctx.getSizeType();
+ case AsPtrDiff: return Ctx.getPointerDiffType();
+ }
+
+ if (CS.isUIntArg())
+ switch (LM) {
+ case AsLongDouble:
+ return ArgTypeResult::Invalid();
+ case None: return Ctx.UnsignedIntTy;
+ case AsChar: return Ctx.UnsignedCharTy;
+ case AsShort: return Ctx.UnsignedShortTy;
+ case AsLong: return Ctx.UnsignedLongTy;
+ case AsLongLong: return Ctx.UnsignedLongLongTy;
+ case AsIntMax:
+ // FIXME: Return unknown for now.
+ return ArgTypeResult();
+ case AsSizeT:
+ // FIXME: How to get the corresponding unsigned
+ // version of size_t?
+ return ArgTypeResult();
+ case AsPtrDiff:
+ // FIXME: How to get the corresponding unsigned
+ // version of ptrdiff_t?
+ return ArgTypeResult();
+ }
+
+ // FIXME: Handle other cases.
+ return ArgTypeResult();
+}
+
More information about the cfe-commits
mailing list