diff options
author | Anders Carlsson <andersca@mac.com> | 2007-08-17 05:31:46 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2007-08-17 05:31:46 +0000 |
commit | 71993dd85eed9cc42c6b2fa61ee5c53026b74817 (patch) | |
tree | 7ea699f260c230851800667074e5f56565fe9087 /Sema/SemaChecking.cpp | |
parent | e77fd3c15c8c4a2f1225e75d5742b6ad07578913 (diff) |
Add initial support for constant CFStrings.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41136 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Sema/SemaChecking.cpp')
-rw-r--r-- | Sema/SemaChecking.cpp | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/Sema/SemaChecking.cpp b/Sema/SemaChecking.cpp index 511f56f2a8..ed4c898349 100644 --- a/Sema/SemaChecking.cpp +++ b/Sema/SemaChecking.cpp @@ -28,7 +28,7 @@ using namespace clang; /// CheckFunctionCall - Check a direct function call for various correctness /// and safety properties not strictly enforced by the C type system. -void +bool Sema::CheckFunctionCall(Expr *Fn, SourceLocation LParenLoc, SourceLocation RParenLoc, FunctionDecl *FDecl, @@ -37,10 +37,17 @@ Sema::CheckFunctionCall(Expr *Fn, // Get the IdentifierInfo* for the called function. IdentifierInfo *FnInfo = FDecl->getIdentifier(); + if (FnInfo->getBuiltinID() == + Builtin::BI__builtin___CFStringMakeConstantString) { + assert(NumArgsInCall == 1 && + "Wrong number of arguments to builtin CFStringMakeConstantString"); + return CheckBuiltinCFStringArgument(Args[0]); + } + // Search the KnownFunctionIDs for the identifier. unsigned i = 0, e = id_num_known_functions; for (; i != e; ++i) { if (KnownFunctionIDs[i] == FnInfo) break; } - if (i == e) return; + if (i == e) return true; // Printf checking. if (i <= id_vprintf) { @@ -66,6 +73,46 @@ Sema::CheckFunctionCall(Expr *Fn, CheckPrintfArguments(Fn, LParenLoc, RParenLoc, HasVAListArg, FDecl, format_idx, Args, NumArgsInCall); } + + return true; +} + +/// CheckBuiltinCFStringArgument - Checks that the argument to the builtin +/// CFString constructor is correct +bool Sema::CheckBuiltinCFStringArgument(Expr* Arg) +{ + while (ParenExpr *PE = dyn_cast<ParenExpr>(Arg)) + Arg = PE->getSubExpr(); + + StringLiteral *Literal = dyn_cast<StringLiteral>(Arg); + + if (!Literal || Literal->isWide()) { + Diag(Arg->getLocStart(), + diag::err_cfstring_literal_not_string_constant, + Arg->getSourceRange()); + return false; + } + + const char *Data = Literal->getStrData(); + unsigned Length = Literal->getByteLength(); + + for (unsigned i = 0; i < Length; ++i) { + if (!isascii(Data[i])) { + Diag(PP.AdvanceToTokenCharacter(Arg->getLocStart(), i + 1), + diag::warn_cfstring_literal_contains_non_ascii_character, + Arg->getSourceRange()); + break; + } + + if (!Data[i]) { + Diag(PP.AdvanceToTokenCharacter(Arg->getLocStart(), i + 1), + diag::warn_cfstring_literal_contains_nul_character, + Arg->getSourceRange()); + break; + } + } + + return true; } /// CheckPrintfArguments - Check calls to printf (and similar functions) for |