| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 1 | //===--- SemaChecking.cpp - Extra Semantic Checking -----------------------===// | 
 | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 0bc735f | 2007-12-29 19:59:25 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 10 | //  This file implements extra semantic analysis beyond what is enforced | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 11 | //  by the C type system. | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
| John McCall | 5f8d604 | 2011-08-27 01:09:30 +0000 | [diff] [blame] | 15 | #include "clang/Sema/Initialization.h" | 
| Douglas Gregor | e737f50 | 2010-08-12 20:07:10 +0000 | [diff] [blame] | 16 | #include "clang/Sema/Sema.h" | 
| John McCall | 2d88708 | 2010-08-25 22:03:47 +0000 | [diff] [blame] | 17 | #include "clang/Sema/SemaInternal.h" | 
| John McCall | 781472f | 2010-08-25 08:40:02 +0000 | [diff] [blame] | 18 | #include "clang/Sema/ScopeInfo.h" | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 19 | #include "clang/Analysis/Analyses/FormatString.h" | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 20 | #include "clang/AST/ASTContext.h" | 
| Ken Dyck | 199c3d6 | 2010-01-11 17:06:35 +0000 | [diff] [blame] | 21 | #include "clang/AST/CharUnits.h" | 
| John McCall | 384aff8 | 2010-08-25 07:42:41 +0000 | [diff] [blame] | 22 | #include "clang/AST/DeclCXX.h" | 
| Daniel Dunbar | c4a1dea | 2008-08-11 05:35:13 +0000 | [diff] [blame] | 23 | #include "clang/AST/DeclObjC.h" | 
| Ted Kremenek | 2324512 | 2007-08-20 16:18:38 +0000 | [diff] [blame] | 24 | #include "clang/AST/ExprCXX.h" | 
| Ted Kremenek | 7ff22b2 | 2008-06-16 18:00:42 +0000 | [diff] [blame] | 25 | #include "clang/AST/ExprObjC.h" | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 26 | #include "clang/AST/EvaluatedExprVisitor.h" | 
| Mike Stump | f8c4921 | 2010-01-21 03:59:47 +0000 | [diff] [blame] | 27 | #include "clang/AST/DeclObjC.h" | 
 | 28 | #include "clang/AST/StmtCXX.h" | 
 | 29 | #include "clang/AST/StmtObjC.h" | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 30 | #include "clang/Lex/Preprocessor.h" | 
| Mike Stump | f8c4921 | 2010-01-21 03:59:47 +0000 | [diff] [blame] | 31 | #include "llvm/ADT/BitVector.h" | 
 | 32 | #include "llvm/ADT/STLExtras.h" | 
| Tom Care | 3bfc5f4 | 2010-06-09 04:11:11 +0000 | [diff] [blame] | 33 | #include "llvm/Support/raw_ostream.h" | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 34 | #include "clang/Basic/TargetBuiltins.h" | 
| Nate Begeman | 26a3142 | 2010-06-08 02:47:44 +0000 | [diff] [blame] | 35 | #include "clang/Basic/TargetInfo.h" | 
| Fariborz Jahanian | 7da7102 | 2010-09-07 19:38:13 +0000 | [diff] [blame] | 36 | #include "clang/Basic/ConvertUTF.h" | 
| Zhongxing Xu | a1f3dba | 2009-05-20 01:55:10 +0000 | [diff] [blame] | 37 | #include <limits> | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 38 | using namespace clang; | 
| John McCall | 781472f | 2010-08-25 08:40:02 +0000 | [diff] [blame] | 39 | using namespace sema; | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 40 |  | 
| Chris Lattner | 6080008 | 2009-02-18 17:49:48 +0000 | [diff] [blame] | 41 | SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL, | 
 | 42 |                                                     unsigned ByteNo) const { | 
| Chris Lattner | 08f92e3 | 2010-11-17 07:37:15 +0000 | [diff] [blame] | 43 |   return SL->getLocationOfByte(ByteNo, PP.getSourceManager(), | 
 | 44 |                                PP.getLangOptions(), PP.getTargetInfo()); | 
| Chris Lattner | 6080008 | 2009-02-18 17:49:48 +0000 | [diff] [blame] | 45 | } | 
| Chris Lattner | 08f92e3 | 2010-11-17 07:37:15 +0000 | [diff] [blame] | 46 |    | 
| Chris Lattner | 6080008 | 2009-02-18 17:49:48 +0000 | [diff] [blame] | 47 |  | 
| Ryan Flynn | 4403a5e | 2009-08-06 03:00:50 +0000 | [diff] [blame] | 48 | /// CheckablePrintfAttr - does a function call have a "printf" attribute | 
 | 49 | /// and arguments that merit checking? | 
 | 50 | bool Sema::CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall) { | 
 | 51 |   if (Format->getType() == "printf") return true; | 
 | 52 |   if (Format->getType() == "printf0") { | 
 | 53 |     // printf0 allows null "format" string; if so don't check format/args | 
 | 54 |     unsigned format_idx = Format->getFormatIdx() - 1; | 
| Sebastian Redl | 4a2614e | 2009-11-17 18:02:24 +0000 | [diff] [blame] | 55 |     // Does the index refer to the implicit object argument? | 
 | 56 |     if (isa<CXXMemberCallExpr>(TheCall)) { | 
 | 57 |       if (format_idx == 0) | 
 | 58 |         return false; | 
 | 59 |       --format_idx; | 
 | 60 |     } | 
| Ryan Flynn | 4403a5e | 2009-08-06 03:00:50 +0000 | [diff] [blame] | 61 |     if (format_idx < TheCall->getNumArgs()) { | 
 | 62 |       Expr *Format = TheCall->getArg(format_idx)->IgnoreParenCasts(); | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 63 |       if (!Format->isNullPointerConstant(Context, | 
 | 64 |                                          Expr::NPC_ValueDependentIsNull)) | 
| Ryan Flynn | 4403a5e | 2009-08-06 03:00:50 +0000 | [diff] [blame] | 65 |         return true; | 
 | 66 |     } | 
 | 67 |   } | 
 | 68 |   return false; | 
 | 69 | } | 
| Chris Lattner | 6080008 | 2009-02-18 17:49:48 +0000 | [diff] [blame] | 70 |  | 
| John McCall | 8e10f3b | 2011-02-26 05:39:39 +0000 | [diff] [blame] | 71 | /// Checks that a call expression's argument count is the desired number. | 
 | 72 | /// This is useful when doing custom type-checking.  Returns true on error. | 
 | 73 | static bool checkArgCount(Sema &S, CallExpr *call, unsigned desiredArgCount) { | 
 | 74 |   unsigned argCount = call->getNumArgs(); | 
 | 75 |   if (argCount == desiredArgCount) return false; | 
 | 76 |  | 
 | 77 |   if (argCount < desiredArgCount) | 
 | 78 |     return S.Diag(call->getLocEnd(), diag::err_typecheck_call_too_few_args) | 
 | 79 |         << 0 /*function call*/ << desiredArgCount << argCount | 
 | 80 |         << call->getSourceRange(); | 
 | 81 |  | 
 | 82 |   // Highlight all the excess arguments. | 
 | 83 |   SourceRange range(call->getArg(desiredArgCount)->getLocStart(), | 
 | 84 |                     call->getArg(argCount - 1)->getLocEnd()); | 
 | 85 |      | 
 | 86 |   return S.Diag(range.getBegin(), diag::err_typecheck_call_too_many_args) | 
 | 87 |     << 0 /*function call*/ << desiredArgCount << argCount | 
 | 88 |     << call->getArg(1)->getSourceRange(); | 
 | 89 | } | 
 | 90 |  | 
| Julien Lerouge | 77f68bb | 2011-09-09 22:41:49 +0000 | [diff] [blame] | 91 | /// CheckBuiltinAnnotationString - Checks that string argument to the builtin | 
 | 92 | /// annotation is a non wide string literal. | 
 | 93 | static bool CheckBuiltinAnnotationString(Sema &S, Expr *Arg) { | 
 | 94 |   Arg = Arg->IgnoreParenCasts(); | 
 | 95 |   StringLiteral *Literal = dyn_cast<StringLiteral>(Arg); | 
 | 96 |   if (!Literal || !Literal->isAscii()) { | 
 | 97 |     S.Diag(Arg->getLocStart(), diag::err_builtin_annotation_not_string_constant) | 
 | 98 |       << Arg->getSourceRange(); | 
 | 99 |     return true; | 
 | 100 |   } | 
 | 101 |   return false; | 
 | 102 | } | 
 | 103 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 104 | ExprResult | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 105 | Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 106 |   ExprResult TheCallResult(Owned(TheCall)); | 
| Douglas Gregor | 2def483 | 2008-11-17 20:34:05 +0000 | [diff] [blame] | 107 |  | 
| Chris Lattner | 946928f | 2010-10-01 23:23:24 +0000 | [diff] [blame] | 108 |   // Find out if any arguments are required to be integer constant expressions. | 
 | 109 |   unsigned ICEArguments = 0; | 
 | 110 |   ASTContext::GetBuiltinTypeError Error; | 
 | 111 |   Context.GetBuiltinType(BuiltinID, Error, &ICEArguments); | 
 | 112 |   if (Error != ASTContext::GE_None) | 
 | 113 |     ICEArguments = 0;  // Don't diagnose previously diagnosed errors. | 
 | 114 |    | 
 | 115 |   // If any arguments are required to be ICE's, check and diagnose. | 
 | 116 |   for (unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) { | 
 | 117 |     // Skip arguments not required to be ICE's. | 
 | 118 |     if ((ICEArguments & (1 << ArgNo)) == 0) continue; | 
 | 119 |      | 
 | 120 |     llvm::APSInt Result; | 
 | 121 |     if (SemaBuiltinConstantArg(TheCall, ArgNo, Result)) | 
 | 122 |       return true; | 
 | 123 |     ICEArguments &= ~(1 << ArgNo); | 
 | 124 |   } | 
 | 125 |    | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 126 |   switch (BuiltinID) { | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 127 |   case Builtin::BI__builtin___CFStringMakeConstantString: | 
| Chris Lattner | 925e60d | 2007-12-28 05:29:59 +0000 | [diff] [blame] | 128 |     assert(TheCall->getNumArgs() == 1 && | 
| Chris Lattner | 1b9a079 | 2007-12-20 00:26:33 +0000 | [diff] [blame] | 129 |            "Wrong # arguments to builtin CFStringMakeConstantString"); | 
| Chris Lattner | 6903981 | 2009-02-18 06:01:06 +0000 | [diff] [blame] | 130 |     if (CheckObjCString(TheCall->getArg(0))) | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 131 |       return ExprError(); | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 132 |     break; | 
| Ted Kremenek | 49ff7a1 | 2008-07-09 17:58:53 +0000 | [diff] [blame] | 133 |   case Builtin::BI__builtin_stdarg_start: | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 134 |   case Builtin::BI__builtin_va_start: | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 135 |     if (SemaBuiltinVAStart(TheCall)) | 
 | 136 |       return ExprError(); | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 137 |     break; | 
| Chris Lattner | 1b9a079 | 2007-12-20 00:26:33 +0000 | [diff] [blame] | 138 |   case Builtin::BI__builtin_isgreater: | 
 | 139 |   case Builtin::BI__builtin_isgreaterequal: | 
 | 140 |   case Builtin::BI__builtin_isless: | 
 | 141 |   case Builtin::BI__builtin_islessequal: | 
 | 142 |   case Builtin::BI__builtin_islessgreater: | 
 | 143 |   case Builtin::BI__builtin_isunordered: | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 144 |     if (SemaBuiltinUnorderedCompare(TheCall)) | 
 | 145 |       return ExprError(); | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 146 |     break; | 
| Benjamin Kramer | e771a7a | 2010-02-15 22:42:31 +0000 | [diff] [blame] | 147 |   case Builtin::BI__builtin_fpclassify: | 
 | 148 |     if (SemaBuiltinFPClassification(TheCall, 6)) | 
 | 149 |       return ExprError(); | 
 | 150 |     break; | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 151 |   case Builtin::BI__builtin_isfinite: | 
 | 152 |   case Builtin::BI__builtin_isinf: | 
 | 153 |   case Builtin::BI__builtin_isinf_sign: | 
 | 154 |   case Builtin::BI__builtin_isnan: | 
 | 155 |   case Builtin::BI__builtin_isnormal: | 
| Benjamin Kramer | 3b1e26b | 2010-02-16 10:07:31 +0000 | [diff] [blame] | 156 |     if (SemaBuiltinFPClassification(TheCall, 1)) | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 157 |       return ExprError(); | 
 | 158 |     break; | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 159 |   case Builtin::BI__builtin_shufflevector: | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 160 |     return SemaBuiltinShuffleVector(TheCall); | 
 | 161 |     // TheCall will be freed by the smart pointer here, but that's fine, since | 
 | 162 |     // SemaBuiltinShuffleVector guts it, but then doesn't release it. | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 163 |   case Builtin::BI__builtin_prefetch: | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 164 |     if (SemaBuiltinPrefetch(TheCall)) | 
 | 165 |       return ExprError(); | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 166 |     break; | 
| Daniel Dunbar | d5f8a4f | 2008-09-03 21:13:56 +0000 | [diff] [blame] | 167 |   case Builtin::BI__builtin_object_size: | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 168 |     if (SemaBuiltinObjectSize(TheCall)) | 
 | 169 |       return ExprError(); | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 170 |     break; | 
| Eli Friedman | d875fed | 2009-05-03 04:46:36 +0000 | [diff] [blame] | 171 |   case Builtin::BI__builtin_longjmp: | 
 | 172 |     if (SemaBuiltinLongjmp(TheCall)) | 
 | 173 |       return ExprError(); | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 174 |     break; | 
| John McCall | 8e10f3b | 2011-02-26 05:39:39 +0000 | [diff] [blame] | 175 |  | 
 | 176 |   case Builtin::BI__builtin_classify_type: | 
 | 177 |     if (checkArgCount(*this, TheCall, 1)) return true; | 
 | 178 |     TheCall->setType(Context.IntTy); | 
 | 179 |     break; | 
| Chris Lattner | 75c29a0 | 2010-10-12 17:47:42 +0000 | [diff] [blame] | 180 |   case Builtin::BI__builtin_constant_p: | 
| John McCall | 8e10f3b | 2011-02-26 05:39:39 +0000 | [diff] [blame] | 181 |     if (checkArgCount(*this, TheCall, 1)) return true; | 
 | 182 |     TheCall->setType(Context.IntTy); | 
| Chris Lattner | 75c29a0 | 2010-10-12 17:47:42 +0000 | [diff] [blame] | 183 |     break; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 184 |   case Builtin::BI__sync_fetch_and_add: | 
 | 185 |   case Builtin::BI__sync_fetch_and_sub: | 
 | 186 |   case Builtin::BI__sync_fetch_and_or: | 
 | 187 |   case Builtin::BI__sync_fetch_and_and: | 
 | 188 |   case Builtin::BI__sync_fetch_and_xor: | 
 | 189 |   case Builtin::BI__sync_add_and_fetch: | 
 | 190 |   case Builtin::BI__sync_sub_and_fetch: | 
 | 191 |   case Builtin::BI__sync_and_and_fetch: | 
 | 192 |   case Builtin::BI__sync_or_and_fetch: | 
 | 193 |   case Builtin::BI__sync_xor_and_fetch: | 
 | 194 |   case Builtin::BI__sync_val_compare_and_swap: | 
 | 195 |   case Builtin::BI__sync_bool_compare_and_swap: | 
 | 196 |   case Builtin::BI__sync_lock_test_and_set: | 
 | 197 |   case Builtin::BI__sync_lock_release: | 
| Chris Lattner | 23aa9c8 | 2011-04-09 03:57:26 +0000 | [diff] [blame] | 198 |   case Builtin::BI__sync_swap: | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 199 |     return SemaBuiltinAtomicOverloaded(move(TheCallResult)); | 
| Julien Lerouge | 77f68bb | 2011-09-09 22:41:49 +0000 | [diff] [blame] | 200 |   case Builtin::BI__builtin_annotation: | 
 | 201 |     if (CheckBuiltinAnnotationString(*this, TheCall->getArg(1))) | 
 | 202 |       return ExprError(); | 
 | 203 |     break; | 
| Nate Begeman | 26a3142 | 2010-06-08 02:47:44 +0000 | [diff] [blame] | 204 |   } | 
 | 205 |    | 
 | 206 |   // Since the target specific builtins for each arch overlap, only check those | 
 | 207 |   // of the arch we are compiling for. | 
 | 208 |   if (BuiltinID >= Builtin::FirstTSBuiltin) { | 
| Douglas Gregor | bcfd1f5 | 2011-09-02 00:18:52 +0000 | [diff] [blame] | 209 |     switch (Context.getTargetInfo().getTriple().getArch()) { | 
| Nate Begeman | 26a3142 | 2010-06-08 02:47:44 +0000 | [diff] [blame] | 210 |       case llvm::Triple::arm: | 
 | 211 |       case llvm::Triple::thumb: | 
 | 212 |         if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall)) | 
 | 213 |           return ExprError(); | 
 | 214 |         break; | 
| Nate Begeman | 26a3142 | 2010-06-08 02:47:44 +0000 | [diff] [blame] | 215 |       default: | 
 | 216 |         break; | 
 | 217 |     } | 
 | 218 |   } | 
 | 219 |  | 
 | 220 |   return move(TheCallResult); | 
 | 221 | } | 
 | 222 |  | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 223 | // Get the valid immediate range for the specified NEON type code. | 
 | 224 | static unsigned RFT(unsigned t, bool shift = false) { | 
 | 225 |   bool quad = t & 0x10; | 
 | 226 |    | 
 | 227 |   switch (t & 0x7) { | 
 | 228 |     case 0: // i8 | 
| Nate Begeman | d69ec16 | 2010-06-17 02:26:59 +0000 | [diff] [blame] | 229 |       return shift ? 7 : (8 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 230 |     case 1: // i16 | 
| Nate Begeman | d69ec16 | 2010-06-17 02:26:59 +0000 | [diff] [blame] | 231 |       return shift ? 15 : (4 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 232 |     case 2: // i32 | 
| Nate Begeman | d69ec16 | 2010-06-17 02:26:59 +0000 | [diff] [blame] | 233 |       return shift ? 31 : (2 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 234 |     case 3: // i64 | 
| Nate Begeman | d69ec16 | 2010-06-17 02:26:59 +0000 | [diff] [blame] | 235 |       return shift ? 63 : (1 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 236 |     case 4: // f32 | 
 | 237 |       assert(!shift && "cannot shift float types!"); | 
| Nate Begeman | d69ec16 | 2010-06-17 02:26:59 +0000 | [diff] [blame] | 238 |       return (2 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 239 |     case 5: // poly8 | 
| Bob Wilson | 42499f9 | 2010-12-10 19:45:06 +0000 | [diff] [blame] | 240 |       return shift ? 7 : (8 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 241 |     case 6: // poly16 | 
| Bob Wilson | 42499f9 | 2010-12-10 19:45:06 +0000 | [diff] [blame] | 242 |       return shift ? 15 : (4 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 243 |     case 7: // float16 | 
 | 244 |       assert(!shift && "cannot shift float types!"); | 
| Nate Begeman | d69ec16 | 2010-06-17 02:26:59 +0000 | [diff] [blame] | 245 |       return (4 << (int)quad) - 1; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 246 |   } | 
 | 247 |   return 0; | 
 | 248 | } | 
 | 249 |  | 
| Nate Begeman | 26a3142 | 2010-06-08 02:47:44 +0000 | [diff] [blame] | 250 | bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { | 
| Nate Begeman | 1c2a88c | 2010-06-09 01:10:23 +0000 | [diff] [blame] | 251 |   llvm::APSInt Result; | 
 | 252 |  | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 253 |   unsigned mask = 0; | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 254 |   unsigned TV = 0; | 
| Nate Begeman | 1c2a88c | 2010-06-09 01:10:23 +0000 | [diff] [blame] | 255 |   switch (BuiltinID) { | 
| Nate Begeman | a23326b | 2010-06-17 04:17:01 +0000 | [diff] [blame] | 256 | #define GET_NEON_OVERLOAD_CHECK | 
 | 257 | #include "clang/Basic/arm_neon.inc" | 
 | 258 | #undef GET_NEON_OVERLOAD_CHECK | 
| Nate Begeman | 1c2a88c | 2010-06-09 01:10:23 +0000 | [diff] [blame] | 259 |   } | 
 | 260 |    | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 261 |   // For NEON intrinsics which are overloaded on vector element type, validate | 
 | 262 |   // the immediate which specifies which variant to emit. | 
 | 263 |   if (mask) { | 
 | 264 |     unsigned ArgNo = TheCall->getNumArgs()-1; | 
 | 265 |     if (SemaBuiltinConstantArg(TheCall, ArgNo, Result)) | 
 | 266 |       return true; | 
 | 267 |      | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 268 |     TV = Result.getLimitedValue(32); | 
 | 269 |     if ((TV > 31) || (mask & (1 << TV)) == 0) | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 270 |       return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code) | 
 | 271 |         << TheCall->getArg(ArgNo)->getSourceRange(); | 
 | 272 |   } | 
| Nate Begeman | 1c2a88c | 2010-06-09 01:10:23 +0000 | [diff] [blame] | 273 |    | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 274 |   // For NEON intrinsics which take an immediate value as part of the  | 
 | 275 |   // instruction, range check them here. | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 276 |   unsigned i = 0, l = 0, u = 0; | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 277 |   switch (BuiltinID) { | 
 | 278 |   default: return false; | 
| Nate Begeman | bb37f50 | 2010-07-29 22:48:34 +0000 | [diff] [blame] | 279 |   case ARM::BI__builtin_arm_ssat: i = 1; l = 1; u = 31; break; | 
 | 280 |   case ARM::BI__builtin_arm_usat: i = 1; u = 31; break; | 
| Nate Begeman | 99c40bb | 2010-08-03 21:32:34 +0000 | [diff] [blame] | 281 |   case ARM::BI__builtin_arm_vcvtr_f: | 
 | 282 |   case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break; | 
| Nate Begeman | a23326b | 2010-06-17 04:17:01 +0000 | [diff] [blame] | 283 | #define GET_NEON_IMMEDIATE_CHECK | 
 | 284 | #include "clang/Basic/arm_neon.inc" | 
 | 285 | #undef GET_NEON_IMMEDIATE_CHECK | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 286 |   }; | 
 | 287 |  | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 288 |   // Check that the immediate argument is actually a constant. | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 289 |   if (SemaBuiltinConstantArg(TheCall, i, Result)) | 
 | 290 |     return true; | 
 | 291 |  | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 292 |   // Range check against the upper/lower values for this isntruction. | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 293 |   unsigned Val = Result.getZExtValue(); | 
| Nate Begeman | 61eecf5 | 2010-06-14 05:21:25 +0000 | [diff] [blame] | 294 |   if (Val < l || Val > (u + l)) | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 295 |     return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) | 
| Benjamin Kramer | 476d8b8 | 2010-08-11 14:47:12 +0000 | [diff] [blame] | 296 |       << l << u+l << TheCall->getArg(i)->getSourceRange(); | 
| Nate Begeman | 0d15c53 | 2010-06-13 04:47:52 +0000 | [diff] [blame] | 297 |  | 
| Nate Begeman | 99c40bb | 2010-08-03 21:32:34 +0000 | [diff] [blame] | 298 |   // FIXME: VFP Intrinsics should error if VFP not present. | 
| Nate Begeman | 26a3142 | 2010-06-08 02:47:44 +0000 | [diff] [blame] | 299 |   return false; | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 300 | } | 
| Daniel Dunbar | de45428 | 2008-10-02 18:44:07 +0000 | [diff] [blame] | 301 |  | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 302 | /// CheckFunctionCall - Check a direct function call for various correctness | 
 | 303 | /// and safety properties not strictly enforced by the C type system. | 
 | 304 | bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { | 
 | 305 |   // Get the IdentifierInfo* for the called function. | 
 | 306 |   IdentifierInfo *FnInfo = FDecl->getIdentifier(); | 
 | 307 |  | 
 | 308 |   // None of the checks below are needed for functions that don't have | 
 | 309 |   // simple names (e.g., C++ conversion functions). | 
 | 310 |   if (!FnInfo) | 
 | 311 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 312 |  | 
| Daniel Dunbar | de45428 | 2008-10-02 18:44:07 +0000 | [diff] [blame] | 313 |   // FIXME: This mechanism should be abstracted to be less fragile and | 
 | 314 |   // more efficient. For example, just map function ids to custom | 
 | 315 |   // handlers. | 
 | 316 |  | 
| Ted Kremenek | c82faca | 2010-09-09 04:33:05 +0000 | [diff] [blame] | 317 |   // Printf and scanf checking. | 
 | 318 |   for (specific_attr_iterator<FormatAttr> | 
 | 319 |          i = FDecl->specific_attr_begin<FormatAttr>(), | 
 | 320 |          e = FDecl->specific_attr_end<FormatAttr>(); i != e ; ++i) { | 
 | 321 |  | 
 | 322 |     const FormatAttr *Format = *i; | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 323 |     const bool b = Format->getType() == "scanf"; | 
 | 324 |     if (b || CheckablePrintfAttr(Format, TheCall)) { | 
| Ted Kremenek | 3d692df | 2009-02-27 17:58:43 +0000 | [diff] [blame] | 325 |       bool HasVAListArg = Format->getFirstArg() == 0; | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 326 |       CheckPrintfScanfArguments(TheCall, HasVAListArg, | 
 | 327 |                                 Format->getFormatIdx() - 1, | 
 | 328 |                                 HasVAListArg ? 0 : Format->getFirstArg() - 1, | 
 | 329 |                                 !b); | 
| Douglas Gregor | 3c385e5 | 2009-02-14 18:57:46 +0000 | [diff] [blame] | 330 |     } | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 331 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 332 |  | 
| Ted Kremenek | c82faca | 2010-09-09 04:33:05 +0000 | [diff] [blame] | 333 |   for (specific_attr_iterator<NonNullAttr> | 
 | 334 |          i = FDecl->specific_attr_begin<NonNullAttr>(), | 
 | 335 |          e = FDecl->specific_attr_end<NonNullAttr>(); i != e; ++i) { | 
| Nick Lewycky | 909a70d | 2011-03-25 01:44:32 +0000 | [diff] [blame] | 336 |     CheckNonNullArguments(*i, TheCall->getArgs(), | 
 | 337 |                           TheCall->getCallee()->getLocStart()); | 
| Ted Kremenek | c82faca | 2010-09-09 04:33:05 +0000 | [diff] [blame] | 338 |   } | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 339 |  | 
| Ted Kremenek | bd5da9d | 2011-08-18 20:55:45 +0000 | [diff] [blame] | 340 |   // Builtin handling | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 341 |   int CMF = -1; | 
 | 342 |   switch (FDecl->getBuiltinID()) { | 
 | 343 |   case Builtin::BI__builtin_memset: | 
 | 344 |   case Builtin::BI__builtin___memset_chk: | 
 | 345 |   case Builtin::BImemset: | 
 | 346 |     CMF = CMF_Memset; | 
 | 347 |     break; | 
 | 348 |      | 
 | 349 |   case Builtin::BI__builtin_memcpy: | 
 | 350 |   case Builtin::BI__builtin___memcpy_chk: | 
 | 351 |   case Builtin::BImemcpy: | 
 | 352 |     CMF = CMF_Memcpy; | 
 | 353 |     break; | 
 | 354 |      | 
 | 355 |   case Builtin::BI__builtin_memmove: | 
 | 356 |   case Builtin::BI__builtin___memmove_chk: | 
 | 357 |   case Builtin::BImemmove: | 
 | 358 |     CMF = CMF_Memmove; | 
 | 359 |     break; | 
| Ted Kremenek | bd5da9d | 2011-08-18 20:55:45 +0000 | [diff] [blame] | 360 |  | 
 | 361 |   case Builtin::BIstrlcpy: | 
 | 362 |   case Builtin::BIstrlcat: | 
 | 363 |     CheckStrlcpycatArguments(TheCall, FnInfo); | 
 | 364 |     break; | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 365 |      | 
| Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 366 |   case Builtin::BI__builtin_memcmp: | 
 | 367 |     CMF = CMF_Memcmp; | 
 | 368 |     break; | 
 | 369 |      | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 370 |   default: | 
 | 371 |     if (FDecl->getLinkage() == ExternalLinkage && | 
 | 372 |         (!getLangOptions().CPlusPlus || FDecl->isExternC())) { | 
 | 373 |       if (FnInfo->isStr("memset")) | 
 | 374 |         CMF = CMF_Memset; | 
 | 375 |       else if (FnInfo->isStr("memcpy")) | 
 | 376 |         CMF = CMF_Memcpy; | 
 | 377 |       else if (FnInfo->isStr("memmove")) | 
 | 378 |         CMF = CMF_Memmove; | 
| Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 379 |       else if (FnInfo->isStr("memcmp")) | 
 | 380 |         CMF = CMF_Memcmp; | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 381 |     } | 
 | 382 |     break; | 
| Douglas Gregor | 06bc9eb | 2011-05-03 20:37:33 +0000 | [diff] [blame] | 383 |   } | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 384 |     | 
| Ted Kremenek | bd5da9d | 2011-08-18 20:55:45 +0000 | [diff] [blame] | 385 |   // Memset/memcpy/memmove handling | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 386 |   if (CMF != -1) | 
| Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 387 |     CheckMemaccessArguments(TheCall, CheckedMemoryFunction(CMF), FnInfo); | 
| Chandler Carruth | 7ccc95b | 2011-04-27 07:05:31 +0000 | [diff] [blame] | 388 |  | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 389 |   return false; | 
| Anders Carlsson | 71993dd | 2007-08-17 05:31:46 +0000 | [diff] [blame] | 390 | } | 
 | 391 |  | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 392 | bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) { | 
| Fariborz Jahanian | 725165f | 2009-05-18 21:05:18 +0000 | [diff] [blame] | 393 |   // Printf checking. | 
| Argyrios Kyrtzidis | 40b598e | 2009-06-30 02:34:44 +0000 | [diff] [blame] | 394 |   const FormatAttr *Format = NDecl->getAttr<FormatAttr>(); | 
| Fariborz Jahanian | 725165f | 2009-05-18 21:05:18 +0000 | [diff] [blame] | 395 |   if (!Format) | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 396 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 397 |  | 
| Fariborz Jahanian | 725165f | 2009-05-18 21:05:18 +0000 | [diff] [blame] | 398 |   const VarDecl *V = dyn_cast<VarDecl>(NDecl); | 
 | 399 |   if (!V) | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 400 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 401 |  | 
| Fariborz Jahanian | 725165f | 2009-05-18 21:05:18 +0000 | [diff] [blame] | 402 |   QualType Ty = V->getType(); | 
 | 403 |   if (!Ty->isBlockPointerType()) | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 404 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 405 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 406 |   const bool b = Format->getType() == "scanf"; | 
 | 407 |   if (!b && !CheckablePrintfAttr(Format, TheCall)) | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 408 |     return false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 409 |  | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 410 |   bool HasVAListArg = Format->getFirstArg() == 0; | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 411 |   CheckPrintfScanfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1, | 
 | 412 |                             HasVAListArg ? 0 : Format->getFirstArg() - 1, !b); | 
| Anders Carlsson | d406bf0 | 2009-08-16 01:56:34 +0000 | [diff] [blame] | 413 |  | 
 | 414 |   return false; | 
| Fariborz Jahanian | 725165f | 2009-05-18 21:05:18 +0000 | [diff] [blame] | 415 | } | 
 | 416 |  | 
| John McCall | 5f8d604 | 2011-08-27 01:09:30 +0000 | [diff] [blame] | 417 | /// checkBuiltinArgument - Given a call to a builtin function, perform | 
 | 418 | /// normal type-checking on the given argument, updating the call in | 
 | 419 | /// place.  This is useful when a builtin function requires custom | 
 | 420 | /// type-checking for some of its arguments but not necessarily all of | 
 | 421 | /// them. | 
 | 422 | /// | 
 | 423 | /// Returns true on error. | 
 | 424 | static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex) { | 
 | 425 |   FunctionDecl *Fn = E->getDirectCallee(); | 
 | 426 |   assert(Fn && "builtin call without direct callee!"); | 
 | 427 |  | 
 | 428 |   ParmVarDecl *Param = Fn->getParamDecl(ArgIndex); | 
 | 429 |   InitializedEntity Entity = | 
 | 430 |     InitializedEntity::InitializeParameter(S.Context, Param); | 
 | 431 |  | 
 | 432 |   ExprResult Arg = E->getArg(0); | 
 | 433 |   Arg = S.PerformCopyInitialization(Entity, SourceLocation(), Arg); | 
 | 434 |   if (Arg.isInvalid()) | 
 | 435 |     return true; | 
 | 436 |  | 
 | 437 |   E->setArg(ArgIndex, Arg.take()); | 
 | 438 |   return false; | 
 | 439 | } | 
 | 440 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 441 | /// SemaBuiltinAtomicOverloaded - We have a call to a function like | 
 | 442 | /// __sync_fetch_and_add, which is an overloaded function based on the pointer | 
 | 443 | /// type of its first argument.  The main ActOnCallExpr routines have already | 
 | 444 | /// promoted the types of arguments because all of these calls are prototyped as | 
 | 445 | /// void(...). | 
 | 446 | /// | 
 | 447 | /// This function goes through and does final semantic checking for these | 
 | 448 | /// builtins, | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 449 | ExprResult | 
 | 450 | Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 451 |   CallExpr *TheCall = (CallExpr *)TheCallResult.get(); | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 452 |   DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); | 
 | 453 |   FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl()); | 
 | 454 |  | 
 | 455 |   // Ensure that we have at least one argument to do type inference from. | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 456 |   if (TheCall->getNumArgs() < 1) { | 
 | 457 |     Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least) | 
 | 458 |       << 0 << 1 << TheCall->getNumArgs() | 
 | 459 |       << TheCall->getCallee()->getSourceRange(); | 
 | 460 |     return ExprError(); | 
 | 461 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 462 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 463 |   // Inspect the first argument of the atomic builtin.  This should always be | 
 | 464 |   // a pointer type, whose element is an integral scalar or pointer type. | 
 | 465 |   // Because it is a pointer type, we don't have to worry about any implicit | 
 | 466 |   // casts here. | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 467 |   // FIXME: We don't allow floating point scalars as input. | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 468 |   Expr *FirstArg = TheCall->getArg(0); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 469 |   const PointerType *pointerType = FirstArg->getType()->getAs<PointerType>(); | 
 | 470 |   if (!pointerType) { | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 471 |     Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer) | 
 | 472 |       << FirstArg->getType() << FirstArg->getSourceRange(); | 
 | 473 |     return ExprError(); | 
 | 474 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 475 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 476 |   QualType ValType = pointerType->getPointeeType(); | 
| Chris Lattner | dd5fa7a | 2010-09-17 21:12:38 +0000 | [diff] [blame] | 477 |   if (!ValType->isIntegerType() && !ValType->isAnyPointerType() && | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 478 |       !ValType->isBlockPointerType()) { | 
 | 479 |     Diag(DRE->getLocStart(), diag::err_atomic_builtin_must_be_pointer_intptr) | 
 | 480 |       << FirstArg->getType() << FirstArg->getSourceRange(); | 
 | 481 |     return ExprError(); | 
 | 482 |   } | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 483 |  | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 484 |   switch (ValType.getObjCLifetime()) { | 
 | 485 |   case Qualifiers::OCL_None: | 
 | 486 |   case Qualifiers::OCL_ExplicitNone: | 
 | 487 |     // okay | 
 | 488 |     break; | 
 | 489 |  | 
 | 490 |   case Qualifiers::OCL_Weak: | 
 | 491 |   case Qualifiers::OCL_Strong: | 
 | 492 |   case Qualifiers::OCL_Autoreleasing: | 
| Argyrios Kyrtzidis | b8b0313 | 2011-06-24 00:08:59 +0000 | [diff] [blame] | 493 |     Diag(DRE->getLocStart(), diag::err_arc_atomic_ownership) | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 494 |       << ValType << FirstArg->getSourceRange(); | 
 | 495 |     return ExprError(); | 
 | 496 |   } | 
 | 497 |  | 
