1826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 28f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 38f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// The LLVM Compiler Infrastructure 48f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 58f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// This file is distributed under the University of Illinois Open Source 68f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// License. See LICENSE.TXT for details. 78f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 88f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek//===----------------------------------------------------------------------===// 98f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 108f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// Handling of format string in printf and friends. The structure of format 118f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// strings for fprintf() are described in C99 7.19.6.1. 128f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 138f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek//===----------------------------------------------------------------------===// 148f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 15826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "clang/Analysis/Analyses/FormatString.h" 16826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "FormatStringParsing.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/TargetInfo.h" 188f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 19f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgusing clang::analyze_format_string::ArgType; 20826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::FormatStringHandler; 21826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::LengthModifier; 22826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::OptionalAmount; 236ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenekusing clang::analyze_format_string::ConversionSpecifier; 24826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_printf::PrintfSpecifier; 25efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 26808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenekusing namespace clang; 278f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 28826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenektypedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 29826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifierResult; 304e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 314e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 324e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek// Methods for parsing format strings. 334e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 348f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 35826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::ParseNonPositionAmount; 36efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 37826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekstatic bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 38efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek const char *Start, const char *&Beg, const char *E, 39efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek unsigned *argIndex) { 40efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (argIndex) { 41efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 423060178ad9df29789505c1e6debcfc80a3a13587Chad Rosier } else { 43efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 44826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek analyze_format_string::PrecisionPos); 45efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (Amt.isInvalid()) 46efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 47efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.setPrecision(Amt); 48efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 49efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return false; 50efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek} 51efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 52826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekstatic PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 5374d56a168966ff015824279a24aaf566180ed97dTed Kremenek const char *&Beg, 547f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek const char *E, 55d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg unsigned &argIndex, 56275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const LangOptions &LO, 57275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const TargetInfo &Target) { 584e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 596ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek using namespace clang::analyze_format_string; 604b220fae2f525fda39685ddfa7759950db1185e2Ted Kremenek using namespace clang::analyze_printf; 614e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 628f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek const char *I = Beg; 636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const char *Start = nullptr; 648f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek UpdateOnReturn <const char*> UpdateBeg(Beg, I); 658f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 668f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for a '%' character that indicates the start of a format specifier. 67e729acbba75903f42e79e72e46cdebe3f4c35521Ted Kremenek for ( ; I != E ; ++I) { 688f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek char c = *I; 698f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (c == '\0') { 708f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Detect spurious null characters, which are likely errors. 718f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek H.HandleNullChar(I); 728f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 738f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 748f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (c == '%') { 75e729acbba75903f42e79e72e46cdebe3f4c35521Ted Kremenek Start = I++; // Record the start of the format specifier. 768f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek break; 778f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 788f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 794e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 808f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No format specifier found? 818f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!Start) 828f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return false; 834e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 848f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 858f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 86826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 878f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 888f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 894e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 90826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifier FS; 91efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParseArgPosition(H, FS, Start, I, E)) 92efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 93efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 94efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (I == E) { 95efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek // No more characters left? 96826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 97efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 98efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 994e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1008f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for flags (if any). 1018f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek bool hasMore = true; 1028f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek for ( ; I != E; ++I) { 1038f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek switch (*I) { 1048f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek default: hasMore = false; break; 105dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi case '\'': 106bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek // FIXME: POSIX specific. Always accept? 107bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek FS.setHasThousandsGrouping(I); 108bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek break; 109e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '-': FS.setIsLeftJustified(I); break; 110e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '+': FS.setHasPlusPrefix(I); break; 111e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ' ': FS.setHasSpacePrefix(I); break; 112e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '#': FS.setHasAlternativeForm(I); break; 113e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '0': FS.setHasLeadingZeros(I); break; 1148f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1158f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!hasMore) 1168f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek break; 1174e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 1188f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1198f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1208f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 121826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1228f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1238f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1244e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1258f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for the field width (if any). 126efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParseFieldWidth(H, FS, Start, I, E, 1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FS.usesPositionalArg() ? nullptr : &argIndex)) 128efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 1294e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1308f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1318f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 132826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1338f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1344e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 1354e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1364e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek // Look for the precision (if any). 1378f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (*I == '.') { 138808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek ++I; 1398f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 140826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1418f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1428f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1434e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 144efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParsePrecision(H, FS, Start, I, E, 1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FS.usesPositionalArg() ? nullptr : &argIndex)) 146efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 1478f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1488f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1498f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 150826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1518f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1528f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1538f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1548f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1558f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for the length modifier. 156d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg if (ParseLengthModifier(FS, I, E, LO) && I == E) { 1578f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 158826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1598f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1608f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 161df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek 1624dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek if (*I == '\0') { 163df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek // Detect spurious null characters, which are likely errors. 164df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek H.HandleNullChar(I); 165df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek return true; 1664dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek } 1674e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1688f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Finally, look for the conversion specifier. 169a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek const char *conversionPosition = I++; 17026ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 171a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek switch (*conversionPosition) { 1728f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek default: 17326ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek break; 174c7cbb9bf8e0bf8c3191ef0b782ec198c433d2a4eTed Kremenek // C99: 7.19.6.1 (section 8). 17587260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case '%': k = ConversionSpecifier::PercentArg; break; 17687260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'A': k = ConversionSpecifier::AArg; break; 177a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'E': k = ConversionSpecifier::EArg; break; 17887260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'F': k = ConversionSpecifier::FArg; break; 179a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'G': k = ConversionSpecifier::GArg; break; 18087260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'X': k = ConversionSpecifier::XArg; break; 181a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'a': k = ConversionSpecifier::aArg; break; 18292a6febe130dd9ad726983835297e11b2fa3b93fTed Kremenek case 'c': k = ConversionSpecifier::cArg; break; 18387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'd': k = ConversionSpecifier::dArg; break; 18487260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'e': k = ConversionSpecifier::eArg; break; 18587260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'f': k = ConversionSpecifier::fArg; break; 18687260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'g': k = ConversionSpecifier::gArg; break; 18787260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'i': k = ConversionSpecifier::iArg; break; 18835d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case 'n': k = ConversionSpecifier::nArg; break; 18987260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'o': k = ConversionSpecifier::oArg; break; 19047ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case 'p': k = ConversionSpecifier::pArg; break; 19147ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case 's': k = ConversionSpecifier::sArg; break; 19287260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'u': k = ConversionSpecifier::uArg; break; 19387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'x': k = ConversionSpecifier::xArg; break; 194bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek // POSIX specific. 19587260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'C': k = ConversionSpecifier::CArg; break; 196de183a48dd8fcff5e0343e84c8a6b563088447ceTed Kremenek case 'S': k = ConversionSpecifier::SArg; break; 197c7cbb9bf8e0bf8c3191ef0b782ec198c433d2a4eTed Kremenek // Objective-C. 1984dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek case '@': k = ConversionSpecifier::ObjCObjArg; break; 199df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek // Glibc specific. 2004dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek case 'm': k = ConversionSpecifier::PrintErrno; break; 201275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose // Apple-specific 202275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case 'D': 203275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose if (Target.getTriple().isOSDarwin()) 204275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose k = ConversionSpecifier::DArg; 205275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose break; 206275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case 'O': 207275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose if (Target.getTriple().isOSDarwin()) 208275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose k = ConversionSpecifier::OArg; 209275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose break; 210275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case 'U': 211275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose if (Target.getTriple().isOSDarwin()) 212275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose k = ConversionSpecifier::UArg; 213275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose break; 2148f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 2156ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek PrintfConversionSpecifier CS(conversionPosition, k); 2167f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek FS.setConversionSpecifier(CS); 217efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 2187f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek FS.setArgIndex(argIndex++); 21926ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek 22026ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek if (k == ConversionSpecifier::InvalidSpecifier) { 2217f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // Assume the conversion takes one argument. 2227966297a70996977f167a8676568f02f4283bdd6Ted Kremenek return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 22326ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek } 224826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return PrintfSpecifierResult(Start, FS); 2258f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek} 2268f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 227826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 228826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *I, 229d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const char *E, 230275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const LangOptions &LO, 231275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const TargetInfo &Target) { 2327f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 2337f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek unsigned argIndex = 0; 2347f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 2358f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Keep looking for a format specifier until we have exhausted the string. 2368f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek while (I != E) { 237d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 238275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose LO, Target); 23926ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // Did a fail-stop error of any kind occur when parsing the specifier? 24026ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // If so, don't do any more processing. 24126ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek if (FSR.shouldStop()) 2421ad23d62007162df82b58bca31b4aa277a5f6586Dmitri Gribenko return true; 24326ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // Did we exhaust the string or encounter an error that 24426ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // we can recover from? 2458f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!FSR.hasValue()) 24626ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek continue; 2478f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // We have a format specifier. Pass it to the callback. 248826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 249a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek I - FSR.getStart())) 2504dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek return true; 2514e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 2524e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek assert(I == E && "Format string not exhausted"); 2538f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return false; 2548f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek} 2558f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 2564e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 257826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on PrintfSpecifier. 25833567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek//===----------------------------------------------------------------------===// 25933567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 260f3749f4168c5cee59627a681ca4ca6e4116d0761Hans WennborgArgType PrintfSpecifier::getArgType(ASTContext &Ctx, 261f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg bool IsObjCLiteral) const { 2626ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const PrintfConversionSpecifier &CS = getConversionSpecifier(); 263dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 26433567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (!CS.consumesDataArgument()) 265f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType::Invalid(); 2664e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 2679325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek if (CS.getKind() == ConversionSpecifier::cArg) 2689325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek switch (LM.getKind()) { 2699325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek case LengthModifier::None: return Ctx.IntTy; 270f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg case LengthModifier::AsLong: 271f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(ArgType::WIntTy, "wint_t"); 2729325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek default: 273f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType::Invalid(); 2749325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek } 275dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 27633567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (CS.isIntArg()) 2773bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (LM.getKind()) { 2783bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongDouble: 2799d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek // GNU extension. 2809d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek return Ctx.LongLongTy; 28147ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::None: 28247ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer return Ctx.IntTy; 28347ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt32: 28447ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer return ArgType(Ctx.IntTy, "__int32"); 285f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg case LengthModifier::AsChar: return ArgType::AnyCharTy; 2863bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsShort: return Ctx.ShortTy; 2873bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLong: return Ctx.LongTy; 28832addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsLongLong: 28932addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsQuad: 29032addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg return Ctx.LongLongTy; 29147ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt64: 29247ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer return ArgType(Ctx.LongLongTy, "__int64"); 293a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsIntMax: 294f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(Ctx.getIntMaxType(), "intmax_t"); 29529e97cb35fab314388f62b68fefa78947e93c1dcHans Wennborg case LengthModifier::AsSizeT: 29629e97cb35fab314388f62b68fefa78947e93c1dcHans Wennborg // FIXME: How to get the corresponding signed version of size_t? 297f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(); 29847ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt3264: 299df72071db0ddfd7264485105c19230c315e8ce2cDavid Majnemer return Ctx.getTargetInfo().getTriple().isArch64Bit() 300df72071db0ddfd7264485105c19230c315e8ce2cDavid Majnemer ? ArgType(Ctx.LongLongTy, "__int64") 301df72071db0ddfd7264485105c19230c315e8ce2cDavid Majnemer : ArgType(Ctx.IntTy, "__int32"); 302a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsPtrDiff: 303f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"); 304d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case LengthModifier::AsAllocate: 30537969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case LengthModifier::AsMAllocate: 306f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType::Invalid(); 30733567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek } 30833567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 30933567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (CS.isUIntArg()) 3103bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (LM.getKind()) { 3113bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongDouble: 3129d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek // GNU extension. 3139d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek return Ctx.UnsignedLongLongTy; 31447ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::None: 31547ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer return Ctx.UnsignedIntTy; 31647ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt32: 31747ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer return ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 3183bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 3193bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 3203bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 32132addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsLongLong: 32232addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsQuad: 32332addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg return Ctx.UnsignedLongLongTy; 32447ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt64: 32547ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64"); 326a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsIntMax: 327f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(Ctx.getUIntMaxType(), "uintmax_t"); 3283bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsSizeT: 329f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(Ctx.getSizeType(), "size_t"); 33047ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt3264: 33147ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer return Ctx.getTargetInfo().getTriple().isArch64Bit() 332df72071db0ddfd7264485105c19230c315e8ce2cDavid Majnemer ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64") 333df72071db0ddfd7264485105c19230c315e8ce2cDavid Majnemer : ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 3343bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsPtrDiff: 33533567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // FIXME: How to get the corresponding unsigned 33633567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // version of ptrdiff_t? 337f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(); 338d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case LengthModifier::AsAllocate: 33937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case LengthModifier::AsMAllocate: 340f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType::Invalid(); 34133567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek } 3424e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 343f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek if (CS.isDoubleArg()) { 3443bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (LM.getKind() == LengthModifier::AsLongDouble) 345f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek return Ctx.LongDoubleTy; 346c9a89fec60a20eb3269caa95eca048d45ab215adTed Kremenek return Ctx.DoubleTy; 347f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek } 3487f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 349f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg if (CS.getKind() == ConversionSpecifier::nArg) { 350f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg switch (LM.getKind()) { 351f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::None: 352f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::PtrTo(Ctx.IntTy); 353f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsChar: 354f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::PtrTo(Ctx.SignedCharTy); 355f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsShort: 356f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::PtrTo(Ctx.ShortTy); 357f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsLong: 358f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::PtrTo(Ctx.LongTy); 359f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsLongLong: 360f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsQuad: 361f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::PtrTo(Ctx.LongLongTy); 362f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsIntMax: 363f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); 364f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsSizeT: 365f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType(); // FIXME: ssize_t 366f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsPtrDiff: 367f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); 368f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsLongDouble: 369f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType(); // FIXME: Is this a known extension? 370f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsAllocate: 371f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg case LengthModifier::AsMAllocate: 37247ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt32: 37347ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt3264: 37447ad6ce1afad6b70927347dfa15e0f1dc76bf5bbDavid Majnemer case LengthModifier::AsInt64: 375f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg return ArgType::Invalid(); 376f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg } 377f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg } 378f7158fa034174d2756736d1032b75d01d9deeb4cHans Wennborg 37987260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek switch (CS.getKind()) { 380630821869c4ec4604ab479d66e5ff81147a858e1Hans Wennborg case ConversionSpecifier::sArg: 381339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (LM.getKind() == LengthModifier::AsWideChar) { 382339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (IsObjCLiteral) 3832cd3440369d9241173e994485ddf2589a50a7d80Jordan Rose return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 3842cd3440369d9241173e994485ddf2589a50a7d80Jordan Rose "const unichar *"); 385f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(ArgType::WCStrTy, "wchar_t *"); 386339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber } 387f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType::CStrTy; 388de183a48dd8fcff5e0343e84c8a6b563088447ceTed Kremenek case ConversionSpecifier::SArg: 389339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (IsObjCLiteral) 3902cd3440369d9241173e994485ddf2589a50a7d80Jordan Rose return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 3912cd3440369d9241173e994485ddf2589a50a7d80Jordan Rose "const unichar *"); 392f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(ArgType::WCStrTy, "wchar_t *"); 39387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case ConversionSpecifier::CArg: 394339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (IsObjCLiteral) 3952cd3440369d9241173e994485ddf2589a50a7d80Jordan Rose return ArgType(Ctx.UnsignedShortTy, "unichar"); 39615f92bad58c8650b1306729744b1a1230197497aHans Wennborg return ArgType(Ctx.WideCharTy, "wchar_t"); 39766932056da99d2441e27c10b27c82706671e1dbfTed Kremenek case ConversionSpecifier::pArg: 398f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType::CPointerTy; 399e6ca97f2aeb301e28d20988b27c4297a9b540991Ted Kremenek case ConversionSpecifier::ObjCObjArg: 400f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType::ObjCPointerTy; 40187260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek default: 40287260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek break; 40387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek } 4047f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 40533567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // FIXME: Handle other cases. 406f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg return ArgType(); 40733567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek} 40833567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 409be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborgbool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, 410be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg ASTContext &Ctx, bool IsObjCLiteral) { 411cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg // %n is different from other conversion specifiers; don't try to fix it. 412cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg if (CS.getKind() == ConversionSpecifier::nArg) 413cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg return false; 414cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg 415153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // Handle Objective-C objects first. Note that while the '%@' specifier will 416153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // not warn for structure pointer or void pointer arguments (because that's 417153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // how CoreFoundation objects are implemented), we only show a fixit for '%@' 418153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // if we know it's an object (block, id, class, or __attribute__((NSObject))). 419153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose if (QT->isObjCRetainableType()) { 420153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose if (!IsObjCLiteral) 421153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose return false; 422153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 423153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose CS.setKind(ConversionSpecifier::ObjCObjArg); 424153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 425153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // Disable irrelevant flags 426153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasThousandsGrouping = false; 427153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasPlusPrefix = false; 428153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasSpacePrefix = false; 429153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasAlternativeForm = false; 430153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasLeadingZeroes = false; 431153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose Precision.setHowSpecified(OptionalAmount::NotSpecified); 432153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose LM.setKind(LengthModifier::None); 433153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 434153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose return true; 435153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose } 436153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 437153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // Handle strings next (char *, wchar_t *) 4383bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 43999196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek CS.setKind(ConversionSpecifier::sArg); 4403bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 441876e994957472eda4b40136d4e1d6e08e2be338fTom Care // Disable irrelevant flags 442876e994957472eda4b40136d4e1d6e08e2be338fTom Care HasAlternativeForm = 0; 443876e994957472eda4b40136d4e1d6e08e2be338fTom Care HasLeadingZeroes = 0; 444876e994957472eda4b40136d4e1d6e08e2be338fTom Care 4453bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set the long length modifier for wide characters 4463bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (QT->getPointeeType()->isWideCharType()) 4473bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsWideChar); 448117348caf0a8f91782e9e32e32a8689576f394d7Hans Wennborg else 449117348caf0a8f91782e9e32e32a8689576f394d7Hans Wennborg LM.setKind(LengthModifier::None); 4503bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4513bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return true; 4523bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4533bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 454033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose // If it's an enum, get its underlying type. 455033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose if (const EnumType *ETy = QT->getAs<EnumType>()) 456033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose QT = ETy->getDecl()->getIntegerType(); 457033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose 4583bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // We can only work with builtin types. 4593bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care const BuiltinType *BT = QT->getAs<BuiltinType>(); 4602dde35bc626153492f5f58202506c88a27fbff5bJohn McCall if (!BT) 4612dde35bc626153492f5f58202506c88a27fbff5bJohn McCall return false; 462876e994957472eda4b40136d4e1d6e08e2be338fTom Care 4633bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set length modifier 4643bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (BT->getKind()) { 46506d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Bool: 46606d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::WChar_U: 46706d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::WChar_S: 46806d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Char16: 46906d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Char32: 47006d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::UInt128: 47106d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Int128: 472aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov case BuiltinType::Half: 4732dde35bc626153492f5f58202506c88a27fbff5bJohn McCall // Various types which are non-trivial to correct. 47406d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman return false; 47506d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman 4762dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define SIGNED_TYPE(Id, SingletonId) 4772dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define UNSIGNED_TYPE(Id, SingletonId) 4782dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define FLOATING_TYPE(Id, SingletonId) 4792dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define BUILTIN_TYPE(Id, SingletonId) \ 4802dde35bc626153492f5f58202506c88a27fbff5bJohn McCall case BuiltinType::Id: 4812dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#include "clang/AST/BuiltinTypes.def" 48206d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman // Misc other stuff which doesn't make sense here. 48306d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman return false; 48406d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman 48506d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::UInt: 48606d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Int: 48706d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Float: 48806d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Double: 489876e994957472eda4b40136d4e1d6e08e2be338fTom Care LM.setKind(LengthModifier::None); 4903bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 491876e994957472eda4b40136d4e1d6e08e2be338fTom Care 4924d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Char_U: 4934d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::UChar: 4944d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Char_S: 4954d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::SChar: 4964d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::AsChar); 4974d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek break; 4984d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek 4994d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Short: 5004d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::UShort: 5014d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::AsShort); 5024d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek break; 5034d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek 5043bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::Long: 5053bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::ULong: 5063bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLong); 5073bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 5083bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5093bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::LongLong: 5103bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::ULongLong: 5113bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLongLong); 5123bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 5133bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5143bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::LongDouble: 5153bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLongDouble); 5163bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 5173bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 5183bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 519a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 52080ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11)) 5214684778993c667246039b4664acbce59dc99440cHans Wennborg namedTypeToLengthModifier(QT, LM); 522a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg 523242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose // If fixing the length modifier was enough, we might be done. 524bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose if (hasValidLengthModifier(Ctx.getTargetInfo())) { 525242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose // If we're going to offer a fix anyway, make sure the sign matches. 526242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose switch (CS.getKind()) { 527242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose case ConversionSpecifier::uArg: 528242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose case ConversionSpecifier::UArg: 529242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose if (QT->isSignedIntegerType()) 530242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg); 531242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose break; 532242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose case ConversionSpecifier::dArg: 533242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose case ConversionSpecifier::DArg: 534242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose case ConversionSpecifier::iArg: 535cdbe1e0d85d7d32452dd1c52758d7bfaa1c0663bJordan Rose if (QT->isUnsignedIntegerType() && !HasPlusPrefix) 536242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg); 537242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose break; 538242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose default: 539242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose // Other specifiers do not have signed/unsigned variants. 540242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose break; 541242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose } 542242ae3d6805185fcb4fd45e96af5beba93e3532cJordan Rose 543bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral); 544bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose if (ATR.isValid() && ATR.matchesType(Ctx, QT)) 545bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose return true; 546bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose } 547be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg 5483bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set conversion specifier and disable any flags which do not apply to it. 5494d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek // Let typedefs to char fall through to int, as %c is silly for uint8_t. 550ff7be48165548c9c01492010609d166973607068Jordan Rose if (!isa<TypedefType>(QT) && QT->isCharType()) { 55192a6febe130dd9ad726983835297e11b2fa3b93fTed Kremenek CS.setKind(ConversionSpecifier::cArg); 5524d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::None); 5533bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care Precision.setHowSpecified(OptionalAmount::NotSpecified); 5543bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 5553bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasLeadingZeroes = 0; 556e4ee9663168dfb2b4122c768091e30217328c9faTom Care HasPlusPrefix = 0; 5573bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 5583bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 5590c293ea13d452c1a47a05ada5a5ee9acc69c66ccDouglas Gregor else if (QT->isRealFloatingType()) { 5603bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care CS.setKind(ConversionSpecifier::fArg); 5613bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 5623bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care else if (QT->isSignedIntegerType()) { 5633bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care CS.setKind(ConversionSpecifier::dArg); 5643bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 5653bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 566c8c4b4088cf0b3afeda425b25fa7c77d3873b12cDouglas Gregor else if (QT->isUnsignedIntegerType()) { 567be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg CS.setKind(ConversionSpecifier::uArg); 5683bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 569e4ee9663168dfb2b4122c768091e30217328c9faTom Care HasPlusPrefix = 0; 5703060178ad9df29789505c1e6debcfc80a3a13587Chad Rosier } else { 571b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unexpected type"); 5723bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 5733bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5743bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return true; 5753bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care} 5763bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5775f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid PrintfSpecifier::toString(raw_ostream &os) const { 5783bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Whilst some features have no defined order, we are using the order 5790099530a2288df7c2140dd8992b7310b9f6930a9NAKAMURA Takumi // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 5803bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << "%"; 5813bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5823bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Positional args 5833bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (usesPositionalArg()) { 5843bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << getPositionalArgIndex() << "$"; 5853bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 5863bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5873bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Conversion flags 5883bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (IsLeftJustified) os << "-"; 5893bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasPlusPrefix) os << "+"; 5903bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasSpacePrefix) os << " "; 5913bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasAlternativeForm) os << "#"; 5923bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasLeadingZeroes) os << "0"; 5933bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5943bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Minimum field width 5953bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care FieldWidth.toString(os); 5963bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Precision 5973bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care Precision.toString(os); 5983bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Length modifier 5993bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << LM.toString(); 6003bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Conversion specifier 6013bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << CS.toString(); 6023bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care} 603e4ee9663168dfb2b4122c768091e30217328c9faTom Care 604826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidPlusPrefix() const { 605e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasPlusPrefix) 606e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 607e4ee9663168dfb2b4122c768091e30217328c9faTom Care 608e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The plus prefix only makes sense for signed conversions 609e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 610e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 611275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 612e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 613e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 614e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 615e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 616e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 617e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 618e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 619e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 620e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 621e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 622e4ee9663168dfb2b4122c768091e30217328c9faTom Care 623e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 624e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 625e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 626e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 627e4ee9663168dfb2b4122c768091e30217328c9faTom Care 628826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidAlternativeForm() const { 629e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasAlternativeForm) 630e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 631e4ee9663168dfb2b4122c768091e30217328c9faTom Care 6322e6c19abcf97c25f4d7458a9db89c5ab0158717dAnders Carlsson // Alternate form flag only valid with the oxXaAeEfFgG conversions 633e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 634e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 635275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::OArg: 636e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 6372e6c19abcf97c25f4d7458a9db89c5ab0158717dAnders Carlsson case ConversionSpecifier::XArg: 638e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 639e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 640e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 641e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 642e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 643e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 644e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 645e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 646e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 647e4ee9663168dfb2b4122c768091e30217328c9faTom Care 648e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 649e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 650e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 651e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 652e4ee9663168dfb2b4122c768091e30217328c9faTom Care 653826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidLeadingZeros() const { 654e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasLeadingZeroes) 655e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 656e4ee9663168dfb2b4122c768091e30217328c9faTom Care 657e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 658e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 659e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 660275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 661e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 662e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 663275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::OArg: 664e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::uArg: 665275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::UArg: 666e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 667e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::XArg: 668e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 669e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 670e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 671e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 672e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 673e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 674e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 675e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 676e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 677e4ee9663168dfb2b4122c768091e30217328c9faTom Care 678e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 679e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 680e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 681e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 682e4ee9663168dfb2b4122c768091e30217328c9faTom Care 683826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidSpacePrefix() const { 684e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasSpacePrefix) 685e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 686e4ee9663168dfb2b4122c768091e30217328c9faTom Care 687e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The space prefix only makes sense for signed conversions 688e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 689e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 690275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 691e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 692e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 693e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 694e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 695e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 696e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 697e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 698e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 699e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 700e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 701e4ee9663168dfb2b4122c768091e30217328c9faTom Care 702e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 703e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 704e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 705e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 706e4ee9663168dfb2b4122c768091e30217328c9faTom Care 707826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidLeftJustified() const { 708e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!IsLeftJustified) 709e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 710e4ee9663168dfb2b4122c768091e30217328c9faTom Care 711e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The left justified flag is valid for all conversions except n 712e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 71335d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case ConversionSpecifier::nArg: 714e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 715e4ee9663168dfb2b4122c768091e30217328c9faTom Care 716e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 717e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 718e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 719e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 720e4ee9663168dfb2b4122c768091e30217328c9faTom Care 72165197b4b0c55bb74af0450230d61ee9461223721Ted Kremenekbool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 72265197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek if (!HasThousandsGrouping) 72365197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return true; 724dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 72565197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek switch (CS.getKind()) { 72665197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::dArg: 727275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 72865197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::iArg: 72965197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::uArg: 730275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::UArg: 73165197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::fArg: 73265197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::FArg: 73365197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::gArg: 73465197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::GArg: 73565197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return true; 73665197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek default: 73765197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return false; 73865197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek } 73965197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek} 74065197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek 741826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidPrecision() const { 742e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 743e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 744e4ee9663168dfb2b4122c768091e30217328c9faTom Care 745e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Precision is only valid with the diouxXaAeEfFgGs conversions 746e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 747e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 748275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 749e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 750e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 751275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::OArg: 752e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::uArg: 753275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::UArg: 754e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 755e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::XArg: 756e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 757e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 758e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 759e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 760e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 761e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 762e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 763e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 76499196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek case ConversionSpecifier::sArg: 765e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 766e4ee9663168dfb2b4122c768091e30217328c9faTom Care 767e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 768e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 769e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 770e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 771826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidFieldWidth() const { 772e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 773e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 774e4ee9663168dfb2b4122c768091e30217328c9faTom Care 775e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The field width is valid for all conversions except n 776e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 77735d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case ConversionSpecifier::nArg: 778e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 779e4ee9663168dfb2b4122c768091e30217328c9faTom Care 780e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 781e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 782e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 783e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 784