[cfe-commits] r56639 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Sema/SemaDeclAttr.cpp test/SemaObjC/format-strings-objc.m
Daniel Dunbar
daniel at zuster.org
Thu Sep 25 20:33:00 PDT 2008
Author: ddunbar
Date: Thu Sep 25 22:32:58 2008
New Revision: 56639
URL: http://llvm.org/viewvc/llvm-project?rev=56639&view=rev
Log:
Add support for CFString in format attribute.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/SemaObjC/format-strings-objc.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=56639&r1=56638&r2=56639&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Thu Sep 25 22:32:58 2008
@@ -658,10 +658,8 @@
"strftime format attribute requires 3rd parameter to be 0")
DIAG(err_format_attribute_requires_variadic, ERROR,
"format attribute requires variadic function")
-DIAG(err_format_attribute_not_string, ERROR,
- "format argument not a string type")
-DIAG(err_format_attribute_not_NSString, ERROR,
- "format argument is not an NSString")
+DIAG(err_format_attribute_not, ERROR,
+ "format argument not %0")
DIAG(err_attribute_invalid_size, ERROR,
"vector size not an integral multiple of component size")
DIAG(err_attribute_zero_size, ERROR,
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=56639&r1=56638&r2=56639&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Sep 25 22:32:58 2008
@@ -61,6 +61,22 @@
ClsName == &Ctx.Idents.get("NSMutableString");
}
+static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
+ const PointerType *PT = T->getAsPointerType();
+ if (!PT)
+ return false;
+
+ const RecordType *RT = PT->getPointeeType()->getAsRecordType();
+ if (!RT)
+ return false;
+
+ const RecordDecl *RD = RT->getDecl();
+ if (RD->getTagKind() != TagDecl::TK_struct)
+ return false;
+
+ return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
+}
+
//===----------------------------------------------------------------------===//
// Attribute Implementations
//===----------------------------------------------------------------------===//
@@ -648,6 +664,7 @@
bool Supported = false;
bool is_NSString = false;
bool is_strftime = false;
+ bool is_CFString = false;
switch (FormatLen) {
default: break;
@@ -655,8 +672,9 @@
case 6: Supported = !memcmp(Format, "printf", 6); break;
case 7: Supported = !memcmp(Format, "strfmon", 7); break;
case 8:
- Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
- (is_NSString = !memcmp(Format, "NSString", 8));
+ Supported = (is_strftime = !memcmp(Format, "strftime", 8)) ||
+ (is_NSString = !memcmp(Format, "NSString", 8)) ||
+ (is_CFString = !memcmp(Format, "CFString", 8));
break;
}
@@ -687,22 +705,28 @@
// make sure the format string is really a string
QualType Ty = proto->getArgType(ArgIdx);
- if (is_NSString) {
+ if (is_CFString) {
+ if (!isCFStringType(Ty, S.Context)) {
+ S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
+ "a CFString", IdxExpr->getSourceRange());
+ return;
+ }
+ } else if (is_NSString) {
// FIXME: do we need to check if the type is NSString*? What are
// the semantics?
if (!isNSStringType(Ty, S.Context)) {
// FIXME: Should highlight the actual expression that has the
// wrong type.
- S.Diag(Attr.getLoc(), diag::err_format_attribute_not_NSString,
- IdxExpr->getSourceRange());
+ S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
+ "an NSString", IdxExpr->getSourceRange());
return;
}
} else if (!Ty->isPointerType() ||
!Ty->getAsPointerType()->getPointeeType()->isCharType()) {
// FIXME: Should highlight the actual expression that has the
// wrong type.
- S.Diag(Attr.getLoc(), diag::err_format_attribute_not_string,
- IdxExpr->getSourceRange());
+ S.Diag(Attr.getLoc(), diag::err_format_attribute_not,
+ "a string type", IdxExpr->getSourceRange());
return;
}
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=56639&r1=56638&r2=56639&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/format-strings-objc.m (original)
+++ cfe/trunk/test/SemaObjC/format-strings-objc.m Thu Sep 25 22:32:58 2008
@@ -26,6 +26,9 @@
@interface NSConstantString : NSSimpleCString @end
extern void *_NSConstantStringClassReference;
+typedef const struct __CFString * CFStringRef;
+extern void CFStringCreateWithFormat(CFStringRef format, ...) __attribute__((format(CFString, 1, 2)));
+
//===----------------------------------------------------------------------===//
// Test cases.
//===----------------------------------------------------------------------===//
@@ -34,3 +37,7 @@
NSLog(@"%d%%", k); // no-warning
NSLog(@"%s%lb%d", "unix", 10,20); // expected-warning {{lid conversion '%lb'}}
}
+
+// Check type validation
+extern void NSLog2(int format, ...) __attribute__((format(__NSString__, 1, 2))); // expected-error {{format argument not an NSString}}
+extern void CFStringCreateWithFormat2(int *format, ...) __attribute__((format(CFString, 1, 2))); // expected-error {{format argument not a CFString}}
More information about the cfe-commits
mailing list