| John McCall | b45ae25 | 2011-10-05 07:41:44 +0000 | [diff] [blame] | 498 |   // Strip any qualifiers off ValType. | 
 | 499 |   ValType = ValType.getUnqualifiedType(); | 
 | 500 |  | 
| Chandler Carruth | 8d13d22 | 2010-07-18 20:54:12 +0000 | [diff] [blame] | 501 |   // The majority of builtins return a value, but a few have special return | 
 | 502 |   // types, so allow them to override appropriately below. | 
 | 503 |   QualType ResultType = ValType; | 
 | 504 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 505 |   // We need to figure out which concrete builtin this maps onto.  For example, | 
 | 506 |   // __sync_fetch_and_add with a 2 byte object turns into | 
 | 507 |   // __sync_fetch_and_add_2. | 
 | 508 | #define BUILTIN_ROW(x) \ | 
 | 509 |   { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \ | 
 | 510 |     Builtin::BI##x##_8, Builtin::BI##x##_16 } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 511 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 512 |   static const unsigned BuiltinIndices[][5] = { | 
 | 513 |     BUILTIN_ROW(__sync_fetch_and_add), | 
 | 514 |     BUILTIN_ROW(__sync_fetch_and_sub), | 
 | 515 |     BUILTIN_ROW(__sync_fetch_and_or), | 
 | 516 |     BUILTIN_ROW(__sync_fetch_and_and), | 
 | 517 |     BUILTIN_ROW(__sync_fetch_and_xor), | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 518 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 519 |     BUILTIN_ROW(__sync_add_and_fetch), | 
 | 520 |     BUILTIN_ROW(__sync_sub_and_fetch), | 
 | 521 |     BUILTIN_ROW(__sync_and_and_fetch), | 
 | 522 |     BUILTIN_ROW(__sync_or_and_fetch), | 
 | 523 |     BUILTIN_ROW(__sync_xor_and_fetch), | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 524 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 525 |     BUILTIN_ROW(__sync_val_compare_and_swap), | 
 | 526 |     BUILTIN_ROW(__sync_bool_compare_and_swap), | 
 | 527 |     BUILTIN_ROW(__sync_lock_test_and_set), | 
| Chris Lattner | 23aa9c8 | 2011-04-09 03:57:26 +0000 | [diff] [blame] | 528 |     BUILTIN_ROW(__sync_lock_release), | 
 | 529 |     BUILTIN_ROW(__sync_swap) | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 530 |   }; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 531 | #undef BUILTIN_ROW | 
 | 532 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 533 |   // Determine the index of the size. | 
 | 534 |   unsigned SizeIndex; | 
| Ken Dyck | 199c3d6 | 2010-01-11 17:06:35 +0000 | [diff] [blame] | 535 |   switch (Context.getTypeSizeInChars(ValType).getQuantity()) { | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 536 |   case 1: SizeIndex = 0; break; | 
 | 537 |   case 2: SizeIndex = 1; break; | 
 | 538 |   case 4: SizeIndex = 2; break; | 
 | 539 |   case 8: SizeIndex = 3; break; | 
 | 540 |   case 16: SizeIndex = 4; break; | 
 | 541 |   default: | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 542 |     Diag(DRE->getLocStart(), diag::err_atomic_builtin_pointer_size) | 
 | 543 |       << FirstArg->getType() << FirstArg->getSourceRange(); | 
 | 544 |     return ExprError(); | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 545 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 546 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 547 |   // Each of these builtins has one pointer argument, followed by some number of | 
 | 548 |   // values (0, 1 or 2) followed by a potentially empty varags list of stuff | 
 | 549 |   // that we ignore.  Find out which row of BuiltinIndices to read from as well | 
 | 550 |   // as the number of fixed args. | 
| Douglas Gregor | 7814e6d | 2009-09-12 00:22:50 +0000 | [diff] [blame] | 551 |   unsigned BuiltinID = FDecl->getBuiltinID(); | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 552 |   unsigned BuiltinIndex, NumFixed = 1; | 
 | 553 |   switch (BuiltinID) { | 
| David Blaikie | b219cfc | 2011-09-23 05:06:16 +0000 | [diff] [blame] | 554 |   default: llvm_unreachable("Unknown overloaded atomic builtin!"); | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 555 |   case Builtin::BI__sync_fetch_and_add: BuiltinIndex = 0; break; | 
 | 556 |   case Builtin::BI__sync_fetch_and_sub: BuiltinIndex = 1; break; | 
 | 557 |   case Builtin::BI__sync_fetch_and_or:  BuiltinIndex = 2; break; | 
 | 558 |   case Builtin::BI__sync_fetch_and_and: BuiltinIndex = 3; break; | 
 | 559 |   case Builtin::BI__sync_fetch_and_xor: BuiltinIndex = 4; break; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 560 |  | 
| Daniel Dunbar | 7eff7c4 | 2010-03-25 17:13:09 +0000 | [diff] [blame] | 561 |   case Builtin::BI__sync_add_and_fetch: BuiltinIndex = 5; break; | 
 | 562 |   case Builtin::BI__sync_sub_and_fetch: BuiltinIndex = 6; break; | 
 | 563 |   case Builtin::BI__sync_and_and_fetch: BuiltinIndex = 7; break; | 
 | 564 |   case Builtin::BI__sync_or_and_fetch:  BuiltinIndex = 8; break; | 
 | 565 |   case Builtin::BI__sync_xor_and_fetch: BuiltinIndex = 9; break; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 566 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 567 |   case Builtin::BI__sync_val_compare_and_swap: | 
| Daniel Dunbar | 7eff7c4 | 2010-03-25 17:13:09 +0000 | [diff] [blame] | 568 |     BuiltinIndex = 10; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 569 |     NumFixed = 2; | 
 | 570 |     break; | 
 | 571 |   case Builtin::BI__sync_bool_compare_and_swap: | 
| Daniel Dunbar | 7eff7c4 | 2010-03-25 17:13:09 +0000 | [diff] [blame] | 572 |     BuiltinIndex = 11; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 573 |     NumFixed = 2; | 
| Chandler Carruth | 8d13d22 | 2010-07-18 20:54:12 +0000 | [diff] [blame] | 574 |     ResultType = Context.BoolTy; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 575 |     break; | 
| Daniel Dunbar | 7eff7c4 | 2010-03-25 17:13:09 +0000 | [diff] [blame] | 576 |   case Builtin::BI__sync_lock_test_and_set: BuiltinIndex = 12; break; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 577 |   case Builtin::BI__sync_lock_release: | 
| Daniel Dunbar | 7eff7c4 | 2010-03-25 17:13:09 +0000 | [diff] [blame] | 578 |     BuiltinIndex = 13; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 579 |     NumFixed = 0; | 
| Chandler Carruth | 8d13d22 | 2010-07-18 20:54:12 +0000 | [diff] [blame] | 580 |     ResultType = Context.VoidTy; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 581 |     break; | 
| Chris Lattner | 23aa9c8 | 2011-04-09 03:57:26 +0000 | [diff] [blame] | 582 |   case Builtin::BI__sync_swap: BuiltinIndex = 14; break; | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 583 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 584 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 585 |   // Now that we know how many fixed arguments we expect, first check that we | 
 | 586 |   // have at least that many. | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 587 |   if (TheCall->getNumArgs() < 1+NumFixed) { | 
 | 588 |     Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args_at_least) | 
 | 589 |       << 0 << 1+NumFixed << TheCall->getNumArgs() | 
 | 590 |       << TheCall->getCallee()->getSourceRange(); | 
 | 591 |     return ExprError(); | 
 | 592 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 593 |  | 
| Chris Lattner | e7ac0a9 | 2009-05-08 15:36:58 +0000 | [diff] [blame] | 594 |   // Get the decl for the concrete builtin from this, we can tell what the | 
 | 595 |   // concrete integer type we should convert to is. | 
 | 596 |   unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex]; | 
 | 597 |   const char *NewBuiltinName = Context.BuiltinInfo.GetName(NewBuiltinID); | 
 | 598 |   IdentifierInfo *NewBuiltinII = PP.getIdentifierInfo(NewBuiltinName); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 599 |   FunctionDecl *NewBuiltinDecl = | 
| Chris Lattner | e7ac0a9 | 2009-05-08 15:36:58 +0000 | [diff] [blame] | 600 |     cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID, | 
 | 601 |                                            TUScope, false, DRE->getLocStart())); | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 602 |  | 
| John McCall | f871d0c | 2010-08-07 06:22:56 +0000 | [diff] [blame] | 603 |   // The first argument --- the pointer --- has a fixed type; we | 
 | 604 |   // deduce the types of the rest of the arguments accordingly.  Walk | 
 | 605 |   // the remaining arguments, converting them to the deduced value type. | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 606 |   for (unsigned i = 0; i != NumFixed; ++i) { | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 607 |     ExprResult Arg = TheCall->getArg(i+1); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 608 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 609 |     // If the argument is an implicit cast, then there was a promotion due to | 
 | 610 |     // "...", just remove it now. | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 611 |     if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg.get())) { | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 612 |       Arg = ICE->getSubExpr(); | 
 | 613 |       ICE->setSubExpr(0); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 614 |       TheCall->setArg(i+1, Arg.get()); | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 615 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 616 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 617 |     // GCC does an implicit conversion to the pointer or integer ValType.  This | 
 | 618 |     // can fail in some cases (1i -> int**), check for this error case now. | 
| John McCall | b45ae25 | 2011-10-05 07:41:44 +0000 | [diff] [blame] | 619 |     // Initialize the argument. | 
 | 620 |     InitializedEntity Entity = InitializedEntity::InitializeParameter(Context, | 
 | 621 |                                                    ValType, /*consume*/ false); | 
 | 622 |     Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 623 |     if (Arg.isInvalid()) | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 624 |       return ExprError(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 625 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 626 |     // Okay, we have something that *can* be converted to the right type.  Check | 
 | 627 |     // to see if there is a potentially weird extension going on here.  This can | 
 | 628 |     // happen when you do an atomic operation on something like an char* and | 
 | 629 |     // pass in 42.  The 42 gets converted to char.  This is even more strange | 
 | 630 |     // for things like 45.123 -> char, etc. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 631 |     // FIXME: Do this check. | 
| John McCall | b45ae25 | 2011-10-05 07:41:44 +0000 | [diff] [blame] | 632 |     TheCall->setArg(i+1, Arg.take()); | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 633 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 634 |  | 
| Douglas Gregor | bbcb7ea | 2011-09-09 16:51:10 +0000 | [diff] [blame] | 635 |   ASTContext& Context = this->getASTContext(); | 
 | 636 |  | 
 | 637 |   // Create a new DeclRefExpr to refer to the new decl. | 
 | 638 |   DeclRefExpr* NewDRE = DeclRefExpr::Create( | 
 | 639 |       Context, | 
 | 640 |       DRE->getQualifierLoc(), | 
 | 641 |       NewBuiltinDecl, | 
 | 642 |       DRE->getLocation(), | 
 | 643 |       NewBuiltinDecl->getType(), | 
 | 644 |       DRE->getValueKind()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 645 |  | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 646 |   // Set the callee in the CallExpr. | 
 | 647 |   // FIXME: This leaks the original parens and implicit casts. | 
| Douglas Gregor | bbcb7ea | 2011-09-09 16:51:10 +0000 | [diff] [blame] | 648 |   ExprResult PromotedCall = UsualUnaryConversions(NewDRE); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 649 |   if (PromotedCall.isInvalid()) | 
 | 650 |     return ExprError(); | 
 | 651 |   TheCall->setCallee(PromotedCall.take()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 652 |  | 
| Chandler Carruth | db4325b | 2010-07-18 07:23:17 +0000 | [diff] [blame] | 653 |   // Change the result type of the call to match the original value type. This | 
 | 654 |   // is arbitrary, but the codegen for these builtins ins design to handle it | 
 | 655 |   // gracefully. | 
| Chandler Carruth | 8d13d22 | 2010-07-18 20:54:12 +0000 | [diff] [blame] | 656 |   TheCall->setType(ResultType); | 
| Chandler Carruth | d201457 | 2010-07-09 18:59:35 +0000 | [diff] [blame] | 657 |  | 
 | 658 |   return move(TheCallResult); | 
| Chris Lattner | 5caa370 | 2009-05-08 06:58:22 +0000 | [diff] [blame] | 659 | } | 
 | 660 |  | 
| Chris Lattner | 6903981 | 2009-02-18 06:01:06 +0000 | [diff] [blame] | 661 | /// CheckObjCString - Checks that the argument to the builtin | 
| Anders Carlsson | 71993dd | 2007-08-17 05:31:46 +0000 | [diff] [blame] | 662 | /// CFString constructor is correct | 
| Steve Naroff | fd94262 | 2009-04-13 20:26:29 +0000 | [diff] [blame] | 663 | /// Note: It might also make sense to do the UTF-16 conversion here (would | 
 | 664 | /// simplify the backend). | 
| Chris Lattner | 6903981 | 2009-02-18 06:01:06 +0000 | [diff] [blame] | 665 | bool Sema::CheckObjCString(Expr *Arg) { | 
| Chris Lattner | 56f3494 | 2008-02-13 01:02:39 +0000 | [diff] [blame] | 666 |   Arg = Arg->IgnoreParenCasts(); | 
| Anders Carlsson | 71993dd | 2007-08-17 05:31:46 +0000 | [diff] [blame] | 667 |   StringLiteral *Literal = dyn_cast<StringLiteral>(Arg); | 
 | 668 |  | 
| Douglas Gregor | 5cee119 | 2011-07-27 05:40:30 +0000 | [diff] [blame] | 669 |   if (!Literal || !Literal->isAscii()) { | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 670 |     Diag(Arg->getLocStart(), diag::err_cfstring_literal_not_string_constant) | 
 | 671 |       << Arg->getSourceRange(); | 
| Anders Carlsson | 9cdc4d3 | 2007-08-17 15:44:17 +0000 | [diff] [blame] | 672 |     return true; | 
| Anders Carlsson | 71993dd | 2007-08-17 05:31:46 +0000 | [diff] [blame] | 673 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 674 |  | 
| Fariborz Jahanian | 7da7102 | 2010-09-07 19:38:13 +0000 | [diff] [blame] | 675 |   if (Literal->containsNonAsciiOrNull()) { | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 676 |     StringRef String = Literal->getString(); | 
| Fariborz Jahanian | 7da7102 | 2010-09-07 19:38:13 +0000 | [diff] [blame] | 677 |     unsigned NumBytes = String.size(); | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 678 |     SmallVector<UTF16, 128> ToBuf(NumBytes); | 
| Fariborz Jahanian | 7da7102 | 2010-09-07 19:38:13 +0000 | [diff] [blame] | 679 |     const UTF8 *FromPtr = (UTF8 *)String.data(); | 
 | 680 |     UTF16 *ToPtr = &ToBuf[0]; | 
 | 681 |      | 
 | 682 |     ConversionResult Result = ConvertUTF8toUTF16(&FromPtr, FromPtr + NumBytes, | 
 | 683 |                                                  &ToPtr, ToPtr + NumBytes, | 
 | 684 |                                                  strictConversion); | 
 | 685 |     // Check for conversion failure. | 
 | 686 |     if (Result != conversionOK) | 
 | 687 |       Diag(Arg->getLocStart(), | 
 | 688 |            diag::warn_cfstring_truncated) << Arg->getSourceRange(); | 
 | 689 |   } | 
| Anders Carlsson | 9cdc4d3 | 2007-08-17 15:44:17 +0000 | [diff] [blame] | 690 |   return false; | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 691 | } | 
 | 692 |  | 
| Chris Lattner | c27c665 | 2007-12-20 00:05:45 +0000 | [diff] [blame] | 693 | /// SemaBuiltinVAStart - Check the arguments to __builtin_va_start for validity. | 
 | 694 | /// Emit an error and return true on failure, return false on success. | 
| Chris Lattner | 925e60d | 2007-12-28 05:29:59 +0000 | [diff] [blame] | 695 | bool Sema::SemaBuiltinVAStart(CallExpr *TheCall) { | 
 | 696 |   Expr *Fn = TheCall->getCallee(); | 
 | 697 |   if (TheCall->getNumArgs() > 2) { | 
| Chris Lattner | 2c21a07 | 2008-11-21 18:44:24 +0000 | [diff] [blame] | 698 |     Diag(TheCall->getArg(2)->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 699 |          diag::err_typecheck_call_too_many_args) | 
| Eric Christopher | ccfa963 | 2010-04-16 04:56:46 +0000 | [diff] [blame] | 700 |       << 0 /*function call*/ << 2 << TheCall->getNumArgs() | 
 | 701 |       << Fn->getSourceRange() | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 702 |       << SourceRange(TheCall->getArg(2)->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 703 |                      (*(TheCall->arg_end()-1))->getLocEnd()); | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 704 |     return true; | 
 | 705 |   } | 
| Eli Friedman | 56f20ae | 2008-12-15 22:05:35 +0000 | [diff] [blame] | 706 |  | 
 | 707 |   if (TheCall->getNumArgs() < 2) { | 
| Eric Christopher | d77b9a2 | 2010-04-16 04:48:22 +0000 | [diff] [blame] | 708 |     return Diag(TheCall->getLocEnd(), | 
 | 709 |       diag::err_typecheck_call_too_few_args_at_least) | 
 | 710 |       << 0 /*function call*/ << 2 << TheCall->getNumArgs(); | 
| Eli Friedman | 56f20ae | 2008-12-15 22:05:35 +0000 | [diff] [blame] | 711 |   } | 
 | 712 |  | 
| John McCall | 5f8d604 | 2011-08-27 01:09:30 +0000 | [diff] [blame] | 713 |   // Type-check the first argument normally. | 
 | 714 |   if (checkBuiltinArgument(*this, TheCall, 0)) | 
 | 715 |     return true; | 
 | 716 |  | 
| Chris Lattner | c27c665 | 2007-12-20 00:05:45 +0000 | [diff] [blame] | 717 |   // Determine whether the current function is variadic or not. | 
| Douglas Gregor | 9ea9bdb | 2010-03-01 23:15:13 +0000 | [diff] [blame] | 718 |   BlockScopeInfo *CurBlock = getCurBlock(); | 
| Chris Lattner | c27c665 | 2007-12-20 00:05:45 +0000 | [diff] [blame] | 719 |   bool isVariadic; | 
| Steve Naroff | cd9c514 | 2009-04-15 19:33:47 +0000 | [diff] [blame] | 720 |   if (CurBlock) | 
| John McCall | c71a491 | 2010-06-04 19:02:56 +0000 | [diff] [blame] | 721 |     isVariadic = CurBlock->TheDecl->isVariadic(); | 
| Ted Kremenek | 9498d38 | 2010-04-29 16:49:01 +0000 | [diff] [blame] | 722 |   else if (FunctionDecl *FD = getCurFunctionDecl()) | 
 | 723 |     isVariadic = FD->isVariadic(); | 
 | 724 |   else | 
| Argyrios Kyrtzidis | 53d0ea5 | 2008-06-28 06:07:14 +0000 | [diff] [blame] | 725 |     isVariadic = getCurMethodDecl()->isVariadic(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 726 |  | 
| Chris Lattner | c27c665 | 2007-12-20 00:05:45 +0000 | [diff] [blame] | 727 |   if (!isVariadic) { | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 728 |     Diag(Fn->getLocStart(), diag::err_va_start_used_in_non_variadic_function); | 
 | 729 |     return true; | 
 | 730 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 731 |  | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 732 |   // Verify that the second argument to the builtin is the last argument of the | 
 | 733 |   // current function or method. | 
 | 734 |   bool SecondArgIsLastNamedArgument = false; | 
| Anders Carlsson | e2c1410 | 2008-02-13 01:22:59 +0000 | [diff] [blame] | 735 |   const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 736 |  | 
| Anders Carlsson | 88cf226 | 2008-02-11 04:20:54 +0000 | [diff] [blame] | 737 |   if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) { | 
 | 738 |     if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) { | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 739 |       // FIXME: This isn't correct for methods (results in bogus warning). | 
 | 740 |       // Get the last formal in the current function. | 
| Anders Carlsson | 88cf226 | 2008-02-11 04:20:54 +0000 | [diff] [blame] | 741 |       const ParmVarDecl *LastArg; | 
| Steve Naroff | cd9c514 | 2009-04-15 19:33:47 +0000 | [diff] [blame] | 742 |       if (CurBlock) | 
 | 743 |         LastArg = *(CurBlock->TheDecl->param_end()-1); | 
 | 744 |       else if (FunctionDecl *FD = getCurFunctionDecl()) | 
| Chris Lattner | 371f258 | 2008-12-04 23:50:19 +0000 | [diff] [blame] | 745 |         LastArg = *(FD->param_end()-1); | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 746 |       else | 
| Argyrios Kyrtzidis | 53d0ea5 | 2008-06-28 06:07:14 +0000 | [diff] [blame] | 747 |         LastArg = *(getCurMethodDecl()->param_end()-1); | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 748 |       SecondArgIsLastNamedArgument = PV == LastArg; | 
 | 749 |     } | 
 | 750 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 751 |  | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 752 |   if (!SecondArgIsLastNamedArgument) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 753 |     Diag(TheCall->getArg(1)->getLocStart(), | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 754 |          diag::warn_second_parameter_of_va_start_not_last_named_argument); | 
 | 755 |   return false; | 
| Eli Friedman | 6cfda23 | 2008-05-20 08:23:37 +0000 | [diff] [blame] | 756 | } | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 757 |  | 
| Chris Lattner | 1b9a079 | 2007-12-20 00:26:33 +0000 | [diff] [blame] | 758 | /// SemaBuiltinUnorderedCompare - Handle functions like __builtin_isgreater and | 
 | 759 | /// friends.  This is declared to take (...), so we have to check everything. | 
| Chris Lattner | 925e60d | 2007-12-28 05:29:59 +0000 | [diff] [blame] | 760 | bool Sema::SemaBuiltinUnorderedCompare(CallExpr *TheCall) { | 
 | 761 |   if (TheCall->getNumArgs() < 2) | 
| Chris Lattner | 2c21a07 | 2008-11-21 18:44:24 +0000 | [diff] [blame] | 762 |     return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) | 
| Eric Christopher | d77b9a2 | 2010-04-16 04:48:22 +0000 | [diff] [blame] | 763 |       << 0 << 2 << TheCall->getNumArgs()/*function call*/; | 
| Chris Lattner | 925e60d | 2007-12-28 05:29:59 +0000 | [diff] [blame] | 764 |   if (TheCall->getNumArgs() > 2) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 765 |     return Diag(TheCall->getArg(2)->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 766 |                 diag::err_typecheck_call_too_many_args) | 
| Eric Christopher | ccfa963 | 2010-04-16 04:56:46 +0000 | [diff] [blame] | 767 |       << 0 /*function call*/ << 2 << TheCall->getNumArgs() | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 768 |       << SourceRange(TheCall->getArg(2)->getLocStart(), | 
 | 769 |                      (*(TheCall->arg_end()-1))->getLocEnd()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 770 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 771 |   ExprResult OrigArg0 = TheCall->getArg(0); | 
 | 772 |   ExprResult OrigArg1 = TheCall->getArg(1); | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 773 |  | 
| Chris Lattner | 1b9a079 | 2007-12-20 00:26:33 +0000 | [diff] [blame] | 774 |   // Do standard promotions between the two arguments, returning their common | 
 | 775 |   // type. | 
| Chris Lattner | 925e60d | 2007-12-28 05:29:59 +0000 | [diff] [blame] | 776 |   QualType Res = UsualArithmeticConversions(OrigArg0, OrigArg1, false); | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 777 |   if (OrigArg0.isInvalid() || OrigArg1.isInvalid()) | 
 | 778 |     return true; | 
| Daniel Dunbar | 403bc2b | 2009-02-19 19:28:43 +0000 | [diff] [blame] | 779 |  | 
 | 780 |   // Make sure any conversions are pushed back into the call; this is | 
 | 781 |   // type safe since unordered compare builtins are declared as "_Bool | 
 | 782 |   // foo(...)". | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 783 |   TheCall->setArg(0, OrigArg0.get()); | 
 | 784 |   TheCall->setArg(1, OrigArg1.get()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 785 |  | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 786 |   if (OrigArg0.get()->isTypeDependent() || OrigArg1.get()->isTypeDependent()) | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 787 |     return false; | 
 | 788 |  | 
| Chris Lattner | 1b9a079 | 2007-12-20 00:26:33 +0000 | [diff] [blame] | 789 |   // If the common type isn't a real floating type, then the arguments were | 
 | 790 |   // invalid for this operation. | 
 | 791 |   if (!Res->isRealFloatingType()) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 792 |     return Diag(OrigArg0.get()->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 793 |                 diag::err_typecheck_call_invalid_ordered_compare) | 
| John Wiegley | 429bb27 | 2011-04-08 18:41:53 +0000 | [diff] [blame] | 794 |       << OrigArg0.get()->getType() << OrigArg1.get()->getType() | 
 | 795 |       << SourceRange(OrigArg0.get()->getLocStart(), OrigArg1.get()->getLocEnd()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 796 |  | 
| Chris Lattner | 1b9a079 | 2007-12-20 00:26:33 +0000 | [diff] [blame] | 797 |   return false; | 
 | 798 | } | 
 | 799 |  | 
| Benjamin Kramer | e771a7a | 2010-02-15 22:42:31 +0000 | [diff] [blame] | 800 | /// SemaBuiltinSemaBuiltinFPClassification - Handle functions like | 
 | 801 | /// __builtin_isnan and friends.  This is declared to take (...), so we have | 
| Benjamin Kramer | 3b1e26b | 2010-02-16 10:07:31 +0000 | [diff] [blame] | 802 | /// to check everything. We expect the last argument to be a floating point | 
 | 803 | /// value. | 
 | 804 | bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) { | 
 | 805 |   if (TheCall->getNumArgs() < NumArgs) | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 806 |     return Diag(TheCall->getLocEnd(), diag::err_typecheck_call_too_few_args) | 
| Eric Christopher | d77b9a2 | 2010-04-16 04:48:22 +0000 | [diff] [blame] | 807 |       << 0 << NumArgs << TheCall->getNumArgs()/*function call*/; | 
| Benjamin Kramer | 3b1e26b | 2010-02-16 10:07:31 +0000 | [diff] [blame] | 808 |   if (TheCall->getNumArgs() > NumArgs) | 
 | 809 |     return Diag(TheCall->getArg(NumArgs)->getLocStart(), | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 810 |                 diag::err_typecheck_call_too_many_args) | 
| Eric Christopher | ccfa963 | 2010-04-16 04:56:46 +0000 | [diff] [blame] | 811 |       << 0 /*function call*/ << NumArgs << TheCall->getNumArgs() | 
| Benjamin Kramer | 3b1e26b | 2010-02-16 10:07:31 +0000 | [diff] [blame] | 812 |       << SourceRange(TheCall->getArg(NumArgs)->getLocStart(), | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 813 |                      (*(TheCall->arg_end()-1))->getLocEnd()); | 
 | 814 |  | 
| Benjamin Kramer | 3b1e26b | 2010-02-16 10:07:31 +0000 | [diff] [blame] | 815 |   Expr *OrigArg = TheCall->getArg(NumArgs-1); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 816 |  | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 817 |   if (OrigArg->isTypeDependent()) | 
 | 818 |     return false; | 
 | 819 |  | 
| Chris Lattner | 81368fb | 2010-05-06 05:50:07 +0000 | [diff] [blame] | 820 |   // This operation requires a non-_Complex floating-point number. | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 821 |   if (!OrigArg->getType()->isRealFloatingType()) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 822 |     return Diag(OrigArg->getLocStart(), | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 823 |                 diag::err_typecheck_call_invalid_unary_fp) | 
 | 824 |       << OrigArg->getType() << OrigArg->getSourceRange(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 825 |  | 
| Chris Lattner | 81368fb | 2010-05-06 05:50:07 +0000 | [diff] [blame] | 826 |   // If this is an implicit conversion from float -> double, remove it. | 
 | 827 |   if (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(OrigArg)) { | 
 | 828 |     Expr *CastArg = Cast->getSubExpr(); | 
 | 829 |     if (CastArg->getType()->isSpecificBuiltinType(BuiltinType::Float)) { | 
 | 830 |       assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) && | 
 | 831 |              "promotion from float to double is the only expected cast here"); | 
 | 832 |       Cast->setSubExpr(0); | 
| Chris Lattner | 81368fb | 2010-05-06 05:50:07 +0000 | [diff] [blame] | 833 |       TheCall->setArg(NumArgs-1, CastArg); | 
 | 834 |       OrigArg = CastArg; | 
 | 835 |     } | 
 | 836 |   } | 
 | 837 |    | 
| Eli Friedman | 9ac6f62 | 2009-08-31 20:06:00 +0000 | [diff] [blame] | 838 |   return false; | 
 | 839 | } | 
 | 840 |  | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 841 | /// SemaBuiltinShuffleVector - Handle __builtin_shufflevector. | 
 | 842 | // This is declared to take (...), so we have to check everything. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 843 | ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 844 |   if (TheCall->getNumArgs() < 2) | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 845 |     return ExprError(Diag(TheCall->getLocEnd(), | 
| Eric Christopher | d77b9a2 | 2010-04-16 04:48:22 +0000 | [diff] [blame] | 846 |                           diag::err_typecheck_call_too_few_args_at_least) | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 847 |       << 0 /*function call*/ << 2 << TheCall->getNumArgs() | 
| Eric Christopher | d77b9a2 | 2010-04-16 04:48:22 +0000 | [diff] [blame] | 848 |       << TheCall->getSourceRange()); | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 849 |  | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 850 |   // Determine which of the following types of shufflevector we're checking: | 
 | 851 |   // 1) unary, vector mask: (lhs, mask) | 
 | 852 |   // 2) binary, vector mask: (lhs, rhs, mask) | 
 | 853 |   // 3) binary, scalar mask: (lhs, rhs, index, ..., index) | 
 | 854 |   QualType resType = TheCall->getArg(0)->getType(); | 
 | 855 |   unsigned numElements = 0; | 
 | 856 |    | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 857 |   if (!TheCall->getArg(0)->isTypeDependent() && | 
 | 858 |       !TheCall->getArg(1)->isTypeDependent()) { | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 859 |     QualType LHSType = TheCall->getArg(0)->getType(); | 
 | 860 |     QualType RHSType = TheCall->getArg(1)->getType(); | 
 | 861 |      | 
 | 862 |     if (!LHSType->isVectorType() || !RHSType->isVectorType()) { | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 863 |       Diag(TheCall->getLocStart(), diag::err_shufflevector_non_vector) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 864 |         << SourceRange(TheCall->getArg(0)->getLocStart(), | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 865 |                        TheCall->getArg(1)->getLocEnd()); | 
 | 866 |       return ExprError(); | 
 | 867 |     } | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 868 |      | 
 | 869 |     numElements = LHSType->getAs<VectorType>()->getNumElements(); | 
 | 870 |     unsigned numResElements = TheCall->getNumArgs() - 2; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 871 |  | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 872 |     // Check to see if we have a call with 2 vector arguments, the unary shuffle | 
 | 873 |     // with mask.  If so, verify that RHS is an integer vector type with the | 
 | 874 |     // same number of elts as lhs. | 
 | 875 |     if (TheCall->getNumArgs() == 2) { | 
| Douglas Gregor | f609462 | 2010-07-23 15:58:24 +0000 | [diff] [blame] | 876 |       if (!RHSType->hasIntegerRepresentation() ||  | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 877 |           RHSType->getAs<VectorType>()->getNumElements() != numElements) | 
 | 878 |         Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) | 
 | 879 |           << SourceRange(TheCall->getArg(1)->getLocStart(), | 
 | 880 |                          TheCall->getArg(1)->getLocEnd()); | 
 | 881 |       numResElements = numElements; | 
 | 882 |     } | 
 | 883 |     else if (!Context.hasSameUnqualifiedType(LHSType, RHSType)) { | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 884 |       Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 885 |         << SourceRange(TheCall->getArg(0)->getLocStart(), | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 886 |                        TheCall->getArg(1)->getLocEnd()); | 
 | 887 |       return ExprError(); | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 888 |     } else if (numElements != numResElements) { | 
 | 889 |       QualType eltType = LHSType->getAs<VectorType>()->getElementType(); | 
| Chris Lattner | 788b0fd | 2010-06-23 06:00:24 +0000 | [diff] [blame] | 890 |       resType = Context.getVectorType(eltType, numResElements, | 
| Bob Wilson | e86d78c | 2010-11-10 21:56:12 +0000 | [diff] [blame] | 891 |                                       VectorType::GenericVector); | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 892 |     } | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 893 |   } | 
 | 894 |  | 
 | 895 |   for (unsigned i = 2; i < TheCall->getNumArgs(); i++) { | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 896 |     if (TheCall->getArg(i)->isTypeDependent() || | 
 | 897 |         TheCall->getArg(i)->isValueDependent()) | 
 | 898 |       continue; | 
 | 899 |  | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 900 |     llvm::APSInt Result(32); | 
 | 901 |     if (!TheCall->getArg(i)->isIntegerConstantExpr(Result, Context)) | 
 | 902 |       return ExprError(Diag(TheCall->getLocStart(), | 
 | 903 |                   diag::err_shufflevector_nonconstant_argument) | 
 | 904 |                 << TheCall->getArg(i)->getSourceRange()); | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 905 |  | 
| Chris Lattner | d1a0b6d | 2008-08-10 02:05:13 +0000 | [diff] [blame] | 906 |     if (Result.getActiveBits() > 64 || Result.getZExtValue() >= numElements*2) | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 907 |       return ExprError(Diag(TheCall->getLocStart(), | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 908 |                   diag::err_shufflevector_argument_too_large) | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 909 |                << TheCall->getArg(i)->getSourceRange()); | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 910 |   } | 
 | 911 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 912 |   SmallVector<Expr*, 32> exprs; | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 913 |  | 
| Chris Lattner | d1a0b6d | 2008-08-10 02:05:13 +0000 | [diff] [blame] | 914 |   for (unsigned i = 0, e = TheCall->getNumArgs(); i != e; i++) { | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 915 |     exprs.push_back(TheCall->getArg(i)); | 
 | 916 |     TheCall->setArg(i, 0); | 
 | 917 |   } | 
 | 918 |  | 
| Nate Begeman | a88dc30 | 2009-08-12 02:10:25 +0000 | [diff] [blame] | 919 |   return Owned(new (Context) ShuffleVectorExpr(Context, exprs.begin(), | 
| Nate Begeman | 37b6a57 | 2010-06-08 00:16:34 +0000 | [diff] [blame] | 920 |                                             exprs.size(), resType, | 
| Ted Kremenek | 8189cde | 2009-02-07 01:47:29 +0000 | [diff] [blame] | 921 |                                             TheCall->getCallee()->getLocStart(), | 
 | 922 |                                             TheCall->getRParenLoc())); | 
| Eli Friedman | d38617c | 2008-05-14 19:38:39 +0000 | [diff] [blame] | 923 | } | 
| Chris Lattner | 30ce344 | 2007-12-19 23:59:04 +0000 | [diff] [blame] | 924 |  | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 925 | /// SemaBuiltinPrefetch - Handle __builtin_prefetch. | 
 | 926 | // This is declared to take (const void*, ...) and can take two | 
 | 927 | // optional constant int args. | 
 | 928 | bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 929 |   unsigned NumArgs = TheCall->getNumArgs(); | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 930 |  | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 931 |   if (NumArgs > 3) | 
