Author: kremenek Date: Wed Jun 16 16:23:04 2010 New Revision: 106151 URL: http://llvm.org/viewvc/llvm-project?rev=106151&view=rev Log: Extend format string type-checking to include '%p'. Fixes remaining cases PR 4468.
Modified: cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h cfe/trunk/lib/Analysis/PrintfFormatString.cpp cfe/trunk/test/Sema/format-strings-fixit.c cfe/trunk/test/Sema/format-strings.c cfe/trunk/test/SemaObjC/format-strings-objc.m 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=106151&r1=106150&r2=106151&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h (original) +++ cfe/trunk/include/clang/Analysis/Analyses/PrintfFormatString.h Wed Jun 16 16:23:04 2010 @@ -25,8 +25,8 @@ class ArgTypeResult { public: - enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CStrTy, - WCStrTy }; + enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy, + CStrTy, WCStrTy }; private: const Kind K; QualType T; Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=106151&r1=106150&r2=106151&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original) +++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Wed Jun 16 16:23:04 2010 @@ -39,7 +39,6 @@ const FormatSpecifier &fs) : FS(fs), Start(start), Stop(false) {} - const char *getStart() const { return Start; } bool shouldStop() const { return Stop; } bool hasValue() const { return Start != 0; } @@ -179,7 +178,6 @@ return false; } - static bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &FS, const char *Start, const char *&Beg, const char *E) { @@ -424,95 +422,111 @@ //===----------------------------------------------------------------------===// bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const { - assert(isValid()); - - if (K == UnknownTy) - return true; - - if (K == SpecificTy) { - argTy = C.getCanonicalType(argTy).getUnqualifiedType(); - - if (T == argTy) + switch (K) { + case InvalidTy: + assert(false && "ArgTypeResult must be valid"); return true; - if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) - switch (BT->getKind()) { - default: - break; - case BuiltinType::Char_S: - case BuiltinType::SChar: - return T == C.UnsignedCharTy; - case BuiltinType::Char_U: - case BuiltinType::UChar: - return T == C.SignedCharTy; - case BuiltinType::Short: - return T == C.UnsignedShortTy; - case BuiltinType::UShort: - return T == C.ShortTy; - case BuiltinType::Int: - return T == C.UnsignedIntTy; - case BuiltinType::UInt: - return T == C.IntTy; - case BuiltinType::Long: - return T == C.UnsignedLongTy; - case BuiltinType::ULong: - return T == C.LongTy; - case BuiltinType::LongLong: - return T == C.UnsignedLongLongTy; - case BuiltinType::ULongLong: - return T == C.LongLongTy; - } - - return false; - } + case UnknownTy: + return true; - if (K == CStrTy) { - const PointerType *PT = argTy->getAs<PointerType>(); - if (!PT) + case SpecificTy: { + argTy = C.getCanonicalType(argTy).getUnqualifiedType(); + if (T == argTy) + return true; + if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) + switch (BT->getKind()) { + default: + break; + case BuiltinType::Char_S: + case BuiltinType::SChar: + return T == C.UnsignedCharTy; + case BuiltinType::Char_U: + case BuiltinType::UChar: + return T == C.SignedCharTy; + case BuiltinType::Short: + return T == C.UnsignedShortTy; + case BuiltinType::UShort: + return T == C.ShortTy; + case BuiltinType::Int: + return T == C.UnsignedIntTy; + case BuiltinType::UInt: + return T == C.IntTy; + case BuiltinType::Long: + return T == C.UnsignedLongTy; + case BuiltinType::ULong: + return T == C.LongTy; + case BuiltinType::LongLong: + return T == C.UnsignedLongLongTy; + case BuiltinType::ULongLong: + return T == C.LongLongTy; + } return false; + } - QualType pointeeTy = PT->getPointeeType(); - - if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) - switch (BT->getKind()) { - case BuiltinType::Void: - case BuiltinType::Char_U: - case BuiltinType::UChar: - case BuiltinType::Char_S: - case BuiltinType::SChar: - return true; - default: - break; - } - - return false; - } + case CStrTy: { + const PointerType *PT = argTy->getAs<PointerType>(); + if (!PT) + return false; + QualType pointeeTy = PT->getPointeeType(); + if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) + switch (BT->getKind()) { + case BuiltinType::Void: + case BuiltinType::Char_U: + case BuiltinType::UChar: + case BuiltinType::Char_S: + case BuiltinType::SChar: + return true; + default: + break; + } - if (K == WCStrTy) { - const PointerType *PT = argTy->getAs<PointerType>(); - if (!PT) return false; + } - QualType pointeeTy = - C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); + case WCStrTy: { + const PointerType *PT = argTy->getAs<PointerType>(); + if (!PT) + return false; + QualType pointeeTy = + C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); + return pointeeTy == C.getWCharType(); + } - return pointeeTy == C.getWCharType(); + case CPointerTy: + return argTy->getAs<PointerType>() != NULL || + argTy->getAs<ObjCObjectPointerType>() != NULL; + + case ObjCPointerTy: + return argTy->getAs<ObjCObjectPointerType>() != NULL; } + // FIXME: Should be unreachable, but Clang is currently emitting + // a warning. return false; } QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const { - assert(isValid()); - if (K == SpecificTy) - return T; - if (K == CStrTy) - return C.getPointerType(C.CharTy); - if (K == WCStrTy) - return C.getPointerType(C.getWCharType()); - if (K == ObjCPointerTy) - return C.ObjCBuiltinIdTy; + switch (K) { + case InvalidTy: + assert(false && "No representative type for Invalid ArgTypeResult"); + // Fall-through. + case UnknownTy: + return QualType(); + case SpecificTy: + return T; + case CStrTy: + return C.getPointerType(C.CharTy); + case WCStrTy: + return C.getPointerType(C.getWCharType()); + case ObjCPointerTy: + return C.ObjCBuiltinIdTy; + case CPointerTy: + return C.VoidPtrTy; + } + // FIXME: Should be unreachable, but Clang is currently emitting + // a warning. return QualType(); } @@ -673,6 +687,8 @@ return ArgTypeResult::WCStrTy; case ConversionSpecifier::CArg: return Ctx.WCharTy; + case ConversionSpecifier::VoidPtrArg: + return ArgTypeResult::CPointerTy; default: break; } Modified: cfe/trunk/test/Sema/format-strings-fixit.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-fixit.c?rev=106151&r1=106150&r2=106151&view=diff ============================================================================== --- cfe/trunk/test/Sema/format-strings-fixit.c (original) +++ cfe/trunk/test/Sema/format-strings-fixit.c Wed Jun 16 16:23:04 2010 @@ -14,6 +14,7 @@ printf("%s", (int) 123); printf("abc%0f", "testing testing 123"); printf("%u", (long) -12); + printf("%p", 123); // Larger types printf("%+.2d", (unsigned long long) 123456); Modified: cfe/trunk/test/Sema/format-strings.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=106151&r1=106150&r2=106151&view=diff ============================================================================== --- cfe/trunk/test/Sema/format-strings.c (original) +++ cfe/trunk/test/Sema/format-strings.c Wed Jun 16 16:23:04 2010 @@ -176,6 +176,7 @@ void test11(void *p, char *s) { printf("%p", p); // no-warning + printf("%p", 123); // expected-warning{{conversion specifies type 'void *' but the argument has type 'int'}} printf("%.4p", p); // expected-warning{{precision used in 'p' conversion specifier (where it has no meaning)}} printf("%+p", p); // expected-warning{{flag '+' results in undefined behavior in 'p' conversion specifier}} printf("% p", p); // expected-warning{{flag ' ' results in undefined behavior in 'p' conversion specifier}} Modified: cfe/trunk/test/SemaObjC/format-strings-objc.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/format-strings-objc.m?rev=106151&r1=106150&r2=106151&view=diff ============================================================================== --- cfe/trunk/test/SemaObjC/format-strings-objc.m (original) +++ cfe/trunk/test/SemaObjC/format-strings-objc.m Wed Jun 16 16:23:04 2010 @@ -55,3 +55,11 @@ void rdar_7697748() { NSLog(@"%...@!"); // expected-warning{{more '%' conversions than data arguments}} } + +...@protocol Foo; + +void test_p_conversion_with_objc_pointer(id x, id<Foo> y) { + printf("%p", x); // no-warning + printf("%p", y); // no-warning +} + _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits