SemaChecking.cpp revision b7c21018ec1049580cf6df88db09e606550a7baa
159907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner//===--- SemaChecking.cpp - Extra Semantic Checking -----------------------===// 259907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner// 359907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner// The LLVM Compiler Infrastructure 459907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 759907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner// 859907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner//===----------------------------------------------------------------------===// 959907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner// 101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump// This file implements extra semantic analysis beyond what is enforced 1159907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner// by the C type system. 1259907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner// 1359907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner//===----------------------------------------------------------------------===// 1459907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner 1559907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner#include "Sema.h" 16826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "clang/Analysis/Analyses/FormatString.h" 1759907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner#include "clang/AST/ASTContext.h" 18199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck#include "clang/AST/CharUnits.h" 19c4a1dea2dc56bd1357ec91b829a0b9e68229a13eDaniel Dunbar#include "clang/AST/DeclObjC.h" 202324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek#include "clang/AST/ExprCXX.h" 217ff22b259d4d4729f701679e3a7f0e242365e07fTed Kremenek#include "clang/AST/ExprObjC.h" 22f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump#include "clang/AST/DeclObjC.h" 23f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump#include "clang/AST/StmtCXX.h" 24f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump#include "clang/AST/StmtObjC.h" 25719e61573f27c11057ecfe0dd8f141621602c571Chris Lattner#include "clang/Lex/LiteralSupport.h" 2659907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner#include "clang/Lex/Preprocessor.h" 27f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump#include "llvm/ADT/BitVector.h" 28f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump#include "llvm/ADT/STLExtras.h" 290d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman#include "llvm/ADT/StringExtras.h" 303bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care#include "llvm/Support/raw_ostream.h" 31691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher#include "clang/Basic/TargetBuiltins.h" 3226a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman#include "clang/Basic/TargetInfo.h" 33a1f3dba77b7418575c1ff539ffa74ebaa068280cZhongxing Xu#include <limits> 3459907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattnerusing namespace clang; 3559907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner 3660800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner/// getLocationOfStringLiteralByte - Return a source location that points to the 3760800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner/// specified byte of the specified string literal. 3860800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner/// 3960800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner/// Strings are amazingly complex. They can be formed from multiple tokens and 4060800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner/// can have escape sequences in them in addition to the usual trigraph and 4160800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner/// escaped newline business. This routine handles this complexity. 4260800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner/// 4360800081361b0ffc114877b8abbc81cb57b4edf6Chris LattnerSourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL, 4460800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner unsigned ByteNo) const { 4560800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner assert(!SL->isWide() && "This doesn't work for wide strings yet"); 461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4760800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // Loop over all of the tokens in this string until we find the one that 4860800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // contains the byte we're looking for. 4960800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner unsigned TokNo = 0; 5060800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner while (1) { 5160800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner assert(TokNo < SL->getNumConcatenated() && "Invalid byte number!"); 5260800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner SourceLocation StrTokLoc = SL->getStrTokenLoc(TokNo); 531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5460800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // Get the spelling of the string so that we can get the data that makes up 5560800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // the string literal, not the identifier for the macro it is potentially 5660800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // expanded through. 5760800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner SourceLocation StrTokSpellingLoc = SourceMgr.getSpellingLoc(StrTokLoc); 5860800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner 5960800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // Re-lex the token to get its length and original spelling. 6060800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner std::pair<FileID, unsigned> LocInfo = 6160800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner SourceMgr.getDecomposedLoc(StrTokSpellingLoc); 62f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor bool Invalid = false; 63f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer llvm::StringRef Buffer = SourceMgr.getBufferData(LocInfo.first, &Invalid); 64f715ca12bfc9fddfde75f98a197424434428b821Douglas Gregor if (Invalid) 65aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor return StrTokSpellingLoc; 66aea67dbd653a2dd6dd5cc2159279e81e855b2482Douglas Gregor 67f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer const char *StrData = Buffer.data()+LocInfo.second; 681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6960800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // Create a langops struct and enable trigraphs. This is sufficient for 7060800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // relexing tokens. 7160800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner LangOptions LangOpts; 7260800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner LangOpts.Trigraphs = true; 731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7460800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // Create a lexer starting at the beginning of this token. 75f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer Lexer TheLexer(StrTokSpellingLoc, LangOpts, Buffer.begin(), StrData, 76f6ac97b101c8840efa92bf29166077ce4049e293Benjamin Kramer Buffer.end()); 7760800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner Token TheTok; 7860800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner TheLexer.LexFromRawLexer(TheTok); 791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 80443e53c7845f01c8ed693ccd137abb0bd76564f6Chris Lattner // Use the StringLiteralParser to compute the length of the string in bytes. 81b90f4b3fb94056609da9cca5eef7358d95a363b2Douglas Gregor StringLiteralParser SLP(&TheTok, 1, PP, /*Complain=*/false); 82443e53c7845f01c8ed693ccd137abb0bd76564f6Chris Lattner unsigned TokNumBytes = SLP.GetStringLength(); 831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 842197c963543397777919cec22b65feb31a9ddf79Chris Lattner // If the byte is in this token, return the location of the byte. 8560800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner if (ByteNo < TokNumBytes || 8660800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner (ByteNo == TokNumBytes && TokNo == SL->getNumConcatenated())) { 871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned Offset = 88b90f4b3fb94056609da9cca5eef7358d95a363b2Douglas Gregor StringLiteralParser::getOffsetOfStringByte(TheTok, ByteNo, PP, 89b90f4b3fb94056609da9cca5eef7358d95a363b2Douglas Gregor /*Complain=*/false); 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 91719e61573f27c11057ecfe0dd8f141621602c571Chris Lattner // Now that we know the offset of the token in the spelling, use the 92719e61573f27c11057ecfe0dd8f141621602c571Chris Lattner // preprocessor to get the offset in the original source. 93719e61573f27c11057ecfe0dd8f141621602c571Chris Lattner return PP.AdvanceToTokenCharacter(StrTokLoc, Offset); 9460800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner } 951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9660800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner // Move to the next string token. 9760800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner ++TokNo; 9860800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner ByteNo -= TokNumBytes; 9960800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner } 10060800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner} 10160800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner 1024403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn/// CheckablePrintfAttr - does a function call have a "printf" attribute 1034403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn/// and arguments that merit checking? 1044403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynnbool Sema::CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall) { 1054403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn if (Format->getType() == "printf") return true; 1064403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn if (Format->getType() == "printf0") { 1074403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn // printf0 allows null "format" string; if so don't check format/args 1084403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn unsigned format_idx = Format->getFormatIdx() - 1; 1094a2614e94672c47395abcde60518776fbebec589Sebastian Redl // Does the index refer to the implicit object argument? 1104a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (isa<CXXMemberCallExpr>(TheCall)) { 1114a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (format_idx == 0) 1124a2614e94672c47395abcde60518776fbebec589Sebastian Redl return false; 1134a2614e94672c47395abcde60518776fbebec589Sebastian Redl --format_idx; 1144a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 1154403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn if (format_idx < TheCall->getNumArgs()) { 1164403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn Expr *Format = TheCall->getArg(format_idx)->IgnoreParenCasts(); 117efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (!Format->isNullPointerConstant(Context, 118efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek Expr::NPC_ValueDependentIsNull)) 1194403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn return true; 1204403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn } 1214403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn } 1224403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn return false; 1234403a5e1f956fa86d515492dbe7c7a2817d8780dRyan Flynn} 12460800081361b0ffc114877b8abbc81cb57b4edf6Chris Lattner 1250eb23307222bda7ad95d968eac4e1ab30864b213Sebastian RedlAction::OwningExprResult 126d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders CarlssonSema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { 1270eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl OwningExprResult TheCallResult(Owned(TheCall)); 1282def48394f6d48bde0dec2b514193c2b533265b5Douglas Gregor 129d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson switch (BuiltinID) { 13030ce344307f8a8b00054021307015571f83c7364Chris Lattner case Builtin::BI__builtin___CFStringMakeConstantString: 131925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner assert(TheCall->getNumArgs() == 1 && 1321b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner "Wrong # arguments to builtin CFStringMakeConstantString"); 133690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner if (CheckObjCString(TheCall->getArg(0))) 1340eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(); 135d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson break; 13649ff7a1c8c67d56e62d3b4627463b705c0d5008cTed Kremenek case Builtin::BI__builtin_stdarg_start: 13730ce344307f8a8b00054021307015571f83c7364Chris Lattner case Builtin::BI__builtin_va_start: 1380eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl if (SemaBuiltinVAStart(TheCall)) 1390eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(); 140d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson break; 1411b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner case Builtin::BI__builtin_isgreater: 1421b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner case Builtin::BI__builtin_isgreaterequal: 1431b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner case Builtin::BI__builtin_isless: 1441b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner case Builtin::BI__builtin_islessequal: 1451b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner case Builtin::BI__builtin_islessgreater: 1461b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner case Builtin::BI__builtin_isunordered: 1470eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl if (SemaBuiltinUnorderedCompare(TheCall)) 1480eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(); 149d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson break; 150e771a7ac11fb27f0e734e5de4d858f2c268895e5Benjamin Kramer case Builtin::BI__builtin_fpclassify: 151e771a7ac11fb27f0e734e5de4d858f2c268895e5Benjamin Kramer if (SemaBuiltinFPClassification(TheCall, 6)) 152e771a7ac11fb27f0e734e5de4d858f2c268895e5Benjamin Kramer return ExprError(); 153e771a7ac11fb27f0e734e5de4d858f2c268895e5Benjamin Kramer break; 1549ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman case Builtin::BI__builtin_isfinite: 1559ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman case Builtin::BI__builtin_isinf: 1569ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman case Builtin::BI__builtin_isinf_sign: 1579ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman case Builtin::BI__builtin_isnan: 1589ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman case Builtin::BI__builtin_isnormal: 1593b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer if (SemaBuiltinFPClassification(TheCall, 1)) 1609ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman return ExprError(); 1619ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman break; 1626cfda23b3768f93a6eb0b2a9135c8334a20125bbEli Friedman case Builtin::BI__builtin_return_address: 163691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher case Builtin::BI__builtin_frame_address: { 164691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher llvm::APSInt Result; 165691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (SemaBuiltinConstantArg(TheCall, 0, Result)) 1660eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(); 167d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson break; 168691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher } 169691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher case Builtin::BI__builtin_eh_return_data_regno: { 170691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher llvm::APSInt Result; 171691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (SemaBuiltinConstantArg(TheCall, 0, Result)) 17221fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner return ExprError(); 17321fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner break; 174691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher } 175d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman case Builtin::BI__builtin_shufflevector: 1760eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return SemaBuiltinShuffleVector(TheCall); 1770eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl // TheCall will be freed by the smart pointer here, but that's fine, since 1780eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl // SemaBuiltinShuffleVector guts it, but then doesn't release it. 1794493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar case Builtin::BI__builtin_prefetch: 1800eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl if (SemaBuiltinPrefetch(TheCall)) 1810eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(); 182d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson break; 183d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar case Builtin::BI__builtin_object_size: 1840eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl if (SemaBuiltinObjectSize(TheCall)) 1850eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(); 186d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson break; 187d875fed28578835de89cd407e9db4be788596d7cEli Friedman case Builtin::BI__builtin_longjmp: 188d875fed28578835de89cd407e9db4be788596d7cEli Friedman if (SemaBuiltinLongjmp(TheCall)) 189d875fed28578835de89cd407e9db4be788596d7cEli Friedman return ExprError(); 190d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson break; 1915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add: 1925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub: 1935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or: 1945caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and: 1955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor: 1965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_add_and_fetch: 1975caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_sub_and_fetch: 1985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_and_and_fetch: 1995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_or_and_fetch: 2005caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_xor_and_fetch: 2015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap: 2025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap: 2035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_test_and_set: 2045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release: 205d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return SemaBuiltinAtomicOverloaded(move(TheCallResult)); 20626a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman } 20726a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman 20826a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman // Since the target specific builtins for each arch overlap, only check those 20926a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman // of the arch we are compiling for. 21026a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman if (BuiltinID >= Builtin::FirstTSBuiltin) { 21126a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman switch (Context.Target.getTriple().getArch()) { 21226a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman case llvm::Triple::arm: 21326a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman case llvm::Triple::thumb: 21426a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall)) 21526a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman return ExprError(); 21626a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman break; 21726a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman case llvm::Triple::x86: 21826a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman case llvm::Triple::x86_64: 21926a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman if (CheckX86BuiltinFunctionCall(BuiltinID, TheCall)) 22026a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman return ExprError(); 22126a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman break; 22226a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman default: 22326a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman break; 22426a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman } 22526a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman } 22626a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman 22726a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman return move(TheCallResult); 22826a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman} 22926a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman 23026a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begemanbool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { 23126a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman switch (BuiltinID) { 232691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher case X86::BI__builtin_ia32_palignr128: 233691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher case X86::BI__builtin_ia32_palignr: { 234691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher llvm::APSInt Result; 235691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (SemaBuiltinConstantArg(TheCall, 2, Result)) 23626a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman return true; 237691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher break; 238691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher } 23971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson } 24026a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman return false; 24126a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman} 2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 24361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman// Get the valid immediate range for the specified NEON type code. 24461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begemanstatic unsigned RFT(unsigned t, bool shift = false) { 24561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman bool quad = t & 0x10; 24661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 24761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman switch (t & 0x7) { 24861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 0: // i8 249d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return shift ? 7 : (8 << (int)quad) - 1; 25061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 1: // i16 251d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return shift ? 15 : (4 << (int)quad) - 1; 25261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 2: // i32 253d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return shift ? 31 : (2 << (int)quad) - 1; 25461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 3: // i64 255d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return shift ? 63 : (1 << (int)quad) - 1; 25661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 4: // f32 25761eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman assert(!shift && "cannot shift float types!"); 258d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return (2 << (int)quad) - 1; 25961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 5: // poly8 26061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman assert(!shift && "cannot shift polynomial types!"); 261d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return (8 << (int)quad) - 1; 26261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 6: // poly16 26361eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman assert(!shift && "cannot shift polynomial types!"); 264d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return (4 << (int)quad) - 1; 26561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman case 7: // float16 26661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman assert(!shift && "cannot shift float types!"); 267d69ec16b1b03b4a97c571ff14f15769fe13c1e5aNate Begeman return (4 << (int)quad) - 1; 26861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman } 26961eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman return 0; 27061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman} 27161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman 27226a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begemanbool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { 2731c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman llvm::APSInt Result; 2741c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman 2750d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman unsigned mask = 0; 27661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman unsigned TV = 0; 2771c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman switch (BuiltinID) { 278a23326b5c244a03bf61ebb86db60a777ea26f926Nate Begeman#define GET_NEON_OVERLOAD_CHECK 279a23326b5c244a03bf61ebb86db60a777ea26f926Nate Begeman#include "clang/Basic/arm_neon.inc" 280a23326b5c244a03bf61ebb86db60a777ea26f926Nate Begeman#undef GET_NEON_OVERLOAD_CHECK 2811c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman } 2821c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman 2830d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman // For NEON intrinsics which are overloaded on vector element type, validate 2840d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman // the immediate which specifies which variant to emit. 2850d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman if (mask) { 2860d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman unsigned ArgNo = TheCall->getNumArgs()-1; 2870d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman if (SemaBuiltinConstantArg(TheCall, ArgNo, Result)) 2880d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman return true; 2890d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman 29061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman TV = Result.getLimitedValue(32); 29161eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman if ((TV > 31) || (mask & (1 << TV)) == 0) 2920d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code) 2930d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman << TheCall->getArg(ArgNo)->getSourceRange(); 2940d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman } 2951c2a88cfaeb11227d3a6bf7204207e0c8cf6de6fNate Begeman 2960d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman // For NEON intrinsics which take an immediate value as part of the 2970d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman // instruction, range check them here. 29861eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman unsigned i = 0, l = 0, u = 0; 2990d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman switch (BuiltinID) { 3000d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman default: return false; 301a23326b5c244a03bf61ebb86db60a777ea26f926Nate Begeman#define GET_NEON_IMMEDIATE_CHECK 302a23326b5c244a03bf61ebb86db60a777ea26f926Nate Begeman#include "clang/Basic/arm_neon.inc" 303a23326b5c244a03bf61ebb86db60a777ea26f926Nate Begeman#undef GET_NEON_IMMEDIATE_CHECK 3040d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman }; 3050d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman 30661eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman // Check that the immediate argument is actually a constant. 3070d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman if (SemaBuiltinConstantArg(TheCall, i, Result)) 3080d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman return true; 3090d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman 31061eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman // Range check against the upper/lower values for this isntruction. 3110d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman unsigned Val = Result.getZExtValue(); 31261eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman if (Val < l || Val > (u + l)) 3130d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) 31461eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman << llvm::utostr(l) << llvm::utostr(u+l) 31561eecf5aea018ea65c9ab0bccacd2996b15c632dNate Begeman << TheCall->getArg(i)->getSourceRange(); 3160d15c5321a11a5fee53b17ca8e9e0d72d6192b23Nate Begeman 31726a31428f130b66f61834d1b4d1cf72f590f70b9Nate Begeman return false; 318d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson} 319d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson 320d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson/// CheckFunctionCall - Check a direct function call for various correctness 321d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson/// and safety properties not strictly enforced by the C type system. 322d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlssonbool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { 323d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson // Get the IdentifierInfo* for the called function. 324d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson IdentifierInfo *FnInfo = FDecl->getIdentifier(); 325de45428f923b38d80407dbb9ede0df504256f9f6Daniel Dunbar 326d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson // None of the checks below are needed for functions that don't have 327d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson // simple names (e.g., C++ conversion functions). 328d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson if (!FnInfo) 329d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson return false; 3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 331de45428f923b38d80407dbb9ede0df504256f9f6Daniel Dunbar // FIXME: This mechanism should be abstracted to be less fragile and 332de45428f923b38d80407dbb9ede0df504256f9f6Daniel Dunbar // more efficient. For example, just map function ids to custom 333de45428f923b38d80407dbb9ede0df504256f9f6Daniel Dunbar // handlers. 334de45428f923b38d80407dbb9ede0df504256f9f6Daniel Dunbar 33559907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner // Printf checking. 33640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) { 337826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const bool b = Format->getType() == "scanf"; 338826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (b || CheckablePrintfAttr(Format, TheCall)) { 3393d692df4b9c58895f9843b03543ec57447c93679Ted Kremenek bool HasVAListArg = Format->getFirstArg() == 0; 340826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckPrintfScanfArguments(TheCall, HasVAListArg, 341826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Format->getFormatIdx() - 1, 342826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasVAListArg ? 0 : Format->getFirstArg() - 1, 343826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek !b); 3443c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor } 34559907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner } 3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull; 348d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson NonNull = NonNull->getNext<NonNullAttr>()) 349d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson CheckNonNullArguments(NonNull, TheCall); 3500eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl 351d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson return false; 35271993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson} 35371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson 354d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlssonbool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) { 355725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian // Printf checking. 35640b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis const FormatAttr *Format = NDecl->getAttr<FormatAttr>(); 357725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian if (!Format) 358d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson return false; 3591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 360725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian const VarDecl *V = dyn_cast<VarDecl>(NDecl); 361725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian if (!V) 362d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson return false; 3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 364725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian QualType Ty = V->getType(); 365725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian if (!Ty->isBlockPointerType()) 366d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson return false; 3671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 368826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const bool b = Format->getType() == "scanf"; 369826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!b && !CheckablePrintfAttr(Format, TheCall)) 370d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson return false; 3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 372d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson bool HasVAListArg = Format->getFirstArg() == 0; 373826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckPrintfScanfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1, 374826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasVAListArg ? 0 : Format->getFirstArg() - 1, !b); 375d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson 376d406bf0e8c17012110a8476d03c6f9a97b56ecf7Anders Carlsson return false; 377725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian} 378725165f2846bd37d3aaf863747fa30126992085eFariborz Jahanian 3795caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// SemaBuiltinAtomicOverloaded - We have a call to a function like 3805caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// __sync_fetch_and_add, which is an overloaded function based on the pointer 3815caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// type of its first argument. The main ActOnCallExpr routines have already 3825caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// promoted the types of arguments because all of these calls are prototyped as 3835caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// void(...). 3845caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// 3855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// This function goes through and does final semantic checking for these 3865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner/// builtins, 387d201457cc781f1b13d0f4b1268ff934e6004cbffChandler CarruthSema::OwningExprResult 388d201457cc781f1b13d0f4b1268ff934e6004cbffChandler CarruthSema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) { 389d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth CallExpr *TheCall = (CallExpr *)TheCallResult.get(); 3905caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); 3915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl()); 3925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner 3935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Ensure that we have at least one argument to do type inference from. 394d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth if (TheCall->getNumArgs() < 1) { 395d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least) 396d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth << 0 << 1 << TheCall->getNumArgs() 397d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth << TheCall->getCallee()->getSourceRange(); 398d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return ExprError(); 399d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth } 4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4015caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Inspect the first argument of the atomic builtin. This should always be 4025caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // a pointer type, whose element is an integral scalar or pointer type. 4035caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Because it is a pointer type, we don't have to worry about any implicit 4045caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // casts here. 405d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth // FIXME: We don't allow floating point scalars as input. 4065caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner Expr *FirstArg = TheCall->getArg(0); 407d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth if (!FirstArg->getType()->isPointerType()) { 408d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer) 409d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth << FirstArg->getType() << FirstArg->getSourceRange(); 410d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return ExprError(); 411d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth } 4121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 413d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth QualType ValType = 414d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth FirstArg->getType()->getAs<PointerType>()->getPointeeType(); 4151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!ValType->isIntegerType() && !ValType->isPointerType() && 416d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth !ValType->isBlockPointerType()) { 417d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer_intptr) 418d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth << FirstArg->getType() << FirstArg->getSourceRange(); 419d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return ExprError(); 420d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth } 4215caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner 4225caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // We need to figure out which concrete builtin this maps onto. For example, 4235caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // __sync_fetch_and_add with a 2 byte object turns into 4245caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // __sync_fetch_and_add_2. 4255caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner#define BUILTIN_ROW(x) \ 4265caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \ 4275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner Builtin::BI##x##_8, Builtin::BI##x##_16 } 4281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner static const unsigned BuiltinIndices[][5] = { 4305caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_fetch_and_add), 4315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_fetch_and_sub), 4325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_fetch_and_or), 4335caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_fetch_and_and), 4345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_fetch_and_xor), 4351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4365caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_add_and_fetch), 4375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_sub_and_fetch), 4385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_and_and_fetch), 4395caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_or_and_fetch), 4405caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_xor_and_fetch), 4411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4425caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_val_compare_and_swap), 4435caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_bool_compare_and_swap), 4445caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_lock_test_and_set), 4455caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner BUILTIN_ROW(__sync_lock_release) 4465caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner }; 4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#undef BUILTIN_ROW 4481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4495caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Determine the index of the size. 4505caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner unsigned SizeIndex; 451199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck switch (Context.getTypeSizeInChars(ValType).getQuantity()) { 4525caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case 1: SizeIndex = 0; break; 4535caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case 2: SizeIndex = 1; break; 4545caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case 4: SizeIndex = 2; break; 4555caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case 8: SizeIndex = 3; break; 4565caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case 16: SizeIndex = 4; break; 4575caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner default: 458d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Diag(DRE->getLocStart(), diag::err_atomic_builtin_pointer_size) 459d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth << FirstArg->getType() << FirstArg->getSourceRange(); 460d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return ExprError(); 4615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner } 4621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4635caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Each of these builtins has one pointer argument, followed by some number of 4645caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // values (0, 1 or 2) followed by a potentially empty varags list of stuff 4655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // that we ignore. Find out which row of BuiltinIndices to read from as well 4665caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // as the number of fixed args. 4677814e6d6645d587891293d59ecf6576defcfac92Douglas Gregor unsigned BuiltinID = FDecl->getBuiltinID(); 4685caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner unsigned BuiltinIndex, NumFixed = 1; 4695caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner switch (BuiltinID) { 4705caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner default: assert(0 && "Unknown overloaded atomic builtin!"); 4715caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_add: BuiltinIndex = 0; break; 4725caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_sub: BuiltinIndex = 1; break; 4735caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_or: BuiltinIndex = 2; break; 4745caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_and: BuiltinIndex = 3; break; 4755caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_fetch_and_xor: BuiltinIndex = 4; break; 4761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4777eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar case Builtin::BI__sync_add_and_fetch: BuiltinIndex = 5; break; 4787eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar case Builtin::BI__sync_sub_and_fetch: BuiltinIndex = 6; break; 4797eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar case Builtin::BI__sync_and_and_fetch: BuiltinIndex = 7; break; 4807eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar case Builtin::BI__sync_or_and_fetch: BuiltinIndex = 8; break; 4817eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar case Builtin::BI__sync_xor_and_fetch: BuiltinIndex = 9; break; 4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4835caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_val_compare_and_swap: 4847eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar BuiltinIndex = 10; 4855caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner NumFixed = 2; 4865caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner break; 4875caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_bool_compare_and_swap: 4887eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar BuiltinIndex = 11; 4895caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner NumFixed = 2; 4905caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner break; 4917eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar case Builtin::BI__sync_lock_test_and_set: BuiltinIndex = 12; break; 4925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner case Builtin::BI__sync_lock_release: 4937eff7c4153faf45b19b5919ef409ee5f6794eb25Daniel Dunbar BuiltinIndex = 13; 4945caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner NumFixed = 0; 4955caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner break; 4965caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner } 4971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4985caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Now that we know how many fixed arguments we expect, first check that we 4995caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // have at least that many. 500d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth if (TheCall->getNumArgs() < 1+NumFixed) { 501d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least) 502d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth << 0 << 1+NumFixed << TheCall->getNumArgs() 503d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth << TheCall->getCallee()->getSourceRange(); 504d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return ExprError(); 505d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth } 5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 507e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner // Get the decl for the concrete builtin from this, we can tell what the 508e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner // concrete integer type we should convert to is. 509e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; 510e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner const char *NewBuiltinName = Context.BuiltinInfo.GetName(NewBuiltinID); 511e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner IdentifierInfo *NewBuiltinII = PP.getIdentifierInfo(NewBuiltinName); 5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump FunctionDecl *NewBuiltinDecl = 513e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID, 514e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner TUScope, false, DRE->getLocStart())); 515e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner const FunctionProtoType *BuiltinFT = 516183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall NewBuiltinDecl->getType()->getAs<FunctionProtoType>(); 517d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth 518d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth QualType OrigValType = ValType; 5196217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek ValType = BuiltinFT->getArgType(0)->getAs<PointerType>()->getPointeeType(); 5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 521e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner // If the first type needs to be converted (e.g. void** -> int*), do it now. 522e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner if (BuiltinFT->getArgType(0) != FirstArg->getType()) { 52373c39abdbb79927605d740c93dd9629e3e4f9bfeEli Friedman ImpCastExprToType(FirstArg, BuiltinFT->getArgType(0), CastExpr::CK_BitCast); 524e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner TheCall->setArg(0, FirstArg); 525e7ac0a94f1dee3fae9292eb8372962b6d70b3e0dChris Lattner } 5261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5275caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Next, walk the valid ones promoting to the right type. 5285caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner for (unsigned i = 0; i != NumFixed; ++i) { 5295caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner Expr *Arg = TheCall->getArg(i+1); 5301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5315caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // If the argument is an implicit cast, then there was a promotion due to 5325caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // "...", just remove it now. 5335caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) { 5345caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner Arg = ICE->getSubExpr(); 5355caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner ICE->setSubExpr(0); 5365caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner ICE->Destroy(Context); 5375caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner TheCall->setArg(i+1, Arg); 5385caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner } 5391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5405caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // GCC does an implicit conversion to the pointer or integer ValType. This 5415caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // can fail in some cases (1i -> int**), check for this error case now. 542cdb61979755c1c0699c1ee25eede9a50bf94d29bAnders Carlsson CastExpr::CastKind Kind = CastExpr::CK_Unknown; 5435cf86ba6b5a724bf91cb52feade1158f1fbeb605Anders Carlsson CXXBaseSpecifierArray BasePath; 5445cf86ba6b5a724bf91cb52feade1158f1fbeb605Anders Carlsson if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath)) 545d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return ExprError(); 5461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5475caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Okay, we have something that *can* be converted to the right type. Check 5485caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // to see if there is a potentially weird extension going on here. This can 5495caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // happen when you do an atomic operation on something like an char* and 5505caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // pass in 42. The 42 gets converted to char. This is even more strange 5515caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // for things like 45.123 -> char, etc. 5521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // FIXME: Do this check. 55380971bdba20b5b280a00b7b9829026b33d3206f9Anders Carlsson ImpCastExprToType(Arg, ValType, Kind); 5545caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner TheCall->setArg(i+1, Arg); 5555caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner } 5561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5575caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Switch the DeclRefExpr to refer to the new decl. 5585caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner DRE->setDecl(NewBuiltinDecl); 5595caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner DRE->setType(NewBuiltinDecl->getType()); 5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5615caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Set the callee in the CallExpr. 5625caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // FIXME: This leaks the original parens and implicit casts. 5635caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner Expr *PromotedCall = DRE; 5645caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner UsualUnaryConversions(PromotedCall); 5655caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner TheCall->setCallee(PromotedCall); 5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5675caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner // Change the result type of the call to match the result type of the decl. 5685291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor TheCall->setType(NewBuiltinDecl->getCallResultType()); 569d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth 570d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth // If the value type was converted to an integer when processing the 571d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth // arguments (e.g. void* -> int), we need to convert the result back. 572d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth if (!Context.hasSameUnqualifiedType(ValType, OrigValType)) { 573d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Expr *E = TheCallResult.takeAs<Expr>(); 574d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth 575d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth assert(ValType->isIntegerType() && 576d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth "We always convert atomic operation values to integers."); 5777479ef6b5dd4903a7d832b4a4207045d7005a812Chandler Carruth // FIXME: Handle floating point value type here too. 578d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth CastExpr::CastKind Kind; 579d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth if (OrigValType->isIntegerType()) 580d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Kind = CastExpr::CK_IntegralCast; 581d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth else if (OrigValType->hasPointerRepresentation()) 582d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth Kind = CastExpr::CK_IntegralToPointer; 583d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth else 584d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth llvm_unreachable("Unhandled original value type!"); 585d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth 586d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth ImpCastExprToType(E, OrigValType, Kind); 587d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return Owned(E); 588d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth } 589d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth 590d201457cc781f1b13d0f4b1268ff934e6004cbffChandler Carruth return move(TheCallResult); 5915caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner} 5925caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner 5935caa370ea6f70bd3e7e4a9cc3b69ac1a849c8534Chris Lattner 594690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattner/// CheckObjCString - Checks that the argument to the builtin 59571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson/// CFString constructor is correct 596fd942628abfe30e30427875db953222ae99b4325Steve Naroff/// FIXME: GCC currently emits the following warning: 5971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// "warning: input conversion stopped due to an input byte that does not 598fd942628abfe30e30427875db953222ae99b4325Steve Naroff/// belong to the input codeset UTF-8" 599fd942628abfe30e30427875db953222ae99b4325Steve Naroff/// Note: It might also make sense to do the UTF-16 conversion here (would 600fd942628abfe30e30427875db953222ae99b4325Steve Naroff/// simplify the backend). 601690398188ea5b428f06aa13c7d4ce6eb741ad4f9Chris Lattnerbool Sema::CheckObjCString(Expr *Arg) { 60256f349400c5932a196509c0480ff6f99a9a0b48fChris Lattner Arg = Arg->IgnoreParenCasts(); 60371993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson StringLiteral *Literal = dyn_cast<StringLiteral>(Arg); 60471993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson 60571993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson if (!Literal || Literal->isWide()) { 606fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(Arg->getLocStart(), diag::err_cfstring_literal_not_string_constant) 607fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << Arg->getSourceRange(); 6089cdc4d3834f203dcde3ff274b8928e4620a914d5Anders Carlsson return true; 60971993dd85eed9cc42c6b2fa61ee5c53026b74817Anders Carlsson } 6101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 611f015b034159d40e7033309e50036804eb1971787Daniel Dunbar const char *Data = Literal->getStrData(); 612f015b034159d40e7033309e50036804eb1971787Daniel Dunbar unsigned Length = Literal->getByteLength(); 613f015b034159d40e7033309e50036804eb1971787Daniel Dunbar 614f015b034159d40e7033309e50036804eb1971787Daniel Dunbar for (unsigned i = 0; i < Length; ++i) { 615f015b034159d40e7033309e50036804eb1971787Daniel Dunbar if (!Data[i]) { 616f015b034159d40e7033309e50036804eb1971787Daniel Dunbar Diag(getLocationOfStringLiteralByte(Literal, i), 617f015b034159d40e7033309e50036804eb1971787Daniel Dunbar diag::warn_cfstring_literal_contains_nul_character) 618f015b034159d40e7033309e50036804eb1971787Daniel Dunbar << Arg->getSourceRange(); 619f015b034159d40e7033309e50036804eb1971787Daniel Dunbar break; 620f015b034159d40e7033309e50036804eb1971787Daniel Dunbar } 621f015b034159d40e7033309e50036804eb1971787Daniel Dunbar } 6221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6239cdc4d3834f203dcde3ff274b8928e4620a914d5Anders Carlsson return false; 62459907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner} 62559907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner 626c27c665c88b49dfb212aedc7bab8b9bf67658b9eChris Lattner/// SemaBuiltinVAStart - Check the arguments to __builtin_va_start for validity. 627c27c665c88b49dfb212aedc7bab8b9bf67658b9eChris Lattner/// Emit an error and return true on failure, return false on success. 628925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattnerbool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { 629925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner Expr *Fn = TheCall->getCallee(); 630925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner if (TheCall->getNumArgs() > 2) { 6312c21a073525cdfa68e4439b7af551385dc2796abChris Lattner Diag(TheCall->getArg(2)->getLocStart(), 632fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner diag::err_typecheck_call_too_many_args) 633ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher << 0 /*function call*/ << 2 << TheCall->getNumArgs() 634ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher << Fn->getSourceRange() 6351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump << SourceRange(TheCall->getArg(2)->getLocStart(), 636fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner (*(TheCall->arg_end()-1))->getLocEnd()); 63730ce344307f8a8b00054021307015571f83c7364Chris Lattner return true; 63830ce344307f8a8b00054021307015571f83c7364Chris Lattner } 63956f20ae1010aa71defd7572f660b41288c56cdd1Eli Friedman 64056f20ae1010aa71defd7572f660b41288c56cdd1Eli Friedman if (TheCall->getNumArgs() < 2) { 641d77b9a29651d748f0e30a8dad8969635fc04f725Eric Christopher return Diag(TheCall->getLocEnd(), 642d77b9a29651d748f0e30a8dad8969635fc04f725Eric Christopher diag::err_typecheck_call_too_few_args_at_least) 643d77b9a29651d748f0e30a8dad8969635fc04f725Eric Christopher << 0 /*function call*/ << 2 << TheCall->getNumArgs(); 64456f20ae1010aa71defd7572f660b41288c56cdd1Eli Friedman } 64556f20ae1010aa71defd7572f660b41288c56cdd1Eli Friedman 646c27c665c88b49dfb212aedc7bab8b9bf67658b9eChris Lattner // Determine whether the current function is variadic or not. 6479ea9bdbc14374f7bacdb50d3e52c664ff12150ffDouglas Gregor BlockScopeInfo *CurBlock = getCurBlock(); 648c27c665c88b49dfb212aedc7bab8b9bf67658b9eChris Lattner bool isVariadic; 649cd9c51433c06705645d1ee5a13da3c9a72d7d025Steve Naroff if (CurBlock) 650c71a4915ca216847599d03cab4ed1c5086b0eb43John McCall isVariadic = CurBlock->TheDecl->isVariadic(); 6519498d388810d284d3970aef0d69fa4d069fd6cafTed Kremenek else if (FunctionDecl *FD = getCurFunctionDecl()) 6529498d388810d284d3970aef0d69fa4d069fd6cafTed Kremenek isVariadic = FD->isVariadic(); 6539498d388810d284d3970aef0d69fa4d069fd6cafTed Kremenek else 65453d0ea5f5bfa647ec23418bf3a3b7c183b51e4bdArgyrios Kyrtzidis isVariadic = getCurMethodDecl()->isVariadic(); 6551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 656c27c665c88b49dfb212aedc7bab8b9bf67658b9eChris Lattner if (!isVariadic) { 65730ce344307f8a8b00054021307015571f83c7364Chris Lattner Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function); 65830ce344307f8a8b00054021307015571f83c7364Chris Lattner return true; 65930ce344307f8a8b00054021307015571f83c7364Chris Lattner } 6601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66130ce344307f8a8b00054021307015571f83c7364Chris Lattner // Verify that the second argument to the builtin is the last argument of the 66230ce344307f8a8b00054021307015571f83c7364Chris Lattner // current function or method. 66330ce344307f8a8b00054021307015571f83c7364Chris Lattner bool SecondArgIsLastNamedArgument = false; 664e2c14103dec39cbd24dac9d7b3e91277b109c14fAnders Carlsson const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts(); 6651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66688cf226caee50956ef47edd4d44cf7b80703a26cAnders Carlsson if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) { 66788cf226caee50956ef47edd4d44cf7b80703a26cAnders Carlsson if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) { 66830ce344307f8a8b00054021307015571f83c7364Chris Lattner // FIXME: This isn't correct for methods (results in bogus warning). 66930ce344307f8a8b00054021307015571f83c7364Chris Lattner // Get the last formal in the current function. 67088cf226caee50956ef47edd4d44cf7b80703a26cAnders Carlsson const ParmVarDecl *LastArg; 671cd9c51433c06705645d1ee5a13da3c9a72d7d025Steve Naroff if (CurBlock) 672cd9c51433c06705645d1ee5a13da3c9a72d7d025Steve Naroff LastArg = *(CurBlock->TheDecl->param_end()-1); 673cd9c51433c06705645d1ee5a13da3c9a72d7d025Steve Naroff else if (FunctionDecl *FD = getCurFunctionDecl()) 674371f258e61e1365b951b17931a3c5ac1530fd1a0Chris Lattner LastArg = *(FD->param_end()-1); 67530ce344307f8a8b00054021307015571f83c7364Chris Lattner else 67653d0ea5f5bfa647ec23418bf3a3b7c183b51e4bdArgyrios Kyrtzidis LastArg = *(getCurMethodDecl()->param_end()-1); 67730ce344307f8a8b00054021307015571f83c7364Chris Lattner SecondArgIsLastNamedArgument = PV == LastArg; 67830ce344307f8a8b00054021307015571f83c7364Chris Lattner } 67930ce344307f8a8b00054021307015571f83c7364Chris Lattner } 6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 68130ce344307f8a8b00054021307015571f83c7364Chris Lattner if (!SecondArgIsLastNamedArgument) 6821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(TheCall->getArg(1)->getLocStart(), 68330ce344307f8a8b00054021307015571f83c7364Chris Lattner diag::warn_second_parameter_of_va_start_not_last_named_argument); 68430ce344307f8a8b00054021307015571f83c7364Chris Lattner return false; 6856cfda23b3768f93a6eb0b2a9135c8334a20125bbEli Friedman} 68630ce344307f8a8b00054021307015571f83c7364Chris Lattner 6871b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner/// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and 6881b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner/// friends. This is declared to take (...), so we have to check everything. 689925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattnerbool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { 690925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner if (TheCall->getNumArgs() < 2) 6912c21a073525cdfa68e4439b7af551385dc2796abChris Lattner return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) 692d77b9a29651d748f0e30a8dad8969635fc04f725Eric Christopher << 0 << 2 << TheCall->getNumArgs()/*function call*/; 693925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner if (TheCall->getNumArgs() > 2) 6941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Diag(TheCall->getArg(2)->getLocStart(), 695fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner diag::err_typecheck_call_too_many_args) 696ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher << 0 /*function call*/ << 2 << TheCall->getNumArgs() 697fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << SourceRange(TheCall->getArg(2)->getLocStart(), 698fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner (*(TheCall->arg_end()-1))->getLocEnd()); 6991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 700925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner Expr *OrigArg0 = TheCall->getArg(0); 701925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner Expr *OrigArg1 = TheCall->getArg(1); 702cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor 7031b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner // Do standard promotions between the two arguments, returning their common 7041b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner // type. 705925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false); 706403bc2bd9edffe51d73776643fa87696c9417678Daniel Dunbar 707403bc2bd9edffe51d73776643fa87696c9417678Daniel Dunbar // Make sure any conversions are pushed back into the call; this is 708403bc2bd9edffe51d73776643fa87696c9417678Daniel Dunbar // type safe since unordered compare builtins are declared as "_Bool 709403bc2bd9edffe51d73776643fa87696c9417678Daniel Dunbar // foo(...)". 710403bc2bd9edffe51d73776643fa87696c9417678Daniel Dunbar TheCall->setArg(0, OrigArg0); 711403bc2bd9edffe51d73776643fa87696c9417678Daniel Dunbar TheCall->setArg(1, OrigArg1); 7121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 713cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor if (OrigArg0->isTypeDependent() || OrigArg1->isTypeDependent()) 714cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor return false; 715cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor 7161b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner // If the common type isn't a real floating type, then the arguments were 7171b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner // invalid for this operation. 7181b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner if (!Res->isRealFloatingType()) 7191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Diag(OrigArg0->getLocStart(), 720fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner diag::err_typecheck_call_invalid_ordered_compare) 721d162584991885ab004a02573a73ce06422b921fcChris Lattner << OrigArg0->getType() << OrigArg1->getType() 722fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << SourceRange(OrigArg0->getLocStart(), OrigArg1->getLocEnd()); 7231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7241b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner return false; 7251b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner} 7261b9a0793955070738cac6f04b5abe9496be9b317Chris Lattner 727e771a7ac11fb27f0e734e5de4d858f2c268895e5Benjamin Kramer/// SemaBuiltinSemaBuiltinFPClassification - Handle functions like 728e771a7ac11fb27f0e734e5de4d858f2c268895e5Benjamin Kramer/// __builtin_isnan and friends. This is declared to take (...), so we have 7293b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer/// to check everything. We expect the last argument to be a floating point 7303b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer/// value. 7313b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramerbool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) { 7323b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer if (TheCall->getNumArgs() < NumArgs) 7339ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) 734d77b9a29651d748f0e30a8dad8969635fc04f725Eric Christopher << 0 << NumArgs << TheCall->getNumArgs()/*function call*/; 7353b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer if (TheCall->getNumArgs() > NumArgs) 7363b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer return Diag(TheCall->getArg(NumArgs)->getLocStart(), 7379ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman diag::err_typecheck_call_too_many_args) 738ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher << 0 /*function call*/ << NumArgs << TheCall->getNumArgs() 7393b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer << SourceRange(TheCall->getArg(NumArgs)->getLocStart(), 7409ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman (*(TheCall->arg_end()-1))->getLocEnd()); 7419ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman 7423b1e26b708e8d00d4ba10ff857201bae2aff6baeBenjamin Kramer Expr *OrigArg = TheCall->getArg(NumArgs-1); 7431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7449ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman if (OrigArg->isTypeDependent()) 7459ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman return false; 7469ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman 74781368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner // This operation requires a non-_Complex floating-point number. 7489ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman if (!OrigArg->getType()->isRealFloatingType()) 7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return Diag(OrigArg->getLocStart(), 7509ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman diag::err_typecheck_call_invalid_unary_fp) 7519ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman << OrigArg->getType() << OrigArg->getSourceRange(); 7521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 75381368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner // If this is an implicit conversion from float -> double, remove it. 75481368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) { 75581368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner Expr *CastArg = Cast->getSubExpr(); 75681368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) { 75781368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) && 75881368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner "promotion from float to double is the only expected cast here"); 75981368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner Cast->setSubExpr(0); 76081368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner Cast->Destroy(Context); 76181368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner TheCall->setArg(NumArgs-1, CastArg); 76281368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner OrigArg = CastArg; 76381368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner } 76481368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner } 76581368fbfd6d57150f66c993dc9041d62a7a32c4fChris Lattner 7669ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman return false; 7679ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman} 7689ac6f62a77be5b281a7ddc24a16669b457ac47c2Eli Friedman 769d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman/// SemaBuiltinShuffleVector - Handle __builtin_shufflevector. 770d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman// This is declared to take (...), so we have to check everything. 7710eb23307222bda7ad95d968eac4e1ab30864b213Sebastian RedlAction::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { 77237b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman if (TheCall->getNumArgs() < 2) 7730eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(Diag(TheCall->getLocEnd(), 774d77b9a29651d748f0e30a8dad8969635fc04f725Eric Christopher diag::err_typecheck_call_too_few_args_at_least) 77537b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman << 0 /*function call*/ << 2 << TheCall->getNumArgs() 776d77b9a29651d748f0e30a8dad8969635fc04f725Eric Christopher << TheCall->getSourceRange()); 777d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman 77837b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman // Determine which of the following types of shufflevector we're checking: 77937b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman // 1) unary, vector mask: (lhs, mask) 78037b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman // 2) binary, vector mask: (lhs, rhs, mask) 78137b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman // 3) binary, scalar mask: (lhs, rhs, index, ..., index) 78237b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman QualType resType = TheCall->getArg(0)->getType(); 78337b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman unsigned numElements = 0; 78437b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman 785cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor if (!TheCall->getArg(0)->isTypeDependent() && 786cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor !TheCall->getArg(1)->isTypeDependent()) { 78737b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman QualType LHSType = TheCall->getArg(0)->getType(); 78837b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman QualType RHSType = TheCall->getArg(1)->getType(); 78937b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman 79037b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman if (!LHSType->isVectorType() || !RHSType->isVectorType()) { 791cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector) 7921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump << SourceRange(TheCall->getArg(0)->getLocStart(), 793cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor TheCall->getArg(1)->getLocEnd()); 794cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor return ExprError(); 795cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor } 79637b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman 79737b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman numElements = LHSType->getAs<VectorType>()->getNumElements(); 79837b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman unsigned numResElements = TheCall->getNumArgs() - 2; 79937b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman 80037b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman // Check to see if we have a call with 2 vector arguments, the unary shuffle 80137b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman // with mask. If so, verify that RHS is an integer vector type with the 80237b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman // same number of elts as lhs. 80337b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman if (TheCall->getNumArgs() == 2) { 80437b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman if (!RHSType->isIntegerType() || 80537b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman RHSType->getAs<VectorType>()->getNumElements() != numElements) 80637b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) 80737b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman << SourceRange(TheCall->getArg(1)->getLocStart(), 80837b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman TheCall->getArg(1)->getLocEnd()); 80937b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman numResElements = numElements; 81037b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman } 81137b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) { 812cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) 8131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump << SourceRange(TheCall->getArg(0)->getLocStart(), 814cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor TheCall->getArg(1)->getLocEnd()); 815cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor return ExprError(); 81637b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman } else if (numElements != numResElements) { 81737b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman QualType eltType = LHSType->getAs<VectorType>()->getElementType(); 818788b0fd67e1992f23555454efcdb16a19dfefac3Chris Lattner resType = Context.getVectorType(eltType, numResElements, 819788b0fd67e1992f23555454efcdb16a19dfefac3Chris Lattner VectorType::NotAltiVec); 820cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor } 821d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman } 822d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman 823d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman for (unsigned i = 2; i < TheCall->getNumArgs(); i++) { 824cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor if (TheCall->getArg(i)->isTypeDependent() || 825cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor TheCall->getArg(i)->isValueDependent()) 826cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor continue; 827cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor 82837b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman llvm::APSInt Result(32); 82937b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context)) 83037b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman return ExprError(Diag(TheCall->getLocStart(), 83137b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman diag::err_shufflevector_nonconstant_argument) 83237b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman << TheCall->getArg(i)->getSourceRange()); 8330eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl 834d1a0b6d3dfb208f638d3d750b588d9c0daa49289Chris Lattner if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2) 8350eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl return ExprError(Diag(TheCall->getLocStart(), 836fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner diag::err_shufflevector_argument_too_large) 8370eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl << TheCall->getArg(i)->getSourceRange()); 838d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman } 839d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman 840d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman llvm::SmallVector<Expr*, 32> exprs; 841d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman 842d1a0b6d3dfb208f638d3d750b588d9c0daa49289Chris Lattner for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) { 843d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman exprs.push_back(TheCall->getArg(i)); 844d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman TheCall->setArg(i, 0); 845d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman } 846d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman 847a88dc3079bedf70a5cfc39791727e43a10383006Nate Begeman return Owned(new (Context) ShuffleVectorExpr(Context, exprs.begin(), 84837b6a5731a47f811d754f0d48aa93edf30e30513Nate Begeman exprs.size(), resType, 8498189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek TheCall->getCallee()->getLocStart(), 8508189cde56b4f6f938cd65f53c932fe1860d0204cTed Kremenek TheCall->getRParenLoc())); 851d38617c8a50f9729c254ab76cd359af797c6739bEli Friedman} 85230ce344307f8a8b00054021307015571f83c7364Chris Lattner 8534493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar/// SemaBuiltinPrefetch - Handle __builtin_prefetch. 8544493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar// This is declared to take (const void*, ...) and can take two 8554493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar// optional constant int args. 8564493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbarbool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { 857fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner unsigned NumArgs = TheCall->getNumArgs(); 8584493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar 859fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner if (NumArgs > 3) 860ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher return Diag(TheCall->getLocEnd(), 861ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher diag::err_typecheck_call_too_many_args_at_most) 862ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher << 0 /*function call*/ << 3 << NumArgs 863ccfa9639f8d09733bcf1c2572c5bd3daba5bd632Eric Christopher << TheCall->getSourceRange(); 8644493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar 8654493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // Argument 0 is checked for us and the remaining arguments must be 8664493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // constant integers. 867fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner for (unsigned i = 1; i != NumArgs; ++i) { 8684493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar Expr *Arg = TheCall->getArg(i); 869691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher 8709aef7263d84d9224575e113878cfbb06b8343cbfEli Friedman llvm::APSInt Result; 871691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (SemaBuiltinConstantArg(TheCall, i, Result)) 872691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher return true; 8731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8744493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // FIXME: gcc issues a warning and rewrites these to 0. These 8754493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // seems especially odd for the third argument since the default 8764493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar // is 3. 877fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner if (i == 1) { 8789aef7263d84d9224575e113878cfbb06b8343cbfEli Friedman if (Result.getLimitedValue() > 1) 879fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) 88021fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner << "0" << "1" << Arg->getSourceRange(); 8814493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } else { 8829aef7263d84d9224575e113878cfbb06b8343cbfEli Friedman if (Result.getLimitedValue() > 3) 883fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) 88421fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner << "0" << "3" << Arg->getSourceRange(); 8854493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } 8864493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar } 8874493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar 888fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner return false; 8894493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar} 8904493f79fce48cd9cbd9f55fa9d452cde736747a0Daniel Dunbar 891691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher/// SemaBuiltinConstantArg - Handle a check if argument ArgNum of CallExpr 892691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher/// TheCall is a constant expression. 893691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopherbool Sema::SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, 894691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher llvm::APSInt &Result) { 895691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher Expr *Arg = TheCall->getArg(ArgNum); 896691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); 897691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl()); 898691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher 899691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (Arg->isTypeDependent() || Arg->isValueDependent()) return false; 900691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher 901691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (!Arg->isIntegerConstantExpr(Result, Context)) 902691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher return Diag(TheCall->getLocStart(), diag::err_constant_integer_arg_type) 9035e8965525282a48fd34af05183b8c3705a5b00d5Eric Christopher << FDecl->getDeclName() << Arg->getSourceRange(); 904691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher 90521fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner return false; 90621fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner} 90721fb98ee003e992b0c4e204d98a19e0ef544cae3Chris Lattner 908d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar/// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr, 909d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar/// int type). This simply type checks that type is one of the defined 910d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar/// constants (0-3). 911fee667f35e64751baa7fefe70b4e7bab06c8cd86Eric Christopher// For compatability check 0-3, llvm only handles 0 and 2. 912d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbarbool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) { 913691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher llvm::APSInt Result; 914691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher 915691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher // Check constant-ness first. 916691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (SemaBuiltinConstantArg(TheCall, 1, Result)) 917691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher return true; 918d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar 919691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher Expr *Arg = TheCall->getArg(1); 920d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) { 921fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) 922fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << "0" << "3" << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); 923d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar } 924d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar 925d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar return false; 926d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar} 927d5f8a4fd4d6dfb0415b93bb7ab721bba5cab1332Daniel Dunbar 928586d6a81428da2d1ce70bcb98df29d749361cbf3Eli Friedman/// SemaBuiltinLongjmp - Handle __builtin_longjmp(void *env[5], int val). 929d875fed28578835de89cd407e9db4be788596d7cEli Friedman/// This checks that val is a constant 1. 930d875fed28578835de89cd407e9db4be788596d7cEli Friedmanbool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) { 931d875fed28578835de89cd407e9db4be788596d7cEli Friedman Expr *Arg = TheCall->getArg(1); 932691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher llvm::APSInt Result; 933cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor 934691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher // TODO: This is less than ideal. Overload this to take a value. 935691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (SemaBuiltinConstantArg(TheCall, 1, Result)) 936691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher return true; 937691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher 938691ebc3f3225542e5abd85e107ebdbec907cf510Eric Christopher if (Result != 1) 939d875fed28578835de89cd407e9db4be788596d7cEli Friedman return Diag(TheCall->getLocStart(), diag::err_builtin_longjmp_invalid_val) 940d875fed28578835de89cd407e9db4be788596d7cEli Friedman << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); 941d875fed28578835de89cd407e9db4be788596d7cEli Friedman 942d875fed28578835de89cd407e9db4be788596d7cEli Friedman return false; 943d875fed28578835de89cd407e9db4be788596d7cEli Friedman} 944d875fed28578835de89cd407e9db4be788596d7cEli Friedman 945d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek// Handle i > 1 ? "x" : "y", recursivelly 946082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenekbool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, 947082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek bool HasVAListArg, 948826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned format_idx, unsigned firstDataArg, 949826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool isPrintf) { 950826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 951cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor if (E->isTypeDependent() || E->isValueDependent()) 952cde01739dffe574c53a6ba1def1a57a2cc7b4a8bDouglas Gregor return false; 953d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek 954d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek switch (E->getStmtClass()) { 955d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek case Stmt::ConditionalOperatorClass: { 956082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek const ConditionalOperator *C = cast<ConditionalOperator>(E); 957826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return SemaCheckStringLiteral(C->getTrueExpr(), TheCall, HasVAListArg, 958826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek format_idx, firstDataArg, isPrintf) 959826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek && SemaCheckStringLiteral(C->getRHS(), TheCall, HasVAListArg, 960826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek format_idx, firstDataArg, isPrintf); 961d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek } 962d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek 963d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek case Stmt::ImplicitCastExprClass: { 964082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek const ImplicitCastExpr *Expr = cast<ImplicitCastExpr>(E); 965d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg, 966826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek format_idx, firstDataArg, isPrintf); 967d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek } 968d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek 969d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek case Stmt::ParenExprClass: { 970082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek const ParenExpr *Expr = cast<ParenExpr>(E); 971d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg, 972826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek format_idx, firstDataArg, isPrintf); 973d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek } 9741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 975082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek case Stmt::DeclRefExprClass: { 976082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek const DeclRefExpr *DR = cast<DeclRefExpr>(E); 9771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 978082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek // As an exception, do not flag errors for variables binding to 979082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek // const string literals. 980082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { 981082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek bool isConstant = false; 982082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek QualType T = DR->getType(); 983082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek 984082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek if (const ArrayType *AT = Context.getAsArrayType(T)) { 985082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek isConstant = AT->getElementType().isConstant(Context); 986ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else if (const PointerType *PT = T->getAs<PointerType>()) { 9871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump isConstant = T.isConstant(Context) && 988082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek PT->getPointeeType().isConstant(Context); 989082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek } 9901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 991082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek if (isConstant) { 99231310a21fb2a9f13950f864f681c86080b05d5b2Sebastian Redl if (const Expr *Init = VD->getAnyInitializer()) 993082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek return SemaCheckStringLiteral(Init, TheCall, 994826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasVAListArg, format_idx, firstDataArg, 995826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek isPrintf); 996082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek } 9971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 998d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // For vprintf* functions (i.e., HasVAListArg==true), we add a 999d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // special check to see if the format string is a function parameter 1000d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // of the function calling the printf function. If the function 1001d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // has an attribute indicating it is a printf-like function, then we 1002d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // should suppress warnings concerning non-literals being used in a call 1003d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // to a vprintf function. For example: 1004d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // 1005d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // void 1006d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...){ 1007d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // va_list ap; 1008d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // va_start(ap, fmt); 1009d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // vprintf(fmt, ap); // Do NOT emit a warning about "fmt". 1010d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // ... 1011d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // 1012d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // 1013d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // FIXME: We don't have full attribute support yet, so just check to see 1014d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // if the argument is a DeclRefExpr that references a parameter. We'll 1015d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson // add proper support for checking the attribute later. 1016d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson if (HasVAListArg) 1017d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson if (isa<ParmVarDecl>(VD)) 1018d966a55bccae13f34d18958877c5e71dd643a125Anders Carlsson return true; 1019082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek } 10201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1021082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek return false; 1022082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek } 1023d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek 10248f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson case Stmt::CallExprClass: { 10258f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson const CallExpr *CE = cast<CallExpr>(E); 10261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (const ImplicitCastExpr *ICE 10278f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson = dyn_cast<ImplicitCastExpr>(CE->getCallee())) { 10288f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) { 10298f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) { 103040b598eea1310ec9ed554d56ce3e25b34c585458Argyrios Kyrtzidis if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) { 10318f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson unsigned ArgIndex = FA->getFormatIdx(); 10328f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson const Expr *Arg = CE->getArg(ArgIndex - 1); 10331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg, 1035826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek format_idx, firstDataArg, isPrintf); 10368f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson } 10378f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson } 10388f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson } 10398f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson } 10401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10418f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson return false; 10428f031b3b14e726b093fb8693c2be4ab6d779e331Anders Carlsson } 1043082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek case Stmt::ObjCStringLiteralClass: 1044082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek case Stmt::StringLiteralClass: { 1045082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek const StringLiteral *StrE = NULL; 10461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1047082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek if (const ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(E)) 1048d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek StrE = ObjCFExpr->getString(); 1049d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek else 1050082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek StrE = cast<StringLiteral>(E); 10511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1052d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek if (StrE) { 1053826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckFormatString(StrE, E, TheCall, HasVAListArg, format_idx, 1054826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek firstDataArg, isPrintf); 1055d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek return true; 1056d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek } 10571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1058d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek return false; 1059d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek } 10601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1061082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek default: 1062082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek return false; 1063d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek } 1064d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek} 1065d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek 1066e898f8a94947c6074d76ff83943b47d5bbdf210dFariborz Jahanianvoid 10671eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpSema::CheckNonNullArguments(const NonNullAttr *NonNull, 10681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CallExpr *TheCall) { 1069e898f8a94947c6074d76ff83943b47d5bbdf210dFariborz Jahanian for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end(); 1070e898f8a94947c6074d76ff83943b47d5bbdf210dFariborz Jahanian i != e; ++i) { 107112b97ff9ce1412e388444f03049bfa6ad1bb5eb9Chris Lattner const Expr *ArgExpr = TheCall->getArg(*i); 10724e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek if (ArgExpr->isNullPointerConstant(Context, 1073ce94049b69f75b44c18584fe79cd238978b6b0d5Douglas Gregor Expr::NPC_ValueDependentIsNotNull)) 107412b97ff9ce1412e388444f03049bfa6ad1bb5eb9Chris Lattner Diag(TheCall->getCallee()->getLocStart(), diag::warn_null_arg) 107512b97ff9ce1412e388444f03049bfa6ad1bb5eb9Chris Lattner << ArgExpr->getSourceRange(); 1076e898f8a94947c6074d76ff83943b47d5bbdf210dFariborz Jahanian } 1077e898f8a94947c6074d76ff83943b47d5bbdf210dFariborz Jahanian} 1078d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek 1079826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// CheckPrintfScanfArguments - Check calls to printf and scanf (and similar 1080826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// functions) for correct use of format strings. 108159907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattnervoid 1082826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekSema::CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg, 1083826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned format_idx, unsigned firstDataArg, 1084826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool isPrintf) { 1085826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1086082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek const Expr *Fn = TheCall->getCallee(); 1087925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner 10884a2614e94672c47395abcde60518776fbebec589Sebastian Redl // The way the format attribute works in GCC, the implicit this argument 10894a2614e94672c47395abcde60518776fbebec589Sebastian Redl // of member functions is counted. However, it doesn't appear in our own 10904a2614e94672c47395abcde60518776fbebec589Sebastian Redl // lists, so decrement format_idx in that case. 10914a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (isa<CXXMemberCallExpr>(TheCall)) { 10924a2614e94672c47395abcde60518776fbebec589Sebastian Redl // Catch a format attribute mistakenly referring to the object argument. 10934a2614e94672c47395abcde60518776fbebec589Sebastian Redl if (format_idx == 0) 10944a2614e94672c47395abcde60518776fbebec589Sebastian Redl return; 10954a2614e94672c47395abcde60518776fbebec589Sebastian Redl --format_idx; 10964a2614e94672c47395abcde60518776fbebec589Sebastian Redl if(firstDataArg != 0) 10974a2614e94672c47395abcde60518776fbebec589Sebastian Redl --firstDataArg; 10984a2614e94672c47395abcde60518776fbebec589Sebastian Redl } 10994a2614e94672c47395abcde60518776fbebec589Sebastian Redl 1100826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // CHECK: printf/scanf-like function is called with no format string. 1101925e60d3fa706f31886027c876989af79eb0e0d2Chris Lattner if (format_idx >= TheCall->getNumArgs()) { 1102826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Diag(TheCall->getRParenLoc(), diag::warn_missing_format_string) 1103dcd5ef12488e4c7ea844327835896ca86b609a97Chris Lattner << Fn->getSourceRange(); 110471895b9aa3ad71957359497e136b50fcb6136bdfTed Kremenek return; 110571895b9aa3ad71957359497e136b50fcb6136bdfTed Kremenek } 11061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1107082d936a5b8323ac2c04558d8bca277a647831a3Ted Kremenek const Expr *OrigFormatExpr = TheCall->getArg(format_idx)->IgnoreParenCasts(); 11081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 110959907c4d8f6fc8aacfdaa0273bd7a9c140fbb45fChris Lattner // CHECK: format string is not a string literal. 11101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // 111171895b9aa3ad71957359497e136b50fcb6136bdfTed Kremenek // Dynamically generated format strings are difficult to 111271895b9aa3ad71957359497e136b50fcb6136bdfTed Kremenek // automatically vet at compile time. Requiring that format strings 111371895b9aa3ad71957359497e136b50fcb6136bdfTed Kremenek // are string literals: (1) permits the checking of format strings by 111471895b9aa3ad71957359497e136b50fcb6136bdfTed Kremenek // the compiler and thereby (2) can practically remove the source of 111571895b9aa3ad71957359497e136b50fcb6136bdfTed Kremenek // many format string exploits. 11167ff22b259d4d4729f701679e3a7f0e242365e07fTed Kremenek 11171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // Format string can be either ObjC string (e.g. @"%d") or 11187ff22b259d4d4729f701679e3a7f0e242365e07fTed Kremenek // C string (e.g. "%d") 11191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // ObjC string uses the same format specifiers as C string, so we can use 11207ff22b259d4d4729f701679e3a7f0e242365e07fTed Kremenek // the same format string checking logic for both ObjC and C strings. 11211cd3e1f72c3a1c256fb6a5c3d4512bca1f1b751dChris Lattner if (SemaCheckStringLiteral(OrigFormatExpr, TheCall, HasVAListArg, format_idx, 1122826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek firstDataArg, isPrintf)) 11231cd3e1f72c3a1c256fb6a5c3d4512bca1f1b751dChris Lattner return; // Literal format string found, check done! 11241cd3e1f72c3a1c256fb6a5c3d4512bca1f1b751dChris Lattner 1125655f141f4d4c92eeebcc880211313e84c0a8b2f2Chris Lattner // If there are no arguments specified, warn with -Wformat-security, otherwise 1126655f141f4d4c92eeebcc880211313e84c0a8b2f2Chris Lattner // warn only with -Wformat-nonliteral. 1127655f141f4d4c92eeebcc880211313e84c0a8b2f2Chris Lattner if (TheCall->getNumArgs() == format_idx+1) 11281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(TheCall->getArg(format_idx)->getLocStart(), 1129826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_format_nonliteral_noargs) 1130655f141f4d4c92eeebcc880211313e84c0a8b2f2Chris Lattner << OrigFormatExpr->getSourceRange(); 1131655f141f4d4c92eeebcc880211313e84c0a8b2f2Chris Lattner else 11321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump Diag(TheCall->getArg(format_idx)->getLocStart(), 1133826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_format_nonliteral) 1134655f141f4d4c92eeebcc880211313e84c0a8b2f2Chris Lattner << OrigFormatExpr->getSourceRange(); 1135d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek} 1136d30ef87f34015d18bde20b9632032d0063d761aaTed Kremenek 1137e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremeneknamespace { 1138826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass CheckFormatHandler : public analyze_format_string::FormatStringHandler { 1139826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekprotected: 1140e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek Sema &S; 1141e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const StringLiteral *FExpr; 1142e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const Expr *OrigFormatExpr; 11436ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek const unsigned FirstDataArg; 1144e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const unsigned NumDataArgs; 1145e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const bool IsObjCLiteral; 1146e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const char *Beg; // Start of format string. 11470d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek const bool HasVAListArg; 11480d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek const CallExpr *TheCall; 11490d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek unsigned FormatIdx; 11507f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek llvm::BitVector CoveredArgs; 1151efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek bool usesPositionalArgs; 1152efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek bool atFirstArg; 11534e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenekpublic: 1154826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckFormatHandler(Sema &s, const StringLiteral *fexpr, 11556ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek const Expr *origFormatExpr, unsigned firstDataArg, 1156e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek unsigned numDataArgs, bool isObjCLiteral, 11570d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek const char *beg, bool hasVAListArg, 11580d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek const CallExpr *theCall, unsigned formatIdx) 1159e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), 11606ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek FirstDataArg(firstDataArg), 11617f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek NumDataArgs(numDataArgs), 11620d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek IsObjCLiteral(isObjCLiteral), Beg(beg), 11630d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek HasVAListArg(hasVAListArg), 1164efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek TheCall(theCall), FormatIdx(formatIdx), 1165efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek usesPositionalArgs(false), atFirstArg(true) { 11667f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek CoveredArgs.resize(numDataArgs); 11677f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek CoveredArgs.reset(); 11687f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek } 11694e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 117007d161f38e708a91486bf1c031d525faebbb249dTed Kremenek void DoneProcessing(); 11714e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1172826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void HandleIncompleteSpecifier(const char *startSpecifier, 1173826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen); 1174826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1175efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek virtual void HandleInvalidPosition(const char *startSpecifier, 1176efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek unsigned specifierLen, 1177826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek analyze_format_string::PositionContext p); 1178efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 1179efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek virtual void HandleZeroPosition(const char *startPos, unsigned posLen); 1180efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 1181e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek void HandleNullChar(const char *nullCharacter); 11824e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1183826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekprotected: 1184f88c8e02da48afea6a04091f675af5c4facd99f1Ted Kremenek SourceRange getFormatStringRange(); 1185826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CharSourceRange getSpecifierRange(const char *startSpecifier, 1186826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen); 1187e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek SourceLocation getLocationOfByte(const char *x); 11884e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 11890d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek const Expr *getDataArg(unsigned i) const; 1190e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek}; 1191e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek} 1192e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1193826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekSourceRange CheckFormatHandler::getFormatStringRange() { 1194e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek return OrigFormatExpr->getSourceRange(); 1195e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek} 1196e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1197826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekCharSourceRange CheckFormatHandler:: 1198826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekgetSpecifierRange(const char *startSpecifier, unsigned specifierLen) { 119945f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care SourceLocation Start = getLocationOfByte(startSpecifier); 120045f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1); 120145f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care 120245f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care // Advance the end SourceLocation by one due to half-open ranges. 120345f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care End = End.getFileLocWithOffset(1); 120445f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care 120545f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care return CharSourceRange::getCharRange(Start, End); 1206f88c8e02da48afea6a04091f675af5c4facd99f1Ted Kremenek} 1207f88c8e02da48afea6a04091f675af5c4facd99f1Ted Kremenek 1208826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekSourceLocation CheckFormatHandler::getLocationOfByte(const char *x) { 12094e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek return S.getLocationOfStringLiteralByte(FExpr, x - Beg); 1210e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek} 1211e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1212826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekvoid CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier, 1213826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen){ 1214808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek SourceLocation Loc = getLocationOfByte(startSpecifier); 1215808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek S.Diag(Loc, diag::warn_printf_incomplete_specifier) 1216826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1217808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek} 1218808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek 1219efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenekvoid 1220826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekCheckFormatHandler::HandleInvalidPosition(const char *startPos, unsigned posLen, 1221826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek analyze_format_string::PositionContext p) { 1222efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek SourceLocation Loc = getLocationOfByte(startPos); 1223826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(Loc, diag::warn_format_invalid_positional_specifier) 1224826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << (unsigned) p << getSpecifierRange(startPos, posLen); 1225efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek} 1226efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 1227826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekvoid CheckFormatHandler::HandleZeroPosition(const char *startPos, 1228efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek unsigned posLen) { 1229efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek SourceLocation Loc = getLocationOfByte(startPos); 1230826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(Loc, diag::warn_format_zero_positional_specifier) 1231826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startPos, posLen); 1232efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek} 1233efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 1234826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekvoid CheckFormatHandler::HandleNullChar(const char *nullCharacter) { 1235826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // The presence of a null character is likely an error. 1236826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(getLocationOfByte(nullCharacter), 1237826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_printf_format_string_contains_null_char) 1238826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getFormatStringRange(); 1239826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 1240826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1241826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekconst Expr *CheckFormatHandler::getDataArg(unsigned i) const { 1242826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return TheCall->getArg(FirstDataArg + i); 1243826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 12444e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1245826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekvoid CheckFormatHandler::DoneProcessing() { 1246826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Does the number of data arguments exceed the number of 1247826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // format conversions in the format string? 1248826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!HasVAListArg) { 1249826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Find any arguments that weren't covered. 1250826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CoveredArgs.flip(); 1251826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek signed notCoveredArg = CoveredArgs.find_first(); 1252826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (notCoveredArg >= 0) { 1253826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert((unsigned)notCoveredArg < NumDataArgs); 1254826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(getDataArg((unsigned) notCoveredArg)->getLocStart(), 1255826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_printf_data_arg_not_used) 1256826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getFormatStringRange(); 1257826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1258826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1259826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 1260826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1261826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===--- CHECK: Printf format string checking ------------------------------===// 1262826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1263826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremeneknamespace { 1264826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass CheckPrintfHandler : public CheckFormatHandler { 1265826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 1266826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckPrintfHandler(Sema &s, const StringLiteral *fexpr, 1267826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const Expr *origFormatExpr, unsigned firstDataArg, 1268826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned numDataArgs, bool isObjCLiteral, 1269826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *beg, bool hasVAListArg, 1270826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const CallExpr *theCall, unsigned formatIdx) 1271826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, 1272826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek numDataArgs, isObjCLiteral, beg, hasVAListArg, 1273826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek theCall, formatIdx) {} 1274826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1275826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1276826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool HandleInvalidPrintfConversionSpecifier( 1277826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::PrintfSpecifier &FS, 1278826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 1279826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen); 1280826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1281826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, 1282826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 1283826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen); 1284826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1285826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool HandleAmount(const analyze_format_string::OptionalAmount &Amt, unsigned k, 1286826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, unsigned specifierLen); 1287826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void HandleInvalidAmount(const analyze_printf::PrintfSpecifier &FS, 1288826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::OptionalAmount &Amt, 1289826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned type, 1290826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, unsigned specifierLen); 1291826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void HandleFlag(const analyze_printf::PrintfSpecifier &FS, 1292826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::OptionalFlag &flag, 1293826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, unsigned specifierLen); 1294826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void HandleIgnoredFlag(const analyze_printf::PrintfSpecifier &FS, 1295826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::OptionalFlag &ignoredFlag, 1296826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::OptionalFlag &flag, 1297826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, unsigned specifierLen); 1298826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 1299826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 1300826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1301826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier( 1302826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::PrintfSpecifier &FS, 1303826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 1304826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) { 1305826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 13067f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek unsigned argIndex = FS.getArgIndex(); 13077f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek bool keepGoing = true; 13087f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek if (argIndex < NumDataArgs) { 1309826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Consider the argument coverered, even though the specifier doesn't 1310826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // make sense. 13117f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek CoveredArgs.set(argIndex); 13127f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek } 13137f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek else { 13147f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // If argIndex exceeds the number of data arguments we 13157f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // don't issue a warning because that is just a cascade of warnings (and 13167f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // they may have intended '%%' anyway). We don't want to continue processing 13177f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // the format string after this point, however, as we will like just get 13187f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // gibberish when trying to match arguments. 13197f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek keepGoing = false; 13207f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek } 1321826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1322808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek const analyze_printf::ConversionSpecifier &CS = 1323826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FS.getConversionSpecifier(); 1324808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek SourceLocation Loc = getLocationOfByte(CS.getStart()); 132526ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek S.Diag(Loc, diag::warn_printf_invalid_conversion) 1326826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << llvm::StringRef(CS.getStart(), CS.getLength()) 1327826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1328826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 13297f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek return keepGoing; 133026ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek} 133126ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek 1332826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool CheckPrintfHandler::HandleAmount( 1333826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_format_string::OptionalAmount &Amt, 1334826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned k, const char *startSpecifier, 1335826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) { 13360d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek 13370d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek if (Amt.hasDataArgument()) { 13380d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek if (!HasVAListArg) { 13397f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek unsigned argIndex = Amt.getArgIndex(); 13407f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek if (argIndex >= NumDataArgs) { 1341efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek S.Diag(getLocationOfByte(Amt.getStart()), 1342efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek diag::warn_printf_asterisk_missing_arg) 1343826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << k << getSpecifierRange(startSpecifier, specifierLen); 13440d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek // Don't do any more checking. We will just emit 13450d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek // spurious errors. 13460d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek return false; 13470d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek } 13484e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 13490d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek // Type check the data argument. It should be an 'int'. 135031f8e32788adb299acad455363eb7fd244642c82Ted Kremenek // Although not in conformance with C99, we also allow the argument to be 135131f8e32788adb299acad455363eb7fd244642c82Ted Kremenek // an 'unsigned int' as that is a reasonably safe case. GCC also 135231f8e32788adb299acad455363eb7fd244642c82Ted Kremenek // doesn't emit a warning for that case. 13537f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek CoveredArgs.set(argIndex); 13547f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek const Expr *Arg = getDataArg(argIndex); 13550d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek QualType T = Arg->getType(); 13564e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 13574e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek const analyze_printf::ArgTypeResult &ATR = Amt.getArgType(S.Context); 13584e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek assert(ATR.isValid()); 13594e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 13604e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek if (!ATR.matchesType(S.Context, T)) { 1361efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek S.Diag(getLocationOfByte(Amt.getStart()), 1362efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek diag::warn_printf_asterisk_wrong_type) 1363efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek << k 13644e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek << ATR.getRepresentativeType(S.Context) << T 1365826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen) 1366d635c5fcc45c952b75743dd2f4c86d6950e4954eTed Kremenek << Arg->getSourceRange(); 13670d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek // Don't do any more checking. We will just emit 13680d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek // spurious errors. 13690d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek return false; 13700d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek } 13710d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek } 13720d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek } 13730d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek return true; 13740d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek} 13750d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek 1376e4ee9663168dfb2b4122c768091e30217328c9faTom Carevoid CheckPrintfHandler::HandleInvalidAmount( 1377826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::PrintfSpecifier &FS, 1378e4ee9663168dfb2b4122c768091e30217328c9faTom Care const analyze_printf::OptionalAmount &Amt, 1379e4ee9663168dfb2b4122c768091e30217328c9faTom Care unsigned type, 1380e4ee9663168dfb2b4122c768091e30217328c9faTom Care const char *startSpecifier, 1381e4ee9663168dfb2b4122c768091e30217328c9faTom Care unsigned specifierLen) { 1382e4ee9663168dfb2b4122c768091e30217328c9faTom Care const analyze_printf::ConversionSpecifier &CS = FS.getConversionSpecifier(); 1383e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (Amt.getHowSpecified()) { 1384e4ee9663168dfb2b4122c768091e30217328c9faTom Care case analyze_printf::OptionalAmount::Constant: 1385e4ee9663168dfb2b4122c768091e30217328c9faTom Care S.Diag(getLocationOfByte(Amt.getStart()), 1386e4ee9663168dfb2b4122c768091e30217328c9faTom Care diag::warn_printf_nonsensical_optional_amount) 1387e4ee9663168dfb2b4122c768091e30217328c9faTom Care << type 1388e4ee9663168dfb2b4122c768091e30217328c9faTom Care << CS.toString() 1389826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen) 1390826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << FixItHint::CreateRemoval(getSpecifierRange(Amt.getStart(), 1391e4ee9663168dfb2b4122c768091e30217328c9faTom Care Amt.getConstantLength())); 1392e4ee9663168dfb2b4122c768091e30217328c9faTom Care break; 1393e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1394e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 1395e4ee9663168dfb2b4122c768091e30217328c9faTom Care S.Diag(getLocationOfByte(Amt.getStart()), 1396e4ee9663168dfb2b4122c768091e30217328c9faTom Care diag::warn_printf_nonsensical_optional_amount) 1397e4ee9663168dfb2b4122c768091e30217328c9faTom Care << type 1398e4ee9663168dfb2b4122c768091e30217328c9faTom Care << CS.toString() 1399826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1400e4ee9663168dfb2b4122c768091e30217328c9faTom Care break; 1401e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 1402e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 1403e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1404826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekvoid CheckPrintfHandler::HandleFlag(const analyze_printf::PrintfSpecifier &FS, 1405e4ee9663168dfb2b4122c768091e30217328c9faTom Care const analyze_printf::OptionalFlag &flag, 1406e4ee9663168dfb2b4122c768091e30217328c9faTom Care const char *startSpecifier, 1407e4ee9663168dfb2b4122c768091e30217328c9faTom Care unsigned specifierLen) { 1408e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Warn about pointless flag with a fixit removal. 1409e4ee9663168dfb2b4122c768091e30217328c9faTom Care const analyze_printf::ConversionSpecifier &CS = FS.getConversionSpecifier(); 1410e4ee9663168dfb2b4122c768091e30217328c9faTom Care S.Diag(getLocationOfByte(flag.getPosition()), 1411e4ee9663168dfb2b4122c768091e30217328c9faTom Care diag::warn_printf_nonsensical_flag) 1412e4ee9663168dfb2b4122c768091e30217328c9faTom Care << flag.toString() << CS.toString() 1413826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen) 1414826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << FixItHint::CreateRemoval(getSpecifierRange(flag.getPosition(), 1)); 1415e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 1416e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1417e4ee9663168dfb2b4122c768091e30217328c9faTom Carevoid CheckPrintfHandler::HandleIgnoredFlag( 1418826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::PrintfSpecifier &FS, 1419e4ee9663168dfb2b4122c768091e30217328c9faTom Care const analyze_printf::OptionalFlag &ignoredFlag, 1420e4ee9663168dfb2b4122c768091e30217328c9faTom Care const analyze_printf::OptionalFlag &flag, 1421e4ee9663168dfb2b4122c768091e30217328c9faTom Care const char *startSpecifier, 1422e4ee9663168dfb2b4122c768091e30217328c9faTom Care unsigned specifierLen) { 1423e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Warn about ignored flag with a fixit removal. 1424e4ee9663168dfb2b4122c768091e30217328c9faTom Care S.Diag(getLocationOfByte(ignoredFlag.getPosition()), 1425e4ee9663168dfb2b4122c768091e30217328c9faTom Care diag::warn_printf_ignored_flag) 1426e4ee9663168dfb2b4122c768091e30217328c9faTom Care << ignoredFlag.toString() << flag.toString() 1427826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen) 1428826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << FixItHint::CreateRemoval(getSpecifierRange( 1429e4ee9663168dfb2b4122c768091e30217328c9faTom Care ignoredFlag.getPosition(), 1)); 1430e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 1431e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1432e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenekbool 1433826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekCheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier 14345c41ee8c49995fb4fd76d686b239c15cbab261eaTed Kremenek &FS, 1435e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const char *startSpecifier, 1436e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek unsigned specifierLen) { 1437e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1438efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek using namespace analyze_printf; 1439e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const ConversionSpecifier &CS = FS.getConversionSpecifier(); 1440e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1441efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (atFirstArg) { 1442efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek atFirstArg = false; 1443efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek usesPositionalArgs = FS.usesPositionalArg(); 1444efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 1445efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek else if (usesPositionalArgs != FS.usesPositionalArg()) { 1446efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek // Cannot mix-and-match positional and non-positional arguments. 1447efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek S.Diag(getLocationOfByte(CS.getStart()), 1448826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_format_mix_positional_nonpositional_args) 1449826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1450efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return false; 1451efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 1452efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 14530d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek // First check if the field width, precision, and conversion specifier 14540d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek // have matching data arguments. 1455efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (!HandleAmount(FS.getFieldWidth(), /* field width */ 0, 1456efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek startSpecifier, specifierLen)) { 14570d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek return false; 14580d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek } 14594e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1460efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (!HandleAmount(FS.getPrecision(), /* precision */ 1, 1461efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek startSpecifier, specifierLen)) { 14620d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek return false; 14630d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek } 14640d27735c51f5bd392e673cf39a675e14e9442387Ted Kremenek 1465f88c8e02da48afea6a04091f675af5c4facd99f1Ted Kremenek if (!CS.consumesDataArgument()) { 1466f88c8e02da48afea6a04091f675af5c4facd99f1Ted Kremenek // FIXME: Technically specifying a precision or field width here 1467f88c8e02da48afea6a04091f675af5c4facd99f1Ted Kremenek // makes no sense. Worth issuing a warning at some point. 14680e5675de2b67eeca754754ae8d3dacba425a38e8Ted Kremenek return true; 1469f88c8e02da48afea6a04091f675af5c4facd99f1Ted Kremenek } 14704e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 14717f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // Consume the argument. 14727f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek unsigned argIndex = FS.getArgIndex(); 1473e3fc54790250076e33ad25b14e5be293514fe5eaTed Kremenek if (argIndex < NumDataArgs) { 1474e3fc54790250076e33ad25b14e5be293514fe5eaTed Kremenek // The check to see if the argIndex is valid will come later. 1475e3fc54790250076e33ad25b14e5be293514fe5eaTed Kremenek // We set the bit here because we may exit early from this 1476e3fc54790250076e33ad25b14e5be293514fe5eaTed Kremenek // function if we encounter some other error. 1477e3fc54790250076e33ad25b14e5be293514fe5eaTed Kremenek CoveredArgs.set(argIndex); 1478e3fc54790250076e33ad25b14e5be293514fe5eaTed Kremenek } 14797f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 14807f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // Check for using an Objective-C specific conversion specifier 14817f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // in a non-ObjC literal. 14827f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek if (!IsObjCLiteral && CS.isObjCArg()) { 1483826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, 1484826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek specifierLen); 14857f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek } 14864e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1487e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Check for invalid use of field width 1488e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!FS.hasValidFieldWidth()) { 148945f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care HandleInvalidAmount(FS, FS.getFieldWidth(), /* field width */ 0, 1490e4ee9663168dfb2b4122c768091e30217328c9faTom Care startSpecifier, specifierLen); 1491e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 1492e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1493e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Check for invalid use of precision 1494e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!FS.hasValidPrecision()) { 1495e4ee9663168dfb2b4122c768091e30217328c9faTom Care HandleInvalidAmount(FS, FS.getPrecision(), /* precision */ 1, 1496e4ee9663168dfb2b4122c768091e30217328c9faTom Care startSpecifier, specifierLen); 1497e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 1498e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1499e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Check each flag does not conflict with any other component. 1500e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!FS.hasValidLeadingZeros()) 1501e4ee9663168dfb2b4122c768091e30217328c9faTom Care HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen); 1502e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!FS.hasValidPlusPrefix()) 1503e4ee9663168dfb2b4122c768091e30217328c9faTom Care HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen); 150445f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care if (!FS.hasValidSpacePrefix()) 150545f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen); 1506e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!FS.hasValidAlternativeForm()) 1507e4ee9663168dfb2b4122c768091e30217328c9faTom Care HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen); 1508e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!FS.hasValidLeftJustified()) 1509e4ee9663168dfb2b4122c768091e30217328c9faTom Care HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen); 1510e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1511e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Check that flags are not ignored by another flag 151245f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care if (FS.hasSpacePrefix() && FS.hasPlusPrefix()) // ' ' ignored by '+' 151345f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(), 151445f9b7e8f23072d662ee1cc758f4ecb0da5e3322Tom Care startSpecifier, specifierLen); 1515e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (FS.hasLeadingZeros() && FS.isLeftJustified()) // '0' ignored by '-' 1516e4ee9663168dfb2b4122c768091e30217328c9faTom Care HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(), 1517e4ee9663168dfb2b4122c768091e30217328c9faTom Care startSpecifier, specifierLen); 1518e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1519e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Check the length modifier is valid with the given conversion specifier. 1520e4ee9663168dfb2b4122c768091e30217328c9faTom Care const LengthModifier &LM = FS.getLengthModifier(); 1521e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!FS.hasValidLengthModifier()) 1522e4ee9663168dfb2b4122c768091e30217328c9faTom Care S.Diag(getLocationOfByte(LM.getStart()), 1523e4ee9663168dfb2b4122c768091e30217328c9faTom Care diag::warn_printf_nonsensical_length) 1524e4ee9663168dfb2b4122c768091e30217328c9faTom Care << LM.toString() << CS.toString() 1525826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen) 1526826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(), 1527e4ee9663168dfb2b4122c768091e30217328c9faTom Care LM.getLength())); 1528e4ee9663168dfb2b4122c768091e30217328c9faTom Care 1529e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Are we using '%n'? 1530e82d804ee761006250543d6fe6e98ee7896cd756Ted Kremenek if (CS.getKind() == ConversionSpecifier::OutIntPtrArg) { 1531e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Issue a warning about this being a possible security issue. 1532e82d804ee761006250543d6fe6e98ee7896cd756Ted Kremenek S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_write_back) 1533826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1534e82d804ee761006250543d6fe6e98ee7896cd756Ted Kremenek // Continue checking the other format specifiers. 1535e82d804ee761006250543d6fe6e98ee7896cd756Ted Kremenek return true; 1536e82d804ee761006250543d6fe6e98ee7896cd756Ted Kremenek } 15375c41ee8c49995fb4fd76d686b239c15cbab261eaTed Kremenek 1538da51f0d136df131a0137c0ec1069fb586d8a296aTed Kremenek // The remaining checks depend on the data arguments. 1539da51f0d136df131a0137c0ec1069fb586d8a296aTed Kremenek if (HasVAListArg) 1540da51f0d136df131a0137c0ec1069fb586d8a296aTed Kremenek return true; 15414e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 15427f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek if (argIndex >= NumDataArgs) { 15436ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek if (FS.usesPositionalArg()) { 15446ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek S.Diag(getLocationOfByte(CS.getStart()), 15456ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek diag::warn_printf_positional_arg_exceeds_data_args) 15466ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek << (argIndex+1) << NumDataArgs 1547826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 15486ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek } 15496ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek else { 15506ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek S.Diag(getLocationOfByte(CS.getStart()), 15516ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek diag::warn_printf_insufficient_data_args) 1552826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 15536ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek } 15546ee765348b2855c702fa593fb030ef6abe0d01f6Ted Kremenek 1555da51f0d136df131a0137c0ec1069fb586d8a296aTed Kremenek // Don't do any more checking. 1556da51f0d136df131a0137c0ec1069fb586d8a296aTed Kremenek return false; 1557da51f0d136df131a0137c0ec1069fb586d8a296aTed Kremenek } 15584e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1559d635c5fcc45c952b75743dd2f4c86d6950e4954eTed Kremenek // Now type check the data expression that matches the 1560d635c5fcc45c952b75743dd2f4c86d6950e4954eTed Kremenek // format specifier. 15617f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek const Expr *Ex = getDataArg(argIndex); 1562d635c5fcc45c952b75743dd2f4c86d6950e4954eTed Kremenek const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context); 15634e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) { 15644e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek // Check if we didn't match because of an implicit cast from a 'char' 15654e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek // or 'short' to an 'int'. This is done because printf is a varargs 15664e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek // function. 15674e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex)) 15684e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek if (ICE->getType() == S.Context.IntTy) 15694e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek if (ATR.matchesType(S.Context, ICE->getSubExpr()->getType())) 15704e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek return true; 1571105d41c0a4bf4dc4b210647ac704e245749a981dTed Kremenek 15723bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // We may be able to offer a FixItHint if it is a supported type. 1573826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifier fixedFS = FS; 15743bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care bool success = fixedFS.fixType(Ex->getType()); 15753bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 15763bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (success) { 15773bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Get the fix string from the fixed format specifier 15783bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care llvm::SmallString<128> buf; 15793bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care llvm::raw_svector_ostream os(buf); 15803bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care fixedFS.toString(os); 15813bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 15823bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care S.Diag(getLocationOfByte(CS.getStart()), 15833bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care diag::warn_printf_conversion_argument_type_mismatch) 15843bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care << ATR.getRepresentativeType(S.Context) << Ex->getType() 1585826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen) 15863bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care << Ex->getSourceRange() 15873bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care << FixItHint::CreateReplacement( 1588826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek getSpecifierRange(startSpecifier, specifierLen), 15893bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os.str()); 15903bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 15913bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care else { 15923bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care S.Diag(getLocationOfByte(CS.getStart()), 15933bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care diag::warn_printf_conversion_argument_type_mismatch) 15943bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care << ATR.getRepresentativeType(S.Context) << Ex->getType() 1595826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen) 15963bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care << Ex->getSourceRange(); 15973bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 1598d635c5fcc45c952b75743dd2f4c86d6950e4954eTed Kremenek } 1599e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1600e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek return true; 1601e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek} 1602e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1603826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===--- CHECK: Scanf format string checking ------------------------------===// 1604826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1605826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremeneknamespace { 1606826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass CheckScanfHandler : public CheckFormatHandler { 1607826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 1608826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckScanfHandler(Sema &s, const StringLiteral *fexpr, 1609826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const Expr *origFormatExpr, unsigned firstDataArg, 1610826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned numDataArgs, bool isObjCLiteral, 1611826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *beg, bool hasVAListArg, 1612826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const CallExpr *theCall, unsigned formatIdx) 1613826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, 1614826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek numDataArgs, isObjCLiteral, beg, hasVAListArg, 1615826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek theCall, formatIdx) {} 1616826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1617826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, 1618826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 1619826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen); 1620b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenek 1621b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenek void HandleIncompleteScanList(const char *start, const char *end); 1622826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 1623826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 1624826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1625b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenekvoid CheckScanfHandler::HandleIncompleteScanList(const char *start, 1626b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenek const char *end) { 1627b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenek S.Diag(getLocationOfByte(end), diag::warn_scanf_scanlist_incomplete) 1628b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenek << getSpecifierRange(start, end - start); 1629b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenek} 1630b7c21018ec1049580cf6df88db09e606550a7baaTed Kremenek 1631826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool CheckScanfHandler::HandleScanfSpecifier( 1632826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_scanf::ScanfSpecifier &FS, 1633826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 1634826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) { 1635826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1636826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek using namespace analyze_scanf; 1637826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek using namespace analyze_format_string; 1638826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1639826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const ConversionSpecifier &CS = FS.getConversionSpecifier(); 1640826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1641826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // FIXME: Handle case where '%' and '*' don't consume an argument. 1642826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // This needs to be done for the printf case as well. 1643826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (atFirstArg) { 1644826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek atFirstArg = false; 1645826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek usesPositionalArgs = FS.usesPositionalArg(); 1646826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1647826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek else if (usesPositionalArgs != FS.usesPositionalArg()) { 1648826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Cannot mix-and-match positional and non-positional arguments. 1649826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(getLocationOfByte(CS.getStart()), 1650826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_format_mix_positional_nonpositional_args) 1651826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1652826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 1653826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1654826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1655826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Check if the field with is non-zero. 1656826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalAmount &Amt = FS.getFieldWidth(); 1657826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (Amt.getHowSpecified() == OptionalAmount::Constant) { 1658826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (Amt.getConstantAmount() == 0) { 1659826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const CharSourceRange &R = getSpecifierRange(Amt.getStart(), 1660826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Amt.getConstantLength()); 1661826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(getLocationOfByte(Amt.getStart()), 1662826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_scanf_nonzero_width) 1663826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << R << FixItHint::CreateRemoval(R); 16647f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek } 16657f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek } 1666826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1667826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!FS.consumesDataArgument()) { 1668826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // FIXME: Technically specifying a precision or field width here 1669826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // makes no sense. Worth issuing a warning at some point. 1670826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 1671826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1672826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1673826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Consume the argument. 1674826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned argIndex = FS.getArgIndex(); 1675826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (argIndex < NumDataArgs) { 1676826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // The check to see if the argIndex is valid will come later. 1677826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // We set the bit here because we may exit early from this 1678826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // function if we encounter some other error. 1679826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CoveredArgs.set(argIndex); 1680826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1681826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1682826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // FIXME: Check that the length modifier is valid with the given 1683826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // conversion specifier. 1684826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1685826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // The remaining checks depend on the data arguments. 1686826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (HasVAListArg) 1687826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 1688826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1689826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (argIndex >= NumDataArgs) { 1690826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (FS.usesPositionalArg()) { 1691826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(getLocationOfByte(CS.getStart()), 1692826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_printf_positional_arg_exceeds_data_args) 1693826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << (argIndex+1) << NumDataArgs 1694826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1695826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1696826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek else { 1697826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek S.Diag(getLocationOfByte(CS.getStart()), 1698826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_printf_insufficient_data_args) 1699826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek << getSpecifierRange(startSpecifier, specifierLen); 1700826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1701826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1702826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Don't do any more checking. 1703826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 1704826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1705826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1706826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // FIXME: Check that the argument type matches the format specifier. 1707826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1708826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 170907d161f38e708a91486bf1c031d525faebbb249dTed Kremenek} 1710e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek 1711826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekvoid Sema::CheckFormatString(const StringLiteral *FExpr, 17120e5675de2b67eeca754754ae8d3dacba425a38e8Ted Kremenek const Expr *OrigFormatExpr, 17130e5675de2b67eeca754754ae8d3dacba425a38e8Ted Kremenek const CallExpr *TheCall, bool HasVAListArg, 1714826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned format_idx, unsigned firstDataArg, 1715826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool isPrintf) { 1716826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1717e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek // CHECK: is the format string a wide literal? 1718e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek if (FExpr->isWide()) { 1719e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek Diag(FExpr->getLocStart(), 1720826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek diag::warn_format_string_is_wide_literal) 1721e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek << OrigFormatExpr->getSourceRange(); 1722e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek return; 1723e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek } 1724826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1725e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek // Str - The format string. NOTE: this is NOT null-terminated! 1726e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek const char *Str = FExpr->getStrData(); 1727826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1728e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek // CHECK: empty format string? 1729e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek unsigned StrLen = FExpr->getByteLength(); 1730826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1731e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek if (StrLen == 0) { 1732826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Diag(FExpr->getLocStart(), diag::warn_empty_format_string) 1733e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek << OrigFormatExpr->getSourceRange(); 1734e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek return; 1735e0e5313c25f3870d0d18fc67e1b3a3a0e1ef8e07Ted Kremenek } 1736826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1737826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (isPrintf) { 1738826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg, 1739826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek TheCall->getNumArgs() - firstDataArg, 1740826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek isa<ObjCStringLiteral>(OrigFormatExpr), Str, 1741826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasVAListArg, TheCall, format_idx); 1742826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1743826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen)) 1744826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.DoneProcessing(); 1745826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1746826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek else { 1747826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CheckScanfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg, 1748826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek TheCall->getNumArgs() - firstDataArg, 1749826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek isa<ObjCStringLiteral>(OrigFormatExpr), Str, 1750826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasVAListArg, TheCall, format_idx); 1751826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 1752826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen)) 1753826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.DoneProcessing(); 1754826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 1755ce7024e8a3793b05861a4904ecdb1272924ada14Ted Kremenek} 1756ce7024e8a3793b05861a4904ecdb1272924ada14Ted Kremenek 175706de276fff91264437fa75111ed76de43097e089Ted Kremenek//===--- CHECK: Return Address of Stack Variable --------------------------===// 175806de276fff91264437fa75111ed76de43097e089Ted Kremenek 175906de276fff91264437fa75111ed76de43097e089Ted Kremenekstatic DeclRefExpr* EvalVal(Expr *E); 176006de276fff91264437fa75111ed76de43097e089Ted Kremenekstatic DeclRefExpr* EvalAddr(Expr* E); 176106de276fff91264437fa75111ed76de43097e089Ted Kremenek 176206de276fff91264437fa75111ed76de43097e089Ted Kremenek/// CheckReturnStackAddr - Check if a return statement returns the address 176306de276fff91264437fa75111ed76de43097e089Ted Kremenek/// of a stack variable. 176406de276fff91264437fa75111ed76de43097e089Ted Kremenekvoid 176506de276fff91264437fa75111ed76de43097e089Ted KremenekSema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, 176606de276fff91264437fa75111ed76de43097e089Ted Kremenek SourceLocation ReturnLoc) { 17671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 176806de276fff91264437fa75111ed76de43097e089Ted Kremenek // Perform checking for returned stack addresses. 1769dd972f20dc2bd3609d833893e5c6544ac09b59a9Steve Naroff if (lhsType->isPointerType() || lhsType->isBlockPointerType()) { 177006de276fff91264437fa75111ed76de43097e089Ted Kremenek if (DeclRefExpr *DR = EvalAddr(RetValExp)) 17713c73c41cefcfe76f36b7bed72c9f1ec195490951Chris Lattner Diag(DR->getLocStart(), diag::warn_ret_stack_addr) 177208631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << DR->getDecl()->getDeclName() << RetValExp->getSourceRange(); 17731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1774c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff // Skip over implicit cast expressions when checking for block expressions. 17754ca606e898293ae58f1793f988500e2218c7a9beChris Lattner RetValExp = RetValExp->IgnoreParenCasts(); 1776c50a4a5f2eac14ac4c631d50b0a55cadc87700ceSteve Naroff 17779e6b37a9f1d499e7ca0950edacd0b6569e491d7fChris Lattner if (BlockExpr *C = dyn_cast<BlockExpr>(RetValExp)) 1778397195bf3077fb42789b326f69f7d417227a0588Mike Stump if (C->hasBlockDeclRefExprs()) 1779397195bf3077fb42789b326f69f7d417227a0588Mike Stump Diag(C->getLocStart(), diag::err_ret_local_block) 1780397195bf3077fb42789b326f69f7d417227a0588Mike Stump << C->getSourceRange(); 17814e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 17829e6b37a9f1d499e7ca0950edacd0b6569e491d7fChris Lattner if (AddrLabelExpr *ALE = dyn_cast<AddrLabelExpr>(RetValExp)) 17839e6b37a9f1d499e7ca0950edacd0b6569e491d7fChris Lattner Diag(ALE->getLocStart(), diag::warn_ret_addr_label) 17849e6b37a9f1d499e7ca0950edacd0b6569e491d7fChris Lattner << ALE->getSourceRange(); 17854e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1786ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else if (lhsType->isReferenceType()) { 1787ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump // Perform checking for stack values returned by reference. 178849badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor // Check for a reference to the stack 178949badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor if (DeclRefExpr *DR = EvalVal(RetValExp)) 1790dcd5ef12488e4c7ea844327835896ca86b609a97Chris Lattner Diag(DR->getLocStart(), diag::warn_ret_stack_ref) 179108631c5fa053867146b5ee8be658c229f6bf127cChris Lattner << DR->getDecl()->getDeclName() << RetValExp->getSourceRange(); 179206de276fff91264437fa75111ed76de43097e089Ted Kremenek } 179306de276fff91264437fa75111ed76de43097e089Ted Kremenek} 179406de276fff91264437fa75111ed76de43097e089Ted Kremenek 179506de276fff91264437fa75111ed76de43097e089Ted Kremenek/// EvalAddr - EvalAddr and EvalVal are mutually recursive functions that 179606de276fff91264437fa75111ed76de43097e089Ted Kremenek/// check if the expression in a return statement evaluates to an address 179706de276fff91264437fa75111ed76de43097e089Ted Kremenek/// to a location on the stack. The recursion is used to traverse the 179806de276fff91264437fa75111ed76de43097e089Ted Kremenek/// AST of the return expression, with recursion backtracking when we 179906de276fff91264437fa75111ed76de43097e089Ted Kremenek/// encounter a subexpression that (1) clearly does not lead to the address 180006de276fff91264437fa75111ed76de43097e089Ted Kremenek/// of a stack variable or (2) is something we cannot determine leads to 180106de276fff91264437fa75111ed76de43097e089Ted Kremenek/// the address of a stack variable based on such local checking. 180206de276fff91264437fa75111ed76de43097e089Ted Kremenek/// 1803e8c600f9fedf2cfd69cdd2cb4bde4a9b39ce2873Ted Kremenek/// EvalAddr processes expressions that are pointers that are used as 1804e8c600f9fedf2cfd69cdd2cb4bde4a9b39ce2873Ted Kremenek/// references (and not L-values). EvalVal handles all other values. 18051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// At the base case of the recursion is a check for a DeclRefExpr* in 180606de276fff91264437fa75111ed76de43097e089Ted Kremenek/// the refers to a stack variable. 180706de276fff91264437fa75111ed76de43097e089Ted Kremenek/// 180806de276fff91264437fa75111ed76de43097e089Ted Kremenek/// This implementation handles: 180906de276fff91264437fa75111ed76de43097e089Ted Kremenek/// 181006de276fff91264437fa75111ed76de43097e089Ted Kremenek/// * pointer-to-pointer casts 181106de276fff91264437fa75111ed76de43097e089Ted Kremenek/// * implicit conversions from array references to pointers 181206de276fff91264437fa75111ed76de43097e089Ted Kremenek/// * taking the address of fields 181306de276fff91264437fa75111ed76de43097e089Ted Kremenek/// * arbitrary interplay between "&" and "*" operators 181406de276fff91264437fa75111ed76de43097e089Ted Kremenek/// * pointer arithmetic from an address of a stack variable 181506de276fff91264437fa75111ed76de43097e089Ted Kremenek/// * taking the address of an array element where the array is on the stack 181606de276fff91264437fa75111ed76de43097e089Ted Kremenekstatic DeclRefExpr* EvalAddr(Expr *E) { 181706de276fff91264437fa75111ed76de43097e089Ted Kremenek // We should only be called for evaluating pointer expressions. 18180f436560640a1cff5b6d96f80f540770f139453fDavid Chisnall assert((E->getType()->isAnyPointerType() || 1819dd972f20dc2bd3609d833893e5c6544ac09b59a9Steve Naroff E->getType()->isBlockPointerType() || 1820a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek E->getType()->isObjCQualifiedIdType()) && 1821fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner "EvalAddr only works on pointers"); 18221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 182306de276fff91264437fa75111ed76de43097e089Ted Kremenek // Our "symbolic interpreter" is just a dispatch off the currently 182406de276fff91264437fa75111ed76de43097e089Ted Kremenek // viewed AST node. We then recursively traverse the AST by calling 182506de276fff91264437fa75111ed76de43097e089Ted Kremenek // EvalAddr and EvalVal appropriately. 182606de276fff91264437fa75111ed76de43097e089Ted Kremenek switch (E->getStmtClass()) { 1827fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner case Stmt::ParenExprClass: 1828fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // Ignore parentheses. 1829fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return EvalAddr(cast<ParenExpr>(E)->getSubExpr()); 183006de276fff91264437fa75111ed76de43097e089Ted Kremenek 1831fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner case Stmt::UnaryOperatorClass: { 1832fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // The only unary operator that make sense to handle here 1833fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // is AddrOf. All others don't make sense as pointers. 1834fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner UnaryOperator *U = cast<UnaryOperator>(E); 18351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1836fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner if (U->getOpcode() == UnaryOperator::AddrOf) 1837fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return EvalVal(U->getSubExpr()); 1838fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner else 1839fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return NULL; 1840fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner } 18411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1842fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner case Stmt::BinaryOperatorClass: { 1843fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // Handle pointer arithmetic. All other binary operators are not valid 1844fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // in this context. 1845fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner BinaryOperator *B = cast<BinaryOperator>(E); 1846fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner BinaryOperator::Opcode op = B->getOpcode(); 18471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1848fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner if (op != BinaryOperator::Add && op != BinaryOperator::Sub) 1849fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return NULL; 18501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1851fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner Expr *Base = B->getLHS(); 18523907323dd6665c0c4e383435cb145233f4533406Anders Carlsson 1853fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // Determine which argument is the real pointer base. It could be 1854fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // the RHS argument instead of the LHS. 1855fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner if (!Base->getType()->isPointerType()) Base = B->getRHS(); 18561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1857fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner assert (Base->getType()->isPointerType()); 1858fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return EvalAddr(Base); 1859fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner } 186061f40a2b67fc2046768e14f66b617e564cbcc3d8Steve Naroff 1861fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // For conditional operators we need to see if either the LHS or RHS are 1862fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // valid DeclRefExpr*s. If one of them is valid, we return it. 1863fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner case Stmt::ConditionalOperatorClass: { 1864fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner ConditionalOperator *C = cast<ConditionalOperator>(E); 18651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1866fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // Handle the GNU extension for missing LHS. 1867fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner if (Expr *lhsExpr = C->getLHS()) 1868fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner if (DeclRefExpr* LHS = EvalAddr(lhsExpr)) 1869fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return LHS; 187006de276fff91264437fa75111ed76de43097e089Ted Kremenek 1871fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return EvalAddr(C->getRHS()); 1872fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner } 18731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 187454b5274f2c190331438375ad114dad12ae098b57Ted Kremenek // For casts, we need to handle conversions from arrays to 187554b5274f2c190331438375ad114dad12ae098b57Ted Kremenek // pointer values, and pointer-to-pointer conversions. 187649badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor case Stmt::ImplicitCastExprClass: 18776eec8e883de118b431e3ead5b1e604a6ac68ff6bDouglas Gregor case Stmt::CStyleCastExprClass: 187849badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor case Stmt::CXXFunctionalCastExprClass: { 18790835a3cdeefe714b4959d31127ea155e56393125Argyrios Kyrtzidis Expr* SubExpr = cast<CastExpr>(E)->getSubExpr(); 188054b5274f2c190331438375ad114dad12ae098b57Ted Kremenek QualType T = SubExpr->getType(); 18811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1882dd972f20dc2bd3609d833893e5c6544ac09b59a9Steve Naroff if (SubExpr->getType()->isPointerType() || 1883dd972f20dc2bd3609d833893e5c6544ac09b59a9Steve Naroff SubExpr->getType()->isBlockPointerType() || 1884dd972f20dc2bd3609d833893e5c6544ac09b59a9Steve Naroff SubExpr->getType()->isObjCQualifiedIdType()) 1885fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return EvalAddr(SubExpr); 188654b5274f2c190331438375ad114dad12ae098b57Ted Kremenek else if (T->isArrayType()) 188754b5274f2c190331438375ad114dad12ae098b57Ted Kremenek return EvalVal(SubExpr); 1888fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner else 188954b5274f2c190331438375ad114dad12ae098b57Ted Kremenek return 0; 1890fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner } 18911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1892fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // C++ casts. For dynamic casts, static casts, and const casts, we 1893fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // are always converting from a pointer-to-pointer, so we just blow 189449badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor // through the cast. In the case the dynamic cast doesn't fail (and 189549badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor // return NULL), we take the conservative route and report cases 1896fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // where we return the address of a stack variable. For Reinterpre 189749badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor // FIXME: The comment about is wrong; we're not always converting 189849badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor // from pointer to pointer. I'm guessing that this code should also 18991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // handle references to objects. 19001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Stmt::CXXStaticCastExprClass: 19011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case Stmt::CXXDynamicCastExprClass: 190249badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor case Stmt::CXXConstCastExprClass: 190349badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor case Stmt::CXXReinterpretCastExprClass: { 190449badde06e066d058d6c7fcf4e628a72999b65a9Douglas Gregor Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr(); 1905dd972f20dc2bd3609d833893e5c6544ac09b59a9Steve Naroff if (S->getType()->isPointerType() || S->getType()->isBlockPointerType()) 1906fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return EvalAddr(S); 190706de276fff91264437fa75111ed76de43097e089Ted Kremenek else 190806de276fff91264437fa75111ed76de43097e089Ted Kremenek return NULL; 1909fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner } 19101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1911fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner // Everything else: we simply don't reason about them. 1912fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner default: 1913fae3f1f6565c74d3238747b58357a6e56fbb0e9cChris Lattner return NULL; 191406de276fff91264437fa75111ed76de43097e089Ted Kremenek } 191506de276fff91264437fa75111ed76de43097e089Ted Kremenek} 19161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 191706de276fff91264437fa75111ed76de43097e089Ted Kremenek 191806de276fff91264437fa75111ed76de43097e089Ted Kremenek/// EvalVal - This function is complements EvalAddr in the mutual recursion. 191906de276fff91264437fa75111ed76de43097e089Ted Kremenek/// See the comments for EvalAddr for more details. 192006de276fff91264437fa75111ed76de43097e089Ted Kremenekstatic DeclRefExpr* EvalVal(Expr *E) { 19211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1922e8c600f9fedf2cfd69cdd2cb4bde4a9b39ce2873Ted Kremenek // We should only be called for evaluating non-pointer expressions, or 1923e8c600f9fedf2cfd69cdd2cb4bde4a9b39ce2873Ted Kremenek // expressions with a pointer type that are not used as references but instead 1924e8c600f9fedf2cfd69cdd2cb4bde4a9b39ce2873Ted Kremenek // are l-values (e.g., DeclRefExpr with a pointer type). 19251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 192606de276fff91264437fa75111ed76de43097e089Ted Kremenek // Our "symbolic interpreter" is just a dispatch off the currently 192706de276fff91264437fa75111ed76de43097e089Ted Kremenek // viewed AST node. We then recursively traverse the AST by calling 192806de276fff91264437fa75111ed76de43097e089Ted Kremenek // EvalAddr and EvalVal appropriately. 192906de276fff91264437fa75111ed76de43097e089Ted Kremenek switch (E->getStmtClass()) { 1930a2813cec2605ce7878d1b13471d685f689b251afDouglas Gregor case Stmt::DeclRefExprClass: { 193106de276fff91264437fa75111ed76de43097e089Ted Kremenek // DeclRefExpr: the base case. When we hit a DeclRefExpr we are looking 193206de276fff91264437fa75111ed76de43097e089Ted Kremenek // at code that refers to a variable's name. We check if it has local 193306de276fff91264437fa75111ed76de43097e089Ted Kremenek // storage within the function, and if so, return the expression. 193406de276fff91264437fa75111ed76de43097e089Ted Kremenek DeclRefExpr *DR = cast<DeclRefExpr>(E); 19351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 193606de276fff91264437fa75111ed76de43097e089Ted Kremenek if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) 19371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (V->hasLocalStorage() && !V->getType()->isReferenceType()) return DR; 19381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 193906de276fff91264437fa75111ed76de43097e089Ted Kremenek return NULL; 194006de276fff91264437fa75111ed76de43097e089Ted Kremenek } 19411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 194206de276fff91264437fa75111ed76de43097e089Ted Kremenek case Stmt::ParenExprClass: 194306de276fff91264437fa75111ed76de43097e089Ted Kremenek // Ignore parentheses. 194406de276fff91264437fa75111ed76de43097e089Ted Kremenek return EvalVal(cast<ParenExpr>(E)->getSubExpr()); 19451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 194606de276fff91264437fa75111ed76de43097e089Ted Kremenek case Stmt::UnaryOperatorClass: { 194706de276fff91264437fa75111ed76de43097e089Ted Kremenek // The only unary operator that make sense to handle here 194806de276fff91264437fa75111ed76de43097e089Ted Kremenek // is Deref. All others don't resolve to a "name." This includes 194906de276fff91264437fa75111ed76de43097e089Ted Kremenek // handling all sorts of rvalues passed to a unary operator. 195006de276fff91264437fa75111ed76de43097e089Ted Kremenek UnaryOperator *U = cast<UnaryOperator>(E); 19511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 195206de276fff91264437fa75111ed76de43097e089Ted Kremenek if (U->getOpcode() == UnaryOperator::Deref) 195306de276fff91264437fa75111ed76de43097e089Ted Kremenek return EvalAddr(U->getSubExpr()); 195406de276fff91264437fa75111ed76de43097e089Ted Kremenek 195506de276fff91264437fa75111ed76de43097e089Ted Kremenek return NULL; 195606de276fff91264437fa75111ed76de43097e089Ted Kremenek } 19571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 195806de276fff91264437fa75111ed76de43097e089Ted Kremenek case Stmt::ArraySubscriptExprClass: { 195906de276fff91264437fa75111ed76de43097e089Ted Kremenek // Array subscripts are potential references to data on the stack. We 196006de276fff91264437fa75111ed76de43097e089Ted Kremenek // retrieve the DeclRefExpr* for the array variable if it indeed 196106de276fff91264437fa75111ed76de43097e089Ted Kremenek // has local storage. 19622324512285caac0332bbbc6e4cab6245d2a370a1Ted Kremenek return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase()); 196306de276fff91264437fa75111ed76de43097e089Ted Kremenek } 19641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 196506de276fff91264437fa75111ed76de43097e089Ted Kremenek case Stmt::ConditionalOperatorClass: { 196606de276fff91264437fa75111ed76de43097e089Ted Kremenek // For conditional operators we need to see if either the LHS or RHS are 196706de276fff91264437fa75111ed76de43097e089Ted Kremenek // non-NULL DeclRefExpr's. If one is non-NULL, we return it. 196806de276fff91264437fa75111ed76de43097e089Ted Kremenek ConditionalOperator *C = cast<ConditionalOperator>(E); 196906de276fff91264437fa75111ed76de43097e089Ted Kremenek 19703907323dd6665c0c4e383435cb145233f4533406Anders Carlsson // Handle the GNU extension for missing LHS. 19713907323dd6665c0c4e383435cb145233f4533406Anders Carlsson if (Expr *lhsExpr = C->getLHS()) 19723907323dd6665c0c4e383435cb145233f4533406Anders Carlsson if (DeclRefExpr *LHS = EvalVal(lhsExpr)) 19733907323dd6665c0c4e383435cb145233f4533406Anders Carlsson return LHS; 19743907323dd6665c0c4e383435cb145233f4533406Anders Carlsson 19753907323dd6665c0c4e383435cb145233f4533406Anders Carlsson return EvalVal(C->getRHS()); 197606de276fff91264437fa75111ed76de43097e089Ted Kremenek } 19771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 197806de276fff91264437fa75111ed76de43097e089Ted Kremenek // Accesses to members are potential references to data on the stack. 197983f6faf37d9bf58986bedc9bc0ea897a56b4dbadDouglas Gregor case Stmt::MemberExprClass: { 198006de276fff91264437fa75111ed76de43097e089Ted Kremenek MemberExpr *M = cast<MemberExpr>(E); 19811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 198206de276fff91264437fa75111ed76de43097e089Ted Kremenek // Check for indirect access. We only want direct field accesses. 198306de276fff91264437fa75111ed76de43097e089Ted Kremenek if (!M->isArrow()) 198406de276fff91264437fa75111ed76de43097e089Ted Kremenek return EvalVal(M->getBase()); 198506de276fff91264437fa75111ed76de43097e089Ted Kremenek else 198606de276fff91264437fa75111ed76de43097e089Ted Kremenek return NULL; 198706de276fff91264437fa75111ed76de43097e089Ted Kremenek } 19881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 198906de276fff91264437fa75111ed76de43097e089Ted Kremenek // Everything else: we simply don't reason about them. 199006de276fff91264437fa75111ed76de43097e089Ted Kremenek default: 199106de276fff91264437fa75111ed76de43097e089Ted Kremenek return NULL; 199206de276fff91264437fa75111ed76de43097e089Ted Kremenek } 199306de276fff91264437fa75111ed76de43097e089Ted Kremenek} 1994588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek 1995588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek//===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===// 1996588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek 1997588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek/// Check for comparisons of floating point operands using != and ==. 1998588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek/// Issue a warning if these are no self-comparisons, as they are not likely 1999588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek/// to do what the programmer intended. 2000588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenekvoid Sema::CheckFloatComparison(SourceLocation loc, Expr* lex, Expr *rex) { 2001588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek bool EmitWarning = true; 20021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20034e99a5fc3b203397a91136c6e695e405fb8fc606Ted Kremenek Expr* LeftExprSansParen = lex->IgnoreParens(); 200432e97b66bbce16c9e81c877794fb7a0aeeb66ccbTed Kremenek Expr* RightExprSansParen = rex->IgnoreParens(); 2005588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek 2006588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek // Special case: check for x == x (which is OK). 2007588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek // Do not emit warnings for such cases. 2008588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen)) 2009588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RightExprSansParen)) 2010588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek if (DRL->getDecl() == DRR->getDecl()) 2011588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek EmitWarning = false; 20121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20141b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek // Special case: check for comparisons against literals that can be exactly 20151b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek // represented by APFloat. In such cases, do not emit a warning. This 20161b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek // is a heuristic: often comparison against such literals are used to 20171b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek // detect if a value in a variable has not changed. This clearly can 20181b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek // lead to false negatives. 20191b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek if (EmitWarning) { 20201b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek if (FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) { 20211b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek if (FLL->isExact()) 20221b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek EmitWarning = false; 2023ac5fc7c6bcb494b60fee7ce615ac931c5db6135eMike Stump } else 20241b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek if (FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen)){ 20251b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek if (FLR->isExact()) 20261b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek EmitWarning = false; 20271b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek } 20281b500bb0d40aa3ebf1ace47340bb5f401a9ae99cTed Kremenek } 20291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2030588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek // Check for comparisons with builtin types. 20310eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl if (EmitWarning) 2032588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen)) 20333c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor if (CL->isBuiltinCall(Context)) 2034588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek EmitWarning = false; 20351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20360eb23307222bda7ad95d968eac4e1ab30864b213Sebastian Redl if (EmitWarning) 2037588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek if (CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen)) 20383c385e5f8d9008fff18597ca302be19fa86e51f6Douglas Gregor if (CR->isBuiltinCall(Context)) 2039588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek EmitWarning = false; 20401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2041588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek // Emit the diagnostic. 2042588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek if (EmitWarning) 2043fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner Diag(loc, diag::warn_floatingpoint_eq) 2044fa25bbb351f4fdd977f51254119cdfc2b525ce90Chris Lattner << lex->getSourceRange() << rex->getSourceRange(); 2045588e5ebee2db045c3611e0c8f601bc4495ebd0f3Ted Kremenek} 2046ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2047f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall//===--- CHECK: Integer mixed-sign comparisons (-Wsign-compare) --------===// 2048f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall//===--- CHECK: Lossy implicit conversions (-Wconversion) --------------===// 2049ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2050f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCallnamespace { 2051ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2052f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// Structure recording the 'active' range of an integer-valued 2053f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// expression. 2054f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCallstruct IntRange { 2055f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall /// The number of bits active in the int. 2056f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall unsigned Width; 2057ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2058f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall /// True if the int is known not to have negative values. 2059f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall bool NonNegative; 206051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2061f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange() {} 2062f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange(unsigned Width, bool NonNegative) 2063f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall : Width(Width), NonNegative(NonNegative) 2064f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall {} 206551313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2066f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Returns the range of the bool type. 2067f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall static IntRange forBoolType() { 2068f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange(1, true); 2069f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall } 207051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2071f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Returns the range of an integral type. 2072f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall static IntRange forType(ASTContext &C, QualType T) { 2073f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return forCanonicalType(C, T->getCanonicalTypeInternal().getTypePtr()); 207451313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 207551313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2076f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Returns the range of an integeral type based on its canonical 2077f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // representation. 2078f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall static IntRange forCanonicalType(ASTContext &C, const Type *T) { 2079f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall assert(T->isCanonicalUnqualified()); 208051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2081f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (const VectorType *VT = dyn_cast<VectorType>(T)) 2082f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall T = VT->getElementType().getTypePtr(); 2083f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (const ComplexType *CT = dyn_cast<ComplexType>(T)) 2084f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall T = CT->getElementType().getTypePtr(); 2085323ed74658bc8375278eabf074b4777458376540John McCall 2086323ed74658bc8375278eabf074b4777458376540John McCall if (const EnumType *ET = dyn_cast<EnumType>(T)) { 2087323ed74658bc8375278eabf074b4777458376540John McCall EnumDecl *Enum = ET->getDecl(); 2088323ed74658bc8375278eabf074b4777458376540John McCall unsigned NumPositive = Enum->getNumPositiveBits(); 2089323ed74658bc8375278eabf074b4777458376540John McCall unsigned NumNegative = Enum->getNumNegativeBits(); 2090323ed74658bc8375278eabf074b4777458376540John McCall 2091323ed74658bc8375278eabf074b4777458376540John McCall return IntRange(std::max(NumPositive, NumNegative), NumNegative == 0); 2092323ed74658bc8375278eabf074b4777458376540John McCall } 209351313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2094f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall const BuiltinType *BT = cast<BuiltinType>(T); 2095f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall assert(BT->isInteger()); 209651313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2097f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger()); 209851313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 209951313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2100f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Returns the supremum of two ranges: i.e. their conservative merge. 2101c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall static IntRange join(IntRange L, IntRange R) { 2102f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange(std::max(L.Width, R.Width), 210360fad45739b764886f707bd204eae9ecce6db1f2John McCall L.NonNegative && R.NonNegative); 210460fad45739b764886f707bd204eae9ecce6db1f2John McCall } 210560fad45739b764886f707bd204eae9ecce6db1f2John McCall 210660fad45739b764886f707bd204eae9ecce6db1f2John McCall // Returns the infinum of two ranges: i.e. their aggressive merge. 2107c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall static IntRange meet(IntRange L, IntRange R) { 210860fad45739b764886f707bd204eae9ecce6db1f2John McCall return IntRange(std::min(L.Width, R.Width), 210960fad45739b764886f707bd204eae9ecce6db1f2John McCall L.NonNegative || R.NonNegative); 211051313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 2111f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall}; 211251313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2113f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCallIntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth) { 2114f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (value.isSigned() && value.isNegative()) 2115f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange(value.getMinSignedBits(), false); 211651313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2117f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (value.getBitWidth() > MaxWidth) 2118f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall value.trunc(MaxWidth); 211951313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2120f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // isNonNegative() just checks the sign bit without considering 2121f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // signedness. 2122f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange(value.getActiveBits(), true); 212351313c39c84407dd6a323be99a8c322bf8d052a9John McCall} 212451313c39c84407dd6a323be99a8c322bf8d052a9John McCall 21250acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCallIntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty, 2126f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall unsigned MaxWidth) { 2127f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (result.isInt()) 2128f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return GetValueRange(C, result.getInt(), MaxWidth); 212951313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2130f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (result.isVector()) { 21310acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall IntRange R = GetValueRange(C, result.getVectorElt(0), Ty, MaxWidth); 21320acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall for (unsigned i = 1, e = result.getVectorLength(); i != e; ++i) { 21330acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall IntRange El = GetValueRange(C, result.getVectorElt(i), Ty, MaxWidth); 21340acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall R = IntRange::join(R, El); 21350acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall } 2136f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return R; 213751313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 213851313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2139f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (result.isComplexInt()) { 2140f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange R = GetValueRange(C, result.getComplexIntReal(), MaxWidth); 2141f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange I = GetValueRange(C, result.getComplexIntImag(), MaxWidth); 2142f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::join(R, I); 2143f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall } 2144f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2145f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // This can happen with lossless casts to intptr_t of "based" lvalues. 2146f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Assume it might use arbitrary bits. 21470acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall // FIXME: The only reason we need to pass the type in here is to get 21480acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall // the sign right on this one case. It would be nice if APValue 21490acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall // preserved this. 2150f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall assert(result.isLValue()); 21510acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall return IntRange(MaxWidth, Ty->isUnsignedIntegerType()); 215251313c39c84407dd6a323be99a8c322bf8d052a9John McCall} 215351313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2154f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// Pseudo-evaluate the given integer expression, estimating the 2155f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// range of values it might take. 2156f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// 2157f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// \param MaxWidth - the width to which the value will be truncated 2158f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCallIntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { 215951313c39c84407dd6a323be99a8c322bf8d052a9John McCall E = E->IgnoreParens(); 216051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2161f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Try a full evaluation first. 2162f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall Expr::EvalResult result; 2163f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (E->Evaluate(result, C)) 21640acc311bf73c85fd34ce6f89a4e786b7ecd214aaJohn McCall return GetValueRange(C, result.Val, E->getType(), MaxWidth); 216551313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2166f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // I think we only want to look through implicit casts here; if the 2167f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // user has an explicit widening cast, we should treat the value as 2168f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // being of the new, wider type. 2169f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) { 2170f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (CE->getCastKind() == CastExpr::CK_NoOp) 2171f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return GetExprRange(C, CE->getSubExpr(), MaxWidth); 217251313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2173f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange OutputTypeRange = IntRange::forType(C, CE->getType()); 217451313c39c84407dd6a323be99a8c322bf8d052a9John McCall 217560fad45739b764886f707bd204eae9ecce6db1f2John McCall bool isIntegerCast = (CE->getCastKind() == CastExpr::CK_IntegralCast); 217660fad45739b764886f707bd204eae9ecce6db1f2John McCall if (!isIntegerCast && CE->getCastKind() == CastExpr::CK_Unknown) 217760fad45739b764886f707bd204eae9ecce6db1f2John McCall isIntegerCast = CE->getSubExpr()->getType()->isIntegerType(); 217860fad45739b764886f707bd204eae9ecce6db1f2John McCall 2179f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Assume that non-integer casts can span the full range of the type. 218060fad45739b764886f707bd204eae9ecce6db1f2John McCall if (!isIntegerCast) 2181f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return OutputTypeRange; 218251313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2183f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange SubRange 2184f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall = GetExprRange(C, CE->getSubExpr(), 2185f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall std::min(MaxWidth, OutputTypeRange.Width)); 218651313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2187f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Bail out if the subexpr's range is as wide as the cast type. 2188f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (SubRange.Width >= OutputTypeRange.Width) 2189f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return OutputTypeRange; 219051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2191f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Otherwise, we take the smaller width, and we're non-negative if 2192f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // either the output type or the subexpr is. 2193f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange(SubRange.Width, 2194f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall SubRange.NonNegative || OutputTypeRange.NonNegative); 2195f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall } 2196f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2197f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { 2198f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // If we can fold the condition, just take that operand. 2199f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall bool CondResult; 2200f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (CO->getCond()->EvaluateAsBooleanCondition(CondResult, C)) 2201f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return GetExprRange(C, CondResult ? CO->getTrueExpr() 2202f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall : CO->getFalseExpr(), 2203f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall MaxWidth); 2204f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2205f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Otherwise, conservatively merge. 2206f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange L = GetExprRange(C, CO->getTrueExpr(), MaxWidth); 2207f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange R = GetExprRange(C, CO->getFalseExpr(), MaxWidth); 2208f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::join(L, R); 220951313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 221051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 221151313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { 221251313c39c84407dd6a323be99a8c322bf8d052a9John McCall switch (BO->getOpcode()) { 221351313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2214f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Boolean-valued operations are single-bit and positive. 221551313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::LAnd: 221651313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::LOr: 221751313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::LT: 221851313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::GT: 221951313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::LE: 222051313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::GE: 222151313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::EQ: 222251313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::NE: 2223f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::forBoolType(); 222451313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2225c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall // The type of these compound assignments is the type of the LHS, 2226c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall // so the RHS is not necessarily an integer. 2227c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::MulAssign: 2228c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::DivAssign: 2229c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::RemAssign: 2230c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::AddAssign: 2231c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::SubAssign: 2232c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall return IntRange::forType(C, E->getType()); 2233c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall 223451313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Operations with opaque sources are black-listed. 223551313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::PtrMemD: 223651313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::PtrMemI: 2237f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::forType(C, E->getType()); 223851313c39c84407dd6a323be99a8c322bf8d052a9John McCall 223960fad45739b764886f707bd204eae9ecce6db1f2John McCall // Bitwise-and uses the *infinum* of the two source ranges. 224060fad45739b764886f707bd204eae9ecce6db1f2John McCall case BinaryOperator::And: 2241c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::AndAssign: 224260fad45739b764886f707bd204eae9ecce6db1f2John McCall return IntRange::meet(GetExprRange(C, BO->getLHS(), MaxWidth), 224360fad45739b764886f707bd204eae9ecce6db1f2John McCall GetExprRange(C, BO->getRHS(), MaxWidth)); 224460fad45739b764886f707bd204eae9ecce6db1f2John McCall 224551313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Left shift gets black-listed based on a judgement call. 224651313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::Shl: 22473aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall // ...except that we want to treat '1 << (blah)' as logically 22483aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall // positive. It's an important idiom. 22493aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall if (IntegerLiteral *I 22503aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) { 22513aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall if (I->getValue() == 1) { 22523aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall IntRange R = IntRange::forType(C, E->getType()); 22533aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall return IntRange(R.Width, /*NonNegative*/ true); 22543aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall } 22553aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall } 22563aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall // fallthrough 22573aae6093dd8f3aecb66d7ff1f4b44e6a86765db4John McCall 2258c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::ShlAssign: 2259f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::forType(C, E->getType()); 226051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 226160fad45739b764886f707bd204eae9ecce6db1f2John McCall // Right shift by a constant can narrow its left argument. 2262c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::Shr: 2263c0cd21d2a3301a7a88e0052aebdd09c2441f826dJohn McCall case BinaryOperator::ShrAssign: { 226460fad45739b764886f707bd204eae9ecce6db1f2John McCall IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth); 226560fad45739b764886f707bd204eae9ecce6db1f2John McCall 226660fad45739b764886f707bd204eae9ecce6db1f2John McCall // If the shift amount is a positive constant, drop the width by 226760fad45739b764886f707bd204eae9ecce6db1f2John McCall // that much. 226860fad45739b764886f707bd204eae9ecce6db1f2John McCall llvm::APSInt shift; 226960fad45739b764886f707bd204eae9ecce6db1f2John McCall if (BO->getRHS()->isIntegerConstantExpr(shift, C) && 227060fad45739b764886f707bd204eae9ecce6db1f2John McCall shift.isNonNegative()) { 227160fad45739b764886f707bd204eae9ecce6db1f2John McCall unsigned zext = shift.getZExtValue(); 227260fad45739b764886f707bd204eae9ecce6db1f2John McCall if (zext >= L.Width) 227360fad45739b764886f707bd204eae9ecce6db1f2John McCall L.Width = (L.NonNegative ? 0 : 1); 227460fad45739b764886f707bd204eae9ecce6db1f2John McCall else 227560fad45739b764886f707bd204eae9ecce6db1f2John McCall L.Width -= zext; 227660fad45739b764886f707bd204eae9ecce6db1f2John McCall } 227760fad45739b764886f707bd204eae9ecce6db1f2John McCall 227860fad45739b764886f707bd204eae9ecce6db1f2John McCall return L; 227960fad45739b764886f707bd204eae9ecce6db1f2John McCall } 228060fad45739b764886f707bd204eae9ecce6db1f2John McCall 228160fad45739b764886f707bd204eae9ecce6db1f2John McCall // Comma acts as its right operand. 228251313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::Comma: 2283f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return GetExprRange(C, BO->getRHS(), MaxWidth); 2284f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 228560fad45739b764886f707bd204eae9ecce6db1f2John McCall // Black-list pointer subtractions. 228651313c39c84407dd6a323be99a8c322bf8d052a9John McCall case BinaryOperator::Sub: 228751313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (BO->getLHS()->getType()->isPointerType()) 2288f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::forType(C, E->getType()); 228951313c39c84407dd6a323be99a8c322bf8d052a9John McCall // fallthrough 22904e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 229151313c39c84407dd6a323be99a8c322bf8d052a9John McCall default: 2292f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall break; 229351313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 2294f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2295f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // Treat every other operator as if it were closed on the 2296f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall // narrowest type that encompasses both operands. 2297f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth); 2298f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IntRange R = GetExprRange(C, BO->getRHS(), MaxWidth); 2299f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::join(L, R); 230051313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 230151313c39c84407dd6a323be99a8c322bf8d052a9John McCall 230251313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { 230351313c39c84407dd6a323be99a8c322bf8d052a9John McCall switch (UO->getOpcode()) { 230451313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Boolean-valued operations are white-listed. 230551313c39c84407dd6a323be99a8c322bf8d052a9John McCall case UnaryOperator::LNot: 2306f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::forBoolType(); 230751313c39c84407dd6a323be99a8c322bf8d052a9John McCall 230851313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Operations with opaque sources are black-listed. 230951313c39c84407dd6a323be99a8c322bf8d052a9John McCall case UnaryOperator::Deref: 231051313c39c84407dd6a323be99a8c322bf8d052a9John McCall case UnaryOperator::AddrOf: // should be impossible 231151313c39c84407dd6a323be99a8c322bf8d052a9John McCall case UnaryOperator::OffsetOf: 2312f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::forType(C, E->getType()); 231351313c39c84407dd6a323be99a8c322bf8d052a9John McCall 231451313c39c84407dd6a323be99a8c322bf8d052a9John McCall default: 2315f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return GetExprRange(C, UO->getSubExpr(), MaxWidth); 231651313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 231751313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 23188ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 23198ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor if (dyn_cast<OffsetOfExpr>(E)) { 23208ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor IntRange::forType(C, E->getType()); 23218ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor } 232251313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2323f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall FieldDecl *BitField = E->getBitField(); 2324f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (BitField) { 2325f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall llvm::APSInt BitWidthAP = BitField->getBitWidth()->EvaluateAsInt(C); 2326f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall unsigned BitWidth = BitWidthAP.getZExtValue(); 232751313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2328f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange(BitWidth, BitField->getType()->isUnsignedIntegerType()); 2329f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall } 2330f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2331f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IntRange::forType(C, E->getType()); 2332f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall} 2333f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2334323ed74658bc8375278eabf074b4777458376540John McCallIntRange GetExprRange(ASTContext &C, Expr *E) { 2335323ed74658bc8375278eabf074b4777458376540John McCall return GetExprRange(C, E, C.getIntWidth(E->getType())); 2336323ed74658bc8375278eabf074b4777458376540John McCall} 2337323ed74658bc8375278eabf074b4777458376540John McCall 2338f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// Checks whether the given value, which currently has the given 2339f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// source semantics, has the same value when coerced through the 2340f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// target semantics. 2341f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCallbool IsSameFloatAfterCast(const llvm::APFloat &value, 2342f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall const llvm::fltSemantics &Src, 2343f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall const llvm::fltSemantics &Tgt) { 2344f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall llvm::APFloat truncated = value; 2345f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2346f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall bool ignored; 2347f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored); 2348f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored); 2349f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2350f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return truncated.bitwiseIsEqual(value); 235151313c39c84407dd6a323be99a8c322bf8d052a9John McCall} 235251313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2353f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// Checks whether the given value, which currently has the given 2354f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// source semantics, has the same value when coerced through the 2355f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// target semantics. 2356f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// 2357f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall/// The value might be a vector of floats (or a complex number). 2358f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCallbool IsSameFloatAfterCast(const APValue &value, 2359f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall const llvm::fltSemantics &Src, 2360f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall const llvm::fltSemantics &Tgt) { 2361f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (value.isFloat()) 2362f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return IsSameFloatAfterCast(value.getFloat(), Src, Tgt); 2363f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2364f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (value.isVector()) { 2365f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall for (unsigned i = 0, e = value.getVectorLength(); i != e; ++i) 2366f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (!IsSameFloatAfterCast(value.getVectorElt(i), Src, Tgt)) 2367f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return false; 2368f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return true; 2369f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall } 2370f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2371f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall assert(value.isComplexFloat()); 2372f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall return (IsSameFloatAfterCast(value.getComplexFloatReal(), Src, Tgt) && 2373f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt)); 2374f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall} 2375f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2376323ed74658bc8375278eabf074b4777458376540John McCallvoid AnalyzeImplicitConversions(Sema &S, Expr *E); 2377323ed74658bc8375278eabf074b4777458376540John McCall 2378323ed74658bc8375278eabf074b4777458376540John McCallbool IsZero(Sema &S, Expr *E) { 2379323ed74658bc8375278eabf074b4777458376540John McCall llvm::APSInt Value; 2380323ed74658bc8375278eabf074b4777458376540John McCall return E->isIntegerConstantExpr(Value, S.Context) && Value == 0; 2381323ed74658bc8375278eabf074b4777458376540John McCall} 2382323ed74658bc8375278eabf074b4777458376540John McCall 2383323ed74658bc8375278eabf074b4777458376540John McCallvoid CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) { 2384323ed74658bc8375278eabf074b4777458376540John McCall BinaryOperator::Opcode op = E->getOpcode(); 2385323ed74658bc8375278eabf074b4777458376540John McCall if (op == BinaryOperator::LT && IsZero(S, E->getRHS())) { 2386323ed74658bc8375278eabf074b4777458376540John McCall S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison) 2387323ed74658bc8375278eabf074b4777458376540John McCall << "< 0" << "false" 2388323ed74658bc8375278eabf074b4777458376540John McCall << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); 2389323ed74658bc8375278eabf074b4777458376540John McCall } else if (op == BinaryOperator::GE && IsZero(S, E->getRHS())) { 2390323ed74658bc8375278eabf074b4777458376540John McCall S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison) 2391323ed74658bc8375278eabf074b4777458376540John McCall << ">= 0" << "true" 2392323ed74658bc8375278eabf074b4777458376540John McCall << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); 2393323ed74658bc8375278eabf074b4777458376540John McCall } else if (op == BinaryOperator::GT && IsZero(S, E->getLHS())) { 2394323ed74658bc8375278eabf074b4777458376540John McCall S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison) 2395323ed74658bc8375278eabf074b4777458376540John McCall << "0 >" << "false" 2396323ed74658bc8375278eabf074b4777458376540John McCall << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); 2397323ed74658bc8375278eabf074b4777458376540John McCall } else if (op == BinaryOperator::LE && IsZero(S, E->getLHS())) { 2398323ed74658bc8375278eabf074b4777458376540John McCall S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison) 2399323ed74658bc8375278eabf074b4777458376540John McCall << "0 <=" << "true" 2400323ed74658bc8375278eabf074b4777458376540John McCall << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); 2401323ed74658bc8375278eabf074b4777458376540John McCall } 2402323ed74658bc8375278eabf074b4777458376540John McCall} 2403323ed74658bc8375278eabf074b4777458376540John McCall 2404323ed74658bc8375278eabf074b4777458376540John McCall/// Analyze the operands of the given comparison. Implements the 2405323ed74658bc8375278eabf074b4777458376540John McCall/// fallback case from AnalyzeComparison. 2406323ed74658bc8375278eabf074b4777458376540John McCallvoid AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) { 2407323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(S, E->getLHS()); 2408323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(S, E->getRHS()); 2409323ed74658bc8375278eabf074b4777458376540John McCall} 2410f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2411ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall/// \brief Implements -Wsign-compare. 2412ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall/// 2413ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall/// \param lex the left-hand expression 2414ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall/// \param rex the right-hand expression 2415ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall/// \param OpLoc the location of the joining operator 2416d1b47bf17fde73fac67d8664bd65273742c00ecdJohn McCall/// \param BinOpc binary opcode or 0 2417323ed74658bc8375278eabf074b4777458376540John McCallvoid AnalyzeComparison(Sema &S, BinaryOperator *E) { 2418323ed74658bc8375278eabf074b4777458376540John McCall // The type the comparison is being performed in. 2419323ed74658bc8375278eabf074b4777458376540John McCall QualType T = E->getLHS()->getType(); 2420323ed74658bc8375278eabf074b4777458376540John McCall assert(S.Context.hasSameUnqualifiedType(T, E->getRHS()->getType()) 2421323ed74658bc8375278eabf074b4777458376540John McCall && "comparison with mismatched types"); 2422323ed74658bc8375278eabf074b4777458376540John McCall 2423323ed74658bc8375278eabf074b4777458376540John McCall // We don't do anything special if this isn't an unsigned integral 2424323ed74658bc8375278eabf074b4777458376540John McCall // comparison: we're only interested in integral comparisons, and 2425323ed74658bc8375278eabf074b4777458376540John McCall // signed comparisons only happen in cases we don't care to warn about. 2426323ed74658bc8375278eabf074b4777458376540John McCall if (!T->isUnsignedIntegerType()) 2427323ed74658bc8375278eabf074b4777458376540John McCall return AnalyzeImpConvsInComparison(S, E); 2428323ed74658bc8375278eabf074b4777458376540John McCall 2429323ed74658bc8375278eabf074b4777458376540John McCall Expr *lex = E->getLHS()->IgnoreParenImpCasts(); 2430323ed74658bc8375278eabf074b4777458376540John McCall Expr *rex = E->getRHS()->IgnoreParenImpCasts(); 2431323ed74658bc8375278eabf074b4777458376540John McCall 2432323ed74658bc8375278eabf074b4777458376540John McCall // Check to see if one of the (unmodified) operands is of different 2433323ed74658bc8375278eabf074b4777458376540John McCall // signedness. 2434323ed74658bc8375278eabf074b4777458376540John McCall Expr *signedOperand, *unsignedOperand; 2435323ed74658bc8375278eabf074b4777458376540John McCall if (lex->getType()->isSignedIntegerType()) { 2436323ed74658bc8375278eabf074b4777458376540John McCall assert(!rex->getType()->isSignedIntegerType() && 2437323ed74658bc8375278eabf074b4777458376540John McCall "unsigned comparison between two signed integer expressions?"); 2438323ed74658bc8375278eabf074b4777458376540John McCall signedOperand = lex; 2439323ed74658bc8375278eabf074b4777458376540John McCall unsignedOperand = rex; 2440323ed74658bc8375278eabf074b4777458376540John McCall } else if (rex->getType()->isSignedIntegerType()) { 2441323ed74658bc8375278eabf074b4777458376540John McCall signedOperand = rex; 2442323ed74658bc8375278eabf074b4777458376540John McCall unsignedOperand = lex; 2443ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall } else { 2444323ed74658bc8375278eabf074b4777458376540John McCall CheckTrivialUnsignedComparison(S, E); 2445323ed74658bc8375278eabf074b4777458376540John McCall return AnalyzeImpConvsInComparison(S, E); 2446ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall } 2447ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2448323ed74658bc8375278eabf074b4777458376540John McCall // Otherwise, calculate the effective range of the signed operand. 2449323ed74658bc8375278eabf074b4777458376540John McCall IntRange signedRange = GetExprRange(S.Context, signedOperand); 2450f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall 2451323ed74658bc8375278eabf074b4777458376540John McCall // Go ahead and analyze implicit conversions in the operands. Note 2452323ed74658bc8375278eabf074b4777458376540John McCall // that we skip the implicit conversions on both sides. 2453323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(S, lex); 2454323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(S, rex); 2455ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2456323ed74658bc8375278eabf074b4777458376540John McCall // If the signed range is non-negative, -Wsign-compare won't fire, 2457323ed74658bc8375278eabf074b4777458376540John McCall // but we should still check for comparisons which are always true 2458323ed74658bc8375278eabf074b4777458376540John McCall // or false. 2459323ed74658bc8375278eabf074b4777458376540John McCall if (signedRange.NonNegative) 2460323ed74658bc8375278eabf074b4777458376540John McCall return CheckTrivialUnsignedComparison(S, E); 2461ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2462ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall // For (in)equality comparisons, if the unsigned operand is a 2463ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall // constant which cannot collide with a overflowed signed operand, 2464ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall // then reinterpreting the signed operand as unsigned will not 2465ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall // change the result of the comparison. 2466323ed74658bc8375278eabf074b4777458376540John McCall if (E->isEqualityOp()) { 2467323ed74658bc8375278eabf074b4777458376540John McCall unsigned comparisonWidth = S.Context.getIntWidth(T); 2468323ed74658bc8375278eabf074b4777458376540John McCall IntRange unsignedRange = GetExprRange(S.Context, unsignedOperand); 2469323ed74658bc8375278eabf074b4777458376540John McCall 2470323ed74658bc8375278eabf074b4777458376540John McCall // We should never be unable to prove that the unsigned operand is 2471323ed74658bc8375278eabf074b4777458376540John McCall // non-negative. 2472323ed74658bc8375278eabf074b4777458376540John McCall assert(unsignedRange.NonNegative && "unsigned range includes negative?"); 2473ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 2474323ed74658bc8375278eabf074b4777458376540John McCall if (unsignedRange.Width < comparisonWidth) 2475323ed74658bc8375278eabf074b4777458376540John McCall return; 2476323ed74658bc8375278eabf074b4777458376540John McCall } 2477323ed74658bc8375278eabf074b4777458376540John McCall 2478323ed74658bc8375278eabf074b4777458376540John McCall S.Diag(E->getOperatorLoc(), diag::warn_mixed_sign_comparison) 2479323ed74658bc8375278eabf074b4777458376540John McCall << lex->getType() << rex->getType() 2480323ed74658bc8375278eabf074b4777458376540John McCall << lex->getSourceRange() << rex->getSourceRange(); 2481ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall} 2482ba26e58c64b4f6233dfc4bcd3ef6ce83aab47ffcJohn McCall 248351313c39c84407dd6a323be99a8c322bf8d052a9John McCall/// Diagnose an implicit cast; purely a helper for CheckImplicitConversion. 2484323ed74658bc8375278eabf074b4777458376540John McCallvoid DiagnoseImpCast(Sema &S, Expr *E, QualType T, unsigned diag) { 248551313c39c84407dd6a323be99a8c322bf8d052a9John McCall S.Diag(E->getExprLoc(), diag) << E->getType() << T << E->getSourceRange(); 248651313c39c84407dd6a323be99a8c322bf8d052a9John McCall} 248751313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2488323ed74658bc8375278eabf074b4777458376540John McCallvoid CheckImplicitConversion(Sema &S, Expr *E, QualType T, 2489323ed74658bc8375278eabf074b4777458376540John McCall bool *ICContext = 0) { 2490323ed74658bc8375278eabf074b4777458376540John McCall if (E->isTypeDependent() || E->isValueDependent()) return; 249151313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2492323ed74658bc8375278eabf074b4777458376540John McCall const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr(); 2493323ed74658bc8375278eabf074b4777458376540John McCall const Type *Target = S.Context.getCanonicalType(T).getTypePtr(); 2494323ed74658bc8375278eabf074b4777458376540John McCall if (Source == Target) return; 2495323ed74658bc8375278eabf074b4777458376540John McCall if (Target->isDependentType()) return; 249651313c39c84407dd6a323be99a8c322bf8d052a9John McCall 249751313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Never diagnose implicit casts to bool. 249851313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (Target->isSpecificBuiltinType(BuiltinType::Bool)) 249951313c39c84407dd6a323be99a8c322bf8d052a9John McCall return; 250051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 250151313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Strip vector types. 250251313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (isa<VectorType>(Source)) { 250351313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (!isa<VectorType>(Target)) 2504323ed74658bc8375278eabf074b4777458376540John McCall return DiagnoseImpCast(S, E, T, diag::warn_impcast_vector_scalar); 250551313c39c84407dd6a323be99a8c322bf8d052a9John McCall 250651313c39c84407dd6a323be99a8c322bf8d052a9John McCall Source = cast<VectorType>(Source)->getElementType().getTypePtr(); 250751313c39c84407dd6a323be99a8c322bf8d052a9John McCall Target = cast<VectorType>(Target)->getElementType().getTypePtr(); 250851313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 250951313c39c84407dd6a323be99a8c322bf8d052a9John McCall 251051313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Strip complex types. 251151313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (isa<ComplexType>(Source)) { 251251313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (!isa<ComplexType>(Target)) 2513323ed74658bc8375278eabf074b4777458376540John McCall return DiagnoseImpCast(S, E, T, diag::warn_impcast_complex_scalar); 251451313c39c84407dd6a323be99a8c322bf8d052a9John McCall 251551313c39c84407dd6a323be99a8c322bf8d052a9John McCall Source = cast<ComplexType>(Source)->getElementType().getTypePtr(); 251651313c39c84407dd6a323be99a8c322bf8d052a9John McCall Target = cast<ComplexType>(Target)->getElementType().getTypePtr(); 251751313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 251851313c39c84407dd6a323be99a8c322bf8d052a9John McCall 251951313c39c84407dd6a323be99a8c322bf8d052a9John McCall const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source); 252051313c39c84407dd6a323be99a8c322bf8d052a9John McCall const BuiltinType *TargetBT = dyn_cast<BuiltinType>(Target); 252151313c39c84407dd6a323be99a8c322bf8d052a9John McCall 252251313c39c84407dd6a323be99a8c322bf8d052a9John McCall // If the source is floating point... 252351313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (SourceBT && SourceBT->isFloatingPoint()) { 252451313c39c84407dd6a323be99a8c322bf8d052a9John McCall // ...and the target is floating point... 252551313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (TargetBT && TargetBT->isFloatingPoint()) { 252651313c39c84407dd6a323be99a8c322bf8d052a9John McCall // ...then warn if we're dropping FP rank. 252751313c39c84407dd6a323be99a8c322bf8d052a9John McCall 252851313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Builtin FP kinds are ordered by increasing FP rank. 252951313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (SourceBT->getKind() > TargetBT->getKind()) { 253051313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Don't warn about float constants that are precisely 253151313c39c84407dd6a323be99a8c322bf8d052a9John McCall // representable in the target type. 253251313c39c84407dd6a323be99a8c322bf8d052a9John McCall Expr::EvalResult result; 2533323ed74658bc8375278eabf074b4777458376540John McCall if (E->Evaluate(result, S.Context)) { 253451313c39c84407dd6a323be99a8c322bf8d052a9John McCall // Value might be a float, a float vector, or a float complex. 253551313c39c84407dd6a323be99a8c322bf8d052a9John McCall if (IsSameFloatAfterCast(result.Val, 2536323ed74658bc8375278eabf074b4777458376540John McCall S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)), 2537323ed74658bc8375278eabf074b4777458376540John McCall S.Context.getFloatTypeSemantics(QualType(SourceBT, 0)))) 253851313c39c84407dd6a323be99a8c322bf8d052a9John McCall return; 253951313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 254051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2541323ed74658bc8375278eabf074b4777458376540John McCall DiagnoseImpCast(S, E, T, diag::warn_impcast_float_precision); 254251313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 254351313c39c84407dd6a323be99a8c322bf8d052a9John McCall return; 254451313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 254551313c39c84407dd6a323be99a8c322bf8d052a9John McCall 254651313c39c84407dd6a323be99a8c322bf8d052a9John McCall // If the target is integral, always warn. 254751313c39c84407dd6a323be99a8c322bf8d052a9John McCall if ((TargetBT && TargetBT->isInteger())) 254851313c39c84407dd6a323be99a8c322bf8d052a9John McCall // TODO: don't warn for integer values? 2549323ed74658bc8375278eabf074b4777458376540John McCall DiagnoseImpCast(S, E, T, diag::warn_impcast_float_integer); 255051313c39c84407dd6a323be99a8c322bf8d052a9John McCall 255151313c39c84407dd6a323be99a8c322bf8d052a9John McCall return; 255251313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 255351313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2554f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (!Source->isIntegerType() || !Target->isIntegerType()) 255551313c39c84407dd6a323be99a8c322bf8d052a9John McCall return; 255651313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2557323ed74658bc8375278eabf074b4777458376540John McCall IntRange SourceRange = GetExprRange(S.Context, E); 2558323ed74658bc8375278eabf074b4777458376540John McCall IntRange TargetRange = IntRange::forCanonicalType(S.Context, Target); 255951313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2560f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (SourceRange.Width > TargetRange.Width) { 256151313c39c84407dd6a323be99a8c322bf8d052a9John McCall // People want to build with -Wshorten-64-to-32 and not -Wconversion 256251313c39c84407dd6a323be99a8c322bf8d052a9John McCall // and by god we'll let them. 2563f2370c9b4aade940e2253b5b33262ba507d1d71fJohn McCall if (SourceRange.Width == 64 && TargetRange.Width == 32) 2564323ed74658bc8375278eabf074b4777458376540John McCall return DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_64_32); 2565323ed74658bc8375278eabf074b4777458376540John McCall return DiagnoseImpCast(S, E, T, diag::warn_impcast_integer_precision); 2566323ed74658bc8375278eabf074b4777458376540John McCall } 2567323ed74658bc8375278eabf074b4777458376540John McCall 2568323ed74658bc8375278eabf074b4777458376540John McCall if ((TargetRange.NonNegative && !SourceRange.NonNegative) || 2569323ed74658bc8375278eabf074b4777458376540John McCall (!TargetRange.NonNegative && SourceRange.NonNegative && 2570323ed74658bc8375278eabf074b4777458376540John McCall SourceRange.Width == TargetRange.Width)) { 2571323ed74658bc8375278eabf074b4777458376540John McCall unsigned DiagID = diag::warn_impcast_integer_sign; 2572323ed74658bc8375278eabf074b4777458376540John McCall 2573323ed74658bc8375278eabf074b4777458376540John McCall // Traditionally, gcc has warned about this under -Wsign-compare. 2574323ed74658bc8375278eabf074b4777458376540John McCall // We also want to warn about it in -Wconversion. 2575323ed74658bc8375278eabf074b4777458376540John McCall // So if -Wconversion is off, use a completely identical diagnostic 2576323ed74658bc8375278eabf074b4777458376540John McCall // in the sign-compare group. 2577323ed74658bc8375278eabf074b4777458376540John McCall // The conditional-checking code will 2578323ed74658bc8375278eabf074b4777458376540John McCall if (ICContext) { 2579323ed74658bc8375278eabf074b4777458376540John McCall DiagID = diag::warn_impcast_integer_sign_conditional; 2580323ed74658bc8375278eabf074b4777458376540John McCall *ICContext = true; 2581323ed74658bc8375278eabf074b4777458376540John McCall } 2582323ed74658bc8375278eabf074b4777458376540John McCall 2583323ed74658bc8375278eabf074b4777458376540John McCall return DiagnoseImpCast(S, E, T, DiagID); 258451313c39c84407dd6a323be99a8c322bf8d052a9John McCall } 258551313c39c84407dd6a323be99a8c322bf8d052a9John McCall 258651313c39c84407dd6a323be99a8c322bf8d052a9John McCall return; 258751313c39c84407dd6a323be99a8c322bf8d052a9John McCall} 258851313c39c84407dd6a323be99a8c322bf8d052a9John McCall 2589323ed74658bc8375278eabf074b4777458376540John McCallvoid CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T); 2590323ed74658bc8375278eabf074b4777458376540John McCall 2591323ed74658bc8375278eabf074b4777458376540John McCallvoid CheckConditionalOperand(Sema &S, Expr *E, QualType T, 2592323ed74658bc8375278eabf074b4777458376540John McCall bool &ICContext) { 2593323ed74658bc8375278eabf074b4777458376540John McCall E = E->IgnoreParenImpCasts(); 2594323ed74658bc8375278eabf074b4777458376540John McCall 2595323ed74658bc8375278eabf074b4777458376540John McCall if (isa<ConditionalOperator>(E)) 2596323ed74658bc8375278eabf074b4777458376540John McCall return CheckConditionalOperator(S, cast<ConditionalOperator>(E), T); 2597323ed74658bc8375278eabf074b4777458376540John McCall 2598323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(S, E); 2599323ed74658bc8375278eabf074b4777458376540John McCall if (E->getType() != T) 2600323ed74658bc8375278eabf074b4777458376540John McCall return CheckImplicitConversion(S, E, T, &ICContext); 2601323ed74658bc8375278eabf074b4777458376540John McCall return; 2602323ed74658bc8375278eabf074b4777458376540John McCall} 2603323ed74658bc8375278eabf074b4777458376540John McCall 2604323ed74658bc8375278eabf074b4777458376540John McCallvoid CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) { 2605323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(S, E->getCond()); 2606323ed74658bc8375278eabf074b4777458376540John McCall 2607323ed74658bc8375278eabf074b4777458376540John McCall bool Suspicious = false; 2608323ed74658bc8375278eabf074b4777458376540John McCall CheckConditionalOperand(S, E->getTrueExpr(), T, Suspicious); 2609323ed74658bc8375278eabf074b4777458376540John McCall CheckConditionalOperand(S, E->getFalseExpr(), T, Suspicious); 2610323ed74658bc8375278eabf074b4777458376540John McCall 2611323ed74658bc8375278eabf074b4777458376540John McCall // If -Wconversion would have warned about either of the candidates 2612323ed74658bc8375278eabf074b4777458376540John McCall // for a signedness conversion to the context type... 2613323ed74658bc8375278eabf074b4777458376540John McCall if (!Suspicious) return; 2614323ed74658bc8375278eabf074b4777458376540John McCall 2615323ed74658bc8375278eabf074b4777458376540John McCall // ...but it's currently ignored... 2616323ed74658bc8375278eabf074b4777458376540John McCall if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional)) 2617323ed74658bc8375278eabf074b4777458376540John McCall return; 2618323ed74658bc8375278eabf074b4777458376540John McCall 2619323ed74658bc8375278eabf074b4777458376540John McCall // ...and -Wsign-compare isn't... 2620323ed74658bc8375278eabf074b4777458376540John McCall if (!S.Diags.getDiagnosticLevel(diag::warn_mixed_sign_conditional)) 2621323ed74658bc8375278eabf074b4777458376540John McCall return; 2622323ed74658bc8375278eabf074b4777458376540John McCall 2623323ed74658bc8375278eabf074b4777458376540John McCall // ...then check whether it would have warned about either of the 2624323ed74658bc8375278eabf074b4777458376540John McCall // candidates for a signedness conversion to the condition type. 2625323ed74658bc8375278eabf074b4777458376540John McCall if (E->getType() != T) { 2626323ed74658bc8375278eabf074b4777458376540John McCall Suspicious = false; 2627323ed74658bc8375278eabf074b4777458376540John McCall CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(), 2628323ed74658bc8375278eabf074b4777458376540John McCall E->getType(), &Suspicious); 2629323ed74658bc8375278eabf074b4777458376540John McCall if (!Suspicious) 2630323ed74658bc8375278eabf074b4777458376540John McCall CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(), 2631323ed74658bc8375278eabf074b4777458376540John McCall E->getType(), &Suspicious); 2632323ed74658bc8375278eabf074b4777458376540John McCall if (!Suspicious) 2633323ed74658bc8375278eabf074b4777458376540John McCall return; 2634323ed74658bc8375278eabf074b4777458376540John McCall } 2635323ed74658bc8375278eabf074b4777458376540John McCall 2636323ed74658bc8375278eabf074b4777458376540John McCall // If so, emit a diagnostic under -Wsign-compare. 2637323ed74658bc8375278eabf074b4777458376540John McCall Expr *lex = E->getTrueExpr()->IgnoreParenImpCasts(); 2638323ed74658bc8375278eabf074b4777458376540John McCall Expr *rex = E->getFalseExpr()->IgnoreParenImpCasts(); 2639323ed74658bc8375278eabf074b4777458376540John McCall S.Diag(E->getQuestionLoc(), diag::warn_mixed_sign_conditional) 2640323ed74658bc8375278eabf074b4777458376540John McCall << lex->getType() << rex->getType() 2641323ed74658bc8375278eabf074b4777458376540John McCall << lex->getSourceRange() << rex->getSourceRange(); 2642323ed74658bc8375278eabf074b4777458376540John McCall} 2643323ed74658bc8375278eabf074b4777458376540John McCall 2644323ed74658bc8375278eabf074b4777458376540John McCall/// AnalyzeImplicitConversions - Find and report any interesting 2645323ed74658bc8375278eabf074b4777458376540John McCall/// implicit conversions in the given expression. There are a couple 2646323ed74658bc8375278eabf074b4777458376540John McCall/// of competing diagnostics here, -Wconversion and -Wsign-compare. 2647323ed74658bc8375278eabf074b4777458376540John McCallvoid AnalyzeImplicitConversions(Sema &S, Expr *OrigE) { 2648323ed74658bc8375278eabf074b4777458376540John McCall QualType T = OrigE->getType(); 2649323ed74658bc8375278eabf074b4777458376540John McCall Expr *E = OrigE->IgnoreParenImpCasts(); 2650323ed74658bc8375278eabf074b4777458376540John McCall 2651323ed74658bc8375278eabf074b4777458376540John McCall // For conditional operators, we analyze the arguments as if they 2652323ed74658bc8375278eabf074b4777458376540John McCall // were being fed directly into the output. 2653323ed74658bc8375278eabf074b4777458376540John McCall if (isa<ConditionalOperator>(E)) { 2654323ed74658bc8375278eabf074b4777458376540John McCall ConditionalOperator *CO = cast<ConditionalOperator>(E); 2655323ed74658bc8375278eabf074b4777458376540John McCall CheckConditionalOperator(S, CO, T); 2656323ed74658bc8375278eabf074b4777458376540John McCall return; 2657323ed74658bc8375278eabf074b4777458376540John McCall } 2658323ed74658bc8375278eabf074b4777458376540John McCall 2659323ed74658bc8375278eabf074b4777458376540John McCall // Go ahead and check any implicit conversions we might have skipped. 2660323ed74658bc8375278eabf074b4777458376540John McCall // The non-canonical typecheck is just an optimization; 2661323ed74658bc8375278eabf074b4777458376540John McCall // CheckImplicitConversion will filter out dead implicit conversions. 2662323ed74658bc8375278eabf074b4777458376540John McCall if (E->getType() != T) 2663323ed74658bc8375278eabf074b4777458376540John McCall CheckImplicitConversion(S, E, T); 2664323ed74658bc8375278eabf074b4777458376540John McCall 2665323ed74658bc8375278eabf074b4777458376540John McCall // Now continue drilling into this expression. 2666323ed74658bc8375278eabf074b4777458376540John McCall 2667323ed74658bc8375278eabf074b4777458376540John McCall // Skip past explicit casts. 2668323ed74658bc8375278eabf074b4777458376540John McCall if (isa<ExplicitCastExpr>(E)) { 2669323ed74658bc8375278eabf074b4777458376540John McCall E = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreParenImpCasts(); 2670323ed74658bc8375278eabf074b4777458376540John McCall return AnalyzeImplicitConversions(S, E); 2671323ed74658bc8375278eabf074b4777458376540John McCall } 2672323ed74658bc8375278eabf074b4777458376540John McCall 2673323ed74658bc8375278eabf074b4777458376540John McCall // Do a somewhat different check with comparison operators. 2674323ed74658bc8375278eabf074b4777458376540John McCall if (isa<BinaryOperator>(E) && cast<BinaryOperator>(E)->isComparisonOp()) 2675323ed74658bc8375278eabf074b4777458376540John McCall return AnalyzeComparison(S, cast<BinaryOperator>(E)); 2676323ed74658bc8375278eabf074b4777458376540John McCall 2677323ed74658bc8375278eabf074b4777458376540John McCall // These break the otherwise-useful invariant below. Fortunately, 2678323ed74658bc8375278eabf074b4777458376540John McCall // we don't really need to recurse into them, because any internal 2679323ed74658bc8375278eabf074b4777458376540John McCall // expressions should have been analyzed already when they were 2680323ed74658bc8375278eabf074b4777458376540John McCall // built into statements. 2681323ed74658bc8375278eabf074b4777458376540John McCall if (isa<StmtExpr>(E)) return; 2682323ed74658bc8375278eabf074b4777458376540John McCall 2683323ed74658bc8375278eabf074b4777458376540John McCall // Don't descend into unevaluated contexts. 2684323ed74658bc8375278eabf074b4777458376540John McCall if (isa<SizeOfAlignOfExpr>(E)) return; 2685323ed74658bc8375278eabf074b4777458376540John McCall 2686323ed74658bc8375278eabf074b4777458376540John McCall // Now just recurse over the expression's children. 2687323ed74658bc8375278eabf074b4777458376540John McCall for (Stmt::child_iterator I = E->child_begin(), IE = E->child_end(); 2688323ed74658bc8375278eabf074b4777458376540John McCall I != IE; ++I) 2689323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(S, cast<Expr>(*I)); 2690323ed74658bc8375278eabf074b4777458376540John McCall} 2691323ed74658bc8375278eabf074b4777458376540John McCall 2692323ed74658bc8375278eabf074b4777458376540John McCall} // end anonymous namespace 2693323ed74658bc8375278eabf074b4777458376540John McCall 2694323ed74658bc8375278eabf074b4777458376540John McCall/// Diagnoses "dangerous" implicit conversions within the given 2695323ed74658bc8375278eabf074b4777458376540John McCall/// expression (which is a full expression). Implements -Wconversion 2696323ed74658bc8375278eabf074b4777458376540John McCall/// and -Wsign-compare. 2697323ed74658bc8375278eabf074b4777458376540John McCallvoid Sema::CheckImplicitConversions(Expr *E) { 2698323ed74658bc8375278eabf074b4777458376540John McCall // Don't diagnose in unevaluated contexts. 2699323ed74658bc8375278eabf074b4777458376540John McCall if (ExprEvalContexts.back().Context == Sema::Unevaluated) 2700323ed74658bc8375278eabf074b4777458376540John McCall return; 2701323ed74658bc8375278eabf074b4777458376540John McCall 2702323ed74658bc8375278eabf074b4777458376540John McCall // Don't diagnose for value- or type-dependent expressions. 2703323ed74658bc8375278eabf074b4777458376540John McCall if (E->isTypeDependent() || E->isValueDependent()) 2704323ed74658bc8375278eabf074b4777458376540John McCall return; 2705323ed74658bc8375278eabf074b4777458376540John McCall 2706323ed74658bc8375278eabf074b4777458376540John McCall AnalyzeImplicitConversions(*this, E); 2707323ed74658bc8375278eabf074b4777458376540John McCall} 2708323ed74658bc8375278eabf074b4777458376540John McCall 2709f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump/// CheckParmsForFunctionDef - Check that the parameters of the given 2710f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump/// function are appropriate for the definition of a function. This 2711f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump/// takes care of any checks that cannot be performed on the 2712f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump/// declaration itself, e.g., that the types of each of the function 2713f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump/// parameters are complete. 2714f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stumpbool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) { 2715f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump bool HasInvalidParm = false; 2716f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) { 2717f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump ParmVarDecl *Param = FD->getParamDecl(p); 2718f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump 2719f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump // C99 6.7.5.3p4: the parameters in a parameter type list in a 2720f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump // function declarator that is part of a function definition of 2721f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump // that function shall not have incomplete type. 2722f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump // 2723f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump // This is also C++ [dcl.fct]p6. 2724f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump if (!Param->isInvalidDecl() && 2725f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump RequireCompleteType(Param->getLocation(), Param->getType(), 2726f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump diag::err_typecheck_decl_incomplete_type)) { 2727f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump Param->setInvalidDecl(); 2728f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump HasInvalidParm = true; 2729f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump } 2730f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump 2731f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump // C99 6.9.1p5: If the declarator includes a parameter type list, the 2732f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump // declaration of each parameter shall include an identifier. 2733f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump if (Param->getIdentifier() == 0 && 2734f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump !Param->isImplicit() && 2735f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump !getLangOptions().CPlusPlus) 2736f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump Diag(Param->getLocation(), diag::err_parameter_name_omitted); 2737d17e340e2d516139931768697bf080f60920ba9dSam Weinig 2738d17e340e2d516139931768697bf080f60920ba9dSam Weinig // C99 6.7.5.3p12: 2739d17e340e2d516139931768697bf080f60920ba9dSam Weinig // If the function declarator is not part of a definition of that 2740d17e340e2d516139931768697bf080f60920ba9dSam Weinig // function, parameters may have incomplete type and may use the [*] 2741d17e340e2d516139931768697bf080f60920ba9dSam Weinig // notation in their sequences of declarator specifiers to specify 2742d17e340e2d516139931768697bf080f60920ba9dSam Weinig // variable length array types. 2743d17e340e2d516139931768697bf080f60920ba9dSam Weinig QualType PType = Param->getOriginalType(); 2744d17e340e2d516139931768697bf080f60920ba9dSam Weinig if (const ArrayType *AT = Context.getAsArrayType(PType)) { 2745d17e340e2d516139931768697bf080f60920ba9dSam Weinig if (AT->getSizeModifier() == ArrayType::Star) { 2746d17e340e2d516139931768697bf080f60920ba9dSam Weinig // FIXME: This diagnosic should point the the '[*]' if source-location 2747d17e340e2d516139931768697bf080f60920ba9dSam Weinig // information is added for it. 2748d17e340e2d516139931768697bf080f60920ba9dSam Weinig Diag(Param->getLocation(), diag::err_array_star_in_function_definition); 2749d17e340e2d516139931768697bf080f60920ba9dSam Weinig } 2750d17e340e2d516139931768697bf080f60920ba9dSam Weinig } 2751f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump } 2752f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump 2753f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump return HasInvalidParm; 2754f8c4921c73d73123e2b79221ad4f1775ce984cfdMike Stump} 2755