| Eric Christopher | ccfa963 | 2010-04-16 04:56:46 +0000 | [diff] [blame] | 932 |     return Diag(TheCall->getLocEnd(), | 
 | 933 |              diag::err_typecheck_call_too_many_args_at_most) | 
 | 934 |              << 0 /*function call*/ << 3 << NumArgs | 
 | 935 |              << TheCall->getSourceRange(); | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 936 |  | 
 | 937 |   // Argument 0 is checked for us and the remaining arguments must be | 
 | 938 |   // constant integers. | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 939 |   for (unsigned i = 1; i != NumArgs; ++i) { | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 940 |     Expr *Arg = TheCall->getArg(i); | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 941 |      | 
| Eli Friedman | 9aef726 | 2009-12-04 00:30:06 +0000 | [diff] [blame] | 942 |     llvm::APSInt Result; | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 943 |     if (SemaBuiltinConstantArg(TheCall, i, Result)) | 
 | 944 |       return true; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 945 |  | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 946 |     // FIXME: gcc issues a warning and rewrites these to 0. These | 
 | 947 |     // seems especially odd for the third argument since the default | 
 | 948 |     // is 3. | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 949 |     if (i == 1) { | 
| Eli Friedman | 9aef726 | 2009-12-04 00:30:06 +0000 | [diff] [blame] | 950 |       if (Result.getLimitedValue() > 1) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 951 |         return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) | 
| Chris Lattner | 21fb98e | 2009-09-23 06:06:36 +0000 | [diff] [blame] | 952 |              << "0" << "1" << Arg->getSourceRange(); | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 953 |     } else { | 
| Eli Friedman | 9aef726 | 2009-12-04 00:30:06 +0000 | [diff] [blame] | 954 |       if (Result.getLimitedValue() > 3) | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 955 |         return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) | 
| Chris Lattner | 21fb98e | 2009-09-23 06:06:36 +0000 | [diff] [blame] | 956 |             << "0" << "3" << Arg->getSourceRange(); | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 957 |     } | 
 | 958 |   } | 
 | 959 |  | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 960 |   return false; | 
| Daniel Dunbar | 4493f79 | 2008-07-21 22:59:13 +0000 | [diff] [blame] | 961 | } | 
 | 962 |  | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 963 | /// SemaBuiltinConstantArg - Handle a check if argument ArgNum of CallExpr | 
 | 964 | /// TheCall is a constant expression. | 
 | 965 | bool Sema::SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, | 
 | 966 |                                   llvm::APSInt &Result) { | 
 | 967 |   Expr *Arg = TheCall->getArg(ArgNum); | 
 | 968 |   DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); | 
 | 969 |   FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl()); | 
 | 970 |    | 
 | 971 |   if (Arg->isTypeDependent() || Arg->isValueDependent()) return false; | 
 | 972 |    | 
 | 973 |   if (!Arg->isIntegerConstantExpr(Result, Context)) | 
 | 974 |     return Diag(TheCall->getLocStart(), diag::err_constant_integer_arg_type) | 
| Eric Christopher | 5e89655 | 2010-04-19 18:23:02 +0000 | [diff] [blame] | 975 |                 << FDecl->getDeclName() <<  Arg->getSourceRange(); | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 976 |    | 
| Chris Lattner | 21fb98e | 2009-09-23 06:06:36 +0000 | [diff] [blame] | 977 |   return false; | 
 | 978 | } | 
 | 979 |  | 
| Daniel Dunbar | d5f8a4f | 2008-09-03 21:13:56 +0000 | [diff] [blame] | 980 | /// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr, | 
 | 981 | /// int type). This simply type checks that type is one of the defined | 
 | 982 | /// constants (0-3). | 
| Chris Lattner | fc8f0e1 | 2011-04-15 05:22:18 +0000 | [diff] [blame] | 983 | // For compatibility check 0-3, llvm only handles 0 and 2. | 
| Daniel Dunbar | d5f8a4f | 2008-09-03 21:13:56 +0000 | [diff] [blame] | 984 | bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) { | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 985 |   llvm::APSInt Result; | 
 | 986 |    | 
 | 987 |   // Check constant-ness first. | 
 | 988 |   if (SemaBuiltinConstantArg(TheCall, 1, Result)) | 
 | 989 |     return true; | 
 | 990 |  | 
| Daniel Dunbar | d5f8a4f | 2008-09-03 21:13:56 +0000 | [diff] [blame] | 991 |   Expr *Arg = TheCall->getArg(1); | 
| Daniel Dunbar | d5f8a4f | 2008-09-03 21:13:56 +0000 | [diff] [blame] | 992 |   if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) { | 
| Chris Lattner | fa25bbb | 2008-11-19 05:08:23 +0000 | [diff] [blame] | 993 |     return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range) | 
 | 994 |              << "0" << "3" << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); | 
| Daniel Dunbar | d5f8a4f | 2008-09-03 21:13:56 +0000 | [diff] [blame] | 995 |   } | 
 | 996 |  | 
 | 997 |   return false; | 
 | 998 | } | 
 | 999 |  | 
| Eli Friedman | 586d6a8 | 2009-05-03 06:04:26 +0000 | [diff] [blame] | 1000 | /// SemaBuiltinLongjmp - Handle __builtin_longjmp(void *env[5], int val). | 
| Eli Friedman | d875fed | 2009-05-03 04:46:36 +0000 | [diff] [blame] | 1001 | /// This checks that val is a constant 1. | 
 | 1002 | bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) { | 
 | 1003 |   Expr *Arg = TheCall->getArg(1); | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 1004 |   llvm::APSInt Result; | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 1005 |  | 
| Eric Christopher | 691ebc3 | 2010-04-17 02:26:23 +0000 | [diff] [blame] | 1006 |   // TODO: This is less than ideal. Overload this to take a value. | 
 | 1007 |   if (SemaBuiltinConstantArg(TheCall, 1, Result)) | 
 | 1008 |     return true; | 
 | 1009 |    | 
 | 1010 |   if (Result != 1) | 
| Eli Friedman | d875fed | 2009-05-03 04:46:36 +0000 | [diff] [blame] | 1011 |     return Diag(TheCall->getLocStart(), diag::err_builtin_longjmp_invalid_val) | 
 | 1012 |              << SourceRange(Arg->getLocStart(), Arg->getLocEnd()); | 
 | 1013 |  | 
 | 1014 |   return false; | 
 | 1015 | } | 
 | 1016 |  | 
| Ted Kremenek | b43e8ad | 2011-02-24 23:03:04 +0000 | [diff] [blame] | 1017 | // Handle i > 1 ? "x" : "y", recursively. | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1018 | bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, | 
 | 1019 |                                   bool HasVAListArg, | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1020 |                                   unsigned format_idx, unsigned firstDataArg, | 
 | 1021 |                                   bool isPrintf) { | 
| Ted Kremenek | 4fe6441 | 2010-09-09 03:51:39 +0000 | [diff] [blame] | 1022 |  tryAgain: | 
| Douglas Gregor | cde0173 | 2009-05-19 22:10:17 +0000 | [diff] [blame] | 1023 |   if (E->isTypeDependent() || E->isValueDependent()) | 
 | 1024 |     return false; | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1025 |  | 
| Peter Collingbourne | f111d93 | 2011-04-15 00:35:48 +0000 | [diff] [blame] | 1026 |   E = E->IgnoreParens(); | 
 | 1027 |  | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1028 |   switch (E->getStmtClass()) { | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 1029 |   case Stmt::BinaryConditionalOperatorClass: | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1030 |   case Stmt::ConditionalOperatorClass: { | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 1031 |     const AbstractConditionalOperator *C = cast<AbstractConditionalOperator>(E); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1032 |     return SemaCheckStringLiteral(C->getTrueExpr(), TheCall, HasVAListArg, | 
 | 1033 |                                   format_idx, firstDataArg, isPrintf) | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 1034 |         && SemaCheckStringLiteral(C->getFalseExpr(), TheCall, HasVAListArg, | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1035 |                                   format_idx, firstDataArg, isPrintf); | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1036 |   } | 
 | 1037 |  | 
| Ted Kremenek | 95355bb | 2010-09-09 03:51:42 +0000 | [diff] [blame] | 1038 |   case Stmt::IntegerLiteralClass: | 
 | 1039 |     // Technically -Wformat-nonliteral does not warn about this case. | 
 | 1040 |     // The behavior of printf and friends in this case is implementation | 
 | 1041 |     // dependent.  Ideally if the format string cannot be null then | 
 | 1042 |     // it should have a 'nonnull' attribute in the function prototype. | 
 | 1043 |     return true; | 
 | 1044 |  | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1045 |   case Stmt::ImplicitCastExprClass: { | 
| Ted Kremenek | 4fe6441 | 2010-09-09 03:51:39 +0000 | [diff] [blame] | 1046 |     E = cast<ImplicitCastExpr>(E)->getSubExpr(); | 
 | 1047 |     goto tryAgain; | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1048 |   } | 
 | 1049 |  | 
| John McCall | 56ca35d | 2011-02-17 10:25:35 +0000 | [diff] [blame] | 1050 |   case Stmt::OpaqueValueExprClass: | 
 | 1051 |     if (const Expr *src = cast<OpaqueValueExpr>(E)->getSourceExpr()) { | 
 | 1052 |       E = src; | 
 | 1053 |       goto tryAgain; | 
 | 1054 |     } | 
 | 1055 |     return false; | 
 | 1056 |  | 
| Ted Kremenek | b43e8ad | 2011-02-24 23:03:04 +0000 | [diff] [blame] | 1057 |   case Stmt::PredefinedExprClass: | 
 | 1058 |     // While __func__, etc., are technically not string literals, they | 
 | 1059 |     // cannot contain format specifiers and thus are not a security | 
 | 1060 |     // liability. | 
 | 1061 |     return true; | 
 | 1062 |        | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1063 |   case Stmt::DeclRefExprClass: { | 
 | 1064 |     const DeclRefExpr *DR = cast<DeclRefExpr>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1065 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1066 |     // As an exception, do not flag errors for variables binding to | 
 | 1067 |     // const string literals. | 
 | 1068 |     if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { | 
 | 1069 |       bool isConstant = false; | 
 | 1070 |       QualType T = DR->getType(); | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1071 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1072 |       if (const ArrayType *AT = Context.getAsArrayType(T)) { | 
 | 1073 |         isConstant = AT->getElementType().isConstant(Context); | 
| Mike Stump | ac5fc7c | 2009-08-04 21:02:39 +0000 | [diff] [blame] | 1074 |       } else if (const PointerType *PT = T->getAs<PointerType>()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1075 |         isConstant = T.isConstant(Context) && | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1076 |                      PT->getPointeeType().isConstant(Context); | 
 | 1077 |       } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1078 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1079 |       if (isConstant) { | 
| Sebastian Redl | 31310a2 | 2010-02-01 20:16:42 +0000 | [diff] [blame] | 1080 |         if (const Expr *Init = VD->getAnyInitializer()) | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1081 |           return SemaCheckStringLiteral(Init, TheCall, | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1082 |                                         HasVAListArg, format_idx, firstDataArg, | 
 | 1083 |                                         isPrintf); | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1084 |       } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1085 |  | 
| Anders Carlsson | d966a55 | 2009-06-28 19:55:58 +0000 | [diff] [blame] | 1086 |       // For vprintf* functions (i.e., HasVAListArg==true), we add a | 
 | 1087 |       // special check to see if the format string is a function parameter | 
 | 1088 |       // of the function calling the printf function.  If the function | 
 | 1089 |       // has an attribute indicating it is a printf-like function, then we | 
 | 1090 |       // should suppress warnings concerning non-literals being used in a call | 
 | 1091 |       // to a vprintf function.  For example: | 
 | 1092 |       // | 
 | 1093 |       // void | 
 | 1094 |       // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...){ | 
 | 1095 |       //      va_list ap; | 
 | 1096 |       //      va_start(ap, fmt); | 
 | 1097 |       //      vprintf(fmt, ap);  // Do NOT emit a warning about "fmt". | 
 | 1098 |       //      ... | 
 | 1099 |       // | 
 | 1100 |       // | 
 | 1101 |       //  FIXME: We don't have full attribute support yet, so just check to see | 
 | 1102 |       //    if the argument is a DeclRefExpr that references a parameter.  We'll | 
 | 1103 |       //    add proper support for checking the attribute later. | 
 | 1104 |       if (HasVAListArg) | 
 | 1105 |         if (isa<ParmVarDecl>(VD)) | 
 | 1106 |           return true; | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1107 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1108 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1109 |     return false; | 
 | 1110 |   } | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1111 |  | 
| Anders Carlsson | 8f031b3 | 2009-06-27 04:05:33 +0000 | [diff] [blame] | 1112 |   case Stmt::CallExprClass: { | 
 | 1113 |     const CallExpr *CE = cast<CallExpr>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1114 |     if (const ImplicitCastExpr *ICE | 
| Anders Carlsson | 8f031b3 | 2009-06-27 04:05:33 +0000 | [diff] [blame] | 1115 |           = dyn_cast<ImplicitCastExpr>(CE->getCallee())) { | 
 | 1116 |       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) { | 
 | 1117 |         if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) { | 
| Argyrios Kyrtzidis | 40b598e | 2009-06-30 02:34:44 +0000 | [diff] [blame] | 1118 |           if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) { | 
| Anders Carlsson | 8f031b3 | 2009-06-27 04:05:33 +0000 | [diff] [blame] | 1119 |             unsigned ArgIndex = FA->getFormatIdx(); | 
 | 1120 |             const Expr *Arg = CE->getArg(ArgIndex - 1); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1121 |  | 
 | 1122 |             return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg, | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1123 |                                           format_idx, firstDataArg, isPrintf); | 
| Anders Carlsson | 8f031b3 | 2009-06-27 04:05:33 +0000 | [diff] [blame] | 1124 |           } | 
 | 1125 |         } | 
 | 1126 |       } | 
 | 1127 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1128 |  | 
| Anders Carlsson | 8f031b3 | 2009-06-27 04:05:33 +0000 | [diff] [blame] | 1129 |     return false; | 
 | 1130 |   } | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1131 |   case Stmt::ObjCStringLiteralClass: | 
 | 1132 |   case Stmt::StringLiteralClass: { | 
 | 1133 |     const StringLiteral *StrE = NULL; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1134 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1135 |     if (const ObjCStringLiteral *ObjCFExpr = dyn_cast<ObjCStringLiteral>(E)) | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1136 |       StrE = ObjCFExpr->getString(); | 
 | 1137 |     else | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1138 |       StrE = cast<StringLiteral>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1139 |  | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1140 |     if (StrE) { | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1141 |       CheckFormatString(StrE, E, TheCall, HasVAListArg, format_idx, | 
 | 1142 |                         firstDataArg, isPrintf); | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1143 |       return true; | 
 | 1144 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1145 |  | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1146 |     return false; | 
 | 1147 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1148 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1149 |   default: | 
 | 1150 |     return false; | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1151 |   } | 
 | 1152 | } | 
 | 1153 |  | 
| Fariborz Jahanian | e898f8a | 2009-05-21 18:48:51 +0000 | [diff] [blame] | 1154 | void | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1155 | Sema::CheckNonNullArguments(const NonNullAttr *NonNull, | 
| Nick Lewycky | 909a70d | 2011-03-25 01:44:32 +0000 | [diff] [blame] | 1156 |                             const Expr * const *ExprArgs, | 
 | 1157 |                             SourceLocation CallSiteLoc) { | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 1158 |   for (NonNullAttr::args_iterator i = NonNull->args_begin(), | 
 | 1159 |                                   e = NonNull->args_end(); | 
| Fariborz Jahanian | e898f8a | 2009-05-21 18:48:51 +0000 | [diff] [blame] | 1160 |        i != e; ++i) { | 
| Nick Lewycky | 909a70d | 2011-03-25 01:44:32 +0000 | [diff] [blame] | 1161 |     const Expr *ArgExpr = ExprArgs[*i]; | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1162 |     if (ArgExpr->isNullPointerConstant(Context, | 
| Douglas Gregor | ce94049 | 2009-09-25 04:25:58 +0000 | [diff] [blame] | 1163 |                                        Expr::NPC_ValueDependentIsNotNull)) | 
| Nick Lewycky | 909a70d | 2011-03-25 01:44:32 +0000 | [diff] [blame] | 1164 |       Diag(CallSiteLoc, diag::warn_null_arg) << ArgExpr->getSourceRange(); | 
| Fariborz Jahanian | e898f8a | 2009-05-21 18:48:51 +0000 | [diff] [blame] | 1165 |   } | 
 | 1166 | } | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1167 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1168 | /// CheckPrintfScanfArguments - Check calls to printf and scanf (and similar | 
 | 1169 | /// functions) for correct use of format strings. | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 1170 | void | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1171 | Sema::CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg, | 
 | 1172 |                                 unsigned format_idx, unsigned firstDataArg, | 
 | 1173 |                                 bool isPrintf) { | 
 | 1174 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1175 |   const Expr *Fn = TheCall->getCallee(); | 
| Chris Lattner | 925e60d | 2007-12-28 05:29:59 +0000 | [diff] [blame] | 1176 |  | 
| Sebastian Redl | 4a2614e | 2009-11-17 18:02:24 +0000 | [diff] [blame] | 1177 |   // The way the format attribute works in GCC, the implicit this argument | 
 | 1178 |   // of member functions is counted. However, it doesn't appear in our own | 
 | 1179 |   // lists, so decrement format_idx in that case. | 
 | 1180 |   if (isa<CXXMemberCallExpr>(TheCall)) { | 
| Chandler Carruth | 9263a30 | 2010-11-16 08:49:43 +0000 | [diff] [blame] | 1181 |     const CXXMethodDecl *method_decl = | 
 | 1182 |       dyn_cast<CXXMethodDecl>(TheCall->getCalleeDecl()); | 
 | 1183 |     if (method_decl && method_decl->isInstance()) { | 
 | 1184 |       // Catch a format attribute mistakenly referring to the object argument. | 
 | 1185 |       if (format_idx == 0) | 
 | 1186 |         return; | 
 | 1187 |       --format_idx; | 
 | 1188 |       if(firstDataArg != 0) | 
 | 1189 |         --firstDataArg; | 
 | 1190 |     } | 
| Sebastian Redl | 4a2614e | 2009-11-17 18:02:24 +0000 | [diff] [blame] | 1191 |   } | 
 | 1192 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1193 |   // CHECK: printf/scanf-like function is called with no format string. | 
| Chris Lattner | 925e60d | 2007-12-28 05:29:59 +0000 | [diff] [blame] | 1194 |   if (format_idx >= TheCall->getNumArgs()) { | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1195 |     Diag(TheCall->getRParenLoc(), diag::warn_missing_format_string) | 
| Chris Lattner | dcd5ef1 | 2008-11-19 05:27:50 +0000 | [diff] [blame] | 1196 |       << Fn->getSourceRange(); | 
| Ted Kremenek | 71895b9 | 2007-08-14 17:39:48 +0000 | [diff] [blame] | 1197 |     return; | 
 | 1198 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1199 |  | 
| Ted Kremenek | 082d936 | 2009-03-20 21:35:28 +0000 | [diff] [blame] | 1200 |   const Expr *OrigFormatExpr = TheCall->getArg(format_idx)->IgnoreParenCasts(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1201 |  | 
| Chris Lattner | 59907c4 | 2007-08-10 20:18:51 +0000 | [diff] [blame] | 1202 |   // CHECK: format string is not a string literal. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1203 |   // | 
| Ted Kremenek | 71895b9 | 2007-08-14 17:39:48 +0000 | [diff] [blame] | 1204 |   // Dynamically generated format strings are difficult to | 
 | 1205 |   // automatically vet at compile time.  Requiring that format strings | 
 | 1206 |   // are string literals: (1) permits the checking of format strings by | 
 | 1207 |   // the compiler and thereby (2) can practically remove the source of | 
 | 1208 |   // many format string exploits. | 
| Ted Kremenek | 7ff22b2 | 2008-06-16 18:00:42 +0000 | [diff] [blame] | 1209 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1210 |   // Format string can be either ObjC string (e.g. @"%d") or | 
| Ted Kremenek | 7ff22b2 | 2008-06-16 18:00:42 +0000 | [diff] [blame] | 1211 |   // C string (e.g. "%d") | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1212 |   // ObjC string uses the same format specifiers as C string, so we can use | 
| Ted Kremenek | 7ff22b2 | 2008-06-16 18:00:42 +0000 | [diff] [blame] | 1213 |   // the same format string checking logic for both ObjC and C strings. | 
| Chris Lattner | 1cd3e1f | 2009-04-29 04:49:34 +0000 | [diff] [blame] | 1214 |   if (SemaCheckStringLiteral(OrigFormatExpr, TheCall, HasVAListArg, format_idx, | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1215 |                              firstDataArg, isPrintf)) | 
| Chris Lattner | 1cd3e1f | 2009-04-29 04:49:34 +0000 | [diff] [blame] | 1216 |     return;  // Literal format string found, check done! | 
| Ted Kremenek | 7ff22b2 | 2008-06-16 18:00:42 +0000 | [diff] [blame] | 1217 |  | 
| Chris Lattner | 655f141 | 2009-04-29 04:59:47 +0000 | [diff] [blame] | 1218 |   // If there are no arguments specified, warn with -Wformat-security, otherwise | 
 | 1219 |   // warn only with -Wformat-nonliteral. | 
 | 1220 |   if (TheCall->getNumArgs() == format_idx+1) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1221 |     Diag(TheCall->getArg(format_idx)->getLocStart(), | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1222 |          diag::warn_format_nonliteral_noargs) | 
| Chris Lattner | 655f141 | 2009-04-29 04:59:47 +0000 | [diff] [blame] | 1223 |       << OrigFormatExpr->getSourceRange(); | 
 | 1224 |   else | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1225 |     Diag(TheCall->getArg(format_idx)->getLocStart(), | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1226 |          diag::warn_format_nonliteral) | 
| Chris Lattner | 655f141 | 2009-04-29 04:59:47 +0000 | [diff] [blame] | 1227 |            << OrigFormatExpr->getSourceRange(); | 
| Ted Kremenek | d30ef87 | 2009-01-12 23:09:09 +0000 | [diff] [blame] | 1228 | } | 
| Ted Kremenek | 71895b9 | 2007-08-14 17:39:48 +0000 | [diff] [blame] | 1229 |  | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1230 | namespace { | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1231 | class CheckFormatHandler : public analyze_format_string::FormatStringHandler { | 
 | 1232 | protected: | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1233 |   Sema &S; | 
 | 1234 |   const StringLiteral *FExpr; | 
 | 1235 |   const Expr *OrigFormatExpr; | 
| Ted Kremenek | 6ee7653 | 2010-03-25 03:59:12 +0000 | [diff] [blame] | 1236 |   const unsigned FirstDataArg; | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1237 |   const unsigned NumDataArgs; | 
 | 1238 |   const bool IsObjCLiteral; | 
 | 1239 |   const char *Beg; // Start of format string. | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1240 |   const bool HasVAListArg; | 
 | 1241 |   const CallExpr *TheCall; | 
 | 1242 |   unsigned FormatIdx; | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1243 |   llvm::BitVector CoveredArgs; | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1244 |   bool usesPositionalArgs; | 
 | 1245 |   bool atFirstArg; | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1246 | public: | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1247 |   CheckFormatHandler(Sema &s, const StringLiteral *fexpr, | 
| Ted Kremenek | 6ee7653 | 2010-03-25 03:59:12 +0000 | [diff] [blame] | 1248 |                      const Expr *origFormatExpr, unsigned firstDataArg, | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1249 |                      unsigned numDataArgs, bool isObjCLiteral, | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1250 |                      const char *beg, bool hasVAListArg, | 
 | 1251 |                      const CallExpr *theCall, unsigned formatIdx) | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1252 |     : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), | 
| Ted Kremenek | 6ee7653 | 2010-03-25 03:59:12 +0000 | [diff] [blame] | 1253 |       FirstDataArg(firstDataArg), | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1254 |       NumDataArgs(numDataArgs), | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1255 |       IsObjCLiteral(isObjCLiteral), Beg(beg), | 
 | 1256 |       HasVAListArg(hasVAListArg), | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1257 |       TheCall(theCall), FormatIdx(formatIdx), | 
 | 1258 |       usesPositionalArgs(false), atFirstArg(true) { | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1259 |         CoveredArgs.resize(numDataArgs); | 
 | 1260 |         CoveredArgs.reset(); | 
 | 1261 |       } | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1262 |  | 
| Ted Kremenek | 07d161f | 2010-01-29 01:50:07 +0000 | [diff] [blame] | 1263 |   void DoneProcessing(); | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1264 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1265 |   void HandleIncompleteSpecifier(const char *startSpecifier, | 
 | 1266 |                                  unsigned specifierLen); | 
 | 1267 |      | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1268 |   virtual void HandleInvalidPosition(const char *startSpecifier, | 
 | 1269 |                                      unsigned specifierLen, | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1270 |                                      analyze_format_string::PositionContext p); | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1271 |  | 
 | 1272 |   virtual void HandleZeroPosition(const char *startPos, unsigned posLen); | 
 | 1273 |  | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1274 |   void HandleNullChar(const char *nullCharacter); | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1275 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1276 | protected: | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1277 |   bool HandleInvalidConversionSpecifier(unsigned argIndex, SourceLocation Loc, | 
 | 1278 |                                         const char *startSpec, | 
 | 1279 |                                         unsigned specifierLen, | 
 | 1280 |                                         const char *csStart, unsigned csLen); | 
 | 1281 |    | 
| Ted Kremenek | f88c8e0 | 2010-01-29 20:55:36 +0000 | [diff] [blame] | 1282 |   SourceRange getFormatStringRange(); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1283 |   CharSourceRange getSpecifierRange(const char *startSpecifier, | 
 | 1284 |                                     unsigned specifierLen); | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1285 |   SourceLocation getLocationOfByte(const char *x); | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1286 |  | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1287 |   const Expr *getDataArg(unsigned i) const; | 
| Ted Kremenek | 666a197 | 2010-07-26 19:45:42 +0000 | [diff] [blame] | 1288 |    | 
 | 1289 |   bool CheckNumArgs(const analyze_format_string::FormatSpecifier &FS, | 
 | 1290 |                     const analyze_format_string::ConversionSpecifier &CS, | 
 | 1291 |                     const char *startSpecifier, unsigned specifierLen, | 
 | 1292 |                     unsigned argIndex); | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1293 | }; | 
 | 1294 | } | 
 | 1295 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1296 | SourceRange CheckFormatHandler::getFormatStringRange() { | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1297 |   return OrigFormatExpr->getSourceRange(); | 
 | 1298 | } | 
 | 1299 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1300 | CharSourceRange CheckFormatHandler:: | 
 | 1301 | getSpecifierRange(const char *startSpecifier, unsigned specifierLen) { | 
| Tom Care | 45f9b7e | 2010-06-21 21:21:01 +0000 | [diff] [blame] | 1302 |   SourceLocation Start = getLocationOfByte(startSpecifier); | 
 | 1303 |   SourceLocation End   = getLocationOfByte(startSpecifier + specifierLen - 1); | 
 | 1304 |  | 
 | 1305 |   // Advance the end SourceLocation by one due to half-open ranges. | 
| Argyrios Kyrtzidis | a64ccef | 2011-09-19 20:40:19 +0000 | [diff] [blame] | 1306 |   End = End.getLocWithOffset(1); | 
| Tom Care | 45f9b7e | 2010-06-21 21:21:01 +0000 | [diff] [blame] | 1307 |  | 
 | 1308 |   return CharSourceRange::getCharRange(Start, End); | 
| Ted Kremenek | f88c8e0 | 2010-01-29 20:55:36 +0000 | [diff] [blame] | 1309 | } | 
 | 1310 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1311 | SourceLocation CheckFormatHandler::getLocationOfByte(const char *x) { | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1312 |   return S.getLocationOfStringLiteralByte(FExpr, x - Beg); | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1313 | } | 
 | 1314 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1315 | void CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier, | 
 | 1316 |                                                    unsigned specifierLen){ | 
| Ted Kremenek | 808015a | 2010-01-29 03:16:21 +0000 | [diff] [blame] | 1317 |   SourceLocation Loc = getLocationOfByte(startSpecifier); | 
 | 1318 |   S.Diag(Loc, diag::warn_printf_incomplete_specifier) | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1319 |     << getSpecifierRange(startSpecifier, specifierLen); | 
| Ted Kremenek | 808015a | 2010-01-29 03:16:21 +0000 | [diff] [blame] | 1320 | } | 
 | 1321 |  | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1322 | void | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1323 | CheckFormatHandler::HandleInvalidPosition(const char *startPos, unsigned posLen, | 
 | 1324 |                                      analyze_format_string::PositionContext p) { | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1325 |   SourceLocation Loc = getLocationOfByte(startPos); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1326 |   S.Diag(Loc, diag::warn_format_invalid_positional_specifier) | 
 | 1327 |     << (unsigned) p << getSpecifierRange(startPos, posLen); | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1328 | } | 
 | 1329 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1330 | void CheckFormatHandler::HandleZeroPosition(const char *startPos, | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1331 |                                             unsigned posLen) { | 
 | 1332 |   SourceLocation Loc = getLocationOfByte(startPos); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1333 |   S.Diag(Loc, diag::warn_format_zero_positional_specifier) | 
 | 1334 |     << getSpecifierRange(startPos, posLen); | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1335 | } | 
 | 1336 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1337 | void CheckFormatHandler::HandleNullChar(const char *nullCharacter) { | 
| Ted Kremenek | 0c06944 | 2011-03-15 21:18:48 +0000 | [diff] [blame] | 1338 |   if (!IsObjCLiteral) { | 
 | 1339 |     // The presence of a null character is likely an error. | 
 | 1340 |     S.Diag(getLocationOfByte(nullCharacter), | 
 | 1341 |            diag::warn_printf_format_string_contains_null_char) | 
 | 1342 |       << getFormatStringRange(); | 
 | 1343 |   } | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1344 | } | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1345 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1346 | const Expr *CheckFormatHandler::getDataArg(unsigned i) const { | 
 | 1347 |   return TheCall->getArg(FirstDataArg + i); | 
 | 1348 | } | 
 | 1349 |  | 
 | 1350 | void CheckFormatHandler::DoneProcessing() { | 
 | 1351 |     // Does the number of data arguments exceed the number of | 
 | 1352 |     // format conversions in the format string? | 
 | 1353 |   if (!HasVAListArg) { | 
 | 1354 |       // Find any arguments that weren't covered. | 
 | 1355 |     CoveredArgs.flip(); | 
 | 1356 |     signed notCoveredArg = CoveredArgs.find_first(); | 
 | 1357 |     if (notCoveredArg >= 0) { | 
 | 1358 |       assert((unsigned)notCoveredArg < NumDataArgs); | 
 | 1359 |       S.Diag(getDataArg((unsigned) notCoveredArg)->getLocStart(), | 
 | 1360 |              diag::warn_printf_data_arg_not_used) | 
 | 1361 |       << getFormatStringRange(); | 
 | 1362 |     } | 
 | 1363 |   } | 
 | 1364 | } | 
 | 1365 |  | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1366 | bool | 
 | 1367 | CheckFormatHandler::HandleInvalidConversionSpecifier(unsigned argIndex, | 
 | 1368 |                                                      SourceLocation Loc, | 
 | 1369 |                                                      const char *startSpec, | 
 | 1370 |                                                      unsigned specifierLen, | 
 | 1371 |                                                      const char *csStart, | 
 | 1372 |                                                      unsigned csLen) { | 
 | 1373 |    | 
 | 1374 |   bool keepGoing = true; | 
 | 1375 |   if (argIndex < NumDataArgs) { | 
 | 1376 |     // Consider the argument coverered, even though the specifier doesn't | 
 | 1377 |     // make sense. | 
 | 1378 |     CoveredArgs.set(argIndex); | 
 | 1379 |   } | 
 | 1380 |   else { | 
 | 1381 |     // If argIndex exceeds the number of data arguments we | 
 | 1382 |     // don't issue a warning because that is just a cascade of warnings (and | 
 | 1383 |     // they may have intended '%%' anyway). We don't want to continue processing | 
 | 1384 |     // the format string after this point, however, as we will like just get | 
 | 1385 |     // gibberish when trying to match arguments. | 
 | 1386 |     keepGoing = false; | 
 | 1387 |   } | 
 | 1388 |    | 
 | 1389 |   S.Diag(Loc, diag::warn_format_invalid_conversion) | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1390 |     << StringRef(csStart, csLen) | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1391 |     << getSpecifierRange(startSpec, specifierLen); | 
 | 1392 |    | 
 | 1393 |   return keepGoing; | 
 | 1394 | } | 
 | 1395 |  | 
