PrintfFormatString.cpp revision cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9
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" 178f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 18826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::ArgTypeResult; 19826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::FormatStringHandler; 20826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::LengthModifier; 21826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::OptionalAmount; 226ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenekusing clang::analyze_format_string::ConversionSpecifier; 23826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_printf::PrintfSpecifier; 24efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 25808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenekusing namespace clang; 268f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 27826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenektypedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 28826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifierResult; 294e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 304e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 314e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek// Methods for parsing format strings. 324e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 338f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 34826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::ParseNonPositionAmount; 35efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 36826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekstatic bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 37efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek const char *Start, const char *&Beg, const char *E, 38efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek unsigned *argIndex) { 39efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (argIndex) { 40efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 413060178ad9df29789505c1e6debcfc80a3a13587Chad Rosier } else { 42efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 43826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek analyze_format_string::PrecisionPos); 44efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (Amt.isInvalid()) 45efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 46efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.setPrecision(Amt); 47efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 48efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return false; 49efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek} 50efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 51826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekstatic PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 5274d56a168966ff015824279a24aaf566180ed97dTed Kremenek const char *&Beg, 537f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek const char *E, 54d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg unsigned &argIndex, 55d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const LangOptions &LO) { 564e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 576ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek using namespace clang::analyze_format_string; 584b220fae2f525fda39685ddfa7759950db1185e2Ted Kremenek using namespace clang::analyze_printf; 594e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 608f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek const char *I = Beg; 61c7ae51a3cd9460db8280e8623c90614f246e46d2Ted Kremenek const char *Start = 0; 628f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek UpdateOnReturn <const char*> UpdateBeg(Beg, I); 638f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 648f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for a '%' character that indicates the start of a format specifier. 65e729acbba75903f42e79e72e46cdebe3f4c35521Ted Kremenek for ( ; I != E ; ++I) { 668f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek char c = *I; 678f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (c == '\0') { 688f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Detect spurious null characters, which are likely errors. 698f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek H.HandleNullChar(I); 708f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 718f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 728f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (c == '%') { 73e729acbba75903f42e79e72e46cdebe3f4c35521Ted Kremenek Start = I++; // Record the start of the format specifier. 748f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek break; 758f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 768f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 774e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 788f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No format specifier found? 798f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!Start) 808f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return false; 814e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 828f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 838f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 84826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 858f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 868f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 874e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 88826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifier FS; 89efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParseArgPosition(H, FS, Start, I, E)) 90efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 91efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 92efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (I == E) { 93efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek // No more characters left? 94826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 95efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 96efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 974e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 988f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for flags (if any). 998f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek bool hasMore = true; 1008f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek for ( ; I != E; ++I) { 1018f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek switch (*I) { 1028f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek default: hasMore = false; break; 103dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi case '\'': 104bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek // FIXME: POSIX specific. Always accept? 105bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek FS.setHasThousandsGrouping(I); 106bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek break; 107e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '-': FS.setIsLeftJustified(I); break; 108e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '+': FS.setHasPlusPrefix(I); break; 109e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ' ': FS.setHasSpacePrefix(I); break; 110e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '#': FS.setHasAlternativeForm(I); break; 111e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '0': FS.setHasLeadingZeros(I); break; 1128f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1138f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!hasMore) 1148f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek break; 1154e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 1168f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1178f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1188f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 119826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1208f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1218f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1224e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1238f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for the field width (if any). 124efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParseFieldWidth(H, FS, Start, I, E, 125efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.usesPositionalArg() ? 0 : &argIndex)) 126efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 1274e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1288f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1298f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 130826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1318f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1324e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 1334e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1344e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek // Look for the precision (if any). 1358f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (*I == '.') { 136808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek ++I; 1378f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 138826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1398f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1408f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1414e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 142efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParsePrecision(H, FS, Start, I, E, 143efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.usesPositionalArg() ? 0 : &argIndex)) 144efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 1458f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1468f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1478f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 148826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1498f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1508f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1518f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1528f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1538f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for the length modifier. 154d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg if (ParseLengthModifier(FS, I, E, LO) && I == E) { 1558f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 156826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1578f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1588f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 159df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek 1604dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek if (*I == '\0') { 161df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek // Detect spurious null characters, which are likely errors. 162df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek H.HandleNullChar(I); 163df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek return true; 1644dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek } 1654e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1668f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Finally, look for the conversion specifier. 167a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek const char *conversionPosition = I++; 16826ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 169a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek switch (*conversionPosition) { 1708f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek default: 17126ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek break; 172c7cbb9bf8e0bf8c3191ef0b782ec198c433d2a4eTed Kremenek // C99: 7.19.6.1 (section 8). 17387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case '%': k = ConversionSpecifier::PercentArg; break; 17487260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'A': k = ConversionSpecifier::AArg; break; 175a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'E': k = ConversionSpecifier::EArg; break; 17687260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'F': k = ConversionSpecifier::FArg; break; 177a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'G': k = ConversionSpecifier::GArg; break; 17887260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'X': k = ConversionSpecifier::XArg; break; 179a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'a': k = ConversionSpecifier::aArg; break; 18092a6febe130dd9ad726983835297e11b2fa3b93fTed Kremenek case 'c': k = ConversionSpecifier::cArg; break; 18187260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'd': k = ConversionSpecifier::dArg; break; 18287260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'e': k = ConversionSpecifier::eArg; break; 18387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'f': k = ConversionSpecifier::fArg; break; 18487260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'g': k = ConversionSpecifier::gArg; break; 18587260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'i': k = ConversionSpecifier::iArg; break; 18635d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case 'n': k = ConversionSpecifier::nArg; break; 18787260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'o': k = ConversionSpecifier::oArg; break; 18866932056da99d2441e27c10b27c82706671e1dbfTed Kremenek case 'p': k = ConversionSpecifier::pArg; break; 18999196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek case 's': k = ConversionSpecifier::sArg; break; 19087260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'u': k = ConversionSpecifier::uArg; break; 19187260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'x': k = ConversionSpecifier::xArg; break; 192bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek // POSIX specific. 19387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'C': k = ConversionSpecifier::CArg; break; 194de183a48dd8fcff5e0343e84c8a6b563088447ceTed Kremenek case 'S': k = ConversionSpecifier::SArg; break; 195c7cbb9bf8e0bf8c3191ef0b782ec198c433d2a4eTed Kremenek // Objective-C. 1964dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek case '@': k = ConversionSpecifier::ObjCObjArg; break; 197df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek // Glibc specific. 1984dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek case 'm': k = ConversionSpecifier::PrintErrno; break; 1998f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 2006ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek PrintfConversionSpecifier CS(conversionPosition, k); 2017f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek FS.setConversionSpecifier(CS); 202efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 2037f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek FS.setArgIndex(argIndex++); 20426ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek 20526ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek if (k == ConversionSpecifier::InvalidSpecifier) { 2067f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // Assume the conversion takes one argument. 2077966297a70996977f167a8676568f02f4283bdd6Ted Kremenek return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 20826ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek } 209826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return PrintfSpecifierResult(Start, FS); 2108f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek} 2118f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 212826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 213826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *I, 214d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const char *E, 215d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const LangOptions &LO) { 2167f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 2177f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek unsigned argIndex = 0; 2187f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 2198f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Keep looking for a format specifier until we have exhausted the string. 2208f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek while (I != E) { 221d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 222d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg LO); 22326ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // Did a fail-stop error of any kind occur when parsing the specifier? 22426ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // If so, don't do any more processing. 22526ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek if (FSR.shouldStop()) 2268f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true;; 22726ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // Did we exhaust the string or encounter an error that 22826ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // we can recover from? 2298f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!FSR.hasValue()) 23026ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek continue; 2318f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // We have a format specifier. Pass it to the callback. 232826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 233a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek I - FSR.getStart())) 2344dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek return true; 2354e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 2364e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek assert(I == E && "Format string not exhausted"); 2378f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return false; 2388f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek} 2398f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 2404e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 241826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on PrintfSpecifier. 24233567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek//===----------------------------------------------------------------------===// 24333567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 244339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico WeberArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx, 245339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber bool IsObjCLiteral) const { 2466ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const PrintfConversionSpecifier &CS = getConversionSpecifier(); 247dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 24833567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (!CS.consumesDataArgument()) 24933567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult::Invalid(); 2504e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 2519325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek if (CS.getKind() == ConversionSpecifier::cArg) 2529325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek switch (LM.getKind()) { 2539325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek case LengthModifier::None: return Ctx.IntTy; 254f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg case LengthModifier::AsLong: 255f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg return ArgTypeResult(ArgTypeResult::WIntTy, "wint_t"); 2569325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek default: 2579325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek return ArgTypeResult::Invalid(); 2589325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek } 259dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 26033567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (CS.isIntArg()) 2613bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (LM.getKind()) { 2623bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongDouble: 2639d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek // GNU extension. 2649d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek return Ctx.LongLongTy; 2653bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::None: return Ctx.IntTy; 2666ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy; 2673bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsShort: return Ctx.ShortTy; 2683bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLong: return Ctx.LongTy; 26932addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsLongLong: 27032addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsQuad: 27132addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg return Ctx.LongLongTy; 272a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsIntMax: 273a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t"); 27429e97cb35fab314388f62b68fefa78947e93c1dcHans Wennborg case LengthModifier::AsSizeT: 27529e97cb35fab314388f62b68fefa78947e93c1dcHans Wennborg // FIXME: How to get the corresponding signed version of size_t? 27633567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult(); 277a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsPtrDiff: 278a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t"); 279d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case LengthModifier::AsAllocate: 28037969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case LengthModifier::AsMAllocate: 281d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg return ArgTypeResult::Invalid(); 28233567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek } 28333567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 28433567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (CS.isUIntArg()) 2853bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (LM.getKind()) { 2863bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongDouble: 2879d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek // GNU extension. 2889d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek return Ctx.UnsignedLongLongTy; 2893bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::None: return Ctx.UnsignedIntTy; 2903bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 2913bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 2923bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 29332addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsLongLong: 29432addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsQuad: 29532addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg return Ctx.UnsignedLongLongTy; 296a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsIntMax: 297a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t"); 2983bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsSizeT: 299a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getSizeType(), "size_t"); 3003bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsPtrDiff: 30133567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // FIXME: How to get the corresponding unsigned 30233567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // version of ptrdiff_t? 30333567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult(); 304d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case LengthModifier::AsAllocate: 30537969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case LengthModifier::AsMAllocate: 306d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg return ArgTypeResult::Invalid(); 30733567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek } 3084e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 309f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek if (CS.isDoubleArg()) { 3103bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (LM.getKind() == LengthModifier::AsLongDouble) 311f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek return Ctx.LongDoubleTy; 312c9a89fec60a20eb3269caa95eca048d45ab215adTed Kremenek return Ctx.DoubleTy; 313f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek } 3147f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 31587260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek switch (CS.getKind()) { 316630821869c4ec4604ab479d66e5ff81147a858e1Hans Wennborg case ConversionSpecifier::sArg: 317339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (LM.getKind() == LengthModifier::AsWideChar) { 318339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (IsObjCLiteral) 319339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()); 320f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); 321339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber } 322f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg return ArgTypeResult::CStrTy; 323de183a48dd8fcff5e0343e84c8a6b563088447ceTed Kremenek case ConversionSpecifier::SArg: 324339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (IsObjCLiteral) 325339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()); 326f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); 32787260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case ConversionSpecifier::CArg: 328339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber if (IsObjCLiteral) 329339b9072e26a2a0fe796dc69c4d28d964d0ec86dNico Weber return Ctx.UnsignedShortTy; 330f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg return ArgTypeResult(Ctx.WCharTy, "wchar_t"); 33166932056da99d2441e27c10b27c82706671e1dbfTed Kremenek case ConversionSpecifier::pArg: 33213927a431dd733336cfd664bf0840747a71b0a43Ted Kremenek return ArgTypeResult::CPointerTy; 333cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg case ConversionSpecifier::nArg: 334cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg return Ctx.getPointerType(Ctx.IntTy); 335e6ca97f2aeb301e28d20988b27c4297a9b540991Ted Kremenek case ConversionSpecifier::ObjCObjArg: 336e6ca97f2aeb301e28d20988b27c4297a9b540991Ted Kremenek return ArgTypeResult::ObjCPointerTy; 33787260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek default: 33887260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek break; 33987260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek } 3407f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 34133567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // FIXME: Handle other cases. 34240888ada6022cfd4ab2a7c07ab276639860ffc5aTed Kremenek return ArgTypeResult(); 34333567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek} 34433567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 345be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborgbool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, 346be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg ASTContext &Ctx, bool IsObjCLiteral) { 347cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg // %n is different from other conversion specifiers; don't try to fix it. 348cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg if (CS.getKind() == ConversionSpecifier::nArg) 349cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg return false; 350cec9ce49dcf4b4b768043f96c8ef8c1d4cdbb6b9Hans Wennborg 351153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // Handle Objective-C objects first. Note that while the '%@' specifier will 352153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // not warn for structure pointer or void pointer arguments (because that's 353153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // how CoreFoundation objects are implemented), we only show a fixit for '%@' 354153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // if we know it's an object (block, id, class, or __attribute__((NSObject))). 355153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose if (QT->isObjCRetainableType()) { 356153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose if (!IsObjCLiteral) 357153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose return false; 358153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 359153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose CS.setKind(ConversionSpecifier::ObjCObjArg); 360153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 361153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // Disable irrelevant flags 362153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasThousandsGrouping = false; 363153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasPlusPrefix = false; 364153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasSpacePrefix = false; 365153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasAlternativeForm = false; 366153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose HasLeadingZeroes = false; 367153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose Precision.setHowSpecified(OptionalAmount::NotSpecified); 368153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose LM.setKind(LengthModifier::None); 369153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 370153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose return true; 371153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose } 372153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose 373153acdb7310b20a72e608cbb10946621f161eb70Jordan Rose // Handle strings next (char *, wchar_t *) 3743bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 37599196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek CS.setKind(ConversionSpecifier::sArg); 3763bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 377876e994957472eda4b40136d4e1d6e08e2be338fTom Care // Disable irrelevant flags 378876e994957472eda4b40136d4e1d6e08e2be338fTom Care HasAlternativeForm = 0; 379876e994957472eda4b40136d4e1d6e08e2be338fTom Care HasLeadingZeroes = 0; 380876e994957472eda4b40136d4e1d6e08e2be338fTom Care 3813bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set the long length modifier for wide characters 3823bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (QT->getPointeeType()->isWideCharType()) 3833bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsWideChar); 384117348caf0a8f91782e9e32e32a8689576f394d7Hans Wennborg else 385117348caf0a8f91782e9e32e32a8689576f394d7Hans Wennborg LM.setKind(LengthModifier::None); 3863bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 3873bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return true; 3883bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 3893bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 390033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose // If it's an enum, get its underlying type. 391033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose if (const EnumType *ETy = QT->getAs<EnumType>()) 392033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose QT = ETy->getDecl()->getIntegerType(); 393033a9c0804f48119a03b73a2af42a04d4d0294ceJordan Rose 3943bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // We can only work with builtin types. 3953bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care const BuiltinType *BT = QT->getAs<BuiltinType>(); 3962dde35bc626153492f5f58202506c88a27fbff5bJohn McCall if (!BT) 3972dde35bc626153492f5f58202506c88a27fbff5bJohn McCall return false; 398876e994957472eda4b40136d4e1d6e08e2be338fTom Care 3993bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set length modifier 4003bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (BT->getKind()) { 40106d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Bool: 40206d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::WChar_U: 40306d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::WChar_S: 40406d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Char16: 40506d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Char32: 40606d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::UInt128: 40706d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Int128: 408aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov case BuiltinType::Half: 4092dde35bc626153492f5f58202506c88a27fbff5bJohn McCall // Various types which are non-trivial to correct. 41006d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman return false; 41106d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman 4122dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define SIGNED_TYPE(Id, SingletonId) 4132dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define UNSIGNED_TYPE(Id, SingletonId) 4142dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define FLOATING_TYPE(Id, SingletonId) 4152dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define BUILTIN_TYPE(Id, SingletonId) \ 4162dde35bc626153492f5f58202506c88a27fbff5bJohn McCall case BuiltinType::Id: 4172dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#include "clang/AST/BuiltinTypes.def" 41806d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman // Misc other stuff which doesn't make sense here. 41906d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman return false; 42006d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman 42106d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::UInt: 42206d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Int: 42306d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Float: 42406d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Double: 425876e994957472eda4b40136d4e1d6e08e2be338fTom Care LM.setKind(LengthModifier::None); 4263bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 427876e994957472eda4b40136d4e1d6e08e2be338fTom Care 4284d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Char_U: 4294d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::UChar: 4304d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Char_S: 4314d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::SChar: 4324d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::AsChar); 4334d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek break; 4344d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek 4354d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Short: 4364d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::UShort: 4374d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::AsShort); 4384d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek break; 4394d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek 4403bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::Long: 4413bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::ULong: 4423bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLong); 4433bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 4443bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4453bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::LongLong: 4463bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::ULongLong: 4473bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLongLong); 4483bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 4493bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4503bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::LongDouble: 4513bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLongDouble); 4523bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 4533bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4543bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 455a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 4564684778993c667246039b4664acbce59dc99440cHans Wennborg if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) 4574684778993c667246039b4664acbce59dc99440cHans Wennborg namedTypeToLengthModifier(QT, LM); 458a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg 459be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg // If fixing the length modifier was enough, we are done. 460be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg const analyze_printf::ArgTypeResult &ATR = getArgType(Ctx, IsObjCLiteral); 461be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg if (hasValidLengthModifier() && ATR.isValid() && ATR.matchesType(Ctx, QT)) 462be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg return true; 463be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg 4643bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set conversion specifier and disable any flags which do not apply to it. 4654d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek // Let typedefs to char fall through to int, as %c is silly for uint8_t. 4664d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) { 46792a6febe130dd9ad726983835297e11b2fa3b93fTed Kremenek CS.setKind(ConversionSpecifier::cArg); 4684d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::None); 4693bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care Precision.setHowSpecified(OptionalAmount::NotSpecified); 4703bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 4713bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasLeadingZeroes = 0; 472e4ee9663168dfb2b4122c768091e30217328c9faTom Care HasPlusPrefix = 0; 4733bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4743bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 4750c293ea13d452c1a47a05ada5a5ee9acc69c66ccDouglas Gregor else if (QT->isRealFloatingType()) { 4763bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care CS.setKind(ConversionSpecifier::fArg); 4773bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4783bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care else if (QT->isSignedIntegerType()) { 4793bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care CS.setKind(ConversionSpecifier::dArg); 4803bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 4813bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 482c8c4b4088cf0b3afeda425b25fa7c77d3873b12cDouglas Gregor else if (QT->isUnsignedIntegerType()) { 483be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg CS.setKind(ConversionSpecifier::uArg); 4843bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 485e4ee9663168dfb2b4122c768091e30217328c9faTom Care HasPlusPrefix = 0; 4863060178ad9df29789505c1e6debcfc80a3a13587Chad Rosier } else { 487b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unexpected type"); 4883bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4893bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4903bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return true; 4913bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care} 4923bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid PrintfSpecifier::toString(raw_ostream &os) const { 4943bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Whilst some features have no defined order, we are using the order 4950099530a2288df7c2140dd8992b7310b9f6930a9NAKAMURA Takumi // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 4963bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << "%"; 4973bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4983bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Positional args 4993bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (usesPositionalArg()) { 5003bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << getPositionalArgIndex() << "$"; 5013bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 5023bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5033bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Conversion flags 5043bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (IsLeftJustified) os << "-"; 5053bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasPlusPrefix) os << "+"; 5063bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasSpacePrefix) os << " "; 5073bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasAlternativeForm) os << "#"; 5083bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasLeadingZeroes) os << "0"; 5093bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 5103bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Minimum field width 5113bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care FieldWidth.toString(os); 5123bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Precision 5133bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care Precision.toString(os); 5143bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Length modifier 5153bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << LM.toString(); 5163bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Conversion specifier 5173bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << CS.toString(); 5183bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care} 519e4ee9663168dfb2b4122c768091e30217328c9faTom Care 520826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidPlusPrefix() const { 521e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasPlusPrefix) 522e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 523e4ee9663168dfb2b4122c768091e30217328c9faTom Care 524e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The plus prefix only makes sense for signed conversions 525e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 526e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 527e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 528e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 529e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 530e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 531e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 532e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 533e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 534e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 535e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 536e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 537e4ee9663168dfb2b4122c768091e30217328c9faTom Care 538e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 539e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 540e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 541e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 542e4ee9663168dfb2b4122c768091e30217328c9faTom Care 543826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidAlternativeForm() const { 544e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasAlternativeForm) 545e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 546e4ee9663168dfb2b4122c768091e30217328c9faTom Care 5472e6c19abcf97c25f4d7458a9db89c5ab0158717dAnders Carlsson // Alternate form flag only valid with the oxXaAeEfFgG conversions 548e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 549e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 550e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 5512e6c19abcf97c25f4d7458a9db89c5ab0158717dAnders Carlsson case ConversionSpecifier::XArg: 552e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 553e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 554e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 555e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 556e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 557e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 558e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 559e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 560e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 561e4ee9663168dfb2b4122c768091e30217328c9faTom Care 562e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 563e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 564e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 565e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 566e4ee9663168dfb2b4122c768091e30217328c9faTom Care 567826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidLeadingZeros() const { 568e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasLeadingZeroes) 569e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 570e4ee9663168dfb2b4122c768091e30217328c9faTom Care 571e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 572e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 573e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 574e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 575e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 576e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::uArg: 577e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 578e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::XArg: 579e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 580e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 581e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 582e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 583e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 584e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 585e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 586e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 587e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 588e4ee9663168dfb2b4122c768091e30217328c9faTom Care 589e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 590e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 591e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 592e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 593e4ee9663168dfb2b4122c768091e30217328c9faTom Care 594826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidSpacePrefix() const { 595e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasSpacePrefix) 596e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 597e4ee9663168dfb2b4122c768091e30217328c9faTom Care 598e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The space prefix only makes sense for signed conversions 599e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 600e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 601e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 602e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 603e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 604e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 605e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 606e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 607e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 608e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 609e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 610e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 611e4ee9663168dfb2b4122c768091e30217328c9faTom Care 612e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 613e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 614e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 615e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 616e4ee9663168dfb2b4122c768091e30217328c9faTom Care 617826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidLeftJustified() const { 618e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!IsLeftJustified) 619e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 620e4ee9663168dfb2b4122c768091e30217328c9faTom Care 621e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The left justified flag is valid for all conversions except n 622e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 62335d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case ConversionSpecifier::nArg: 624e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 625e4ee9663168dfb2b4122c768091e30217328c9faTom Care 626e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 627e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 628e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 629e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 630e4ee9663168dfb2b4122c768091e30217328c9faTom Care 63165197b4b0c55bb74af0450230d61ee9461223721Ted Kremenekbool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 63265197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek if (!HasThousandsGrouping) 63365197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return true; 634dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 63565197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek switch (CS.getKind()) { 63665197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::dArg: 63765197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::iArg: 63865197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::uArg: 63965197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::fArg: 64065197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::FArg: 64165197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::gArg: 64265197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::GArg: 64365197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return true; 64465197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek default: 64565197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return false; 64665197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek } 64765197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek} 64865197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek 649826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidPrecision() const { 650e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 651e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 652e4ee9663168dfb2b4122c768091e30217328c9faTom Care 653e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Precision is only valid with the diouxXaAeEfFgGs conversions 654e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 655e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 656e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 657e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 658e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::uArg: 659e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 660e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::XArg: 661e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 662e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 663e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 664e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 665e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 666e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 667e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 668e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 66999196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek case ConversionSpecifier::sArg: 670e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 671e4ee9663168dfb2b4122c768091e30217328c9faTom Care 672e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 673e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 674e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 675e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 676826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidFieldWidth() const { 677e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 678e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 679e4ee9663168dfb2b4122c768091e30217328c9faTom Care 680e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The field width is valid for all conversions except n 681e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 68235d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case ConversionSpecifier::nArg: 683e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 684e4ee9663168dfb2b4122c768091e30217328c9faTom Care 685e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 686e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 687e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 688e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 689