| Ted Kremenek | 666a197 | 2010-07-26 19:45:42 +0000 | [diff] [blame] | 1396 | bool | 
 | 1397 | CheckFormatHandler::CheckNumArgs( | 
 | 1398 |   const analyze_format_string::FormatSpecifier &FS, | 
 | 1399 |   const analyze_format_string::ConversionSpecifier &CS, | 
 | 1400 |   const char *startSpecifier, unsigned specifierLen, unsigned argIndex) { | 
 | 1401 |  | 
 | 1402 |   if (argIndex >= NumDataArgs) { | 
 | 1403 |     if (FS.usesPositionalArg())  { | 
 | 1404 |       S.Diag(getLocationOfByte(CS.getStart()), | 
 | 1405 |              diag::warn_printf_positional_arg_exceeds_data_args) | 
 | 1406 |       << (argIndex+1) << NumDataArgs | 
 | 1407 |       << getSpecifierRange(startSpecifier, specifierLen); | 
 | 1408 |     } | 
 | 1409 |     else { | 
 | 1410 |       S.Diag(getLocationOfByte(CS.getStart()), | 
 | 1411 |              diag::warn_printf_insufficient_data_args) | 
 | 1412 |       << getSpecifierRange(startSpecifier, specifierLen); | 
 | 1413 |     } | 
 | 1414 |      | 
 | 1415 |     return false; | 
 | 1416 |   } | 
 | 1417 |   return true; | 
 | 1418 | } | 
 | 1419 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1420 | //===--- CHECK: Printf format string checking ------------------------------===// | 
 | 1421 |  | 
 | 1422 | namespace { | 
 | 1423 | class CheckPrintfHandler : public CheckFormatHandler { | 
 | 1424 | public: | 
 | 1425 |   CheckPrintfHandler(Sema &s, const StringLiteral *fexpr, | 
 | 1426 |                      const Expr *origFormatExpr, unsigned firstDataArg, | 
 | 1427 |                      unsigned numDataArgs, bool isObjCLiteral, | 
 | 1428 |                      const char *beg, bool hasVAListArg, | 
 | 1429 |                      const CallExpr *theCall, unsigned formatIdx) | 
 | 1430 |   : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, | 
 | 1431 |                        numDataArgs, isObjCLiteral, beg, hasVAListArg, | 
 | 1432 |                        theCall, formatIdx) {} | 
 | 1433 |    | 
 | 1434 |    | 
 | 1435 |   bool HandleInvalidPrintfConversionSpecifier( | 
 | 1436 |                                       const analyze_printf::PrintfSpecifier &FS, | 
 | 1437 |                                       const char *startSpecifier, | 
 | 1438 |                                       unsigned specifierLen); | 
 | 1439 |    | 
 | 1440 |   bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, | 
 | 1441 |                              const char *startSpecifier, | 
 | 1442 |                              unsigned specifierLen); | 
 | 1443 |    | 
 | 1444 |   bool HandleAmount(const analyze_format_string::OptionalAmount &Amt, unsigned k, | 
 | 1445 |                     const char *startSpecifier, unsigned specifierLen); | 
 | 1446 |   void HandleInvalidAmount(const analyze_printf::PrintfSpecifier &FS, | 
 | 1447 |                            const analyze_printf::OptionalAmount &Amt, | 
 | 1448 |                            unsigned type, | 
 | 1449 |                            const char *startSpecifier, unsigned specifierLen); | 
 | 1450 |   void HandleFlag(const analyze_printf::PrintfSpecifier &FS, | 
 | 1451 |                   const analyze_printf::OptionalFlag &flag, | 
 | 1452 |                   const char *startSpecifier, unsigned specifierLen); | 
 | 1453 |   void HandleIgnoredFlag(const analyze_printf::PrintfSpecifier &FS, | 
 | 1454 |                          const analyze_printf::OptionalFlag &ignoredFlag, | 
 | 1455 |                          const analyze_printf::OptionalFlag &flag, | 
 | 1456 |                          const char *startSpecifier, unsigned specifierLen); | 
 | 1457 | };   | 
 | 1458 | } | 
 | 1459 |  | 
 | 1460 | bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier( | 
 | 1461 |                                       const analyze_printf::PrintfSpecifier &FS, | 
 | 1462 |                                       const char *startSpecifier, | 
 | 1463 |                                       unsigned specifierLen) { | 
| Ted Kremenek | 6ecb950 | 2010-07-20 20:04:27 +0000 | [diff] [blame] | 1464 |   const analyze_printf::PrintfConversionSpecifier &CS = | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1465 |     FS.getConversionSpecifier(); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1466 |    | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1467 |   return HandleInvalidConversionSpecifier(FS.getArgIndex(), | 
 | 1468 |                                           getLocationOfByte(CS.getStart()), | 
 | 1469 |                                           startSpecifier, specifierLen, | 
 | 1470 |                                           CS.getStart(), CS.getLength()); | 
| Ted Kremenek | 26ac2e0 | 2010-01-29 02:40:24 +0000 | [diff] [blame] | 1471 | } | 
 | 1472 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1473 | bool CheckPrintfHandler::HandleAmount( | 
 | 1474 |                                const analyze_format_string::OptionalAmount &Amt, | 
 | 1475 |                                unsigned k, const char *startSpecifier, | 
 | 1476 |                                unsigned specifierLen) { | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1477 |  | 
 | 1478 |   if (Amt.hasDataArgument()) { | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1479 |     if (!HasVAListArg) { | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1480 |       unsigned argIndex = Amt.getArgIndex(); | 
 | 1481 |       if (argIndex >= NumDataArgs) { | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1482 |         S.Diag(getLocationOfByte(Amt.getStart()), | 
 | 1483 |                diag::warn_printf_asterisk_missing_arg) | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1484 |           << k << getSpecifierRange(startSpecifier, specifierLen); | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1485 |         // Don't do any more checking.  We will just emit | 
 | 1486 |         // spurious errors. | 
 | 1487 |         return false; | 
 | 1488 |       } | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1489 |  | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1490 |       // Type check the data argument.  It should be an 'int'. | 
| Ted Kremenek | 31f8e32 | 2010-01-29 23:32:22 +0000 | [diff] [blame] | 1491 |       // Although not in conformance with C99, we also allow the argument to be | 
 | 1492 |       // an 'unsigned int' as that is a reasonably safe case.  GCC also | 
 | 1493 |       // doesn't emit a warning for that case. | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1494 |       CoveredArgs.set(argIndex); | 
 | 1495 |       const Expr *Arg = getDataArg(argIndex); | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1496 |       QualType T = Arg->getType(); | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1497 |  | 
 | 1498 |       const analyze_printf::ArgTypeResult &ATR = Amt.getArgType(S.Context); | 
 | 1499 |       assert(ATR.isValid()); | 
 | 1500 |  | 
 | 1501 |       if (!ATR.matchesType(S.Context, T)) { | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1502 |         S.Diag(getLocationOfByte(Amt.getStart()), | 
 | 1503 |                diag::warn_printf_asterisk_wrong_type) | 
 | 1504 |           << k | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1505 |           << ATR.getRepresentativeType(S.Context) << T | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1506 |           << getSpecifierRange(startSpecifier, specifierLen) | 
| Ted Kremenek | d635c5f | 2010-01-30 00:49:51 +0000 | [diff] [blame] | 1507 |           << Arg->getSourceRange(); | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1508 |         // Don't do any more checking.  We will just emit | 
 | 1509 |         // spurious errors. | 
 | 1510 |         return false; | 
 | 1511 |       } | 
 | 1512 |     } | 
 | 1513 |   } | 
 | 1514 |   return true; | 
 | 1515 | } | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1516 |  | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1517 | void CheckPrintfHandler::HandleInvalidAmount( | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1518 |                                       const analyze_printf::PrintfSpecifier &FS, | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1519 |                                       const analyze_printf::OptionalAmount &Amt, | 
 | 1520 |                                       unsigned type, | 
 | 1521 |                                       const char *startSpecifier, | 
 | 1522 |                                       unsigned specifierLen) { | 
| Ted Kremenek | 6ecb950 | 2010-07-20 20:04:27 +0000 | [diff] [blame] | 1523 |   const analyze_printf::PrintfConversionSpecifier &CS = | 
 | 1524 |     FS.getConversionSpecifier(); | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1525 |   switch (Amt.getHowSpecified()) { | 
 | 1526 |   case analyze_printf::OptionalAmount::Constant: | 
 | 1527 |     S.Diag(getLocationOfByte(Amt.getStart()), | 
 | 1528 |         diag::warn_printf_nonsensical_optional_amount) | 
 | 1529 |       << type | 
 | 1530 |       << CS.toString() | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1531 |       << getSpecifierRange(startSpecifier, specifierLen) | 
 | 1532 |       << FixItHint::CreateRemoval(getSpecifierRange(Amt.getStart(), | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1533 |           Amt.getConstantLength())); | 
 | 1534 |     break; | 
 | 1535 |  | 
 | 1536 |   default: | 
 | 1537 |     S.Diag(getLocationOfByte(Amt.getStart()), | 
 | 1538 |         diag::warn_printf_nonsensical_optional_amount) | 
 | 1539 |       << type | 
 | 1540 |       << CS.toString() | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1541 |       << getSpecifierRange(startSpecifier, specifierLen); | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1542 |     break; | 
 | 1543 |   } | 
 | 1544 | } | 
 | 1545 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1546 | void CheckPrintfHandler::HandleFlag(const analyze_printf::PrintfSpecifier &FS, | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1547 |                                     const analyze_printf::OptionalFlag &flag, | 
 | 1548 |                                     const char *startSpecifier, | 
 | 1549 |                                     unsigned specifierLen) { | 
 | 1550 |   // Warn about pointless flag with a fixit removal. | 
| Ted Kremenek | 6ecb950 | 2010-07-20 20:04:27 +0000 | [diff] [blame] | 1551 |   const analyze_printf::PrintfConversionSpecifier &CS = | 
 | 1552 |     FS.getConversionSpecifier(); | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1553 |   S.Diag(getLocationOfByte(flag.getPosition()), | 
 | 1554 |       diag::warn_printf_nonsensical_flag) | 
 | 1555 |     << flag.toString() << CS.toString() | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1556 |     << getSpecifierRange(startSpecifier, specifierLen) | 
 | 1557 |     << FixItHint::CreateRemoval(getSpecifierRange(flag.getPosition(), 1)); | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1558 | } | 
 | 1559 |  | 
 | 1560 | void CheckPrintfHandler::HandleIgnoredFlag( | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1561 |                                 const analyze_printf::PrintfSpecifier &FS, | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1562 |                                 const analyze_printf::OptionalFlag &ignoredFlag, | 
 | 1563 |                                 const analyze_printf::OptionalFlag &flag, | 
 | 1564 |                                 const char *startSpecifier, | 
 | 1565 |                                 unsigned specifierLen) { | 
 | 1566 |   // Warn about ignored flag with a fixit removal. | 
 | 1567 |   S.Diag(getLocationOfByte(ignoredFlag.getPosition()), | 
 | 1568 |       diag::warn_printf_ignored_flag) | 
 | 1569 |     << ignoredFlag.toString() << flag.toString() | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1570 |     << getSpecifierRange(startSpecifier, specifierLen) | 
 | 1571 |     << FixItHint::CreateRemoval(getSpecifierRange( | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1572 |         ignoredFlag.getPosition(), 1)); | 
 | 1573 | } | 
 | 1574 |  | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1575 | bool | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1576 | CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier | 
| Ted Kremenek | 5c41ee8 | 2010-02-11 09:27:41 +0000 | [diff] [blame] | 1577 |                                             &FS, | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1578 |                                           const char *startSpecifier, | 
 | 1579 |                                           unsigned specifierLen) { | 
 | 1580 |  | 
| Ted Kremenek | 6ecb950 | 2010-07-20 20:04:27 +0000 | [diff] [blame] | 1581 |   using namespace analyze_format_string; | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1582 |   using namespace analyze_printf;   | 
| Ted Kremenek | 6ecb950 | 2010-07-20 20:04:27 +0000 | [diff] [blame] | 1583 |   const PrintfConversionSpecifier &CS = FS.getConversionSpecifier(); | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1584 |  | 
| Ted Kremenek | baa4006 | 2010-07-19 22:01:06 +0000 | [diff] [blame] | 1585 |   if (FS.consumesDataArgument()) { | 
 | 1586 |     if (atFirstArg) { | 
 | 1587 |         atFirstArg = false; | 
 | 1588 |         usesPositionalArgs = FS.usesPositionalArg(); | 
 | 1589 |     } | 
 | 1590 |     else if (usesPositionalArgs != FS.usesPositionalArg()) { | 
 | 1591 |       // Cannot mix-and-match positional and non-positional arguments. | 
 | 1592 |       S.Diag(getLocationOfByte(CS.getStart()), | 
 | 1593 |              diag::warn_format_mix_positional_nonpositional_args) | 
 | 1594 |         << getSpecifierRange(startSpecifier, specifierLen); | 
 | 1595 |       return false; | 
 | 1596 |     } | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1597 |   } | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1598 |  | 
| Ted Kremenek | efaff19 | 2010-02-27 01:41:03 +0000 | [diff] [blame] | 1599 |   // First check if the field width, precision, and conversion specifier | 
 | 1600 |   // have matching data arguments. | 
 | 1601 |   if (!HandleAmount(FS.getFieldWidth(), /* field width */ 0, | 
 | 1602 |                     startSpecifier, specifierLen)) { | 
 | 1603 |     return false; | 
 | 1604 |   } | 
 | 1605 |  | 
 | 1606 |   if (!HandleAmount(FS.getPrecision(), /* precision */ 1, | 
 | 1607 |                     startSpecifier, specifierLen)) { | 
| Ted Kremenek | 0d27735 | 2010-01-29 01:06:55 +0000 | [diff] [blame] | 1608 |     return false; | 
 | 1609 |   } | 
 | 1610 |  | 
| Ted Kremenek | f88c8e0 | 2010-01-29 20:55:36 +0000 | [diff] [blame] | 1611 |   if (!CS.consumesDataArgument()) { | 
 | 1612 |     // FIXME: Technically specifying a precision or field width here | 
 | 1613 |     // makes no sense.  Worth issuing a warning at some point. | 
| Ted Kremenek | 0e5675d | 2010-02-10 02:16:30 +0000 | [diff] [blame] | 1614 |     return true; | 
| Ted Kremenek | f88c8e0 | 2010-01-29 20:55:36 +0000 | [diff] [blame] | 1615 |   } | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1616 |  | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1617 |   // Consume the argument. | 
 | 1618 |   unsigned argIndex = FS.getArgIndex(); | 
| Ted Kremenek | e3fc547 | 2010-02-27 08:34:51 +0000 | [diff] [blame] | 1619 |   if (argIndex < NumDataArgs) { | 
 | 1620 |     // The check to see if the argIndex is valid will come later. | 
 | 1621 |     // We set the bit here because we may exit early from this | 
 | 1622 |     // function if we encounter some other error. | 
 | 1623 |     CoveredArgs.set(argIndex); | 
 | 1624 |   } | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1625 |  | 
 | 1626 |   // Check for using an Objective-C specific conversion specifier | 
 | 1627 |   // in a non-ObjC literal. | 
 | 1628 |   if (!IsObjCLiteral && CS.isObjCArg()) { | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1629 |     return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier, | 
 | 1630 |                                                   specifierLen); | 
| Ted Kremenek | 7f70dc8 | 2010-02-26 19:18:41 +0000 | [diff] [blame] | 1631 |   } | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1632 |  | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1633 |   // Check for invalid use of field width | 
 | 1634 |   if (!FS.hasValidFieldWidth()) { | 
| Tom Care | 45f9b7e | 2010-06-21 21:21:01 +0000 | [diff] [blame] | 1635 |     HandleInvalidAmount(FS, FS.getFieldWidth(), /* field width */ 0, | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1636 |         startSpecifier, specifierLen); | 
 | 1637 |   } | 
 | 1638 |  | 
 | 1639 |   // Check for invalid use of precision | 
 | 1640 |   if (!FS.hasValidPrecision()) { | 
 | 1641 |     HandleInvalidAmount(FS, FS.getPrecision(), /* precision */ 1, | 
 | 1642 |         startSpecifier, specifierLen); | 
 | 1643 |   } | 
 | 1644 |  | 
 | 1645 |   // Check each flag does not conflict with any other component. | 
| Ted Kremenek | 65197b4 | 2011-01-08 05:28:46 +0000 | [diff] [blame] | 1646 |   if (!FS.hasValidThousandsGroupingPrefix()) | 
 | 1647 |     HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen); | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1648 |   if (!FS.hasValidLeadingZeros()) | 
 | 1649 |     HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen); | 
 | 1650 |   if (!FS.hasValidPlusPrefix()) | 
 | 1651 |     HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen); | 
| Tom Care | 45f9b7e | 2010-06-21 21:21:01 +0000 | [diff] [blame] | 1652 |   if (!FS.hasValidSpacePrefix()) | 
 | 1653 |     HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen); | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1654 |   if (!FS.hasValidAlternativeForm()) | 
 | 1655 |     HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen); | 
 | 1656 |   if (!FS.hasValidLeftJustified()) | 
 | 1657 |     HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen); | 
 | 1658 |  | 
 | 1659 |   // Check that flags are not ignored by another flag | 
| Tom Care | 45f9b7e | 2010-06-21 21:21:01 +0000 | [diff] [blame] | 1660 |   if (FS.hasSpacePrefix() && FS.hasPlusPrefix()) // ' ' ignored by '+' | 
 | 1661 |     HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(), | 
 | 1662 |         startSpecifier, specifierLen); | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1663 |   if (FS.hasLeadingZeros() && FS.isLeftJustified()) // '0' ignored by '-' | 
 | 1664 |     HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(), | 
 | 1665 |             startSpecifier, specifierLen); | 
 | 1666 |  | 
 | 1667 |   // Check the length modifier is valid with the given conversion specifier. | 
 | 1668 |   const LengthModifier &LM = FS.getLengthModifier(); | 
 | 1669 |   if (!FS.hasValidLengthModifier()) | 
 | 1670 |     S.Diag(getLocationOfByte(LM.getStart()), | 
| Ted Kremenek | 649aecf | 2010-07-20 20:03:43 +0000 | [diff] [blame] | 1671 |         diag::warn_format_nonsensical_length) | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1672 |       << LM.toString() << CS.toString() | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1673 |       << getSpecifierRange(startSpecifier, specifierLen) | 
 | 1674 |       << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(), | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1675 |           LM.getLength())); | 
 | 1676 |  | 
 | 1677 |   // Are we using '%n'? | 
| Ted Kremenek | 35d353b | 2010-07-20 20:04:10 +0000 | [diff] [blame] | 1678 |   if (CS.getKind() == ConversionSpecifier::nArg) { | 
| Tom Care | e4ee966 | 2010-06-17 19:00:27 +0000 | [diff] [blame] | 1679 |     // Issue a warning about this being a possible security issue. | 
| Ted Kremenek | e82d804 | 2010-01-29 01:35:25 +0000 | [diff] [blame] | 1680 |     S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_write_back) | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1681 |       << getSpecifierRange(startSpecifier, specifierLen); | 
| Ted Kremenek | e82d804 | 2010-01-29 01:35:25 +0000 | [diff] [blame] | 1682 |     // Continue checking the other format specifiers. | 
 | 1683 |     return true; | 
 | 1684 |   } | 
| Ted Kremenek | 5c41ee8 | 2010-02-11 09:27:41 +0000 | [diff] [blame] | 1685 |  | 
| Ted Kremenek | da51f0d | 2010-01-29 01:43:31 +0000 | [diff] [blame] | 1686 |   // The remaining checks depend on the data arguments. | 
 | 1687 |   if (HasVAListArg) | 
 | 1688 |     return true; | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1689 |  | 
| Ted Kremenek | 666a197 | 2010-07-26 19:45:42 +0000 | [diff] [blame] | 1690 |   if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex)) | 
| Ted Kremenek | da51f0d | 2010-01-29 01:43:31 +0000 | [diff] [blame] | 1691 |     return false; | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 1692 |  | 
| Michael J. Spencer | 96827eb | 2010-07-27 04:46:02 +0000 | [diff] [blame] | 1693 |   // Now type check the data expression that matches the | 
 | 1694 |   // format specifier. | 
 | 1695 |   const Expr *Ex = getDataArg(argIndex); | 
 | 1696 |   const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context); | 
 | 1697 |   if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) { | 
 | 1698 |     // Check if we didn't match because of an implicit cast from a 'char' | 
 | 1699 |     // or 'short' to an 'int'.  This is done because printf is a varargs | 
 | 1700 |     // function. | 
 | 1701 |     if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex)) | 
| Ted Kremenek | 4d8ae4d | 2010-10-21 04:00:58 +0000 | [diff] [blame] | 1702 |       if (ICE->getType() == S.Context.IntTy) { | 
 | 1703 |         // All further checking is done on the subexpression. | 
 | 1704 |         Ex = ICE->getSubExpr(); | 
 | 1705 |         if (ATR.matchesType(S.Context, Ex->getType())) | 
| Michael J. Spencer | 96827eb | 2010-07-27 04:46:02 +0000 | [diff] [blame] | 1706 |           return true; | 
| Ted Kremenek | 4d8ae4d | 2010-10-21 04:00:58 +0000 | [diff] [blame] | 1707 |       } | 
| Michael J. Spencer | 96827eb | 2010-07-27 04:46:02 +0000 | [diff] [blame] | 1708 |  | 
 | 1709 |     // We may be able to offer a FixItHint if it is a supported type. | 
 | 1710 |     PrintfSpecifier fixedFS = FS; | 
 | 1711 |     bool success = fixedFS.fixType(Ex->getType()); | 
 | 1712 |  | 
 | 1713 |     if (success) { | 
 | 1714 |       // Get the fix string from the fixed format specifier | 
 | 1715 |       llvm::SmallString<128> buf; | 
 | 1716 |       llvm::raw_svector_ostream os(buf); | 
 | 1717 |       fixedFS.toString(os); | 
 | 1718 |  | 
| Ted Kremenek | 9325eaf | 2010-08-24 22:24:51 +0000 | [diff] [blame] | 1719 |       // FIXME: getRepresentativeType() perhaps should return a string | 
 | 1720 |       // instead of a QualType to better handle when the representative | 
 | 1721 |       // type is 'wint_t' (which is defined in the system headers). | 
| Michael J. Spencer | 96827eb | 2010-07-27 04:46:02 +0000 | [diff] [blame] | 1722 |       S.Diag(getLocationOfByte(CS.getStart()), | 
 | 1723 |           diag::warn_printf_conversion_argument_type_mismatch) | 
 | 1724 |         << ATR.getRepresentativeType(S.Context) << Ex->getType() | 
 | 1725 |         << getSpecifierRange(startSpecifier, specifierLen) | 
 | 1726 |         << Ex->getSourceRange() | 
 | 1727 |         << FixItHint::CreateReplacement( | 
 | 1728 |             getSpecifierRange(startSpecifier, specifierLen), | 
 | 1729 |             os.str()); | 
 | 1730 |     } | 
 | 1731 |     else { | 
 | 1732 |       S.Diag(getLocationOfByte(CS.getStart()), | 
 | 1733 |              diag::warn_printf_conversion_argument_type_mismatch) | 
 | 1734 |         << ATR.getRepresentativeType(S.Context) << Ex->getType() | 
 | 1735 |         << getSpecifierRange(startSpecifier, specifierLen) | 
 | 1736 |         << Ex->getSourceRange(); | 
 | 1737 |     } | 
 | 1738 |   } | 
 | 1739 |  | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1740 |   return true; | 
 | 1741 | } | 
 | 1742 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1743 | //===--- CHECK: Scanf format string checking ------------------------------===// | 
 | 1744 |  | 
 | 1745 | namespace {   | 
 | 1746 | class CheckScanfHandler : public CheckFormatHandler { | 
 | 1747 | public: | 
 | 1748 |   CheckScanfHandler(Sema &s, const StringLiteral *fexpr, | 
 | 1749 |                     const Expr *origFormatExpr, unsigned firstDataArg, | 
 | 1750 |                     unsigned numDataArgs, bool isObjCLiteral, | 
 | 1751 |                     const char *beg, bool hasVAListArg, | 
 | 1752 |                     const CallExpr *theCall, unsigned formatIdx) | 
 | 1753 |   : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg, | 
 | 1754 |                        numDataArgs, isObjCLiteral, beg, hasVAListArg, | 
 | 1755 |                        theCall, formatIdx) {} | 
 | 1756 |    | 
 | 1757 |   bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, | 
 | 1758 |                             const char *startSpecifier, | 
 | 1759 |                             unsigned specifierLen); | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1760 |    | 
 | 1761 |   bool HandleInvalidScanfConversionSpecifier( | 
 | 1762 |           const analyze_scanf::ScanfSpecifier &FS, | 
 | 1763 |           const char *startSpecifier, | 
 | 1764 |           unsigned specifierLen); | 
| Ted Kremenek | b7c2101 | 2010-07-16 18:28:03 +0000 | [diff] [blame] | 1765 |  | 
 | 1766 |   void HandleIncompleteScanList(const char *start, const char *end); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1767 | }; | 
| Ted Kremenek | 07d161f | 2010-01-29 01:50:07 +0000 | [diff] [blame] | 1768 | } | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1769 |  | 
| Ted Kremenek | b7c2101 | 2010-07-16 18:28:03 +0000 | [diff] [blame] | 1770 | void CheckScanfHandler::HandleIncompleteScanList(const char *start, | 
 | 1771 |                                                  const char *end) { | 
 | 1772 |   S.Diag(getLocationOfByte(end), diag::warn_scanf_scanlist_incomplete) | 
 | 1773 |     << getSpecifierRange(start, end - start); | 
 | 1774 | } | 
 | 1775 |  | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1776 | bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier( | 
 | 1777 |                                         const analyze_scanf::ScanfSpecifier &FS, | 
 | 1778 |                                         const char *startSpecifier, | 
 | 1779 |                                         unsigned specifierLen) { | 
 | 1780 |  | 
| Ted Kremenek | 6ecb950 | 2010-07-20 20:04:27 +0000 | [diff] [blame] | 1781 |   const analyze_scanf::ScanfConversionSpecifier &CS = | 
| Ted Kremenek | c09b6a5 | 2010-07-19 21:25:57 +0000 | [diff] [blame] | 1782 |     FS.getConversionSpecifier(); | 
 | 1783 |  | 
 | 1784 |   return HandleInvalidConversionSpecifier(FS.getArgIndex(), | 
 | 1785 |                                           getLocationOfByte(CS.getStart()), | 
 | 1786 |                                           startSpecifier, specifierLen, | 
 | 1787 |                                           CS.getStart(), CS.getLength()); | 
 | 1788 | } | 
 | 1789 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1790 | bool CheckScanfHandler::HandleScanfSpecifier( | 
 | 1791 |                                        const analyze_scanf::ScanfSpecifier &FS, | 
 | 1792 |                                        const char *startSpecifier, | 
 | 1793 |                                        unsigned specifierLen) { | 
 | 1794 |    | 
 | 1795 |   using namespace analyze_scanf; | 
 | 1796 |   using namespace analyze_format_string;   | 
 | 1797 |  | 
| Ted Kremenek | 6ecb950 | 2010-07-20 20:04:27 +0000 | [diff] [blame] | 1798 |   const ScanfConversionSpecifier &CS = FS.getConversionSpecifier(); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1799 |  | 
| Ted Kremenek | baa4006 | 2010-07-19 22:01:06 +0000 | [diff] [blame] | 1800 |   // Handle case where '%' and '*' don't consume an argument.  These shouldn't | 
 | 1801 |   // be used to decide if we are using positional arguments consistently. | 
 | 1802 |   if (FS.consumesDataArgument()) { | 
 | 1803 |     if (atFirstArg) { | 
 | 1804 |       atFirstArg = false; | 
 | 1805 |       usesPositionalArgs = FS.usesPositionalArg(); | 
 | 1806 |     } | 
 | 1807 |     else if (usesPositionalArgs != FS.usesPositionalArg()) { | 
 | 1808 |       // Cannot mix-and-match positional and non-positional arguments. | 
 | 1809 |       S.Diag(getLocationOfByte(CS.getStart()), | 
 | 1810 |              diag::warn_format_mix_positional_nonpositional_args) | 
 | 1811 |         << getSpecifierRange(startSpecifier, specifierLen); | 
 | 1812 |       return false; | 
 | 1813 |     } | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1814 |   } | 
 | 1815 |    | 
 | 1816 |   // Check if the field with is non-zero. | 
 | 1817 |   const OptionalAmount &Amt = FS.getFieldWidth(); | 
 | 1818 |   if (Amt.getHowSpecified() == OptionalAmount::Constant) { | 
 | 1819 |     if (Amt.getConstantAmount() == 0) { | 
 | 1820 |       const CharSourceRange &R = getSpecifierRange(Amt.getStart(), | 
 | 1821 |                                                    Amt.getConstantLength()); | 
 | 1822 |       S.Diag(getLocationOfByte(Amt.getStart()), | 
 | 1823 |              diag::warn_scanf_nonzero_width) | 
 | 1824 |         << R << FixItHint::CreateRemoval(R); | 
 | 1825 |     } | 
 | 1826 |   } | 
 | 1827 |    | 
 | 1828 |   if (!FS.consumesDataArgument()) { | 
 | 1829 |     // FIXME: Technically specifying a precision or field width here | 
 | 1830 |     // makes no sense.  Worth issuing a warning at some point. | 
 | 1831 |     return true; | 
 | 1832 |   } | 
 | 1833 |    | 
 | 1834 |   // Consume the argument. | 
 | 1835 |   unsigned argIndex = FS.getArgIndex(); | 
 | 1836 |   if (argIndex < NumDataArgs) { | 
 | 1837 |       // The check to see if the argIndex is valid will come later. | 
 | 1838 |       // We set the bit here because we may exit early from this | 
 | 1839 |       // function if we encounter some other error. | 
 | 1840 |     CoveredArgs.set(argIndex); | 
 | 1841 |   } | 
 | 1842 |    | 
| Ted Kremenek | 1e51c20 | 2010-07-20 20:04:47 +0000 | [diff] [blame] | 1843 |   // Check the length modifier is valid with the given conversion specifier. | 
 | 1844 |   const LengthModifier &LM = FS.getLengthModifier(); | 
 | 1845 |   if (!FS.hasValidLengthModifier()) { | 
 | 1846 |     S.Diag(getLocationOfByte(LM.getStart()), | 
 | 1847 |            diag::warn_format_nonsensical_length) | 
 | 1848 |       << LM.toString() << CS.toString() | 
 | 1849 |       << getSpecifierRange(startSpecifier, specifierLen) | 
 | 1850 |       << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(), | 
 | 1851 |                                                     LM.getLength())); | 
 | 1852 |   } | 
 | 1853 |  | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1854 |   // The remaining checks depend on the data arguments. | 
 | 1855 |   if (HasVAListArg) | 
 | 1856 |     return true; | 
 | 1857 |    | 
| Ted Kremenek | 666a197 | 2010-07-26 19:45:42 +0000 | [diff] [blame] | 1858 |   if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex)) | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1859 |     return false; | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1860 |    | 
 | 1861 |   // FIXME: Check that the argument type matches the format specifier. | 
 | 1862 |    | 
 | 1863 |   return true; | 
 | 1864 | } | 
 | 1865 |  | 
 | 1866 | void Sema::CheckFormatString(const StringLiteral *FExpr, | 
| Ted Kremenek | 0e5675d | 2010-02-10 02:16:30 +0000 | [diff] [blame] | 1867 |                              const Expr *OrigFormatExpr, | 
 | 1868 |                              const CallExpr *TheCall, bool HasVAListArg, | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1869 |                              unsigned format_idx, unsigned firstDataArg, | 
 | 1870 |                              bool isPrintf) { | 
 | 1871 |    | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1872 |   // CHECK: is the format string a wide literal? | 
| Douglas Gregor | 5cee119 | 2011-07-27 05:40:30 +0000 | [diff] [blame] | 1873 |   if (!FExpr->isAscii()) { | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1874 |     Diag(FExpr->getLocStart(), | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1875 |          diag::warn_format_string_is_wide_literal) | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1876 |     << OrigFormatExpr->getSourceRange(); | 
 | 1877 |     return; | 
 | 1878 |   } | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1879 |    | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1880 |   // Str - The format string.  NOTE: this is NOT null-terminated! | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 1881 |   StringRef StrRef = FExpr->getString(); | 
| Benjamin Kramer | 2f4eaef | 2010-08-17 12:54:38 +0000 | [diff] [blame] | 1882 |   const char *Str = StrRef.data(); | 
 | 1883 |   unsigned StrLen = StrRef.size(); | 
| Ted Kremenek | 4cd5791 | 2011-09-29 05:52:16 +0000 | [diff] [blame] | 1884 |   const unsigned numDataArgs = TheCall->getNumArgs() - firstDataArg; | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1885 |    | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1886 |   // CHECK: empty format string? | 
| Ted Kremenek | 4cd5791 | 2011-09-29 05:52:16 +0000 | [diff] [blame] | 1887 |   if (StrLen == 0 && numDataArgs > 0) { | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1888 |     Diag(FExpr->getLocStart(), diag::warn_empty_format_string) | 
| Ted Kremenek | e0e5313 | 2010-01-28 23:39:18 +0000 | [diff] [blame] | 1889 |     << OrigFormatExpr->getSourceRange(); | 
 | 1890 |     return; | 
 | 1891 |   } | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1892 |    | 
 | 1893 |   if (isPrintf) { | 
 | 1894 |     CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg, | 
| Ted Kremenek | 4cd5791 | 2011-09-29 05:52:16 +0000 | [diff] [blame] | 1895 |                          numDataArgs, isa<ObjCStringLiteral>(OrigFormatExpr), | 
 | 1896 |                          Str, HasVAListArg, TheCall, format_idx); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1897 |    | 
 | 1898 |     if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen)) | 
 | 1899 |       H.DoneProcessing(); | 
 | 1900 |   } | 
 | 1901 |   else { | 
 | 1902 |     CheckScanfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg, | 
| Ted Kremenek | 4cd5791 | 2011-09-29 05:52:16 +0000 | [diff] [blame] | 1903 |                         numDataArgs, isa<ObjCStringLiteral>(OrigFormatExpr), | 
 | 1904 |                         Str, HasVAListArg, TheCall, format_idx); | 
| Ted Kremenek | 826a345 | 2010-07-16 02:11:22 +0000 | [diff] [blame] | 1905 |      | 
 | 1906 |     if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen)) | 
 | 1907 |       H.DoneProcessing(); | 
 | 1908 |   } | 
| Ted Kremenek | ce7024e | 2010-01-28 01:18:22 +0000 | [diff] [blame] | 1909 | } | 
 | 1910 |  | 
| Chandler Carruth | 7ccc95b | 2011-04-27 07:05:31 +0000 | [diff] [blame] | 1911 | //===--- CHECK: Standard memory functions ---------------------------------===// | 
 | 1912 |  | 
| Douglas Gregor | 2a053a3 | 2011-05-03 20:05:22 +0000 | [diff] [blame] | 1913 | /// \brief Determine whether the given type is a dynamic class type (e.g., | 
 | 1914 | /// whether it has a vtable). | 
 | 1915 | static bool isDynamicClassType(QualType T) { | 
 | 1916 |   if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) | 
 | 1917 |     if (CXXRecordDecl *Definition = Record->getDefinition()) | 
 | 1918 |       if (Definition->isDynamicClass()) | 
 | 1919 |         return true; | 
 | 1920 |    | 
 | 1921 |   return false; | 
 | 1922 | } | 
 | 1923 |  | 
| Chandler Carruth | a72a12f | 2011-06-21 23:04:20 +0000 | [diff] [blame] | 1924 | /// \brief If E is a sizeof expression, returns its argument expression, | 
| Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 1925 | /// otherwise returns NULL. | 
 | 1926 | static const Expr *getSizeOfExprArg(const Expr* E) { | 
| Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 1927 |   if (const UnaryExprOrTypeTraitExpr *SizeOf = | 
| Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 1928 |       dyn_cast<UnaryExprOrTypeTraitExpr>(E)) | 
 | 1929 |     if (SizeOf->getKind() == clang::UETT_SizeOf && !SizeOf->isArgumentType()) | 
 | 1930 |       return SizeOf->getArgumentExpr()->IgnoreParenImpCasts(); | 
| Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 1931 |  | 
| Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 1932 |   return 0; | 
 | 1933 | } | 
 | 1934 |  | 
| Chandler Carruth | a72a12f | 2011-06-21 23:04:20 +0000 | [diff] [blame] | 1935 | /// \brief If E is a sizeof expression, returns its argument type. | 
| Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 1936 | static QualType getSizeOfArgType(const Expr* E) { | 
 | 1937 |   if (const UnaryExprOrTypeTraitExpr *SizeOf = | 
 | 1938 |       dyn_cast<UnaryExprOrTypeTraitExpr>(E)) | 
 | 1939 |     if (SizeOf->getKind() == clang::UETT_SizeOf) | 
 | 1940 |       return SizeOf->getTypeOfArgument(); | 
 | 1941 |  | 
 | 1942 |   return QualType(); | 
| Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 1943 | } | 
 | 1944 |  | 
| Chandler Carruth | 7ccc95b | 2011-04-27 07:05:31 +0000 | [diff] [blame] | 1945 | /// \brief Check for dangerous or invalid arguments to memset(). | 
 | 1946 | /// | 
| Chandler Carruth | 929f013 | 2011-06-03 06:23:57 +0000 | [diff] [blame] | 1947 | /// This issues warnings on known problematic, dangerous or unspecified | 
| Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 1948 | /// arguments to the standard 'memset', 'memcpy', 'memmove', and 'memcmp' | 
 | 1949 | /// function calls. | 
| Chandler Carruth | 7ccc95b | 2011-04-27 07:05:31 +0000 | [diff] [blame] | 1950 | /// | 
 | 1951 | /// \param Call The call expression to diagnose. | 
| Matt Beaumont-Gay | cc2f30c | 2011-08-05 00:22:34 +0000 | [diff] [blame] | 1952 | void Sema::CheckMemaccessArguments(const CallExpr *Call, | 
 | 1953 |                                    CheckedMemoryFunction CMF, | 
 | 1954 |                                    IdentifierInfo *FnName) { | 
| Ted Kremenek | 1d59f7f | 2011-04-28 01:38:02 +0000 | [diff] [blame] | 1955 |   // It is possible to have a non-standard definition of memset.  Validate | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 1956 |   // we have enough arguments, and if not, abort further checking. | 
 | 1957 |   if (Call->getNumArgs() < 3) | 
| Ted Kremenek | 1d59f7f | 2011-04-28 01:38:02 +0000 | [diff] [blame] | 1958 |     return; | 
 | 1959 |  | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 1960 |   unsigned LastArg = (CMF == CMF_Memset? 1 : 2); | 
| Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 1961 |   const Expr *LenExpr = Call->getArg(2)->IgnoreParenImpCasts(); | 
| Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 1962 |  | 
 | 1963 |   // We have special checking when the length is a sizeof expression. | 
 | 1964 |   QualType SizeOfArgTy = getSizeOfArgType(LenExpr); | 
 | 1965 |   const Expr *SizeOfArg = getSizeOfExprArg(LenExpr); | 
 | 1966 |   llvm::FoldingSetNodeID SizeOfArgID; | 
 | 1967 |  | 
| Douglas Gregor | 06bc9eb | 2011-05-03 20:37:33 +0000 | [diff] [blame] | 1968 |   for (unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) { | 
 | 1969 |     const Expr *Dest = Call->getArg(ArgIdx)->IgnoreParenImpCasts(); | 
| Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 1970 |     SourceRange ArgRange = Call->getArg(ArgIdx)->getSourceRange(); | 
| Chandler Carruth | 7ccc95b | 2011-04-27 07:05:31 +0000 | [diff] [blame] | 1971 |  | 
| Douglas Gregor | 06bc9eb | 2011-05-03 20:37:33 +0000 | [diff] [blame] | 1972 |     QualType DestTy = Dest->getType(); | 
 | 1973 |     if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) { | 
 | 1974 |       QualType PointeeTy = DestPtrTy->getPointeeType(); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 1975 |  | 
| Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 1976 |       // Never warn about void type pointers. This can be used to suppress | 
 | 1977 |       // false positives. | 
 | 1978 |       if (PointeeTy->isVoidType()) | 
| Douglas Gregor | 06bc9eb | 2011-05-03 20:37:33 +0000 | [diff] [blame] | 1979 |         continue; | 
| Chandler Carruth | 7ccc95b | 2011-04-27 07:05:31 +0000 | [diff] [blame] | 1980 |  | 
| Chandler Carruth | 000d428 | 2011-06-16 09:09:40 +0000 | [diff] [blame] | 1981 |       // Catch "memset(p, 0, sizeof(p))" -- needs to be sizeof(*p). Do this by | 
 | 1982 |       // actually comparing the expressions for equality. Because computing the | 
 | 1983 |       // expression IDs can be expensive, we only do this if the diagnostic is | 
 | 1984 |       // enabled. | 
 | 1985 |       if (SizeOfArg && | 
 | 1986 |           Diags.getDiagnosticLevel(diag::warn_sizeof_pointer_expr_memaccess, | 
 | 1987 |                                    SizeOfArg->getExprLoc())) { | 
 | 1988 |         // We only compute IDs for expressions if the warning is enabled, and | 
 | 1989 |         // cache the sizeof arg's ID. | 
 | 1990 |         if (SizeOfArgID == llvm::FoldingSetNodeID()) | 
 | 1991 |           SizeOfArg->Profile(SizeOfArgID, Context, true); | 
 | 1992 |         llvm::FoldingSetNodeID DestID; | 
 | 1993 |         Dest->Profile(DestID, Context, true); | 
 | 1994 |         if (DestID == SizeOfArgID) { | 
 | 1995 |           unsigned ActionIdx = 0; // Default is to suggest dereferencing. | 
 | 1996 |           if (const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest)) | 
 | 1997 |             if (UnaryOp->getOpcode() == UO_AddrOf) | 
 | 1998 |               ActionIdx = 1; // If its an address-of operator, just remove it. | 
 | 1999 |           if (Context.getTypeSize(PointeeTy) == Context.getCharWidth()) | 
 | 2000 |             ActionIdx = 2; // If the pointee's size is sizeof(char), | 
 | 2001 |                            // suggest an explicit length. | 
 | 2002 |           DiagRuntimeBehavior(SizeOfArg->getExprLoc(), Dest, | 
 | 2003 |                               PDiag(diag::warn_sizeof_pointer_expr_memaccess) | 
 | 2004 |                                 << FnName << ArgIdx << ActionIdx | 
 | 2005 |                                 << Dest->getSourceRange() | 
 | 2006 |                                 << SizeOfArg->getSourceRange()); | 
 | 2007 |           break; | 
 | 2008 |         } | 
 | 2009 |       } | 
 | 2010 |  | 
 | 2011 |       // Also check for cases where the sizeof argument is the exact same | 
 | 2012 |       // type as the memory argument, and where it points to a user-defined | 
 | 2013 |       // record type. | 
 | 2014 |       if (SizeOfArgTy != QualType()) { | 
 | 2015 |         if (PointeeTy->isRecordType() && | 
 | 2016 |             Context.typesAreCompatible(SizeOfArgTy, DestTy)) { | 
 | 2017 |           DiagRuntimeBehavior(LenExpr->getExprLoc(), Dest, | 
 | 2018 |                               PDiag(diag::warn_sizeof_pointer_type_memaccess) | 
 | 2019 |                                 << FnName << SizeOfArgTy << ArgIdx | 
 | 2020 |                                 << PointeeTy << Dest->getSourceRange() | 
 | 2021 |                                 << LenExpr->getSourceRange()); | 
 | 2022 |           break; | 
 | 2023 |         } | 
| Nico Weber | e4a1c64 | 2011-06-14 16:14:58 +0000 | [diff] [blame] | 2024 |       } | 
 | 2025 |  | 
| Douglas Gregor | 06bc9eb | 2011-05-03 20:37:33 +0000 | [diff] [blame] | 2026 |       // Always complain about dynamic classes. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2027 |       if (isDynamicClassType(PointeeTy)) | 
| Matt Beaumont-Gay | 5c5218e | 2011-08-19 20:40:18 +0000 | [diff] [blame] | 2028 |         DiagRuntimeBehavior( | 
 | 2029 |           Dest->getExprLoc(), Dest, | 
 | 2030 |           PDiag(diag::warn_dyn_class_memaccess) | 
 | 2031 |             << (CMF == CMF_Memcmp ? ArgIdx + 2 : ArgIdx) << FnName << PointeeTy | 
 | 2032 |             // "overwritten" if we're warning about the destination for any call | 
 | 2033 |             // but memcmp; otherwise a verb appropriate to the call. | 
 | 2034 |             << (ArgIdx == 0 && CMF != CMF_Memcmp ? 0 : (unsigned)CMF) | 
 | 2035 |             << Call->getCallee()->getSourceRange()); | 
| Douglas Gregor | 707a23e | 2011-06-16 17:56:04 +0000 | [diff] [blame] | 2036 |       else if (PointeeTy.hasNonTrivialObjCLifetime() && CMF != CMF_Memset) | 
| Matt Beaumont-Gay | 5c5218e | 2011-08-19 20:40:18 +0000 | [diff] [blame] | 2037 |         DiagRuntimeBehavior( | 
 | 2038 |           Dest->getExprLoc(), Dest, | 
 | 2039 |           PDiag(diag::warn_arc_object_memaccess) | 
 | 2040 |             << ArgIdx << FnName << PointeeTy | 
 | 2041 |             << Call->getCallee()->getSourceRange()); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2042 |       else | 
| Douglas Gregor | 06bc9eb | 2011-05-03 20:37:33 +0000 | [diff] [blame] | 2043 |         continue; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2044 |  | 
 | 2045 |       DiagRuntimeBehavior( | 
 | 2046 |         Dest->getExprLoc(), Dest, | 
| Chandler Carruth | 929f013 | 2011-06-03 06:23:57 +0000 | [diff] [blame] | 2047 |         PDiag(diag::note_bad_memaccess_silence) | 
| Douglas Gregor | 06bc9eb | 2011-05-03 20:37:33 +0000 | [diff] [blame] | 2048 |           << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)")); | 
 | 2049 |       break; | 
 | 2050 |     } | 
| Chandler Carruth | 7ccc95b | 2011-04-27 07:05:31 +0000 | [diff] [blame] | 2051 |   } | 
 | 2052 | } | 
 | 2053 |  | 
| Ted Kremenek | bd5da9d | 2011-08-18 20:55:45 +0000 | [diff] [blame] | 2054 | // A little helper routine: ignore addition and subtraction of integer literals. | 
 | 2055 | // This intentionally does not ignore all integer constant expressions because | 
 | 2056 | // we don't want to remove sizeof(). | 
 | 2057 | static const Expr *ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx) { | 
 | 2058 |   Ex = Ex->IgnoreParenCasts(); | 
 | 2059 |  | 
 | 2060 |   for (;;) { | 
 | 2061 |     const BinaryOperator * BO = dyn_cast<BinaryOperator>(Ex); | 
 | 2062 |     if (!BO || !BO->isAdditiveOp()) | 
 | 2063 |       break; | 
 | 2064 |  | 
 | 2065 |     const Expr *RHS = BO->getRHS()->IgnoreParenCasts(); | 
 | 2066 |     const Expr *LHS = BO->getLHS()->IgnoreParenCasts(); | 
 | 2067 |      | 
 | 2068 |     if (isa<IntegerLiteral>(RHS)) | 
 | 2069 |       Ex = LHS; | 
 | 2070 |     else if (isa<IntegerLiteral>(LHS)) | 
 | 2071 |       Ex = RHS; | 
 | 2072 |     else | 
 | 2073 |       break; | 
 | 2074 |   } | 
 | 2075 |  | 
 | 2076 |   return Ex; | 
 | 2077 | } | 
 | 2078 |  | 
 | 2079 | // Warn if the user has made the 'size' argument to strlcpy or strlcat | 
 | 2080 | // be the size of the source, instead of the destination. | 
 | 2081 | void Sema::CheckStrlcpycatArguments(const CallExpr *Call, | 
 | 2082 |                                     IdentifierInfo *FnName) { | 
 | 2083 |  | 
 | 2084 |   // Don't crash if the user has the wrong number of arguments | 
 | 2085 |   if (Call->getNumArgs() != 3) | 
 | 2086 |     return; | 
 | 2087 |  | 
 | 2088 |   const Expr *SrcArg = ignoreLiteralAdditions(Call->getArg(1), Context); | 
 | 2089 |   const Expr *SizeArg = ignoreLiteralAdditions(Call->getArg(2), Context); | 
 | 2090 |   const Expr *CompareWithSrc = NULL; | 
 | 2091 |    | 
 | 2092 |   // Look for 'strlcpy(dst, x, sizeof(x))' | 
 | 2093 |   if (const Expr *Ex = getSizeOfExprArg(SizeArg)) | 
 | 2094 |     CompareWithSrc = Ex; | 
 | 2095 |   else { | 
 | 2096 |     // Look for 'strlcpy(dst, x, strlen(x))' | 
 | 2097 |     if (const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) { | 
 | 2098 |       if (SizeCall->isBuiltinCall(Context) == Builtin::BIstrlen | 
 | 2099 |           && SizeCall->getNumArgs() == 1) | 
 | 2100 |         CompareWithSrc = ignoreLiteralAdditions(SizeCall->getArg(0), Context); | 
 | 2101 |     } | 
 | 2102 |   } | 
 | 2103 |  | 
 | 2104 |   if (!CompareWithSrc) | 
 | 2105 |     return; | 
 | 2106 |  | 
 | 2107 |   // Determine if the argument to sizeof/strlen is equal to the source | 
 | 2108 |   // argument.  In principle there's all kinds of things you could do | 
 | 2109 |   // here, for instance creating an == expression and evaluating it with | 
 | 2110 |   // EvaluateAsBooleanCondition, but this uses a more direct technique: | 
 | 2111 |   const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg); | 
 | 2112 |   if (!SrcArgDRE) | 
 | 2113 |     return; | 
 | 2114 |    | 
 | 2115 |   const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc); | 
 | 2116 |   if (!CompareWithSrcDRE ||  | 
 | 2117 |       SrcArgDRE->getDecl() != CompareWithSrcDRE->getDecl()) | 
 | 2118 |     return; | 
 | 2119 |    | 
 | 2120 |   const Expr *OriginalSizeArg = Call->getArg(2); | 
 | 2121 |   Diag(CompareWithSrcDRE->getLocStart(), diag::warn_strlcpycat_wrong_size) | 
 | 2122 |     << OriginalSizeArg->getSourceRange() << FnName; | 
 | 2123 |    | 
 | 2124 |   // Output a FIXIT hint if the destination is an array (rather than a | 
 | 2125 |   // pointer to an array).  This could be enhanced to handle some | 
 | 2126 |   // pointers if we know the actual size, like if DstArg is 'array+2' | 
 | 2127 |   // we could say 'sizeof(array)-2'. | 
 | 2128 |   const Expr *DstArg = Call->getArg(0)->IgnoreParenImpCasts(); | 
| Ted Kremenek | 8f74622 | 2011-08-18 22:48:41 +0000 | [diff] [blame] | 2129 |   QualType DstArgTy = DstArg->getType(); | 
| Ted Kremenek | bd5da9d | 2011-08-18 20:55:45 +0000 | [diff] [blame] | 2130 |    | 
| Ted Kremenek | 8f74622 | 2011-08-18 22:48:41 +0000 | [diff] [blame] | 2131 |   // Only handle constant-sized or VLAs, but not flexible members. | 
 | 2132 |   if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(DstArgTy)) { | 
 | 2133 |     // Only issue the FIXIT for arrays of size > 1. | 
 | 2134 |     if (CAT->getSize().getSExtValue() <= 1) | 
 | 2135 |       return; | 
 | 2136 |   } else if (!DstArgTy->isVariableArrayType()) { | 
 | 2137 |     return; | 
| Ted Kremenek | bd5da9d | 2011-08-18 20:55:45 +0000 | [diff] [blame] | 2138 |   } | 
| Ted Kremenek | 8f74622 | 2011-08-18 22:48:41 +0000 | [diff] [blame] | 2139 |  | 
 | 2140 |   llvm::SmallString<128> sizeString; | 
 | 2141 |   llvm::raw_svector_ostream OS(sizeString); | 
 | 2142 |   OS << "sizeof("; | 
| Douglas Gregor | 8987b23 | 2011-09-27 23:30:47 +0000 | [diff] [blame] | 2143 |   DstArg->printPretty(OS, Context, 0, getPrintingPolicy()); | 
| Ted Kremenek | 8f74622 | 2011-08-18 22:48:41 +0000 | [diff] [blame] | 2144 |   OS << ")"; | 
 | 2145 |    | 
 | 2146 |   Diag(OriginalSizeArg->getLocStart(), diag::note_strlcpycat_wrong_size) | 
 | 2147 |     << FixItHint::CreateReplacement(OriginalSizeArg->getSourceRange(), | 
 | 2148 |                                     OS.str()); | 
| Ted Kremenek | bd5da9d | 2011-08-18 20:55:45 +0000 | [diff] [blame] | 2149 | } | 
 | 2150 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2151 | //===--- CHECK: Return Address of Stack Variable --------------------------===// | 
 | 2152 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 2153 | static Expr *EvalVal(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars); | 
 | 2154 | static Expr *EvalAddr(Expr* E, SmallVectorImpl<DeclRefExpr *> &refVars); | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2155 |  | 
 | 2156 | /// CheckReturnStackAddr - Check if a return statement returns the address | 
 | 2157 | ///   of a stack variable. | 
 | 2158 | void | 
 | 2159 | Sema::CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, | 
 | 2160 |                            SourceLocation ReturnLoc) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2161 |  | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2162 |   Expr *stackE = 0; | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 2163 |   SmallVector<DeclRefExpr *, 8> refVars; | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2164 |  | 
 | 2165 |   // Perform checking for returned stack addresses, local blocks, | 
 | 2166 |   // label addresses or references to temporaries. | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2167 |   if (lhsType->isPointerType() || | 
 | 2168 |       (!getLangOptions().ObjCAutoRefCount && lhsType->isBlockPointerType())) { | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2169 |     stackE = EvalAddr(RetValExp, refVars); | 
| Mike Stump | ac5fc7c | 2009-08-04 21:02:39 +0000 | [diff] [blame] | 2170 |   } else if (lhsType->isReferenceType()) { | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2171 |     stackE = EvalVal(RetValExp, refVars); | 
 | 2172 |   } | 
 | 2173 |  | 
 | 2174 |   if (stackE == 0) | 
 | 2175 |     return; // Nothing suspicious was found. | 
 | 2176 |  | 
 | 2177 |   SourceLocation diagLoc; | 
 | 2178 |   SourceRange diagRange; | 
 | 2179 |   if (refVars.empty()) { | 
 | 2180 |     diagLoc = stackE->getLocStart(); | 
 | 2181 |     diagRange = stackE->getSourceRange(); | 
 | 2182 |   } else { | 
 | 2183 |     // We followed through a reference variable. 'stackE' contains the | 
 | 2184 |     // problematic expression but we will warn at the return statement pointing | 
 | 2185 |     // at the reference variable. We will later display the "trail" of | 
 | 2186 |     // reference variables using notes. | 
 | 2187 |     diagLoc = refVars[0]->getLocStart(); | 
 | 2188 |     diagRange = refVars[0]->getSourceRange(); | 
 | 2189 |   } | 
 | 2190 |  | 
 | 2191 |   if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(stackE)) { //address of local var. | 
 | 2192 |     Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_stack_ref | 
 | 2193 |                                              : diag::warn_ret_stack_addr) | 
 | 2194 |      << DR->getDecl()->getDeclName() << diagRange; | 
 | 2195 |   } else if (isa<BlockExpr>(stackE)) { // local block. | 
 | 2196 |     Diag(diagLoc, diag::err_ret_local_block) << diagRange; | 
 | 2197 |   } else if (isa<AddrLabelExpr>(stackE)) { // address of label. | 
 | 2198 |     Diag(diagLoc, diag::warn_ret_addr_label) << diagRange; | 
 | 2199 |   } else { // local temporary. | 
 | 2200 |     Diag(diagLoc, lhsType->isReferenceType() ? diag::warn_ret_local_temp_ref | 
 | 2201 |                                              : diag::warn_ret_local_temp_addr) | 
 | 2202 |      << diagRange; | 
 | 2203 |   } | 
 | 2204 |  | 
 | 2205 |   // Display the "trail" of reference variables that we followed until we | 
 | 2206 |   // found the problematic expression using notes. | 
 | 2207 |   for (unsigned i = 0, e = refVars.size(); i != e; ++i) { | 
 | 2208 |     VarDecl *VD = cast<VarDecl>(refVars[i]->getDecl()); | 
 | 2209 |     // If this var binds to another reference var, show the range of the next | 
 | 2210 |     // var, otherwise the var binds to the problematic expression, in which case | 
 | 2211 |     // show the range of the expression. | 
 | 2212 |     SourceRange range = (i < e-1) ? refVars[i+1]->getSourceRange() | 
 | 2213 |                                   : stackE->getSourceRange(); | 
 | 2214 |     Diag(VD->getLocation(), diag::note_ref_var_local_bind) | 
 | 2215 |       << VD->getDeclName() << range; | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2216 |   } | 
 | 2217 | } | 
 | 2218 |  | 
 | 2219 | /// EvalAddr - EvalAddr and EvalVal are mutually recursive functions that | 
 | 2220 | ///  check if the expression in a return statement evaluates to an address | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2221 | ///  to a location on the stack, a local block, an address of a label, or a | 
 | 2222 | ///  reference to local temporary. The recursion is used to traverse the | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2223 | ///  AST of the return expression, with recursion backtracking when we | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2224 | ///  encounter a subexpression that (1) clearly does not lead to one of the | 
 | 2225 | ///  above problematic expressions (2) is something we cannot determine leads to | 
 | 2226 | ///  a problematic expression based on such local checking. | 
 | 2227 | /// | 
 | 2228 | ///  Both EvalAddr and EvalVal follow through reference variables to evaluate | 
 | 2229 | ///  the expression that they point to. Such variables are added to the | 
 | 2230 | ///  'refVars' vector so that we know what the reference variable "trail" was. | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2231 | /// | 
| Ted Kremenek | e8c600f | 2007-08-28 17:02:55 +0000 | [diff] [blame] | 2232 | ///  EvalAddr processes expressions that are pointers that are used as | 
 | 2233 | ///  references (and not L-values).  EvalVal handles all other values. | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2234 | ///  At the base case of the recursion is a check for the above problematic | 
 | 2235 | ///  expressions. | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2236 | /// | 
 | 2237 | ///  This implementation handles: | 
 | 2238 | /// | 
 | 2239 | ///   * pointer-to-pointer casts | 
 | 2240 | ///   * implicit conversions from array references to pointers | 
 | 2241 | ///   * taking the address of fields | 
 | 2242 | ///   * arbitrary interplay between "&" and "*" operators | 
 | 2243 | ///   * pointer arithmetic from an address of a stack variable | 
 | 2244 | ///   * taking the address of an array element where the array is on the stack | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 2245 | static Expr *EvalAddr(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars) { | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2246 |   if (E->isTypeDependent()) | 
 | 2247 |       return NULL; | 
 | 2248 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2249 |   // We should only be called for evaluating pointer expressions. | 
| David Chisnall | 0f43656 | 2009-08-17 16:35:33 +0000 | [diff] [blame] | 2250 |   assert((E->getType()->isAnyPointerType() || | 
| Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 2251 |           E->getType()->isBlockPointerType() || | 
| Ted Kremenek | a526c5c | 2008-01-07 19:49:32 +0000 | [diff] [blame] | 2252 |           E->getType()->isObjCQualifiedIdType()) && | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2253 |          "EvalAddr only works on pointers"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2254 |  | 
| Peter Collingbourne | f111d93 | 2011-04-15 00:35:48 +0000 | [diff] [blame] | 2255 |   E = E->IgnoreParens(); | 
 | 2256 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2257 |   // Our "symbolic interpreter" is just a dispatch off the currently | 
 | 2258 |   // viewed AST node.  We then recursively traverse the AST by calling | 
 | 2259 |   // EvalAddr and EvalVal appropriately. | 
 | 2260 |   switch (E->getStmtClass()) { | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2261 |   case Stmt::DeclRefExprClass: { | 
 | 2262 |     DeclRefExpr *DR = cast<DeclRefExpr>(E); | 
 | 2263 |  | 
 | 2264 |     if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) | 
 | 2265 |       // If this is a reference variable, follow through to the expression that | 
 | 2266 |       // it points to. | 
 | 2267 |       if (V->hasLocalStorage() && | 
 | 2268 |           V->getType()->isReferenceType() && V->hasInit()) { | 
 | 2269 |         // Add the reference variable to the "trail". | 
 | 2270 |         refVars.push_back(DR); | 
 | 2271 |         return EvalAddr(V->getInit(), refVars); | 
 | 2272 |       } | 
 | 2273 |  | 
 | 2274 |     return NULL; | 
 | 2275 |   } | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2276 |  | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2277 |   case Stmt::UnaryOperatorClass: { | 
 | 2278 |     // The only unary operator that make sense to handle here | 
 | 2279 |     // is AddrOf.  All others don't make sense as pointers. | 
 | 2280 |     UnaryOperator *U = cast<UnaryOperator>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2281 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2282 |     if (U->getOpcode() == UO_AddrOf) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2283 |       return EvalVal(U->getSubExpr(), refVars); | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2284 |     else | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2285 |       return NULL; | 
 | 2286 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2287 |  | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2288 |   case Stmt::BinaryOperatorClass: { | 
 | 2289 |     // Handle pointer arithmetic.  All other binary operators are not valid | 
 | 2290 |     // in this context. | 
 | 2291 |     BinaryOperator *B = cast<BinaryOperator>(E); | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2292 |     BinaryOperatorKind op = B->getOpcode(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2293 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2294 |     if (op != BO_Add && op != BO_Sub) | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2295 |       return NULL; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2296 |  | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2297 |     Expr *Base = B->getLHS(); | 
 | 2298 |  | 
 | 2299 |     // Determine which argument is the real pointer base.  It could be | 
 | 2300 |     // the RHS argument instead of the LHS. | 
 | 2301 |     if (!Base->getType()->isPointerType()) Base = B->getRHS(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2302 |  | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2303 |     assert (Base->getType()->isPointerType()); | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2304 |     return EvalAddr(Base, refVars); | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2305 |   } | 
| Steve Naroff | 61f40a2 | 2008-09-10 19:17:48 +0000 | [diff] [blame] | 2306 |  | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2307 |   // For conditional operators we need to see if either the LHS or RHS are | 
 | 2308 |   // valid DeclRefExpr*s.  If one of them is valid, we return it. | 
 | 2309 |   case Stmt::ConditionalOperatorClass: { | 
 | 2310 |     ConditionalOperator *C = cast<ConditionalOperator>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2311 |  | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2312 |     // Handle the GNU extension for missing LHS. | 
| Douglas Gregor | 9ee5ee8 | 2010-10-21 16:21:08 +0000 | [diff] [blame] | 2313 |     if (Expr *lhsExpr = C->getLHS()) { | 
 | 2314 |     // In C++, we can have a throw-expression, which has 'void' type. | 
 | 2315 |       if (!lhsExpr->getType()->isVoidType()) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2316 |         if (Expr* LHS = EvalAddr(lhsExpr, refVars)) | 
| Douglas Gregor | 9ee5ee8 | 2010-10-21 16:21:08 +0000 | [diff] [blame] | 2317 |           return LHS; | 
 | 2318 |     } | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2319 |  | 
| Douglas Gregor | 9ee5ee8 | 2010-10-21 16:21:08 +0000 | [diff] [blame] | 2320 |     // In C++, we can have a throw-expression, which has 'void' type. | 
 | 2321 |     if (C->getRHS()->getType()->isVoidType()) | 
 | 2322 |       return NULL; | 
 | 2323 |  | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2324 |     return EvalAddr(C->getRHS(), refVars); | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2325 |   } | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2326 |    | 
 | 2327 |   case Stmt::BlockExprClass: | 
| John McCall | 469a1eb | 2011-02-02 13:00:07 +0000 | [diff] [blame] | 2328 |     if (cast<BlockExpr>(E)->getBlockDecl()->hasCaptures()) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2329 |       return E; // local block. | 
 | 2330 |     return NULL; | 
 | 2331 |  | 
 | 2332 |   case Stmt::AddrLabelExprClass: | 
 | 2333 |     return E; // address of label. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2334 |  | 
| Ted Kremenek | 54b5274 | 2008-08-07 00:49:01 +0000 | [diff] [blame] | 2335 |   // For casts, we need to handle conversions from arrays to | 
 | 2336 |   // pointer values, and pointer-to-pointer conversions. | 
| Douglas Gregor | 49badde | 2008-10-27 19:41:14 +0000 | [diff] [blame] | 2337 |   case Stmt::ImplicitCastExprClass: | 
| Douglas Gregor | 6eec8e8 | 2008-10-28 15:36:24 +0000 | [diff] [blame] | 2338 |   case Stmt::CStyleCastExprClass: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 2339 |   case Stmt::CXXFunctionalCastExprClass: | 
 | 2340 |   case Stmt::ObjCBridgedCastExprClass: { | 
| Argyrios Kyrtzidis | 0835a3c | 2008-08-18 23:01:59 +0000 | [diff] [blame] | 2341 |     Expr* SubExpr = cast<CastExpr>(E)->getSubExpr(); | 
| Ted Kremenek | 54b5274 | 2008-08-07 00:49:01 +0000 | [diff] [blame] | 2342 |     QualType T = SubExpr->getType(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2343 |  | 
| Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 2344 |     if (SubExpr->getType()->isPointerType() || | 
 | 2345 |         SubExpr->getType()->isBlockPointerType() || | 
 | 2346 |         SubExpr->getType()->isObjCQualifiedIdType()) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2347 |       return EvalAddr(SubExpr, refVars); | 
| Ted Kremenek | 54b5274 | 2008-08-07 00:49:01 +0000 | [diff] [blame] | 2348 |     else if (T->isArrayType()) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2349 |       return EvalVal(SubExpr, refVars); | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2350 |     else | 
| Ted Kremenek | 54b5274 | 2008-08-07 00:49:01 +0000 | [diff] [blame] | 2351 |       return 0; | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2352 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2353 |  | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2354 |   // C++ casts.  For dynamic casts, static casts, and const casts, we | 
 | 2355 |   // are always converting from a pointer-to-pointer, so we just blow | 
| Douglas Gregor | 49badde | 2008-10-27 19:41:14 +0000 | [diff] [blame] | 2356 |   // through the cast.  In the case the dynamic cast doesn't fail (and | 
 | 2357 |   // return NULL), we take the conservative route and report cases | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2358 |   // where we return the address of a stack variable.  For Reinterpre | 
| Douglas Gregor | 49badde | 2008-10-27 19:41:14 +0000 | [diff] [blame] | 2359 |   // FIXME: The comment about is wrong; we're not always converting | 
 | 2360 |   // from pointer to pointer. I'm guessing that this code should also | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2361 |   // handle references to objects. | 
 | 2362 |   case Stmt::CXXStaticCastExprClass: | 
 | 2363 |   case Stmt::CXXDynamicCastExprClass: | 
| Douglas Gregor | 49badde | 2008-10-27 19:41:14 +0000 | [diff] [blame] | 2364 |   case Stmt::CXXConstCastExprClass: | 
 | 2365 |   case Stmt::CXXReinterpretCastExprClass: { | 
 | 2366 |       Expr *S = cast<CXXNamedCastExpr>(E)->getSubExpr(); | 
| Steve Naroff | dd972f2 | 2008-09-05 22:11:13 +0000 | [diff] [blame] | 2367 |       if (S->getType()->isPointerType() || S->getType()->isBlockPointerType()) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2368 |         return EvalAddr(S, refVars); | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2369 |       else | 
 | 2370 |         return NULL; | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2371 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2372 |  | 
| Douglas Gregor | 03e8003 | 2011-06-21 17:03:29 +0000 | [diff] [blame] | 2373 |   case Stmt::MaterializeTemporaryExprClass: | 
 | 2374 |     if (Expr *Result = EvalAddr( | 
 | 2375 |                          cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr(), | 
 | 2376 |                                 refVars)) | 
 | 2377 |       return Result; | 
 | 2378 |        | 
 | 2379 |     return E; | 
 | 2380 |        | 
| Chris Lattner | fae3f1f | 2007-12-28 05:31:15 +0000 | [diff] [blame] | 2381 |   // Everything else: we simply don't reason about them. | 
 | 2382 |   default: | 
 | 2383 |     return NULL; | 
 | 2384 |   } | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2385 | } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2386 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2387 |  | 
 | 2388 | ///  EvalVal - This function is complements EvalAddr in the mutual recursion. | 
 | 2389 | ///   See the comments for EvalAddr for more details. | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 2390 | static Expr *EvalVal(Expr *E, SmallVectorImpl<DeclRefExpr *> &refVars) { | 
| Ted Kremenek | 68957a9 | 2010-08-04 20:01:07 +0000 | [diff] [blame] | 2391 | do { | 
| Ted Kremenek | e8c600f | 2007-08-28 17:02:55 +0000 | [diff] [blame] | 2392 |   // We should only be called for evaluating non-pointer expressions, or | 
 | 2393 |   // expressions with a pointer type that are not used as references but instead | 
 | 2394 |   // are l-values (e.g., DeclRefExpr with a pointer type). | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2395 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2396 |   // Our "symbolic interpreter" is just a dispatch off the currently | 
 | 2397 |   // viewed AST node.  We then recursively traverse the AST by calling | 
 | 2398 |   // EvalAddr and EvalVal appropriately. | 
| Peter Collingbourne | f111d93 | 2011-04-15 00:35:48 +0000 | [diff] [blame] | 2399 |  | 
 | 2400 |   E = E->IgnoreParens(); | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2401 |   switch (E->getStmtClass()) { | 
| Ted Kremenek | 68957a9 | 2010-08-04 20:01:07 +0000 | [diff] [blame] | 2402 |   case Stmt::ImplicitCastExprClass: { | 
 | 2403 |     ImplicitCastExpr *IE = cast<ImplicitCastExpr>(E); | 
| John McCall | 5baba9d | 2010-08-25 10:28:54 +0000 | [diff] [blame] | 2404 |     if (IE->getValueKind() == VK_LValue) { | 
| Ted Kremenek | 68957a9 | 2010-08-04 20:01:07 +0000 | [diff] [blame] | 2405 |       E = IE->getSubExpr(); | 
 | 2406 |       continue; | 
 | 2407 |     } | 
 | 2408 |     return NULL; | 
 | 2409 |   } | 
 | 2410 |  | 
| Douglas Gregor | a2813ce | 2009-10-23 18:54:35 +0000 | [diff] [blame] | 2411 |   case Stmt::DeclRefExprClass: { | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2412 |     // When we hit a DeclRefExpr we are looking at code that refers to a | 
 | 2413 |     // variable's name. If it's not a reference variable we check if it has | 
 | 2414 |     // local storage within the function, and if so, return the expression. | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2415 |     DeclRefExpr *DR = cast<DeclRefExpr>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2416 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2417 |     if (VarDecl *V = dyn_cast<VarDecl>(DR->getDecl())) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2418 |       if (V->hasLocalStorage()) { | 
 | 2419 |         if (!V->getType()->isReferenceType()) | 
 | 2420 |           return DR; | 
 | 2421 |  | 
 | 2422 |         // Reference variable, follow through to the expression that | 
 | 2423 |         // it points to. | 
 | 2424 |         if (V->hasInit()) { | 
 | 2425 |           // Add the reference variable to the "trail". | 
 | 2426 |           refVars.push_back(DR); | 
 | 2427 |           return EvalVal(V->getInit(), refVars); | 
 | 2428 |         } | 
 | 2429 |       } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2430 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2431 |     return NULL; | 
 | 2432 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2433 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2434 |   case Stmt::UnaryOperatorClass: { | 
 | 2435 |     // The only unary operator that make sense to handle here | 
 | 2436 |     // is Deref.  All others don't resolve to a "name."  This includes | 
 | 2437 |     // handling all sorts of rvalues passed to a unary operator. | 
 | 2438 |     UnaryOperator *U = cast<UnaryOperator>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2439 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2440 |     if (U->getOpcode() == UO_Deref) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2441 |       return EvalAddr(U->getSubExpr(), refVars); | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2442 |  | 
 | 2443 |     return NULL; | 
 | 2444 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2445 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2446 |   case Stmt::ArraySubscriptExprClass: { | 
 | 2447 |     // Array subscripts are potential references to data on the stack.  We | 
 | 2448 |     // retrieve the DeclRefExpr* for the array variable if it indeed | 
 | 2449 |     // has local storage. | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2450 |     return EvalAddr(cast<ArraySubscriptExpr>(E)->getBase(), refVars); | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2451 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2452 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2453 |   case Stmt::ConditionalOperatorClass: { | 
 | 2454 |     // For conditional operators we need to see if either the LHS or RHS are | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2455 |     // non-NULL Expr's.  If one is non-NULL, we return it. | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2456 |     ConditionalOperator *C = cast<ConditionalOperator>(E); | 
 | 2457 |  | 
| Anders Carlsson | 3907323 | 2007-11-30 19:04:31 +0000 | [diff] [blame] | 2458 |     // Handle the GNU extension for missing LHS. | 
 | 2459 |     if (Expr *lhsExpr = C->getLHS()) | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2460 |       if (Expr *LHS = EvalVal(lhsExpr, refVars)) | 
| Anders Carlsson | 3907323 | 2007-11-30 19:04:31 +0000 | [diff] [blame] | 2461 |         return LHS; | 
 | 2462 |  | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2463 |     return EvalVal(C->getRHS(), refVars); | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2464 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2465 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2466 |   // Accesses to members are potential references to data on the stack. | 
| Douglas Gregor | 83f6faf | 2009-08-31 23:41:50 +0000 | [diff] [blame] | 2467 |   case Stmt::MemberExprClass: { | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2468 |     MemberExpr *M = cast<MemberExpr>(E); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2469 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2470 |     // Check for indirect access.  We only want direct field accesses. | 
| Ted Kremenek | a423e81 | 2010-09-02 01:12:13 +0000 | [diff] [blame] | 2471 |     if (M->isArrow()) | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2472 |       return NULL; | 
| Ted Kremenek | a423e81 | 2010-09-02 01:12:13 +0000 | [diff] [blame] | 2473 |  | 
 | 2474 |     // Check whether the member type is itself a reference, in which case | 
 | 2475 |     // we're not going to refer to the member, but to what the member refers to. | 
 | 2476 |     if (M->getMemberDecl()->getType()->isReferenceType()) | 
 | 2477 |       return NULL; | 
 | 2478 |  | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2479 |     return EvalVal(M->getBase(), refVars); | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2480 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2481 |  | 
| Douglas Gregor | 03e8003 | 2011-06-21 17:03:29 +0000 | [diff] [blame] | 2482 |   case Stmt::MaterializeTemporaryExprClass: | 
 | 2483 |     if (Expr *Result = EvalVal( | 
 | 2484 |                           cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr(), | 
 | 2485 |                                refVars)) | 
 | 2486 |       return Result; | 
 | 2487 |        | 
 | 2488 |     return E; | 
 | 2489 |  | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2490 |   default: | 
| Argyrios Kyrtzidis | 26e10be | 2010-11-30 22:57:32 +0000 | [diff] [blame] | 2491 |     // Check that we don't return or take the address of a reference to a | 
 | 2492 |     // temporary. This is only useful in C++. | 
 | 2493 |     if (!E->isTypeDependent() && E->isRValue()) | 
 | 2494 |       return E; | 
 | 2495 |  | 
 | 2496 |     // Everything else: we simply don't reason about them. | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2497 |     return NULL; | 
 | 2498 |   } | 
| Ted Kremenek | 68957a9 | 2010-08-04 20:01:07 +0000 | [diff] [blame] | 2499 | } while (true); | 
| Ted Kremenek | 06de276 | 2007-08-17 16:46:58 +0000 | [diff] [blame] | 2500 | } | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2501 |  | 
 | 2502 | //===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===// | 
 | 2503 |  | 
 | 2504 | /// Check for comparisons of floating point operands using != and ==. | 
 | 2505 | /// Issue a warning if these are no self-comparisons, as they are not likely | 
 | 2506 | /// to do what the programmer intended. | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 2507 | void Sema::CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr *RHS) { | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2508 |   bool EmitWarning = true; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2509 |  | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 2510 |   Expr* LeftExprSansParen = LHS->IgnoreParenImpCasts(); | 
 | 2511 |   Expr* RightExprSansParen = RHS->IgnoreParenImpCasts(); | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2512 |  | 
 | 2513 |   // Special case: check for x == x (which is OK). | 
 | 2514 |   // Do not emit warnings for such cases. | 
 | 2515 |   if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen)) | 
 | 2516 |     if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RightExprSansParen)) | 
 | 2517 |       if (DRL->getDecl() == DRR->getDecl()) | 
 | 2518 |         EmitWarning = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2519 |  | 
 | 2520 |  | 
| Ted Kremenek | 1b500bb | 2007-11-29 00:59:04 +0000 | [diff] [blame] | 2521 |   // Special case: check for comparisons against literals that can be exactly | 
 | 2522 |   //  represented by APFloat.  In such cases, do not emit a warning.  This | 
 | 2523 |   //  is a heuristic: often comparison against such literals are used to | 
 | 2524 |   //  detect if a value in a variable has not changed.  This clearly can | 
 | 2525 |   //  lead to false negatives. | 
 | 2526 |   if (EmitWarning) { | 
 | 2527 |     if (FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) { | 
 | 2528 |       if (FLL->isExact()) | 
 | 2529 |         EmitWarning = false; | 
| Mike Stump | ac5fc7c | 2009-08-04 21:02:39 +0000 | [diff] [blame] | 2530 |     } else | 
| Ted Kremenek | 1b500bb | 2007-11-29 00:59:04 +0000 | [diff] [blame] | 2531 |       if (FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen)){ | 
 | 2532 |         if (FLR->isExact()) | 
 | 2533 |           EmitWarning = false; | 
 | 2534 |     } | 
 | 2535 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2536 |  | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2537 |   // Check for comparisons with builtin types. | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 2538 |   if (EmitWarning) | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2539 |     if (CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen)) | 
| Douglas Gregor | 3c385e5 | 2009-02-14 18:57:46 +0000 | [diff] [blame] | 2540 |       if (CL->isBuiltinCall(Context)) | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2541 |         EmitWarning = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2542 |  | 
| Sebastian Redl | 0eb2330 | 2009-01-19 00:08:26 +0000 | [diff] [blame] | 2543 |   if (EmitWarning) | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2544 |     if (CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen)) | 
| Douglas Gregor | 3c385e5 | 2009-02-14 18:57:46 +0000 | [diff] [blame] | 2545 |       if (CR->isBuiltinCall(Context)) | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2546 |         EmitWarning = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2547 |  | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2548 |   // Emit the diagnostic. | 
 | 2549 |   if (EmitWarning) | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 2550 |     Diag(Loc, diag::warn_floatingpoint_eq) | 
 | 2551 |       << LHS->getSourceRange() << RHS->getSourceRange(); | 
| Ted Kremenek | 588e5eb | 2007-11-25 00:58:00 +0000 | [diff] [blame] | 2552 | } | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 2553 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2554 | //===--- CHECK: Integer mixed-sign comparisons (-Wsign-compare) --------===// | 
 | 2555 | //===--- CHECK: Lossy implicit conversions (-Wconversion) --------------===// | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 2556 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2557 | namespace { | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 2558 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2559 | /// Structure recording the 'active' range of an integer-valued | 
 | 2560 | /// expression. | 
 | 2561 | struct IntRange { | 
 | 2562 |   /// The number of bits active in the int. | 
 | 2563 |   unsigned Width; | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 2564 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2565 |   /// True if the int is known not to have negative values. | 
 | 2566 |   bool NonNegative; | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 2567 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2568 |   IntRange(unsigned Width, bool NonNegative) | 
 | 2569 |     : Width(Width), NonNegative(NonNegative) | 
 | 2570 |   {} | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 2571 |  | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2572 |   /// Returns the range of the bool type. | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2573 |   static IntRange forBoolType() { | 
 | 2574 |     return IntRange(1, true); | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2575 |   } | 
 | 2576 |  | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2577 |   /// Returns the range of an opaque value of the given integral type. | 
 | 2578 |   static IntRange forValueOfType(ASTContext &C, QualType T) { | 
 | 2579 |     return forValueOfCanonicalType(C, | 
 | 2580 |                           T->getCanonicalTypeInternal().getTypePtr()); | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2581 |   } | 
 | 2582 |  | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2583 |   /// Returns the range of an opaque value of a canonical integral type. | 
 | 2584 |   static IntRange forValueOfCanonicalType(ASTContext &C, const Type *T) { | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2585 |     assert(T->isCanonicalUnqualified()); | 
 | 2586 |  | 
 | 2587 |     if (const VectorType *VT = dyn_cast<VectorType>(T)) | 
 | 2588 |       T = VT->getElementType().getTypePtr(); | 
 | 2589 |     if (const ComplexType *CT = dyn_cast<ComplexType>(T)) | 
 | 2590 |       T = CT->getElementType().getTypePtr(); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2591 |  | 
| John McCall | 091f23f | 2010-11-09 22:22:12 +0000 | [diff] [blame] | 2592 |     // For enum types, use the known bit width of the enumerators. | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2593 |     if (const EnumType *ET = dyn_cast<EnumType>(T)) { | 
 | 2594 |       EnumDecl *Enum = ET->getDecl(); | 
| John McCall | 5e1cdac | 2011-10-07 06:10:15 +0000 | [diff] [blame] | 2595 |       if (!Enum->isCompleteDefinition()) | 
| John McCall | 091f23f | 2010-11-09 22:22:12 +0000 | [diff] [blame] | 2596 |         return IntRange(C.getIntWidth(QualType(T, 0)), false); | 
 | 2597 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2598 |       unsigned NumPositive = Enum->getNumPositiveBits(); | 
 | 2599 |       unsigned NumNegative = Enum->getNumNegativeBits(); | 
 | 2600 |  | 
 | 2601 |       return IntRange(std::max(NumPositive, NumNegative), NumNegative == 0); | 
 | 2602 |     } | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2603 |  | 
 | 2604 |     const BuiltinType *BT = cast<BuiltinType>(T); | 
 | 2605 |     assert(BT->isInteger()); | 
 | 2606 |  | 
 | 2607 |     return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger()); | 
 | 2608 |   } | 
 | 2609 |  | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2610 |   /// Returns the "target" range of a canonical integral type, i.e. | 
 | 2611 |   /// the range of values expressible in the type. | 
 | 2612 |   /// | 
 | 2613 |   /// This matches forValueOfCanonicalType except that enums have the | 
 | 2614 |   /// full range of their type, not the range of their enumerators. | 
 | 2615 |   static IntRange forTargetOfCanonicalType(ASTContext &C, const Type *T) { | 
 | 2616 |     assert(T->isCanonicalUnqualified()); | 
 | 2617 |  | 
 | 2618 |     if (const VectorType *VT = dyn_cast<VectorType>(T)) | 
 | 2619 |       T = VT->getElementType().getTypePtr(); | 
 | 2620 |     if (const ComplexType *CT = dyn_cast<ComplexType>(T)) | 
 | 2621 |       T = CT->getElementType().getTypePtr(); | 
 | 2622 |     if (const EnumType *ET = dyn_cast<EnumType>(T)) | 
| Douglas Gregor | 69ff26b | 2011-09-08 23:29:05 +0000 | [diff] [blame] | 2623 |       T = C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr(); | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2624 |  | 
 | 2625 |     const BuiltinType *BT = cast<BuiltinType>(T); | 
 | 2626 |     assert(BT->isInteger()); | 
 | 2627 |  | 
 | 2628 |     return IntRange(C.getIntWidth(QualType(T, 0)), BT->isUnsignedInteger()); | 
 | 2629 |   } | 
 | 2630 |  | 
 | 2631 |   /// Returns the supremum of two ranges: i.e. their conservative merge. | 
| John McCall | c0cd21d | 2010-02-23 19:22:29 +0000 | [diff] [blame] | 2632 |   static IntRange join(IntRange L, IntRange R) { | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2633 |     return IntRange(std::max(L.Width, R.Width), | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2634 |                     L.NonNegative && R.NonNegative); | 
 | 2635 |   } | 
 | 2636 |  | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2637 |   /// Returns the infinum of two ranges: i.e. their aggressive merge. | 
| John McCall | c0cd21d | 2010-02-23 19:22:29 +0000 | [diff] [blame] | 2638 |   static IntRange meet(IntRange L, IntRange R) { | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2639 |     return IntRange(std::min(L.Width, R.Width), | 
 | 2640 |                     L.NonNegative || R.NonNegative); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2641 |   } | 
 | 2642 | }; | 
 | 2643 |  | 
 | 2644 | IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth) { | 
 | 2645 |   if (value.isSigned() && value.isNegative()) | 
 | 2646 |     return IntRange(value.getMinSignedBits(), false); | 
 | 2647 |  | 
 | 2648 |   if (value.getBitWidth() > MaxWidth) | 
| Jay Foad | 9f71a8f | 2010-12-07 08:25:34 +0000 | [diff] [blame] | 2649 |     value = value.trunc(MaxWidth); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2650 |  | 
 | 2651 |   // isNonNegative() just checks the sign bit without considering | 
 | 2652 |   // signedness. | 
 | 2653 |   return IntRange(value.getActiveBits(), true); | 
 | 2654 | } | 
 | 2655 |  | 
| John McCall | 0acc311 | 2010-01-06 22:57:21 +0000 | [diff] [blame] | 2656 | IntRange GetValueRange(ASTContext &C, APValue &result, QualType Ty, | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2657 |                        unsigned MaxWidth) { | 
 | 2658 |   if (result.isInt()) | 
 | 2659 |     return GetValueRange(C, result.getInt(), MaxWidth); | 
 | 2660 |  | 
 | 2661 |   if (result.isVector()) { | 
| John McCall | 0acc311 | 2010-01-06 22:57:21 +0000 | [diff] [blame] | 2662 |     IntRange R = GetValueRange(C, result.getVectorElt(0), Ty, MaxWidth); | 
 | 2663 |     for (unsigned i = 1, e = result.getVectorLength(); i != e; ++i) { | 
 | 2664 |       IntRange El = GetValueRange(C, result.getVectorElt(i), Ty, MaxWidth); | 
 | 2665 |       R = IntRange::join(R, El); | 
 | 2666 |     } | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2667 |     return R; | 
 | 2668 |   } | 
 | 2669 |  | 
 | 2670 |   if (result.isComplexInt()) { | 
 | 2671 |     IntRange R = GetValueRange(C, result.getComplexIntReal(), MaxWidth); | 
 | 2672 |     IntRange I = GetValueRange(C, result.getComplexIntImag(), MaxWidth); | 
 | 2673 |     return IntRange::join(R, I); | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2674 |   } | 
 | 2675 |  | 
 | 2676 |   // This can happen with lossless casts to intptr_t of "based" lvalues. | 
 | 2677 |   // Assume it might use arbitrary bits. | 
| John McCall | 0acc311 | 2010-01-06 22:57:21 +0000 | [diff] [blame] | 2678 |   // FIXME: The only reason we need to pass the type in here is to get | 
 | 2679 |   // the sign right on this one case.  It would be nice if APValue | 
 | 2680 |   // preserved this. | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2681 |   assert(result.isLValue()); | 
| Douglas Gregor | 5e9ebb3 | 2011-05-21 16:28:01 +0000 | [diff] [blame] | 2682 |   return IntRange(MaxWidth, Ty->isUnsignedIntegerOrEnumerationType()); | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2683 | } | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2684 |  | 
 | 2685 | /// Pseudo-evaluate the given integer expression, estimating the | 
 | 2686 | /// range of values it might take. | 
 | 2687 | /// | 
 | 2688 | /// \param MaxWidth - the width to which the value will be truncated | 
 | 2689 | IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) { | 
 | 2690 |   E = E->IgnoreParens(); | 
 | 2691 |  | 
 | 2692 |   // Try a full evaluation first. | 
 | 2693 |   Expr::EvalResult result; | 
 | 2694 |   if (E->Evaluate(result, C)) | 
| John McCall | 0acc311 | 2010-01-06 22:57:21 +0000 | [diff] [blame] | 2695 |     return GetValueRange(C, result.Val, E->getType(), MaxWidth); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2696 |  | 
 | 2697 |   // I think we only want to look through implicit casts here; if the | 
 | 2698 |   // user has an explicit widening cast, we should treat the value as | 
 | 2699 |   // being of the new, wider type. | 
 | 2700 |   if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2701 |     if (CE->getCastKind() == CK_NoOp) | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2702 |       return GetExprRange(C, CE->getSubExpr(), MaxWidth); | 
 | 2703 |  | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2704 |     IntRange OutputTypeRange = IntRange::forValueOfType(C, CE->getType()); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2705 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2706 |     bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast); | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2707 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2708 |     // Assume that non-integer casts can span the full range of the type. | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2709 |     if (!isIntegerCast) | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2710 |       return OutputTypeRange; | 
 | 2711 |  | 
 | 2712 |     IntRange SubRange | 
 | 2713 |       = GetExprRange(C, CE->getSubExpr(), | 
 | 2714 |                      std::min(MaxWidth, OutputTypeRange.Width)); | 
 | 2715 |  | 
 | 2716 |     // Bail out if the subexpr's range is as wide as the cast type. | 
 | 2717 |     if (SubRange.Width >= OutputTypeRange.Width) | 
 | 2718 |       return OutputTypeRange; | 
 | 2719 |  | 
 | 2720 |     // Otherwise, we take the smaller width, and we're non-negative if | 
 | 2721 |     // either the output type or the subexpr is. | 
 | 2722 |     return IntRange(SubRange.Width, | 
 | 2723 |                     SubRange.NonNegative || OutputTypeRange.NonNegative); | 
 | 2724 |   } | 
 | 2725 |  | 
 | 2726 |   if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) { | 
 | 2727 |     // If we can fold the condition, just take that operand. | 
 | 2728 |     bool CondResult; | 
 | 2729 |     if (CO->getCond()->EvaluateAsBooleanCondition(CondResult, C)) | 
 | 2730 |       return GetExprRange(C, CondResult ? CO->getTrueExpr() | 
 | 2731 |                                         : CO->getFalseExpr(), | 
 | 2732 |                           MaxWidth); | 
 | 2733 |  | 
 | 2734 |     // Otherwise, conservatively merge. | 
 | 2735 |     IntRange L = GetExprRange(C, CO->getTrueExpr(), MaxWidth); | 
 | 2736 |     IntRange R = GetExprRange(C, CO->getFalseExpr(), MaxWidth); | 
 | 2737 |     return IntRange::join(L, R); | 
 | 2738 |   } | 
 | 2739 |  | 
 | 2740 |   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { | 
 | 2741 |     switch (BO->getOpcode()) { | 
 | 2742 |  | 
 | 2743 |     // Boolean-valued operations are single-bit and positive. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2744 |     case BO_LAnd: | 
 | 2745 |     case BO_LOr: | 
 | 2746 |     case BO_LT: | 
 | 2747 |     case BO_GT: | 
 | 2748 |     case BO_LE: | 
 | 2749 |     case BO_GE: | 
 | 2750 |     case BO_EQ: | 
 | 2751 |     case BO_NE: | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2752 |       return IntRange::forBoolType(); | 
 | 2753 |  | 
| John McCall | 862ff87 | 2011-07-13 06:35:24 +0000 | [diff] [blame] | 2754 |     // The type of the assignments is the type of the LHS, so the RHS | 
 | 2755 |     // is not necessarily the same type. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2756 |     case BO_MulAssign: | 
 | 2757 |     case BO_DivAssign: | 
 | 2758 |     case BO_RemAssign: | 
 | 2759 |     case BO_AddAssign: | 
 | 2760 |     case BO_SubAssign: | 
| John McCall | 862ff87 | 2011-07-13 06:35:24 +0000 | [diff] [blame] | 2761 |     case BO_XorAssign: | 
 | 2762 |     case BO_OrAssign: | 
 | 2763 |       // TODO: bitfields? | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2764 |       return IntRange::forValueOfType(C, E->getType()); | 
| John McCall | c0cd21d | 2010-02-23 19:22:29 +0000 | [diff] [blame] | 2765 |  | 
| John McCall | 862ff87 | 2011-07-13 06:35:24 +0000 | [diff] [blame] | 2766 |     // Simple assignments just pass through the RHS, which will have | 
 | 2767 |     // been coerced to the LHS type. | 
 | 2768 |     case BO_Assign: | 
 | 2769 |       // TODO: bitfields? | 
 | 2770 |       return GetExprRange(C, BO->getRHS(), MaxWidth); | 
 | 2771 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2772 |     // Operations with opaque sources are black-listed. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2773 |     case BO_PtrMemD: | 
 | 2774 |     case BO_PtrMemI: | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2775 |       return IntRange::forValueOfType(C, E->getType()); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2776 |  | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2777 |     // Bitwise-and uses the *infinum* of the two source ranges. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2778 |     case BO_And: | 
 | 2779 |     case BO_AndAssign: | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2780 |       return IntRange::meet(GetExprRange(C, BO->getLHS(), MaxWidth), | 
 | 2781 |                             GetExprRange(C, BO->getRHS(), MaxWidth)); | 
 | 2782 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2783 |     // Left shift gets black-listed based on a judgement call. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2784 |     case BO_Shl: | 
| John McCall | 3aae609 | 2010-04-07 01:14:35 +0000 | [diff] [blame] | 2785 |       // ...except that we want to treat '1 << (blah)' as logically | 
 | 2786 |       // positive.  It's an important idiom. | 
 | 2787 |       if (IntegerLiteral *I | 
 | 2788 |             = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) { | 
 | 2789 |         if (I->getValue() == 1) { | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2790 |           IntRange R = IntRange::forValueOfType(C, E->getType()); | 
| John McCall | 3aae609 | 2010-04-07 01:14:35 +0000 | [diff] [blame] | 2791 |           return IntRange(R.Width, /*NonNegative*/ true); | 
 | 2792 |         } | 
 | 2793 |       } | 
 | 2794 |       // fallthrough | 
 | 2795 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2796 |     case BO_ShlAssign: | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2797 |       return IntRange::forValueOfType(C, E->getType()); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2798 |  | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2799 |     // Right shift by a constant can narrow its left argument. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2800 |     case BO_Shr: | 
 | 2801 |     case BO_ShrAssign: { | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2802 |       IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth); | 
 | 2803 |  | 
 | 2804 |       // If the shift amount is a positive constant, drop the width by | 
 | 2805 |       // that much. | 
 | 2806 |       llvm::APSInt shift; | 
 | 2807 |       if (BO->getRHS()->isIntegerConstantExpr(shift, C) && | 
 | 2808 |           shift.isNonNegative()) { | 
 | 2809 |         unsigned zext = shift.getZExtValue(); | 
 | 2810 |         if (zext >= L.Width) | 
 | 2811 |           L.Width = (L.NonNegative ? 0 : 1); | 
 | 2812 |         else | 
 | 2813 |           L.Width -= zext; | 
 | 2814 |       } | 
 | 2815 |  | 
 | 2816 |       return L; | 
 | 2817 |     } | 
 | 2818 |  | 
 | 2819 |     // Comma acts as its right operand. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2820 |     case BO_Comma: | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2821 |       return GetExprRange(C, BO->getRHS(), MaxWidth); | 
 | 2822 |  | 
| John McCall | 60fad45 | 2010-01-06 22:07:33 +0000 | [diff] [blame] | 2823 |     // Black-list pointer subtractions. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2824 |     case BO_Sub: | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2825 |       if (BO->getLHS()->getType()->isPointerType()) | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2826 |         return IntRange::forValueOfType(C, E->getType()); | 
| John McCall | 00fe761 | 2011-07-14 22:39:48 +0000 | [diff] [blame] | 2827 |       break; | 
| Ted Kremenek | 4e4b30e | 2010-02-16 01:46:59 +0000 | [diff] [blame] | 2828 |  | 
| John McCall | 00fe761 | 2011-07-14 22:39:48 +0000 | [diff] [blame] | 2829 |     // The width of a division result is mostly determined by the size | 
 | 2830 |     // of the LHS. | 
 | 2831 |     case BO_Div: { | 
 | 2832 |       // Don't 'pre-truncate' the operands. | 
 | 2833 |       unsigned opWidth = C.getIntWidth(E->getType()); | 
 | 2834 |       IntRange L = GetExprRange(C, BO->getLHS(), opWidth); | 
 | 2835 |  | 
 | 2836 |       // If the divisor is constant, use that. | 
 | 2837 |       llvm::APSInt divisor; | 
 | 2838 |       if (BO->getRHS()->isIntegerConstantExpr(divisor, C)) { | 
 | 2839 |         unsigned log2 = divisor.logBase2(); // floor(log_2(divisor)) | 
 | 2840 |         if (log2 >= L.Width) | 
 | 2841 |           L.Width = (L.NonNegative ? 0 : 1); | 
 | 2842 |         else | 
 | 2843 |           L.Width = std::min(L.Width - log2, MaxWidth); | 
 | 2844 |         return L; | 
 | 2845 |       } | 
 | 2846 |  | 
 | 2847 |       // Otherwise, just use the LHS's width. | 
 | 2848 |       IntRange R = GetExprRange(C, BO->getRHS(), opWidth); | 
 | 2849 |       return IntRange(L.Width, L.NonNegative && R.NonNegative); | 
 | 2850 |     } | 
 | 2851 |  | 
 | 2852 |     // The result of a remainder can't be larger than the result of | 
 | 2853 |     // either side. | 
 | 2854 |     case BO_Rem: { | 
 | 2855 |       // Don't 'pre-truncate' the operands. | 
 | 2856 |       unsigned opWidth = C.getIntWidth(E->getType()); | 
 | 2857 |       IntRange L = GetExprRange(C, BO->getLHS(), opWidth); | 
 | 2858 |       IntRange R = GetExprRange(C, BO->getRHS(), opWidth); | 
 | 2859 |  | 
 | 2860 |       IntRange meet = IntRange::meet(L, R); | 
 | 2861 |       meet.Width = std::min(meet.Width, MaxWidth); | 
 | 2862 |       return meet; | 
 | 2863 |     } | 
 | 2864 |  | 
 | 2865 |     // The default behavior is okay for these. | 
 | 2866 |     case BO_Mul: | 
 | 2867 |     case BO_Add: | 
 | 2868 |     case BO_Xor: | 
 | 2869 |     case BO_Or: | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2870 |       break; | 
 | 2871 |     } | 
 | 2872 |  | 
| John McCall | 00fe761 | 2011-07-14 22:39:48 +0000 | [diff] [blame] | 2873 |     // The default case is to treat the operation as if it were closed | 
 | 2874 |     // on the narrowest type that encompasses both operands. | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2875 |     IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth); | 
 | 2876 |     IntRange R = GetExprRange(C, BO->getRHS(), MaxWidth); | 
 | 2877 |     return IntRange::join(L, R); | 
 | 2878 |   } | 
 | 2879 |  | 
 | 2880 |   if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { | 
 | 2881 |     switch (UO->getOpcode()) { | 
 | 2882 |     // Boolean-valued operations are white-listed. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2883 |     case UO_LNot: | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2884 |       return IntRange::forBoolType(); | 
 | 2885 |  | 
 | 2886 |     // Operations with opaque sources are black-listed. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2887 |     case UO_Deref: | 
 | 2888 |     case UO_AddrOf: // should be impossible | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2889 |       return IntRange::forValueOfType(C, E->getType()); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2890 |  | 
 | 2891 |     default: | 
 | 2892 |       return GetExprRange(C, UO->getSubExpr(), MaxWidth); | 
 | 2893 |     } | 
 | 2894 |   } | 
| Douglas Gregor | 8ecdb65 | 2010-04-28 22:16:22 +0000 | [diff] [blame] | 2895 |    | 
 | 2896 |   if (dyn_cast<OffsetOfExpr>(E)) { | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2897 |     IntRange::forValueOfType(C, E->getType()); | 
| Douglas Gregor | 8ecdb65 | 2010-04-28 22:16:22 +0000 | [diff] [blame] | 2898 |   } | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2899 |  | 
 | 2900 |   FieldDecl *BitField = E->getBitField(); | 
 | 2901 |   if (BitField) { | 
 | 2902 |     llvm::APSInt BitWidthAP = BitField->getBitWidth()->EvaluateAsInt(C); | 
 | 2903 |     unsigned BitWidth = BitWidthAP.getZExtValue(); | 
 | 2904 |  | 
| Douglas Gregor | 5e9ebb3 | 2011-05-21 16:28:01 +0000 | [diff] [blame] | 2905 |     return IntRange(BitWidth,  | 
 | 2906 |                     BitField->getType()->isUnsignedIntegerOrEnumerationType()); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2907 |   } | 
 | 2908 |  | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 2909 |   return IntRange::forValueOfType(C, E->getType()); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2910 | } | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2911 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2912 | IntRange GetExprRange(ASTContext &C, Expr *E) { | 
 | 2913 |   return GetExprRange(C, E, C.getIntWidth(E->getType())); | 
 | 2914 | } | 
 | 2915 |  | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2916 | /// Checks whether the given value, which currently has the given | 
 | 2917 | /// source semantics, has the same value when coerced through the | 
 | 2918 | /// target semantics. | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2919 | bool IsSameFloatAfterCast(const llvm::APFloat &value, | 
 | 2920 |                           const llvm::fltSemantics &Src, | 
 | 2921 |                           const llvm::fltSemantics &Tgt) { | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2922 |   llvm::APFloat truncated = value; | 
 | 2923 |  | 
 | 2924 |   bool ignored; | 
 | 2925 |   truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored); | 
 | 2926 |   truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored); | 
 | 2927 |  | 
 | 2928 |   return truncated.bitwiseIsEqual(value); | 
 | 2929 | } | 
 | 2930 |  | 
 | 2931 | /// Checks whether the given value, which currently has the given | 
 | 2932 | /// source semantics, has the same value when coerced through the | 
 | 2933 | /// target semantics. | 
 | 2934 | /// | 
 | 2935 | /// The value might be a vector of floats (or a complex number). | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 2936 | bool IsSameFloatAfterCast(const APValue &value, | 
 | 2937 |                           const llvm::fltSemantics &Src, | 
 | 2938 |                           const llvm::fltSemantics &Tgt) { | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 2939 |   if (value.isFloat()) | 
 | 2940 |     return IsSameFloatAfterCast(value.getFloat(), Src, Tgt); | 
 | 2941 |  | 
 | 2942 |   if (value.isVector()) { | 
 | 2943 |     for (unsigned i = 0, e = value.getVectorLength(); i != e; ++i) | 
 | 2944 |       if (!IsSameFloatAfterCast(value.getVectorElt(i), Src, Tgt)) | 
 | 2945 |         return false; | 
 | 2946 |     return true; | 
 | 2947 |   } | 
 | 2948 |  | 
 | 2949 |   assert(value.isComplexFloat()); | 
 | 2950 |   return (IsSameFloatAfterCast(value.getComplexFloatReal(), Src, Tgt) && | 
 | 2951 |           IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt)); | 
 | 2952 | } | 
 | 2953 |  | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 2954 | void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2955 |  | 
| Ted Kremenek | e3b159c | 2010-09-23 21:43:44 +0000 | [diff] [blame] | 2956 | static bool IsZero(Sema &S, Expr *E) { | 
 | 2957 |   // Suppress cases where we are comparing against an enum constant. | 
 | 2958 |   if (const DeclRefExpr *DR = | 
 | 2959 |       dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) | 
 | 2960 |     if (isa<EnumConstantDecl>(DR->getDecl())) | 
 | 2961 |       return false; | 
 | 2962 |  | 
 | 2963 |   // Suppress cases where the '0' value is expanded from a macro. | 
 | 2964 |   if (E->getLocStart().isMacroID()) | 
 | 2965 |     return false; | 
 | 2966 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2967 |   llvm::APSInt Value; | 
 | 2968 |   return E->isIntegerConstantExpr(Value, S.Context) && Value == 0; | 
 | 2969 | } | 
 | 2970 |  | 
| John McCall | 372e103 | 2010-10-06 00:25:24 +0000 | [diff] [blame] | 2971 | static bool HasEnumType(Expr *E) { | 
 | 2972 |   // Strip off implicit integral promotions. | 
 | 2973 |   while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { | 
| Argyrios Kyrtzidis | 63b57ae | 2010-10-07 21:52:18 +0000 | [diff] [blame] | 2974 |     if (ICE->getCastKind() != CK_IntegralCast && | 
 | 2975 |         ICE->getCastKind() != CK_NoOp) | 
| John McCall | 372e103 | 2010-10-06 00:25:24 +0000 | [diff] [blame] | 2976 |       break; | 
| Argyrios Kyrtzidis | 63b57ae | 2010-10-07 21:52:18 +0000 | [diff] [blame] | 2977 |     E = ICE->getSubExpr(); | 
| John McCall | 372e103 | 2010-10-06 00:25:24 +0000 | [diff] [blame] | 2978 |   } | 
 | 2979 |  | 
 | 2980 |   return E->getType()->isEnumeralType(); | 
 | 2981 | } | 
 | 2982 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2983 | void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2984 |   BinaryOperatorKind op = E->getOpcode(); | 
| Douglas Gregor | 14af91a | 2010-12-21 07:22:56 +0000 | [diff] [blame] | 2985 |   if (E->isValueDependent()) | 
 | 2986 |     return; | 
 | 2987 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2988 |   if (op == BO_LT && IsZero(S, E->getRHS())) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2989 |     S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison) | 
| John McCall | 372e103 | 2010-10-06 00:25:24 +0000 | [diff] [blame] | 2990 |       << "< 0" << "false" << HasEnumType(E->getLHS()) | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2991 |       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2992 |   } else if (op == BO_GE && IsZero(S, E->getRHS())) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2993 |     S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison) | 
| John McCall | 372e103 | 2010-10-06 00:25:24 +0000 | [diff] [blame] | 2994 |       << ">= 0" << "true" << HasEnumType(E->getLHS()) | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2995 |       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 2996 |   } else if (op == BO_GT && IsZero(S, E->getLHS())) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2997 |     S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison) | 
| John McCall | 372e103 | 2010-10-06 00:25:24 +0000 | [diff] [blame] | 2998 |       << "0 >" << "false" << HasEnumType(E->getRHS()) | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 2999 |       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3000 |   } else if (op == BO_LE && IsZero(S, E->getLHS())) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3001 |     S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison) | 
| John McCall | 372e103 | 2010-10-06 00:25:24 +0000 | [diff] [blame] | 3002 |       << "0 <=" << "true" << HasEnumType(E->getRHS()) | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3003 |       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange(); | 
 | 3004 |   } | 
 | 3005 | } | 
 | 3006 |  | 
 | 3007 | /// Analyze the operands of the given comparison.  Implements the | 
 | 3008 | /// fallback case from AnalyzeComparison. | 
 | 3009 | void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E) { | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3010 |   AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); | 
 | 3011 |   AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3012 | } | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3013 |  | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3014 | /// \brief Implements -Wsign-compare. | 
 | 3015 | /// | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3016 | /// \param E the binary operator to check for warnings | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3017 | void AnalyzeComparison(Sema &S, BinaryOperator *E) { | 
 | 3018 |   // The type the comparison is being performed in. | 
 | 3019 |   QualType T = E->getLHS()->getType(); | 
 | 3020 |   assert(S.Context.hasSameUnqualifiedType(T, E->getRHS()->getType()) | 
 | 3021 |          && "comparison with mismatched types"); | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3022 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3023 |   // We don't do anything special if this isn't an unsigned integral | 
 | 3024 |   // comparison:  we're only interested in integral comparisons, and | 
 | 3025 |   // signed comparisons only happen in cases we don't care to warn about. | 
| Douglas Gregor | 3e026e3 | 2011-02-19 22:34:59 +0000 | [diff] [blame] | 3026 |   // | 
 | 3027 |   // We also don't care about value-dependent expressions or expressions | 
 | 3028 |   // whose result is a constant. | 
 | 3029 |   if (!T->hasUnsignedIntegerRepresentation() | 
 | 3030 |       || E->isValueDependent() || E->isIntegerConstantExpr(S.Context)) | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3031 |     return AnalyzeImpConvsInComparison(S, E); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 3032 |  | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3033 |   Expr *LHS = E->getLHS()->IgnoreParenImpCasts(); | 
 | 3034 |   Expr *RHS = E->getRHS()->IgnoreParenImpCasts(); | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3035 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3036 |   // Check to see if one of the (unmodified) operands is of different | 
 | 3037 |   // signedness. | 
 | 3038 |   Expr *signedOperand, *unsignedOperand; | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3039 |   if (LHS->getType()->hasSignedIntegerRepresentation()) { | 
 | 3040 |     assert(!RHS->getType()->hasSignedIntegerRepresentation() && | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3041 |            "unsigned comparison between two signed integer expressions?"); | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3042 |     signedOperand = LHS; | 
 | 3043 |     unsignedOperand = RHS; | 
 | 3044 |   } else if (RHS->getType()->hasSignedIntegerRepresentation()) { | 
 | 3045 |     signedOperand = RHS; | 
 | 3046 |     unsignedOperand = LHS; | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3047 |   } else { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3048 |     CheckTrivialUnsignedComparison(S, E); | 
 | 3049 |     return AnalyzeImpConvsInComparison(S, E); | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3050 |   } | 
 | 3051 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3052 |   // Otherwise, calculate the effective range of the signed operand. | 
 | 3053 |   IntRange signedRange = GetExprRange(S.Context, signedOperand); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 3054 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3055 |   // Go ahead and analyze implicit conversions in the operands.  Note | 
 | 3056 |   // that we skip the implicit conversions on both sides. | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3057 |   AnalyzeImplicitConversions(S, LHS, E->getOperatorLoc()); | 
 | 3058 |   AnalyzeImplicitConversions(S, RHS, E->getOperatorLoc()); | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3059 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3060 |   // If the signed range is non-negative, -Wsign-compare won't fire, | 
 | 3061 |   // but we should still check for comparisons which are always true | 
 | 3062 |   // or false. | 
 | 3063 |   if (signedRange.NonNegative) | 
 | 3064 |     return CheckTrivialUnsignedComparison(S, E); | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3065 |  | 
 | 3066 |   // For (in)equality comparisons, if the unsigned operand is a | 
 | 3067 |   // constant which cannot collide with a overflowed signed operand, | 
 | 3068 |   // then reinterpreting the signed operand as unsigned will not | 
 | 3069 |   // change the result of the comparison. | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3070 |   if (E->isEqualityOp()) { | 
 | 3071 |     unsigned comparisonWidth = S.Context.getIntWidth(T); | 
 | 3072 |     IntRange unsignedRange = GetExprRange(S.Context, unsignedOperand); | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3073 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3074 |     // We should never be unable to prove that the unsigned operand is | 
 | 3075 |     // non-negative. | 
 | 3076 |     assert(unsignedRange.NonNegative && "unsigned range includes negative?"); | 
 | 3077 |  | 
 | 3078 |     if (unsignedRange.Width < comparisonWidth) | 
 | 3079 |       return; | 
 | 3080 |   } | 
 | 3081 |  | 
 | 3082 |   S.Diag(E->getOperatorLoc(), diag::warn_mixed_sign_comparison) | 
| Richard Trieu | dd22509 | 2011-09-15 21:56:47 +0000 | [diff] [blame] | 3083 |     << LHS->getType() << RHS->getType() | 
 | 3084 |     << LHS->getSourceRange() << RHS->getSourceRange(); | 
| John McCall | ba26e58 | 2010-01-04 23:21:16 +0000 | [diff] [blame] | 3085 | } | 
 | 3086 |  | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3087 | /// Analyzes an attempt to assign the given value to a bitfield. | 
 | 3088 | /// | 
 | 3089 | /// Returns true if there was something fishy about the attempt. | 
 | 3090 | bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, | 
 | 3091 |                                SourceLocation InitLoc) { | 
 | 3092 |   assert(Bitfield->isBitField()); | 
 | 3093 |   if (Bitfield->isInvalidDecl()) | 
 | 3094 |     return false; | 
 | 3095 |  | 
| John McCall | 91b6014 | 2010-11-11 05:33:51 +0000 | [diff] [blame] | 3096 |   // White-list bool bitfields. | 
 | 3097 |   if (Bitfield->getType()->isBooleanType()) | 
 | 3098 |     return false; | 
 | 3099 |  | 
| Douglas Gregor | 46ff303 | 2011-02-04 13:09:01 +0000 | [diff] [blame] | 3100 |   // Ignore value- or type-dependent expressions. | 
 | 3101 |   if (Bitfield->getBitWidth()->isValueDependent() || | 
 | 3102 |       Bitfield->getBitWidth()->isTypeDependent() || | 
 | 3103 |       Init->isValueDependent() || | 
 | 3104 |       Init->isTypeDependent()) | 
 | 3105 |     return false; | 
 | 3106 |  | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3107 |   Expr *OriginalInit = Init->IgnoreParenImpCasts(); | 
 | 3108 |  | 
 | 3109 |   llvm::APSInt Width(32); | 
 | 3110 |   Expr::EvalResult InitValue; | 
 | 3111 |   if (!Bitfield->getBitWidth()->isIntegerConstantExpr(Width, S.Context) || | 
| John McCall | 91b6014 | 2010-11-11 05:33:51 +0000 | [diff] [blame] | 3112 |       !OriginalInit->Evaluate(InitValue, S.Context) || | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3113 |       !InitValue.Val.isInt()) | 
 | 3114 |     return false; | 
 | 3115 |  | 
 | 3116 |   const llvm::APSInt &Value = InitValue.Val.getInt(); | 
 | 3117 |   unsigned OriginalWidth = Value.getBitWidth(); | 
 | 3118 |   unsigned FieldWidth = Width.getZExtValue(); | 
 | 3119 |  | 
 | 3120 |   if (OriginalWidth <= FieldWidth) | 
 | 3121 |     return false; | 
 | 3122 |  | 
| Jay Foad | 9f71a8f | 2010-12-07 08:25:34 +0000 | [diff] [blame] | 3123 |   llvm::APSInt TruncatedValue = Value.trunc(FieldWidth); | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3124 |  | 
 | 3125 |   // It's fairly common to write values into signed bitfields | 
 | 3126 |   // that, if sign-extended, would end up becoming a different | 
 | 3127 |   // value.  We don't want to warn about that. | 
 | 3128 |   if (Value.isSigned() && Value.isNegative()) | 
| Jay Foad | 9f71a8f | 2010-12-07 08:25:34 +0000 | [diff] [blame] | 3129 |     TruncatedValue = TruncatedValue.sext(OriginalWidth); | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3130 |   else | 
| Jay Foad | 9f71a8f | 2010-12-07 08:25:34 +0000 | [diff] [blame] | 3131 |     TruncatedValue = TruncatedValue.zext(OriginalWidth); | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3132 |  | 
 | 3133 |   if (Value == TruncatedValue) | 
 | 3134 |     return false; | 
 | 3135 |  | 
 | 3136 |   std::string PrettyValue = Value.toString(10); | 
 | 3137 |   std::string PrettyTrunc = TruncatedValue.toString(10); | 
 | 3138 |  | 
 | 3139 |   S.Diag(InitLoc, diag::warn_impcast_bitfield_precision_constant) | 
 | 3140 |     << PrettyValue << PrettyTrunc << OriginalInit->getType() | 
 | 3141 |     << Init->getSourceRange(); | 
 | 3142 |  | 
 | 3143 |   return true; | 
 | 3144 | } | 
 | 3145 |  | 
| John McCall | beb22aa | 2010-11-09 23:24:47 +0000 | [diff] [blame] | 3146 | /// Analyze the given simple or compound assignment for warning-worthy | 
 | 3147 | /// operations. | 
 | 3148 | void AnalyzeAssignment(Sema &S, BinaryOperator *E) { | 
 | 3149 |   // Just recurse on the LHS. | 
 | 3150 |   AnalyzeImplicitConversions(S, E->getLHS(), E->getOperatorLoc()); | 
 | 3151 |  | 
 | 3152 |   // We want to recurse on the RHS as normal unless we're assigning to | 
 | 3153 |   // a bitfield. | 
 | 3154 |   if (FieldDecl *Bitfield = E->getLHS()->getBitField()) { | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3155 |     if (AnalyzeBitFieldAssignment(S, Bitfield, E->getRHS(), | 
 | 3156 |                                   E->getOperatorLoc())) { | 
 | 3157 |       // Recurse, ignoring any implicit conversions on the RHS. | 
 | 3158 |       return AnalyzeImplicitConversions(S, E->getRHS()->IgnoreParenImpCasts(), | 
 | 3159 |                                         E->getOperatorLoc()); | 
| John McCall | beb22aa | 2010-11-09 23:24:47 +0000 | [diff] [blame] | 3160 |     } | 
 | 3161 |   } | 
 | 3162 |  | 
 | 3163 |   AnalyzeImplicitConversions(S, E->getRHS(), E->getOperatorLoc()); | 
 | 3164 | } | 
 | 3165 |  | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3166 | /// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion. | 
| Douglas Gregor | 5a5b38f | 2011-03-12 00:14:31 +0000 | [diff] [blame] | 3167 | void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T,  | 
 | 3168 |                      SourceLocation CContext, unsigned diag) { | 
 | 3169 |   S.Diag(E->getExprLoc(), diag) | 
 | 3170 |     << SourceType << T << E->getSourceRange() << SourceRange(CContext); | 
 | 3171 | } | 
 | 3172 |  | 
| Chandler Carruth | e1b02e0 | 2011-04-05 06:47:57 +0000 | [diff] [blame] | 3173 | /// Diagnose an implicit cast;  purely a helper for CheckImplicitConversion. | 
 | 3174 | void DiagnoseImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext, | 
 | 3175 |                      unsigned diag) { | 
 | 3176 |   DiagnoseImpCast(S, E, E->getType(), T, CContext, diag); | 
 | 3177 | } | 
 | 3178 |  | 
| Chandler Carruth | f65076e | 2011-04-10 08:36:24 +0000 | [diff] [blame] | 3179 | /// Diagnose an implicit cast from a literal expression. Also attemps to supply | 
 | 3180 | /// fixit hints when the cast wouldn't lose information to simply write the | 
 | 3181 | /// expression with the expected type. | 
 | 3182 | void DiagnoseFloatingLiteralImpCast(Sema &S, FloatingLiteral *FL, QualType T, | 
 | 3183 |                                     SourceLocation CContext) { | 
 | 3184 |   // Emit the primary warning first, then try to emit a fixit hint note if | 
 | 3185 |   // reasonable. | 
 | 3186 |   S.Diag(FL->getExprLoc(), diag::warn_impcast_literal_float_to_integer) | 
 | 3187 |     << FL->getType() << T << FL->getSourceRange() << SourceRange(CContext); | 
 | 3188 |  | 
 | 3189 |   const llvm::APFloat &Value = FL->getValue(); | 
 | 3190 |  | 
 | 3191 |   // Don't attempt to fix PPC double double literals. | 
 | 3192 |   if (&Value.getSemantics() == &llvm::APFloat::PPCDoubleDouble) | 
 | 3193 |     return; | 
 | 3194 |  | 
| Jeffrey Yasskin | 3e1ef78 | 2011-07-15 17:03:07 +0000 | [diff] [blame] | 3195 |   // Try to convert this exactly to an integer. | 
| Chandler Carruth | f65076e | 2011-04-10 08:36:24 +0000 | [diff] [blame] | 3196 |   bool isExact = false; | 
| Jeffrey Yasskin | 3e1ef78 | 2011-07-15 17:03:07 +0000 | [diff] [blame] | 3197 |   llvm::APSInt IntegerValue(S.Context.getIntWidth(T), | 
 | 3198 |                             T->hasUnsignedIntegerRepresentation()); | 
 | 3199 |   if (Value.convertToInteger(IntegerValue, | 
| Chandler Carruth | f65076e | 2011-04-10 08:36:24 +0000 | [diff] [blame] | 3200 |                              llvm::APFloat::rmTowardZero, &isExact) | 
 | 3201 |       != llvm::APFloat::opOK || !isExact) | 
 | 3202 |     return; | 
 | 3203 |  | 
| Jeffrey Yasskin | 3e1ef78 | 2011-07-15 17:03:07 +0000 | [diff] [blame] | 3204 |   std::string LiteralValue = IntegerValue.toString(10); | 
| Chandler Carruth | f65076e | 2011-04-10 08:36:24 +0000 | [diff] [blame] | 3205 |   S.Diag(FL->getExprLoc(), diag::note_fix_integral_float_as_integer) | 
 | 3206 |     << FixItHint::CreateReplacement(FL->getSourceRange(), LiteralValue); | 
 | 3207 | } | 
 | 3208 |  | 
| John McCall | 091f23f | 2010-11-09 22:22:12 +0000 | [diff] [blame] | 3209 | std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range) { | 
 | 3210 |   if (!Range.Width) return "0"; | 
 | 3211 |  | 
 | 3212 |   llvm::APSInt ValueInRange = Value; | 
 | 3213 |   ValueInRange.setIsSigned(!Range.NonNegative); | 
| Jay Foad | 9f71a8f | 2010-12-07 08:25:34 +0000 | [diff] [blame] | 3214 |   ValueInRange = ValueInRange.trunc(Range.Width); | 
| John McCall | 091f23f | 2010-11-09 22:22:12 +0000 | [diff] [blame] | 3215 |   return ValueInRange.toString(10); | 
 | 3216 | } | 
 | 3217 |  | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3218 | static bool isFromSystemMacro(Sema &S, SourceLocation loc) { | 
 | 3219 |   SourceManager &smgr = S.Context.getSourceManager(); | 
 | 3220 |   return loc.isMacroID() && smgr.isInSystemHeader(smgr.getSpellingLoc(loc)); | 
 | 3221 | } | 
| Chandler Carruth | f65076e | 2011-04-10 08:36:24 +0000 | [diff] [blame] | 3222 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3223 | void CheckImplicitConversion(Sema &S, Expr *E, QualType T, | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3224 |                              SourceLocation CC, bool *ICContext = 0) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3225 |   if (E->isTypeDependent() || E->isValueDependent()) return; | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3226 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3227 |   const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr(); | 
 | 3228 |   const Type *Target = S.Context.getCanonicalType(T).getTypePtr(); | 
 | 3229 |   if (Source == Target) return; | 
 | 3230 |   if (Target->isDependentType()) return; | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3231 |  | 
| Chandler Carruth | 108f756 | 2011-07-26 05:40:03 +0000 | [diff] [blame] | 3232 |   // If the conversion context location is invalid don't complain. We also | 
 | 3233 |   // don't want to emit a warning if the issue occurs from the expansion of | 
 | 3234 |   // a system macro. The problem is that 'getSpellingLoc()' is slow, so we | 
 | 3235 |   // delay this check as long as possible. Once we detect we are in that | 
 | 3236 |   // scenario, we just return. | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3237 |   if (CC.isInvalid()) | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3238 |     return; | 
 | 3239 |  | 
| Richard Trieu | f1f8b1a | 2011-09-23 20:10:00 +0000 | [diff] [blame] | 3240 |   // Diagnose implicit casts to bool. | 
 | 3241 |   if (Target->isSpecificBuiltinType(BuiltinType::Bool)) { | 
 | 3242 |     if (isa<StringLiteral>(E)) | 
 | 3243 |       // Warn on string literal to bool.  Checks for string literals in logical | 
 | 3244 |       // expressions, for instances, assert(0 && "error here"), is prevented | 
 | 3245 |       // by a check in AnalyzeImplicitConversions(). | 
 | 3246 |       return DiagnoseImpCast(S, E, T, CC, | 
 | 3247 |                              diag::warn_impcast_string_literal_to_bool); | 
| David Blaikie | e37cdc4 | 2011-09-29 04:06:47 +0000 | [diff] [blame] | 3248 |     return; // Other casts to bool are not checked. | 
| Richard Trieu | f1f8b1a | 2011-09-23 20:10:00 +0000 | [diff] [blame] | 3249 |   } | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3250 |  | 
 | 3251 |   // Strip vector types. | 
 | 3252 |   if (isa<VectorType>(Source)) { | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3253 |     if (!isa<VectorType>(Target)) { | 
 | 3254 |       if (isFromSystemMacro(S, CC)) | 
 | 3255 |         return; | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3256 |       return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_vector_scalar); | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3257 |     } | 
| Chris Lattner | b792b30 | 2011-06-14 04:51:15 +0000 | [diff] [blame] | 3258 |      | 
 | 3259 |     // If the vector cast is cast between two vectors of the same size, it is | 
 | 3260 |     // a bitcast, not a conversion. | 
 | 3261 |     if (S.Context.getTypeSize(Source) == S.Context.getTypeSize(Target)) | 
 | 3262 |       return; | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3263 |  | 
 | 3264 |     Source = cast<VectorType>(Source)->getElementType().getTypePtr(); | 
 | 3265 |     Target = cast<VectorType>(Target)->getElementType().getTypePtr(); | 
 | 3266 |   } | 
 | 3267 |  | 
 | 3268 |   // Strip complex types. | 
 | 3269 |   if (isa<ComplexType>(Source)) { | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3270 |     if (!isa<ComplexType>(Target)) { | 
 | 3271 |       if (isFromSystemMacro(S, CC)) | 
 | 3272 |         return; | 
 | 3273 |  | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3274 |       return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_complex_scalar); | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3275 |     } | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3276 |  | 
 | 3277 |     Source = cast<ComplexType>(Source)->getElementType().getTypePtr(); | 
 | 3278 |     Target = cast<ComplexType>(Target)->getElementType().getTypePtr(); | 
 | 3279 |   } | 
 | 3280 |  | 
 | 3281 |   const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source); | 
 | 3282 |   const BuiltinType *TargetBT = dyn_cast<BuiltinType>(Target); | 
 | 3283 |  | 
 | 3284 |   // If the source is floating point... | 
 | 3285 |   if (SourceBT && SourceBT->isFloatingPoint()) { | 
 | 3286 |     // ...and the target is floating point... | 
 | 3287 |     if (TargetBT && TargetBT->isFloatingPoint()) { | 
 | 3288 |       // ...then warn if we're dropping FP rank. | 
 | 3289 |  | 
 | 3290 |       // Builtin FP kinds are ordered by increasing FP rank. | 
 | 3291 |       if (SourceBT->getKind() > TargetBT->getKind()) { | 
 | 3292 |         // Don't warn about float constants that are precisely | 
 | 3293 |         // representable in the target type. | 
 | 3294 |         Expr::EvalResult result; | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3295 |         if (E->Evaluate(result, S.Context)) { | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3296 |           // Value might be a float, a float vector, or a float complex. | 
 | 3297 |           if (IsSameFloatAfterCast(result.Val, | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3298 |                    S.Context.getFloatTypeSemantics(QualType(TargetBT, 0)), | 
 | 3299 |                    S.Context.getFloatTypeSemantics(QualType(SourceBT, 0)))) | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3300 |             return; | 
 | 3301 |         } | 
 | 3302 |  | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3303 |         if (isFromSystemMacro(S, CC)) | 
 | 3304 |           return; | 
 | 3305 |  | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3306 |         DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_precision); | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3307 |       } | 
 | 3308 |       return; | 
 | 3309 |     } | 
 | 3310 |  | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3311 |     // If the target is integral, always warn.     | 
| Chandler Carruth | a5b9332 | 2011-02-17 11:05:49 +0000 | [diff] [blame] | 3312 |     if ((TargetBT && TargetBT->isInteger())) { | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3313 |       if (isFromSystemMacro(S, CC)) | 
 | 3314 |         return; | 
 | 3315 |        | 
| Chandler Carruth | a5b9332 | 2011-02-17 11:05:49 +0000 | [diff] [blame] | 3316 |       Expr *InnerE = E->IgnoreParenImpCasts(); | 
| Matt Beaumont-Gay | 634c8af | 2011-09-08 22:30:47 +0000 | [diff] [blame] | 3317 |       // We also want to warn on, e.g., "int i = -1.234" | 
 | 3318 |       if (UnaryOperator *UOp = dyn_cast<UnaryOperator>(InnerE)) | 
 | 3319 |         if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus) | 
 | 3320 |           InnerE = UOp->getSubExpr()->IgnoreParenImpCasts(); | 
 | 3321 |  | 
| Chandler Carruth | f65076e | 2011-04-10 08:36:24 +0000 | [diff] [blame] | 3322 |       if (FloatingLiteral *FL = dyn_cast<FloatingLiteral>(InnerE)) { | 
 | 3323 |         DiagnoseFloatingLiteralImpCast(S, FL, T, CC); | 
| Chandler Carruth | a5b9332 | 2011-02-17 11:05:49 +0000 | [diff] [blame] | 3324 |       } else { | 
 | 3325 |         DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_float_integer); | 
 | 3326 |       } | 
 | 3327 |     } | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3328 |  | 
 | 3329 |     return; | 
 | 3330 |   } | 
 | 3331 |  | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 3332 |   if (!Source->isIntegerType() || !Target->isIntegerType()) | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3333 |     return; | 
 | 3334 |  | 
| Richard Trieu | 1838ca5 | 2011-05-29 19:59:02 +0000 | [diff] [blame] | 3335 |   if ((E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull) | 
 | 3336 |            == Expr::NPCK_GNUNull) && Target->isIntegerType()) { | 
 | 3337 |     S.Diag(E->getExprLoc(), diag::warn_impcast_null_pointer_to_integer) | 
 | 3338 |         << E->getSourceRange() << clang::SourceRange(CC); | 
 | 3339 |     return; | 
 | 3340 |   } | 
 | 3341 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3342 |   IntRange SourceRange = GetExprRange(S.Context, E); | 
| John McCall | 1844a6e | 2010-11-10 23:38:19 +0000 | [diff] [blame] | 3343 |   IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target); | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 3344 |  | 
 | 3345 |   if (SourceRange.Width > TargetRange.Width) { | 
| John McCall | 091f23f | 2010-11-09 22:22:12 +0000 | [diff] [blame] | 3346 |     // If the source is a constant, use a default-on diagnostic. | 
 | 3347 |     // TODO: this should happen for bitfield stores, too. | 
 | 3348 |     llvm::APSInt Value(32); | 
 | 3349 |     if (E->isIntegerConstantExpr(Value, S.Context)) { | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3350 |       if (isFromSystemMacro(S, CC)) | 
 | 3351 |         return; | 
 | 3352 |  | 
| John McCall | 091f23f | 2010-11-09 22:22:12 +0000 | [diff] [blame] | 3353 |       std::string PrettySourceValue = Value.toString(10); | 
 | 3354 |       std::string PrettyTargetValue = PrettyPrintInRange(Value, TargetRange); | 
 | 3355 |  | 
 | 3356 |       S.Diag(E->getExprLoc(), diag::warn_impcast_integer_precision_constant) | 
 | 3357 |         << PrettySourceValue << PrettyTargetValue | 
 | 3358 |         << E->getType() << T << E->getSourceRange() << clang::SourceRange(CC); | 
 | 3359 |       return; | 
 | 3360 |     } | 
 | 3361 |  | 
| Chris Lattner | b792b30 | 2011-06-14 04:51:15 +0000 | [diff] [blame] | 3362 |     // People want to build with -Wshorten-64-to-32 and not -Wconversion. | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3363 |     if (isFromSystemMacro(S, CC)) | 
 | 3364 |       return; | 
 | 3365 |      | 
| John McCall | f2370c9 | 2010-01-06 05:24:50 +0000 | [diff] [blame] | 3366 |     if (SourceRange.Width == 64 && TargetRange.Width == 32) | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3367 |       return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_64_32); | 
 | 3368 |     return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_integer_precision); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3369 |   } | 
 | 3370 |  | 
 | 3371 |   if ((TargetRange.NonNegative && !SourceRange.NonNegative) || | 
 | 3372 |       (!TargetRange.NonNegative && SourceRange.NonNegative && | 
 | 3373 |        SourceRange.Width == TargetRange.Width)) { | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3374 |          | 
 | 3375 |     if (isFromSystemMacro(S, CC)) | 
 | 3376 |       return; | 
 | 3377 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3378 |     unsigned DiagID = diag::warn_impcast_integer_sign; | 
 | 3379 |  | 
 | 3380 |     // Traditionally, gcc has warned about this under -Wsign-compare. | 
 | 3381 |     // We also want to warn about it in -Wconversion. | 
 | 3382 |     // So if -Wconversion is off, use a completely identical diagnostic | 
 | 3383 |     // in the sign-compare group. | 
 | 3384 |     // The conditional-checking code will  | 
 | 3385 |     if (ICContext) { | 
 | 3386 |       DiagID = diag::warn_impcast_integer_sign_conditional; | 
 | 3387 |       *ICContext = true; | 
 | 3388 |     } | 
 | 3389 |  | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3390 |     return DiagnoseImpCast(S, E, T, CC, DiagID); | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3391 |   } | 
 | 3392 |  | 
| Douglas Gregor | 284cc8d | 2011-02-22 02:45:07 +0000 | [diff] [blame] | 3393 |   // Diagnose conversions between different enumeration types. | 
| Douglas Gregor | 5a5b38f | 2011-03-12 00:14:31 +0000 | [diff] [blame] | 3394 |   // In C, we pretend that the type of an EnumConstantDecl is its enumeration | 
 | 3395 |   // type, to give us better diagnostics. | 
 | 3396 |   QualType SourceType = E->getType(); | 
 | 3397 |   if (!S.getLangOptions().CPlusPlus) { | 
 | 3398 |     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) | 
 | 3399 |       if (EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(DRE->getDecl())) { | 
 | 3400 |         EnumDecl *Enum = cast<EnumDecl>(ECD->getDeclContext()); | 
 | 3401 |         SourceType = S.Context.getTypeDeclType(Enum); | 
 | 3402 |         Source = S.Context.getCanonicalType(SourceType).getTypePtr(); | 
 | 3403 |       } | 
 | 3404 |   } | 
 | 3405 |    | 
| Douglas Gregor | 284cc8d | 2011-02-22 02:45:07 +0000 | [diff] [blame] | 3406 |   if (const EnumType *SourceEnum = Source->getAs<EnumType>()) | 
 | 3407 |     if (const EnumType *TargetEnum = Target->getAs<EnumType>()) | 
 | 3408 |       if ((SourceEnum->getDecl()->getIdentifier() ||  | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 3409 |            SourceEnum->getDecl()->getTypedefNameForAnonDecl()) && | 
| Douglas Gregor | 284cc8d | 2011-02-22 02:45:07 +0000 | [diff] [blame] | 3410 |           (TargetEnum->getDecl()->getIdentifier() || | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 3411 |            TargetEnum->getDecl()->getTypedefNameForAnonDecl()) && | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3412 |           SourceEnum != TargetEnum) { | 
 | 3413 |         if (isFromSystemMacro(S, CC)) | 
 | 3414 |           return; | 
 | 3415 |  | 
| Douglas Gregor | 5a5b38f | 2011-03-12 00:14:31 +0000 | [diff] [blame] | 3416 |         return DiagnoseImpCast(S, E, SourceType, T, CC,  | 
| Douglas Gregor | 284cc8d | 2011-02-22 02:45:07 +0000 | [diff] [blame] | 3417 |                                diag::warn_impcast_different_enum_types); | 
| Ted Kremenek | ef9ff88 | 2011-03-10 20:03:42 +0000 | [diff] [blame] | 3418 |       } | 
| Douglas Gregor | 284cc8d | 2011-02-22 02:45:07 +0000 | [diff] [blame] | 3419 |    | 
| John McCall | 51313c3 | 2010-01-04 23:31:57 +0000 | [diff] [blame] | 3420 |   return; | 
 | 3421 | } | 
 | 3422 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3423 | void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T); | 
 | 3424 |  | 
 | 3425 | void CheckConditionalOperand(Sema &S, Expr *E, QualType T, | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3426 |                              SourceLocation CC, bool &ICContext) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3427 |   E = E->IgnoreParenImpCasts(); | 
 | 3428 |  | 
 | 3429 |   if (isa<ConditionalOperator>(E)) | 
 | 3430 |     return CheckConditionalOperator(S, cast<ConditionalOperator>(E), T); | 
 | 3431 |  | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3432 |   AnalyzeImplicitConversions(S, E, CC); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3433 |   if (E->getType() != T) | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3434 |     return CheckImplicitConversion(S, E, T, CC, &ICContext); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3435 |   return; | 
 | 3436 | } | 
 | 3437 |  | 
 | 3438 | void CheckConditionalOperator(Sema &S, ConditionalOperator *E, QualType T) { | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3439 |   SourceLocation CC = E->getQuestionLoc(); | 
 | 3440 |  | 
 | 3441 |   AnalyzeImplicitConversions(S, E->getCond(), CC); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3442 |  | 
 | 3443 |   bool Suspicious = false; | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3444 |   CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious); | 
 | 3445 |   CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3446 |  | 
 | 3447 |   // If -Wconversion would have warned about either of the candidates | 
 | 3448 |   // for a signedness conversion to the context type... | 
 | 3449 |   if (!Suspicious) return; | 
 | 3450 |  | 
 | 3451 |   // ...but it's currently ignored... | 
| Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 3452 |   if (S.Diags.getDiagnosticLevel(diag::warn_impcast_integer_sign_conditional, | 
 | 3453 |                                  CC)) | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3454 |     return; | 
 | 3455 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3456 |   // ...then check whether it would have warned about either of the | 
 | 3457 |   // candidates for a signedness conversion to the condition type. | 
| Richard Trieu | 5254161 | 2011-07-21 02:46:28 +0000 | [diff] [blame] | 3458 |   if (E->getType() == T) return; | 
 | 3459 |   | 
 | 3460 |   Suspicious = false; | 
 | 3461 |   CheckImplicitConversion(S, E->getTrueExpr()->IgnoreParenImpCasts(), | 
 | 3462 |                           E->getType(), CC, &Suspicious); | 
 | 3463 |   if (!Suspicious) | 
 | 3464 |     CheckImplicitConversion(S, E->getFalseExpr()->IgnoreParenImpCasts(), | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3465 |                             E->getType(), CC, &Suspicious); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3466 | } | 
 | 3467 |  | 
 | 3468 | /// AnalyzeImplicitConversions - Find and report any interesting | 
 | 3469 | /// implicit conversions in the given expression.  There are a couple | 
 | 3470 | /// of competing diagnostics here, -Wconversion and -Wsign-compare. | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3471 | void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3472 |   QualType T = OrigE->getType(); | 
 | 3473 |   Expr *E = OrigE->IgnoreParenImpCasts(); | 
 | 3474 |  | 
| Douglas Gregor | f8b6e15 | 2011-10-10 17:38:18 +0000 | [diff] [blame] | 3475 |   if (E->isTypeDependent() || E->isValueDependent()) | 
 | 3476 |     return; | 
 | 3477 |  | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3478 |   // For conditional operators, we analyze the arguments as if they | 
 | 3479 |   // were being fed directly into the output. | 
 | 3480 |   if (isa<ConditionalOperator>(E)) { | 
 | 3481 |     ConditionalOperator *CO = cast<ConditionalOperator>(E); | 
 | 3482 |     CheckConditionalOperator(S, CO, T); | 
 | 3483 |     return; | 
 | 3484 |   } | 
 | 3485 |  | 
 | 3486 |   // Go ahead and check any implicit conversions we might have skipped. | 
 | 3487 |   // The non-canonical typecheck is just an optimization; | 
 | 3488 |   // CheckImplicitConversion will filter out dead implicit conversions. | 
 | 3489 |   if (E->getType() != T) | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3490 |     CheckImplicitConversion(S, E, T, CC); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3491 |  | 
 | 3492 |   // Now continue drilling into this expression. | 
 | 3493 |  | 
 | 3494 |   // Skip past explicit casts. | 
 | 3495 |   if (isa<ExplicitCastExpr>(E)) { | 
 | 3496 |     E = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreParenImpCasts(); | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3497 |     return AnalyzeImplicitConversions(S, E, CC); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3498 |   } | 
 | 3499 |  | 
| John McCall | beb22aa | 2010-11-09 23:24:47 +0000 | [diff] [blame] | 3500 |   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { | 
 | 3501 |     // Do a somewhat different check with comparison operators. | 
 | 3502 |     if (BO->isComparisonOp()) | 
 | 3503 |       return AnalyzeComparison(S, BO); | 
 | 3504 |  | 
 | 3505 |     // And with assignments and compound assignments. | 
 | 3506 |     if (BO->isAssignmentOp()) | 
 | 3507 |       return AnalyzeAssignment(S, BO); | 
 | 3508 |   } | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3509 |  | 
 | 3510 |   // These break the otherwise-useful invariant below.  Fortunately, | 
 | 3511 |   // we don't really need to recurse into them, because any internal | 
 | 3512 |   // expressions should have been analyzed already when they were | 
 | 3513 |   // built into statements. | 
 | 3514 |   if (isa<StmtExpr>(E)) return; | 
 | 3515 |  | 
 | 3516 |   // Don't descend into unevaluated contexts. | 
| Peter Collingbourne | f4e3cfb | 2011-03-11 19:24:49 +0000 | [diff] [blame] | 3517 |   if (isa<UnaryExprOrTypeTraitExpr>(E)) return; | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3518 |  | 
 | 3519 |   // Now just recurse over the expression's children. | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3520 |   CC = E->getExprLoc(); | 
| Richard Trieu | f1f8b1a | 2011-09-23 20:10:00 +0000 | [diff] [blame] | 3521 |   BinaryOperator *BO = dyn_cast<BinaryOperator>(E); | 
 | 3522 |   bool IsLogicalOperator = BO && BO->isLogicalOp(); | 
 | 3523 |   for (Stmt::child_range I = E->children(); I; ++I) { | 
 | 3524 |     Expr *ChildExpr = cast<Expr>(*I); | 
 | 3525 |     if (IsLogicalOperator && | 
 | 3526 |         isa<StringLiteral>(ChildExpr->IgnoreParenImpCasts())) | 
 | 3527 |       // Ignore checking string literals that are in logical operators. | 
 | 3528 |       continue; | 
 | 3529 |     AnalyzeImplicitConversions(S, ChildExpr, CC); | 
 | 3530 |   } | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3531 | } | 
 | 3532 |  | 
 | 3533 | } // end anonymous namespace | 
 | 3534 |  | 
 | 3535 | /// Diagnoses "dangerous" implicit conversions within the given | 
 | 3536 | /// expression (which is a full expression).  Implements -Wconversion | 
 | 3537 | /// and -Wsign-compare. | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3538 | /// | 
 | 3539 | /// \param CC the "context" location of the implicit conversion, i.e. | 
 | 3540 | ///   the most location of the syntactic entity requiring the implicit | 
 | 3541 | ///   conversion | 
 | 3542 | void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) { | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3543 |   // Don't diagnose in unevaluated contexts. | 
 | 3544 |   if (ExprEvalContexts.back().Context == Sema::Unevaluated) | 
 | 3545 |     return; | 
 | 3546 |  | 
 | 3547 |   // Don't diagnose for value- or type-dependent expressions. | 
 | 3548 |   if (E->isTypeDependent() || E->isValueDependent()) | 
 | 3549 |     return; | 
 | 3550 |  | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3551 |   // Check for array bounds violations in cases where the check isn't triggered | 
 | 3552 |   // elsewhere for other Expr types (like BinaryOperators), e.g. when an | 
 | 3553 |   // ArraySubscriptExpr is on the RHS of a variable initialization. | 
 | 3554 |   CheckArrayAccess(E); | 
 | 3555 |  | 
| John McCall | b4eb64d | 2010-10-08 02:01:28 +0000 | [diff] [blame] | 3556 |   // This is not the right CC for (e.g.) a variable initialization. | 
 | 3557 |   AnalyzeImplicitConversions(*this, E, CC); | 
| John McCall | 323ed74 | 2010-05-06 08:58:33 +0000 | [diff] [blame] | 3558 | } | 
 | 3559 |  | 
| John McCall | 15d7d12 | 2010-11-11 03:21:53 +0000 | [diff] [blame] | 3560 | void Sema::CheckBitFieldInitialization(SourceLocation InitLoc, | 
 | 3561 |                                        FieldDecl *BitField, | 
 | 3562 |                                        Expr *Init) { | 
 | 3563 |   (void) AnalyzeBitFieldAssignment(*this, BitField, Init, InitLoc); | 
 | 3564 | } | 
 | 3565 |  | 
| Mike Stump | f8c4921 | 2010-01-21 03:59:47 +0000 | [diff] [blame] | 3566 | /// CheckParmsForFunctionDef - Check that the parameters of the given | 
 | 3567 | /// function are appropriate for the definition of a function. This | 
 | 3568 | /// takes care of any checks that cannot be performed on the | 
 | 3569 | /// declaration itself, e.g., that the types of each of the function | 
 | 3570 | /// parameters are complete. | 
| Douglas Gregor | 82aa713 | 2010-11-01 18:37:59 +0000 | [diff] [blame] | 3571 | bool Sema::CheckParmsForFunctionDef(ParmVarDecl **P, ParmVarDecl **PEnd, | 
 | 3572 |                                     bool CheckParameterNames) { | 
| Mike Stump | f8c4921 | 2010-01-21 03:59:47 +0000 | [diff] [blame] | 3573 |   bool HasInvalidParm = false; | 
| Douglas Gregor | 82aa713 | 2010-11-01 18:37:59 +0000 | [diff] [blame] | 3574 |   for (; P != PEnd; ++P) { | 
 | 3575 |     ParmVarDecl *Param = *P; | 
 | 3576 |      | 
| Mike Stump | f8c4921 | 2010-01-21 03:59:47 +0000 | [diff] [blame] | 3577 |     // C99 6.7.5.3p4: the parameters in a parameter type list in a | 
 | 3578 |     // function declarator that is part of a function definition of | 
 | 3579 |     // that function shall not have incomplete type. | 
 | 3580 |     // | 
 | 3581 |     // This is also C++ [dcl.fct]p6. | 
 | 3582 |     if (!Param->isInvalidDecl() && | 
 | 3583 |         RequireCompleteType(Param->getLocation(), Param->getType(), | 
 | 3584 |                                diag::err_typecheck_decl_incomplete_type)) { | 
 | 3585 |       Param->setInvalidDecl(); | 
 | 3586 |       HasInvalidParm = true; | 
 | 3587 |     } | 
 | 3588 |  | 
 | 3589 |     // C99 6.9.1p5: If the declarator includes a parameter type list, the | 
 | 3590 |     // declaration of each parameter shall include an identifier. | 
| Douglas Gregor | 82aa713 | 2010-11-01 18:37:59 +0000 | [diff] [blame] | 3591 |     if (CheckParameterNames && | 
 | 3592 |         Param->getIdentifier() == 0 && | 
| Mike Stump | f8c4921 | 2010-01-21 03:59:47 +0000 | [diff] [blame] | 3593 |         !Param->isImplicit() && | 
 | 3594 |         !getLangOptions().CPlusPlus) | 
 | 3595 |       Diag(Param->getLocation(), diag::err_parameter_name_omitted); | 
| Sam Weinig | d17e340 | 2010-02-01 05:02:49 +0000 | [diff] [blame] | 3596 |  | 
 | 3597 |     // C99 6.7.5.3p12: | 
 | 3598 |     //   If the function declarator is not part of a definition of that | 
 | 3599 |     //   function, parameters may have incomplete type and may use the [*] | 
 | 3600 |     //   notation in their sequences of declarator specifiers to specify | 
 | 3601 |     //   variable length array types. | 
 | 3602 |     QualType PType = Param->getOriginalType(); | 
 | 3603 |     if (const ArrayType *AT = Context.getAsArrayType(PType)) { | 
 | 3604 |       if (AT->getSizeModifier() == ArrayType::Star) { | 
 | 3605 |         // FIXME: This diagnosic should point the the '[*]' if source-location | 
 | 3606 |         // information is added for it. | 
 | 3607 |         Diag(Param->getLocation(), diag::err_array_star_in_function_definition); | 
 | 3608 |       } | 
 | 3609 |     } | 
| Mike Stump | f8c4921 | 2010-01-21 03:59:47 +0000 | [diff] [blame] | 3610 |   } | 
 | 3611 |  | 
 | 3612 |   return HasInvalidParm; | 
 | 3613 | } | 
| John McCall | b7f4ffe | 2010-08-12 21:44:57 +0000 | [diff] [blame] | 3614 |  | 
 | 3615 | /// CheckCastAlign - Implements -Wcast-align, which warns when a | 
 | 3616 | /// pointer cast increases the alignment requirements. | 
 | 3617 | void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) { | 
 | 3618 |   // This is actually a lot of work to potentially be doing on every | 
 | 3619 |   // cast; don't do it if we're ignoring -Wcast_align (as is the default). | 
| Argyrios Kyrtzidis | 0827408 | 2010-12-15 18:44:22 +0000 | [diff] [blame] | 3620 |   if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align, | 
 | 3621 |                                           TRange.getBegin()) | 
| David Blaikie | d6471f7 | 2011-09-25 23:23:43 +0000 | [diff] [blame] | 3622 |         == DiagnosticsEngine::Ignored) | 
| John McCall | b7f4ffe | 2010-08-12 21:44:57 +0000 | [diff] [blame] | 3623 |     return; | 
 | 3624 |  | 
 | 3625 |   // Ignore dependent types. | 
 | 3626 |   if (T->isDependentType() || Op->getType()->isDependentType()) | 
 | 3627 |     return; | 
 | 3628 |  | 
 | 3629 |   // Require that the destination be a pointer type. | 
 | 3630 |   const PointerType *DestPtr = T->getAs<PointerType>(); | 
 | 3631 |   if (!DestPtr) return; | 
 | 3632 |  | 
 | 3633 |   // If the destination has alignment 1, we're done. | 
 | 3634 |   QualType DestPointee = DestPtr->getPointeeType(); | 
 | 3635 |   if (DestPointee->isIncompleteType()) return; | 
 | 3636 |   CharUnits DestAlign = Context.getTypeAlignInChars(DestPointee); | 
 | 3637 |   if (DestAlign.isOne()) return; | 
 | 3638 |  | 
 | 3639 |   // Require that the source be a pointer type. | 
 | 3640 |   const PointerType *SrcPtr = Op->getType()->getAs<PointerType>(); | 
 | 3641 |   if (!SrcPtr) return; | 
 | 3642 |   QualType SrcPointee = SrcPtr->getPointeeType(); | 
 | 3643 |  | 
 | 3644 |   // Whitelist casts from cv void*.  We already implicitly | 
 | 3645 |   // whitelisted casts to cv void*, since they have alignment 1. | 
 | 3646 |   // Also whitelist casts involving incomplete types, which implicitly | 
 | 3647 |   // includes 'void'. | 
 | 3648 |   if (SrcPointee->isIncompleteType()) return; | 
 | 3649 |  | 
 | 3650 |   CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee); | 
 | 3651 |   if (SrcAlign >= DestAlign) return; | 
 | 3652 |  | 
 | 3653 |   Diag(TRange.getBegin(), diag::warn_cast_align) | 
 | 3654 |     << Op->getType() << T | 
 | 3655 |     << static_cast<unsigned>(SrcAlign.getQuantity()) | 
 | 3656 |     << static_cast<unsigned>(DestAlign.getQuantity()) | 
 | 3657 |     << TRange << Op->getSourceRange(); | 
 | 3658 | } | 
 | 3659 |  | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3660 | static const Type* getElementType(const Expr *BaseExpr) { | 
 | 3661 |   const Type* EltType = BaseExpr->getType().getTypePtr(); | 
 | 3662 |   if (EltType->isAnyPointerType()) | 
 | 3663 |     return EltType->getPointeeType().getTypePtr(); | 
 | 3664 |   else if (EltType->isArrayType()) | 
 | 3665 |     return EltType->getBaseElementTypeUnsafe(); | 
 | 3666 |   return EltType; | 
 | 3667 | } | 
 | 3668 |  | 
| Chandler Carruth | c268434 | 2011-08-05 09:10:50 +0000 | [diff] [blame] | 3669 | /// \brief Check whether this array fits the idiom of a size-one tail padded | 
 | 3670 | /// array member of a struct. | 
 | 3671 | /// | 
 | 3672 | /// We avoid emitting out-of-bounds access warnings for such arrays as they are | 
 | 3673 | /// commonly used to emulate flexible arrays in C89 code. | 
 | 3674 | static bool IsTailPaddedMemberArray(Sema &S, llvm::APInt Size, | 
 | 3675 |                                     const NamedDecl *ND) { | 
 | 3676 |   if (Size != 1 || !ND) return false; | 
 | 3677 |  | 
 | 3678 |   const FieldDecl *FD = dyn_cast<FieldDecl>(ND); | 
 | 3679 |   if (!FD) return false; | 
 | 3680 |  | 
 | 3681 |   // Don't consider sizes resulting from macro expansions or template argument | 
 | 3682 |   // substitution to form C89 tail-padded arrays. | 
 | 3683 |   ConstantArrayTypeLoc TL = | 
 | 3684 |     cast<ConstantArrayTypeLoc>(FD->getTypeSourceInfo()->getTypeLoc()); | 
 | 3685 |   const Expr *SizeExpr = dyn_cast<IntegerLiteral>(TL.getSizeExpr()); | 
 | 3686 |   if (!SizeExpr || SizeExpr->getExprLoc().isMacroID()) | 
 | 3687 |     return false; | 
 | 3688 |  | 
 | 3689 |   const RecordDecl *RD = dyn_cast<RecordDecl>(FD->getDeclContext()); | 
 | 3690 |   if (!RD || !RD->isStruct()) | 
 | 3691 |     return false; | 
 | 3692 |  | 
| Benjamin Kramer | 22d4fed | 2011-08-06 03:04:42 +0000 | [diff] [blame] | 3693 |   // See if this is the last field decl in the record. | 
 | 3694 |   const Decl *D = FD; | 
 | 3695 |   while ((D = D->getNextDeclInContext())) | 
 | 3696 |     if (isa<FieldDecl>(D)) | 
 | 3697 |       return false; | 
 | 3698 |   return true; | 
| Chandler Carruth | c268434 | 2011-08-05 09:10:50 +0000 | [diff] [blame] | 3699 | } | 
 | 3700 |  | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3701 | void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, | 
 | 3702 |                             bool isSubscript, bool AllowOnePastEnd) { | 
 | 3703 |   const Type* EffectiveType = getElementType(BaseExpr); | 
 | 3704 |   BaseExpr = BaseExpr->IgnoreParenCasts(); | 
 | 3705 |   IndexExpr = IndexExpr->IgnoreParenCasts(); | 
 | 3706 |  | 
| Chandler Carruth | 3406458 | 2011-02-17 20:55:08 +0000 | [diff] [blame] | 3707 |   const ConstantArrayType *ArrayTy = | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3708 |     Context.getAsConstantArrayType(BaseExpr->getType()); | 
| Chandler Carruth | 3406458 | 2011-02-17 20:55:08 +0000 | [diff] [blame] | 3709 |   if (!ArrayTy) | 
| Ted Kremenek | a0125d8 | 2011-02-16 01:57:07 +0000 | [diff] [blame] | 3710 |     return; | 
| Chandler Carruth | 35001ca | 2011-02-17 21:10:52 +0000 | [diff] [blame] | 3711 |  | 
| Chandler Carruth | 3406458 | 2011-02-17 20:55:08 +0000 | [diff] [blame] | 3712 |   if (IndexExpr->isValueDependent()) | 
| Ted Kremenek | a0125d8 | 2011-02-16 01:57:07 +0000 | [diff] [blame] | 3713 |     return; | 
| Chandler Carruth | 3406458 | 2011-02-17 20:55:08 +0000 | [diff] [blame] | 3714 |   llvm::APSInt index; | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3715 |   if (!IndexExpr->isIntegerConstantExpr(index, Context)) | 
| Ted Kremenek | a0125d8 | 2011-02-16 01:57:07 +0000 | [diff] [blame] | 3716 |     return; | 
| Ted Kremenek | 8fd0a5d | 2011-02-16 04:01:44 +0000 | [diff] [blame] | 3717 |  | 
| Chandler Carruth | ba44712 | 2011-08-05 08:07:29 +0000 | [diff] [blame] | 3718 |   const NamedDecl *ND = NULL; | 
| Chandler Carruth | ba44712 | 2011-08-05 08:07:29 +0000 | [diff] [blame] | 3719 |   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr)) | 
 | 3720 |     ND = dyn_cast<NamedDecl>(DRE->getDecl()); | 
| Chandler Carruth | c268434 | 2011-08-05 09:10:50 +0000 | [diff] [blame] | 3721 |   if (const MemberExpr *ME = dyn_cast<MemberExpr>(BaseExpr)) | 
| Chandler Carruth | ba44712 | 2011-08-05 08:07:29 +0000 | [diff] [blame] | 3722 |     ND = dyn_cast<NamedDecl>(ME->getMemberDecl()); | 
| Chandler Carruth | ba44712 | 2011-08-05 08:07:29 +0000 | [diff] [blame] | 3723 |  | 
| Ted Kremenek | 9e060ca | 2011-02-23 23:06:04 +0000 | [diff] [blame] | 3724 |   if (index.isUnsigned() || !index.isNegative()) { | 
| Ted Kremenek | 25b3b84 | 2011-02-18 02:27:00 +0000 | [diff] [blame] | 3725 |     llvm::APInt size = ArrayTy->getSize(); | 
| Chandler Carruth | 35001ca | 2011-02-17 21:10:52 +0000 | [diff] [blame] | 3726 |     if (!size.isStrictlyPositive()) | 
 | 3727 |       return; | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3728 |  | 
 | 3729 |     const Type* BaseType = getElementType(BaseExpr); | 
| Nico Weber | de5998f | 2011-09-17 22:59:41 +0000 | [diff] [blame] | 3730 |     if (BaseType != EffectiveType) { | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3731 |       // Make sure we're comparing apples to apples when comparing index to size | 
 | 3732 |       uint64_t ptrarith_typesize = Context.getTypeSize(EffectiveType); | 
 | 3733 |       uint64_t array_typesize = Context.getTypeSize(BaseType); | 
| Kaelyn Uhrain | d10f4bc | 2011-08-10 19:47:25 +0000 | [diff] [blame] | 3734 |       // Handle ptrarith_typesize being zero, such as when casting to void* | 
| Kaelyn Uhrain | 18f1697 | 2011-08-10 18:49:28 +0000 | [diff] [blame] | 3735 |       if (!ptrarith_typesize) ptrarith_typesize = 1; | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3736 |       if (ptrarith_typesize != array_typesize) { | 
 | 3737 |         // There's a cast to a different size type involved | 
 | 3738 |         uint64_t ratio = array_typesize / ptrarith_typesize; | 
 | 3739 |         // TODO: Be smarter about handling cases where array_typesize is not a | 
 | 3740 |         // multiple of ptrarith_typesize | 
 | 3741 |         if (ptrarith_typesize * ratio == array_typesize) | 
 | 3742 |           size *= llvm::APInt(size.getBitWidth(), ratio); | 
 | 3743 |       } | 
 | 3744 |     } | 
 | 3745 |  | 
| Chandler Carruth | 3406458 | 2011-02-17 20:55:08 +0000 | [diff] [blame] | 3746 |     if (size.getBitWidth() > index.getBitWidth()) | 
 | 3747 |       index = index.sext(size.getBitWidth()); | 
| Ted Kremenek | 25b3b84 | 2011-02-18 02:27:00 +0000 | [diff] [blame] | 3748 |     else if (size.getBitWidth() < index.getBitWidth()) | 
 | 3749 |       size = size.sext(index.getBitWidth()); | 
 | 3750 |  | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3751 |     // For array subscripting the index must be less than size, but for pointer | 
 | 3752 |     // arithmetic also allow the index (offset) to be equal to size since | 
 | 3753 |     // computing the next address after the end of the array is legal and | 
 | 3754 |     // commonly done e.g. in C++ iterators and range-based for loops. | 
 | 3755 |     if (AllowOnePastEnd ? index.sle(size) : index.slt(size)) | 
| Chandler Carruth | ba44712 | 2011-08-05 08:07:29 +0000 | [diff] [blame] | 3756 |       return; | 
 | 3757 |  | 
 | 3758 |     // Also don't warn for arrays of size 1 which are members of some | 
 | 3759 |     // structure. These are often used to approximate flexible arrays in C89 | 
 | 3760 |     // code. | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3761 |     if (IsTailPaddedMemberArray(*this, size, ND)) | 
| Ted Kremenek | 8fd0a5d | 2011-02-16 04:01:44 +0000 | [diff] [blame] | 3762 |       return; | 
| Chandler Carruth | 3406458 | 2011-02-17 20:55:08 +0000 | [diff] [blame] | 3763 |  | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3764 |     unsigned DiagID = diag::warn_ptr_arith_exceeds_bounds; | 
 | 3765 |     if (isSubscript) | 
 | 3766 |       DiagID = diag::warn_array_index_exceeds_bounds; | 
 | 3767 |  | 
 | 3768 |     DiagRuntimeBehavior(BaseExpr->getLocStart(), BaseExpr, | 
 | 3769 |                         PDiag(DiagID) << index.toString(10, true) | 
 | 3770 |                           << size.toString(10, true) | 
 | 3771 |                           << (unsigned)size.getLimitedValue(~0U) | 
 | 3772 |                           << IndexExpr->getSourceRange()); | 
| Chandler Carruth | 3406458 | 2011-02-17 20:55:08 +0000 | [diff] [blame] | 3773 |   } else { | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3774 |     unsigned DiagID = diag::warn_array_index_precedes_bounds; | 
 | 3775 |     if (!isSubscript) { | 
 | 3776 |       DiagID = diag::warn_ptr_arith_precedes_bounds; | 
 | 3777 |       if (index.isNegative()) index = -index; | 
 | 3778 |     } | 
 | 3779 |  | 
 | 3780 |     DiagRuntimeBehavior(BaseExpr->getLocStart(), BaseExpr, | 
 | 3781 |                         PDiag(DiagID) << index.toString(10, true) | 
 | 3782 |                           << IndexExpr->getSourceRange()); | 
| Ted Kremenek | a0125d8 | 2011-02-16 01:57:07 +0000 | [diff] [blame] | 3783 |   } | 
| Chandler Carruth | 35001ca | 2011-02-17 21:10:52 +0000 | [diff] [blame] | 3784 |  | 
| Chandler Carruth | 35001ca | 2011-02-17 21:10:52 +0000 | [diff] [blame] | 3785 |   if (ND) | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3786 |     DiagRuntimeBehavior(ND->getLocStart(), BaseExpr, | 
 | 3787 |                         PDiag(diag::note_array_index_out_of_bounds) | 
 | 3788 |                           << ND->getDeclName()); | 
| Ted Kremenek | a0125d8 | 2011-02-16 01:57:07 +0000 | [diff] [blame] | 3789 | } | 
 | 3790 |  | 
| Ted Kremenek | 3aea4da | 2011-03-01 18:41:00 +0000 | [diff] [blame] | 3791 | void Sema::CheckArrayAccess(const Expr *expr) { | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3792 |   int AllowOnePastEnd = 0; | 
 | 3793 |   while (expr) { | 
 | 3794 |     expr = expr->IgnoreParenImpCasts(); | 
| Ted Kremenek | 3aea4da | 2011-03-01 18:41:00 +0000 | [diff] [blame] | 3795 |     switch (expr->getStmtClass()) { | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3796 |       case Stmt::ArraySubscriptExprClass: { | 
 | 3797 |         const ArraySubscriptExpr *ASE = cast<ArraySubscriptExpr>(expr); | 
 | 3798 |         CheckArrayAccess(ASE->getBase(), ASE->getIdx(), true, | 
 | 3799 |                          AllowOnePastEnd > 0); | 
| Ted Kremenek | 3aea4da | 2011-03-01 18:41:00 +0000 | [diff] [blame] | 3800 |         return; | 
| Kaelyn Uhrain | d6c8865 | 2011-08-05 23:18:04 +0000 | [diff] [blame] | 3801 |       } | 
 | 3802 |       case Stmt::UnaryOperatorClass: { | 
 | 3803 |         // Only unwrap the * and & unary operators | 
 | 3804 |         const UnaryOperator *UO = cast<UnaryOperator>(expr); | 
 | 3805 |         expr = UO->getSubExpr(); | 
 | 3806 |         switch (UO->getOpcode()) { | 
 | 3807 |           case UO_AddrOf: | 
 | 3808 |             AllowOnePastEnd++; | 
 | 3809 |             break; | 
 | 3810 |           case UO_Deref: | 
 | 3811 |             AllowOnePastEnd--; | 
 | 3812 |             break; | 
 | 3813 |           default: | 
 | 3814 |             return; | 
 | 3815 |         } | 
 | 3816 |         break; | 
 | 3817 |       } | 
| Ted Kremenek | 3aea4da | 2011-03-01 18:41:00 +0000 | [diff] [blame] | 3818 |       case Stmt::ConditionalOperatorClass: { | 
 | 3819 |         const ConditionalOperator *cond = cast<ConditionalOperator>(expr); | 
 | 3820 |         if (const Expr *lhs = cond->getLHS()) | 
 | 3821 |           CheckArrayAccess(lhs); | 
 | 3822 |         if (const Expr *rhs = cond->getRHS()) | 
 | 3823 |           CheckArrayAccess(rhs); | 
 | 3824 |         return; | 
 | 3825 |       } | 
 | 3826 |       default: | 
 | 3827 |         return; | 
 | 3828 |     } | 
| Peter Collingbourne | f111d93 | 2011-04-15 00:35:48 +0000 | [diff] [blame] | 3829 |   } | 
| Ted Kremenek | 3aea4da | 2011-03-01 18:41:00 +0000 | [diff] [blame] | 3830 | } | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 3831 |  | 
 | 3832 | //===--- CHECK: Objective-C retain cycles ----------------------------------// | 
 | 3833 |  | 
 | 3834 | namespace { | 
 | 3835 |   struct RetainCycleOwner { | 
 | 3836 |     RetainCycleOwner() : Variable(0), Indirect(false) {} | 
 | 3837 |     VarDecl *Variable; | 
 | 3838 |     SourceRange Range; | 
 | 3839 |     SourceLocation Loc; | 
 | 3840 |     bool Indirect; | 
 | 3841 |  | 
 | 3842 |     void setLocsFrom(Expr *e) { | 
 | 3843 |       Loc = e->getExprLoc(); | 
 | 3844 |       Range = e->getSourceRange(); | 
 | 3845 |     } | 
 | 3846 |   }; | 
 | 3847 | } | 
 | 3848 |  | 
 | 3849 | /// Consider whether capturing the given variable can possibly lead to | 
 | 3850 | /// a retain cycle. | 
 | 3851 | static bool considerVariable(VarDecl *var, Expr *ref, RetainCycleOwner &owner) { | 
 | 3852 |   // In ARC, it's captured strongly iff the variable has __strong | 
 | 3853 |   // lifetime.  In MRR, it's captured strongly if the variable is | 
 | 3854 |   // __block and has an appropriate type. | 
 | 3855 |   if (var->getType().getObjCLifetime() != Qualifiers::OCL_Strong) | 
 | 3856 |     return false; | 
 | 3857 |  | 
 | 3858 |   owner.Variable = var; | 
 | 3859 |   owner.setLocsFrom(ref); | 
 | 3860 |   return true; | 
 | 3861 | } | 
 | 3862 |  | 
 | 3863 | static bool findRetainCycleOwner(Expr *e, RetainCycleOwner &owner) { | 
 | 3864 |   while (true) { | 
 | 3865 |     e = e->IgnoreParens(); | 
 | 3866 |     if (CastExpr *cast = dyn_cast<CastExpr>(e)) { | 
 | 3867 |       switch (cast->getCastKind()) { | 
 | 3868 |       case CK_BitCast: | 
 | 3869 |       case CK_LValueBitCast: | 
 | 3870 |       case CK_LValueToRValue: | 
| John McCall | 33e56f3 | 2011-09-10 06:18:15 +0000 | [diff] [blame] | 3871 |       case CK_ARCReclaimReturnedObject: | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 3872 |         e = cast->getSubExpr(); | 
 | 3873 |         continue; | 
 | 3874 |  | 
 | 3875 |       case CK_GetObjCProperty: { | 
 | 3876 |         // Bail out if this isn't a strong explicit property. | 
 | 3877 |         const ObjCPropertyRefExpr *pre = cast->getSubExpr()->getObjCProperty(); | 
 | 3878 |         if (pre->isImplicitProperty()) return false; | 
 | 3879 |         ObjCPropertyDecl *property = pre->getExplicitProperty(); | 
| John McCall | 265941b | 2011-09-13 18:31:23 +0000 | [diff] [blame] | 3880 |         if (!property->isRetaining() && | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 3881 |             !(property->getPropertyIvarDecl() && | 
 | 3882 |               property->getPropertyIvarDecl()->getType() | 
 | 3883 |                 .getObjCLifetime() == Qualifiers::OCL_Strong)) | 
 | 3884 |           return false; | 
 | 3885 |  | 
 | 3886 |         owner.Indirect = true; | 
 | 3887 |         e = const_cast<Expr*>(pre->getBase()); | 
 | 3888 |         continue; | 
 | 3889 |       } | 
 | 3890 |          | 
 | 3891 |       default: | 
 | 3892 |         return false; | 
 | 3893 |       } | 
 | 3894 |     } | 
 | 3895 |  | 
 | 3896 |     if (ObjCIvarRefExpr *ref = dyn_cast<ObjCIvarRefExpr>(e)) { | 
 | 3897 |       ObjCIvarDecl *ivar = ref->getDecl(); | 
 | 3898 |       if (ivar->getType().getObjCLifetime() != Qualifiers::OCL_Strong) | 
 | 3899 |         return false; | 
 | 3900 |  | 
 | 3901 |       // Try to find a retain cycle in the base. | 
 | 3902 |       if (!findRetainCycleOwner(ref->getBase(), owner)) | 
 | 3903 |         return false; | 
 | 3904 |  | 
 | 3905 |       if (ref->isFreeIvar()) owner.setLocsFrom(ref); | 
 | 3906 |       owner.Indirect = true; | 
 | 3907 |       return true; | 
 | 3908 |     } | 
 | 3909 |  | 
 | 3910 |     if (DeclRefExpr *ref = dyn_cast<DeclRefExpr>(e)) { | 
 | 3911 |       VarDecl *var = dyn_cast<VarDecl>(ref->getDecl()); | 
 | 3912 |       if (!var) return false; | 
 | 3913 |       return considerVariable(var, ref, owner); | 
 | 3914 |     } | 
 | 3915 |  | 
 | 3916 |     if (BlockDeclRefExpr *ref = dyn_cast<BlockDeclRefExpr>(e)) { | 
 | 3917 |       owner.Variable = ref->getDecl(); | 
 | 3918 |       owner.setLocsFrom(ref); | 
 | 3919 |       return true; | 
 | 3920 |     } | 
 | 3921 |  | 
 | 3922 |     if (MemberExpr *member = dyn_cast<MemberExpr>(e)) { | 
 | 3923 |       if (member->isArrow()) return false; | 
 | 3924 |  | 
 | 3925 |       // Don't count this as an indirect ownership. | 
 | 3926 |       e = member->getBase(); | 
 | 3927 |       continue; | 
 | 3928 |     } | 
 | 3929 |  | 
 | 3930 |     // Array ivars? | 
 | 3931 |  | 
 | 3932 |     return false; | 
 | 3933 |   } | 
 | 3934 | } | 
 | 3935 |  | 
 | 3936 | namespace { | 
 | 3937 |   struct FindCaptureVisitor : EvaluatedExprVisitor<FindCaptureVisitor> { | 
 | 3938 |     FindCaptureVisitor(ASTContext &Context, VarDecl *variable) | 
 | 3939 |       : EvaluatedExprVisitor<FindCaptureVisitor>(Context), | 
 | 3940 |         Variable(variable), Capturer(0) {} | 
 | 3941 |  | 
 | 3942 |     VarDecl *Variable; | 
 | 3943 |     Expr *Capturer; | 
 | 3944 |  | 
 | 3945 |     void VisitDeclRefExpr(DeclRefExpr *ref) { | 
 | 3946 |       if (ref->getDecl() == Variable && !Capturer) | 
 | 3947 |         Capturer = ref; | 
 | 3948 |     } | 
 | 3949 |  | 
 | 3950 |     void VisitBlockDeclRefExpr(BlockDeclRefExpr *ref) { | 
 | 3951 |       if (ref->getDecl() == Variable && !Capturer) | 
 | 3952 |         Capturer = ref; | 
 | 3953 |     } | 
 | 3954 |  | 
 | 3955 |     void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) { | 
 | 3956 |       if (Capturer) return; | 
 | 3957 |       Visit(ref->getBase()); | 
 | 3958 |       if (Capturer && ref->isFreeIvar()) | 
 | 3959 |         Capturer = ref; | 
 | 3960 |     } | 
 | 3961 |  | 
 | 3962 |     void VisitBlockExpr(BlockExpr *block) { | 
 | 3963 |       // Look inside nested blocks  | 
 | 3964 |       if (block->getBlockDecl()->capturesVariable(Variable)) | 
 | 3965 |         Visit(block->getBlockDecl()->getBody()); | 
 | 3966 |     } | 
 | 3967 |   }; | 
 | 3968 | } | 
 | 3969 |  | 
 | 3970 | /// Check whether the given argument is a block which captures a | 
 | 3971 | /// variable. | 
 | 3972 | static Expr *findCapturingExpr(Sema &S, Expr *e, RetainCycleOwner &owner) { | 
 | 3973 |   assert(owner.Variable && owner.Loc.isValid()); | 
 | 3974 |  | 
 | 3975 |   e = e->IgnoreParenCasts(); | 
 | 3976 |   BlockExpr *block = dyn_cast<BlockExpr>(e); | 
 | 3977 |   if (!block || !block->getBlockDecl()->capturesVariable(owner.Variable)) | 
 | 3978 |     return 0; | 
 | 3979 |  | 
 | 3980 |   FindCaptureVisitor visitor(S.Context, owner.Variable); | 
 | 3981 |   visitor.Visit(block->getBlockDecl()->getBody()); | 
 | 3982 |   return visitor.Capturer; | 
 | 3983 | } | 
 | 3984 |  | 
 | 3985 | static void diagnoseRetainCycle(Sema &S, Expr *capturer, | 
 | 3986 |                                 RetainCycleOwner &owner) { | 
 | 3987 |   assert(capturer); | 
 | 3988 |   assert(owner.Variable && owner.Loc.isValid()); | 
 | 3989 |  | 
 | 3990 |   S.Diag(capturer->getExprLoc(), diag::warn_arc_retain_cycle) | 
 | 3991 |     << owner.Variable << capturer->getSourceRange(); | 
 | 3992 |   S.Diag(owner.Loc, diag::note_arc_retain_cycle_owner) | 
 | 3993 |     << owner.Indirect << owner.Range; | 
 | 3994 | } | 
 | 3995 |  | 
 | 3996 | /// Check for a keyword selector that starts with the word 'add' or | 
 | 3997 | /// 'set'. | 
 | 3998 | static bool isSetterLikeSelector(Selector sel) { | 
 | 3999 |   if (sel.isUnarySelector()) return false; | 
 | 4000 |  | 
| Chris Lattner | 5f9e272 | 2011-07-23 10:55:15 +0000 | [diff] [blame] | 4001 |   StringRef str = sel.getNameForSlot(0); | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4002 |   while (!str.empty() && str.front() == '_') str = str.substr(1); | 
 | 4003 |   if (str.startswith("set") || str.startswith("add")) | 
 | 4004 |     str = str.substr(3); | 
 | 4005 |   else | 
 | 4006 |     return false; | 
 | 4007 |  | 
 | 4008 |   if (str.empty()) return true; | 
 | 4009 |   return !islower(str.front()); | 
 | 4010 | } | 
 | 4011 |  | 
 | 4012 | /// Check a message send to see if it's likely to cause a retain cycle. | 
 | 4013 | void Sema::checkRetainCycles(ObjCMessageExpr *msg) { | 
 | 4014 |   // Only check instance methods whose selector looks like a setter. | 
 | 4015 |   if (!msg->isInstanceMessage() || !isSetterLikeSelector(msg->getSelector())) | 
 | 4016 |     return; | 
 | 4017 |  | 
 | 4018 |   // Try to find a variable that the receiver is strongly owned by. | 
 | 4019 |   RetainCycleOwner owner; | 
 | 4020 |   if (msg->getReceiverKind() == ObjCMessageExpr::Instance) { | 
 | 4021 |     if (!findRetainCycleOwner(msg->getInstanceReceiver(), owner)) | 
 | 4022 |       return; | 
 | 4023 |   } else { | 
 | 4024 |     assert(msg->getReceiverKind() == ObjCMessageExpr::SuperInstance); | 
 | 4025 |     owner.Variable = getCurMethodDecl()->getSelfDecl(); | 
 | 4026 |     owner.Loc = msg->getSuperLoc(); | 
 | 4027 |     owner.Range = msg->getSuperLoc(); | 
 | 4028 |   } | 
 | 4029 |  | 
 | 4030 |   // Check whether the receiver is captured by any of the arguments. | 
 | 4031 |   for (unsigned i = 0, e = msg->getNumArgs(); i != e; ++i) | 
 | 4032 |     if (Expr *capturer = findCapturingExpr(*this, msg->getArg(i), owner)) | 
 | 4033 |       return diagnoseRetainCycle(*this, capturer, owner); | 
 | 4034 | } | 
 | 4035 |  | 
 | 4036 | /// Check a property assign to see if it's likely to cause a retain cycle. | 
 | 4037 | void Sema::checkRetainCycles(Expr *receiver, Expr *argument) { | 
 | 4038 |   RetainCycleOwner owner; | 
 | 4039 |   if (!findRetainCycleOwner(receiver, owner)) | 
 | 4040 |     return; | 
 | 4041 |  | 
 | 4042 |   if (Expr *capturer = findCapturingExpr(*this, argument, owner)) | 
 | 4043 |     diagnoseRetainCycle(*this, capturer, owner); | 
 | 4044 | } | 
 | 4045 |  | 
| Fariborz Jahanian | 921c143 | 2011-06-24 18:25:34 +0000 | [diff] [blame] | 4046 | bool Sema::checkUnsafeAssigns(SourceLocation Loc, | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4047 |                               QualType LHS, Expr *RHS) { | 
 | 4048 |   Qualifiers::ObjCLifetime LT = LHS.getObjCLifetime(); | 
 | 4049 |   if (LT != Qualifiers::OCL_Weak && LT != Qualifiers::OCL_ExplicitNone) | 
| Fariborz Jahanian | 921c143 | 2011-06-24 18:25:34 +0000 | [diff] [blame] | 4050 |     return false; | 
 | 4051 |   // strip off any implicit cast added to get to the one arc-specific | 
 | 4052 |   while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) { | 
| John McCall | 33e56f3 | 2011-09-10 06:18:15 +0000 | [diff] [blame] | 4053 |     if (cast->getCastKind() == CK_ARCConsumeObject) { | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4054 |       Diag(Loc, diag::warn_arc_retained_assign) | 
 | 4055 |         << (LT == Qualifiers::OCL_ExplicitNone)  | 
 | 4056 |         << RHS->getSourceRange(); | 
| Fariborz Jahanian | 921c143 | 2011-06-24 18:25:34 +0000 | [diff] [blame] | 4057 |       return true; | 
 | 4058 |     } | 
 | 4059 |     RHS = cast->getSubExpr(); | 
 | 4060 |   } | 
 | 4061 |   return false; | 
| John McCall | f85e193 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 4062 | } | 
 | 4063 |  | 
| Fariborz Jahanian | 921c143 | 2011-06-24 18:25:34 +0000 | [diff] [blame] | 4064 | void Sema::checkUnsafeExprAssigns(SourceLocation Loc, | 
 | 4065 |                               Expr *LHS, Expr *RHS) { | 
 | 4066 |   QualType LHSType = LHS->getType(); | 
 | 4067 |   if (checkUnsafeAssigns(Loc, LHSType, RHS)) | 
 | 4068 |     return; | 
 | 4069 |   Qualifiers::ObjCLifetime LT = LHSType.getObjCLifetime(); | 
 | 4070 |   // FIXME. Check for other life times. | 
 | 4071 |   if (LT != Qualifiers::OCL_None) | 
 | 4072 |     return; | 
 | 4073 |    | 
 | 4074 |   if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(LHS)) { | 
 | 4075 |     if (PRE->isImplicitProperty()) | 
 | 4076 |       return; | 
 | 4077 |     const ObjCPropertyDecl *PD = PRE->getExplicitProperty(); | 
 | 4078 |     if (!PD) | 
 | 4079 |       return; | 
 | 4080 |      | 
 | 4081 |     unsigned Attributes = PD->getPropertyAttributes(); | 
 | 4082 |     if (Attributes & ObjCPropertyDecl::OBJC_PR_assign) | 
 | 4083 |       while (ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(RHS)) { | 
| John McCall | 33e56f3 | 2011-09-10 06:18:15 +0000 | [diff] [blame] | 4084 |         if (cast->getCastKind() == CK_ARCConsumeObject) { | 
| Fariborz Jahanian | 921c143 | 2011-06-24 18:25:34 +0000 | [diff] [blame] | 4085 |           Diag(Loc, diag::warn_arc_retained_property_assign) | 
 | 4086 |           << RHS->getSourceRange(); | 
 | 4087 |           return; | 
 | 4088 |         } | 
 | 4089 |         RHS = cast->getSubExpr(); | 
 | 4090 |       } | 
 | 4091 |   } | 
 | 4092 | } |