xref: /llvm-project/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (revision eeff1a970a6bb09d3c046313e229e2871929cd63)
1 //===--- CallAndMessageChecker.cpp ------------------------------*- C++ -*--==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This defines CallAndMessageChecker, a builtin checker that checks for various
10 // errors of call and objc message expressions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/ExprCXX.h"
15 #include "clang/AST/ParentMap.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
18 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
19 #include "clang/StaticAnalyzer/Core/Checker.h"
20 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
21 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
22 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/raw_ostream.h"
27 
28 using namespace clang;
29 using namespace ento;
30 
31 namespace {
32 
33 class CallAndMessageChecker
34     : public Checker<check::PreObjCMessage, check::ObjCMessageNil,
35                      check::PreCall> {
36   mutable std::unique_ptr<BugType> BT_call_null;
37   mutable std::unique_ptr<BugType> BT_call_undef;
38   mutable std::unique_ptr<BugType> BT_cxx_call_null;
39   mutable std::unique_ptr<BugType> BT_cxx_call_undef;
40   mutable std::unique_ptr<BugType> BT_call_arg;
41   mutable std::unique_ptr<BugType> BT_cxx_delete_undef;
42   mutable std::unique_ptr<BugType> BT_msg_undef;
43   mutable std::unique_ptr<BugType> BT_objc_prop_undef;
44   mutable std::unique_ptr<BugType> BT_objc_subscript_undef;
45   mutable std::unique_ptr<BugType> BT_msg_arg;
46   mutable std::unique_ptr<BugType> BT_msg_ret;
47   mutable std::unique_ptr<BugType> BT_call_few_args;
48 
49 public:
50   enum CheckKind { CK_CallAndMessageUnInitRefArg, CK_NumCheckKinds };
51 
52   DefaultBool ChecksEnabled[CK_NumCheckKinds];
53 
54   void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
55 
56   /// Fill in the return value that results from messaging nil based on the
57   /// return type and architecture and diagnose if the return value will be
58   /// garbage.
59   void checkObjCMessageNil(const ObjCMethodCall &msg, CheckerContext &C) const;
60 
61   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
62 
63   ProgramStateRef checkFunctionPointerCall(const CallExpr *CE,
64                                            CheckerContext &C,
65                                            ProgramStateRef State) const;
66 
67   ProgramStateRef checkCXXMethodCall(const CXXInstanceCall *CC,
68                                      CheckerContext &C,
69                                      ProgramStateRef State) const;
70 
71   ProgramStateRef checkParameterCount(const CallEvent &Call, CheckerContext &C,
72                                       ProgramStateRef State) const;
73 
74   ProgramStateRef checkCXXDeallocation(const CXXDeallocatorCall *DC,
75                                        CheckerContext &C,
76                                        ProgramStateRef State) const;
77 
78   ProgramStateRef checkArgInitializedness(const CallEvent &Call,
79                                           CheckerContext &C,
80                                           ProgramStateRef State) const;
81 
82 private:
83   bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange,
84                           const Expr *ArgEx, int ArgumentNumber,
85                           bool CheckUninitFields, const CallEvent &Call,
86                           std::unique_ptr<BugType> &BT,
87                           const ParmVarDecl *ParamDecl) const;
88 
89   static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
90   void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
91                           ExplodedNode *N) const;
92 
93   void HandleNilReceiver(CheckerContext &C,
94                          ProgramStateRef state,
95                          const ObjCMethodCall &msg) const;
96 
97   void LazyInit_BT(const char *desc, std::unique_ptr<BugType> &BT) const {
98     if (!BT)
99       BT.reset(new BuiltinBug(this, desc));
100   }
101   bool uninitRefOrPointer(CheckerContext &C, const SVal &V,
102                           SourceRange ArgRange, const Expr *ArgEx,
103                           std::unique_ptr<BugType> &BT,
104                           const ParmVarDecl *ParamDecl, const char *BD,
105                           int ArgumentNumber) const;
106 };
107 } // end anonymous namespace
108 
109 void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
110                                         const Expr *BadE) {
111   ExplodedNode *N = C.generateErrorNode();
112   if (!N)
113     return;
114 
115   auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
116   if (BadE) {
117     R->addRange(BadE->getSourceRange());
118     if (BadE->isGLValue())
119       BadE = bugreporter::getDerefExpr(BadE);
120     bugreporter::trackExpressionValue(N, BadE, *R);
121   }
122   C.emitReport(std::move(R));
123 }
124 
125 static void describeUninitializedArgumentInCall(const CallEvent &Call,
126                                                 int ArgumentNumber,
127                                                 llvm::raw_svector_ostream &Os) {
128   switch (Call.getKind()) {
129   case CE_ObjCMessage: {
130     const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
131     switch (Msg.getMessageKind()) {
132     case OCM_Message:
133       Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
134          << " argument in message expression is an uninitialized value";
135       return;
136     case OCM_PropertyAccess:
137       assert(Msg.isSetter() && "Getters have no args");
138       Os << "Argument for property setter is an uninitialized value";
139       return;
140     case OCM_Subscript:
141       if (Msg.isSetter() && (ArgumentNumber == 0))
142         Os << "Argument for subscript setter is an uninitialized value";
143       else
144         Os << "Subscript index is an uninitialized value";
145       return;
146     }
147     llvm_unreachable("Unknown message kind.");
148   }
149   case CE_Block:
150     Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
151        << " block call argument is an uninitialized value";
152     return;
153   default:
154     Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
155        << " function call argument is an uninitialized value";
156     return;
157   }
158 }
159 
160 bool CallAndMessageChecker::uninitRefOrPointer(
161     CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx,
162     std::unique_ptr<BugType> &BT, const ParmVarDecl *ParamDecl, const char *BD,
163     int ArgumentNumber) const {
164   if (!ChecksEnabled[CK_CallAndMessageUnInitRefArg])
165     return false;
166 
167   // No parameter declaration available, i.e. variadic function argument.
168   if(!ParamDecl)
169     return false;
170 
171   // If parameter is declared as pointer to const in function declaration,
172   // then check if corresponding argument in function call is
173   // pointing to undefined symbol value (uninitialized memory).
174   SmallString<200> Buf;
175   llvm::raw_svector_ostream Os(Buf);
176 
177   if (ParamDecl->getType()->isPointerType()) {
178     Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
179        << " function call argument is a pointer to uninitialized value";
180   } else if (ParamDecl->getType()->isReferenceType()) {
181     Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
182        << " function call argument is an uninitialized value";
183   } else
184     return false;
185 
186   if(!ParamDecl->getType()->getPointeeType().isConstQualified())
187     return false;
188 
189   if (const MemRegion *SValMemRegion = V.getAsRegion()) {
190     const ProgramStateRef State = C.getState();
191     const SVal PSV = State->getSVal(SValMemRegion, C.getASTContext().CharTy);
192     if (PSV.isUndef()) {
193       if (ExplodedNode *N = C.generateErrorNode()) {
194         LazyInit_BT(BD, BT);
195         auto R = std::make_unique<PathSensitiveBugReport>(*BT, Os.str(), N);
196         R->addRange(ArgRange);
197         if (ArgEx)
198           bugreporter::trackExpressionValue(N, ArgEx, *R);
199 
200         C.emitReport(std::move(R));
201       }
202       return true;
203     }
204   }
205   return false;
206 }
207 
208 namespace {
209 class FindUninitializedField {
210 public:
211   SmallVector<const FieldDecl *, 10> FieldChain;
212 
213 private:
214   StoreManager &StoreMgr;
215   MemRegionManager &MrMgr;
216   Store store;
217 
218 public:
219   FindUninitializedField(StoreManager &storeMgr, MemRegionManager &mrMgr,
220                          Store s)
221       : StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}
222 
223   bool Find(const TypedValueRegion *R) {
224     QualType T = R->getValueType();
225     if (const RecordType *RT = T->getAsStructureType()) {
226       const RecordDecl *RD = RT->getDecl()->getDefinition();
227       assert(RD && "Referred record has no definition");
228       for (const auto *I : RD->fields()) {
229         const FieldRegion *FR = MrMgr.getFieldRegion(I, R);
230         FieldChain.push_back(I);
231         T = I->getType();
232         if (T->getAsStructureType()) {
233           if (Find(FR))
234             return true;
235         } else {
236           const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
237           if (V.isUndef())
238             return true;
239         }
240         FieldChain.pop_back();
241       }
242     }
243 
244     return false;
245   }
246 };
247 } // namespace
248 
249 bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
250                                                SVal V,
251                                                SourceRange ArgRange,
252                                                const Expr *ArgEx,
253                                                int ArgumentNumber,
254                                                bool CheckUninitFields,
255                                                const CallEvent &Call,
256                                                std::unique_ptr<BugType> &BT,
257                                                const ParmVarDecl *ParamDecl
258                                                ) const {
259   const char *BD = "Uninitialized argument value";
260 
261   if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD,
262                          ArgumentNumber))
263     return true;
264 
265   if (V.isUndef()) {
266     if (ExplodedNode *N = C.generateErrorNode()) {
267       LazyInit_BT(BD, BT);
268       // Generate a report for this bug.
269       SmallString<200> Buf;
270       llvm::raw_svector_ostream Os(Buf);
271       describeUninitializedArgumentInCall(Call, ArgumentNumber, Os);
272       auto R = std::make_unique<PathSensitiveBugReport>(*BT, Os.str(), N);
273 
274       R->addRange(ArgRange);
275       if (ArgEx)
276         bugreporter::trackExpressionValue(N, ArgEx, *R);
277       C.emitReport(std::move(R));
278     }
279     return true;
280   }
281 
282   if (!CheckUninitFields)
283     return false;
284 
285   if (auto LV = V.getAs<nonloc::LazyCompoundVal>()) {
286     const LazyCompoundValData *D = LV->getCVData();
287     FindUninitializedField F(C.getState()->getStateManager().getStoreManager(),
288                              C.getSValBuilder().getRegionManager(),
289                              D->getStore());
290 
291     if (F.Find(D->getRegion())) {
292       if (ExplodedNode *N = C.generateErrorNode()) {
293         LazyInit_BT(BD, BT);
294         SmallString<512> Str;
295         llvm::raw_svector_ostream os(Str);
296         os << "Passed-by-value struct argument contains uninitialized data";
297 
298         if (F.FieldChain.size() == 1)
299           os << " (e.g., field: '" << *F.FieldChain[0] << "')";
300         else {
301           os << " (e.g., via the field chain: '";
302           bool first = true;
303           for (SmallVectorImpl<const FieldDecl *>::iterator
304                DI = F.FieldChain.begin(), DE = F.FieldChain.end(); DI!=DE;++DI){
305             if (first)
306               first = false;
307             else
308               os << '.';
309             os << **DI;
310           }
311           os << "')";
312         }
313 
314         // Generate a report for this bug.
315         auto R = std::make_unique<PathSensitiveBugReport>(*BT, os.str(), N);
316         R->addRange(ArgRange);
317 
318         if (ArgEx)
319           bugreporter::trackExpressionValue(N, ArgEx, *R);
320         // FIXME: enhance track back for uninitialized value for arbitrary
321         // memregions
322         C.emitReport(std::move(R));
323       }
324       return true;
325     }
326   }
327 
328   return false;
329 }
330 
331 ProgramStateRef CallAndMessageChecker::checkFunctionPointerCall(
332     const CallExpr *CE, CheckerContext &C, ProgramStateRef State) const {
333 
334   const Expr *Callee = CE->getCallee()->IgnoreParens();
335   const LocationContext *LCtx = C.getLocationContext();
336   SVal L = State->getSVal(Callee, LCtx);
337 
338   if (L.isUndef()) {
339     if (!BT_call_undef)
340       BT_call_undef.reset(new BuiltinBug(
341           this, "Called function pointer is an uninitialized pointer value"));
342     emitBadCall(BT_call_undef.get(), C, Callee);
343     return nullptr;
344   }
345 
346   ProgramStateRef StNonNull, StNull;
347   std::tie(StNonNull, StNull) = State->assume(L.castAs<DefinedOrUnknownSVal>());
348 
349   if (StNull && !StNonNull) {
350     if (!BT_call_null)
351       BT_call_null.reset(new BuiltinBug(
352           this, "Called function pointer is null (null dereference)"));
353     emitBadCall(BT_call_null.get(), C, Callee);
354     return nullptr;
355   }
356 
357   return StNonNull;
358 }
359 
360 ProgramStateRef CallAndMessageChecker::checkParameterCount(
361     const CallEvent &Call, CheckerContext &C, ProgramStateRef State) const {
362 
363   // If we have a function or block declaration, we can make sure we pass
364   // enough parameters.
365   unsigned Params = Call.parameters().size();
366   if (Call.getNumArgs() >= Params)
367     return State;
368 
369   ExplodedNode *N = C.generateErrorNode();
370   if (!N)
371     return nullptr;
372 
373   LazyInit_BT("Function call with too few arguments", BT_call_few_args);
374 
375   SmallString<512> Str;
376   llvm::raw_svector_ostream os(Str);
377   if (isa<AnyFunctionCall>(Call)) {
378     os << "Function ";
379   } else {
380     assert(isa<BlockCall>(Call));
381     os << "Block ";
382   }
383   os << "taking " << Params << " argument" << (Params == 1 ? "" : "s")
384      << " is called with fewer (" << Call.getNumArgs() << ")";
385 
386   C.emitReport(
387       std::make_unique<PathSensitiveBugReport>(*BT_call_few_args, os.str(), N));
388   return nullptr;
389 }
390 
391 ProgramStateRef CallAndMessageChecker::checkCXXMethodCall(
392     const CXXInstanceCall *CC, CheckerContext &C, ProgramStateRef State) const {
393 
394   SVal V = CC->getCXXThisVal();
395   if (V.isUndef()) {
396     if (!BT_cxx_call_undef)
397       BT_cxx_call_undef.reset(
398           new BuiltinBug(this, "Called C++ object pointer is uninitialized"));
399     emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
400     return nullptr;
401   }
402 
403   ProgramStateRef StNonNull, StNull;
404   std::tie(StNonNull, StNull) = State->assume(V.castAs<DefinedOrUnknownSVal>());
405 
406   if (StNull && !StNonNull) {
407     if (!BT_cxx_call_null)
408       BT_cxx_call_null.reset(
409           new BuiltinBug(this, "Called C++ object pointer is null"));
410     emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
411     return nullptr;
412   }
413 
414   return StNonNull;
415 }
416 
417 ProgramStateRef
418 CallAndMessageChecker::checkCXXDeallocation(const CXXDeallocatorCall *DC,
419                                             CheckerContext &C,
420                                             ProgramStateRef State) const {
421   const CXXDeleteExpr *DE = DC->getOriginExpr();
422   assert(DE);
423   SVal Arg = C.getSVal(DE->getArgument());
424   if (!Arg.isUndef())
425     return State;
426 
427   StringRef Desc;
428   ExplodedNode *N = C.generateErrorNode();
429   if (!N)
430     return nullptr;
431   if (!BT_cxx_delete_undef)
432     BT_cxx_delete_undef.reset(
433         new BuiltinBug(this, "Uninitialized argument value"));
434   if (DE->isArrayFormAsWritten())
435     Desc = "Argument to 'delete[]' is uninitialized";
436   else
437     Desc = "Argument to 'delete' is uninitialized";
438   BugType *BT = BT_cxx_delete_undef.get();
439   auto R = std::make_unique<PathSensitiveBugReport>(*BT, Desc, N);
440   bugreporter::trackExpressionValue(N, DE, *R);
441   C.emitReport(std::move(R));
442   return nullptr;
443 }
444 
445 ProgramStateRef CallAndMessageChecker::checkArgInitializedness(
446     const CallEvent &Call, CheckerContext &C, ProgramStateRef State) const {
447 
448   const Decl *D = Call.getDecl();
449 
450   // Don't check for uninitialized field values in arguments if the
451   // caller has a body that is available and we have the chance to inline it.
452   // This is a hack, but is a reasonable compromise betweens sometimes warning
453   // and sometimes not depending on if we decide to inline a function.
454   const bool checkUninitFields =
455       !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody()));
456 
457   std::unique_ptr<BugType> *BT;
458   if (isa<ObjCMethodCall>(Call))
459     BT = &BT_msg_arg;
460   else
461     BT = &BT_call_arg;
462 
463   const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
464   for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i) {
465     const ParmVarDecl *ParamDecl = nullptr;
466     if (FD && i < FD->getNumParams())
467       ParamDecl = FD->getParamDecl(i);
468     if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i),
469                            Call.getArgExpr(i), i, checkUninitFields, Call, *BT,
470                            ParamDecl))
471       return nullptr;
472   }
473   return State;
474 }
475 
476 void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
477                                          CheckerContext &C) const {
478   ProgramStateRef State = C.getState();
479 
480   if (const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr()))
481     State = checkFunctionPointerCall(CE, C, State);
482 
483   if (!State)
484     return;
485 
486   if (Call.getDecl())
487     State = checkParameterCount(Call, C, State);
488 
489   if (!State)
490     return;
491 
492   if (const auto *CC = dyn_cast<CXXInstanceCall>(&Call))
493     State = checkCXXMethodCall(CC, C, State);
494 
495   if (!State)
496     return;
497 
498   if (const auto *DC = dyn_cast<CXXDeallocatorCall>(&Call))
499     State = checkCXXDeallocation(DC, C, State);
500 
501   if (!State)
502     return;
503 
504   State = checkArgInitializedness(Call, C, State);
505 
506   // If we make it here, record our assumptions about the callee.
507   C.addTransition(State);
508 }
509 
510 void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
511                                                 CheckerContext &C) const {
512   SVal recVal = msg.getReceiverSVal();
513   if (recVal.isUndef()) {
514     if (ExplodedNode *N = C.generateErrorNode()) {
515       BugType *BT = nullptr;
516       switch (msg.getMessageKind()) {
517       case OCM_Message:
518         if (!BT_msg_undef)
519           BT_msg_undef.reset(new BuiltinBug(this,
520                                             "Receiver in message expression "
521                                             "is an uninitialized value"));
522         BT = BT_msg_undef.get();
523         break;
524       case OCM_PropertyAccess:
525         if (!BT_objc_prop_undef)
526           BT_objc_prop_undef.reset(new BuiltinBug(
527               this, "Property access on an uninitialized object pointer"));
528         BT = BT_objc_prop_undef.get();
529         break;
530       case OCM_Subscript:
531         if (!BT_objc_subscript_undef)
532           BT_objc_subscript_undef.reset(new BuiltinBug(
533               this, "Subscript access on an uninitialized object pointer"));
534         BT = BT_objc_subscript_undef.get();
535         break;
536       }
537       assert(BT && "Unknown message kind.");
538 
539       auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
540       const ObjCMessageExpr *ME = msg.getOriginExpr();
541       R->addRange(ME->getReceiverRange());
542 
543       // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
544       if (const Expr *ReceiverE = ME->getInstanceReceiver())
545         bugreporter::trackExpressionValue(N, ReceiverE, *R);
546       C.emitReport(std::move(R));
547     }
548     return;
549   }
550 }
551 
552 void CallAndMessageChecker::checkObjCMessageNil(const ObjCMethodCall &msg,
553                                                 CheckerContext &C) const {
554   HandleNilReceiver(C, C.getState(), msg);
555 }
556 
557 void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
558                                                const ObjCMethodCall &msg,
559                                                ExplodedNode *N) const {
560 
561   if (!BT_msg_ret)
562     BT_msg_ret.reset(
563         new BuiltinBug(this, "Receiver in message expression is 'nil'"));
564 
565   const ObjCMessageExpr *ME = msg.getOriginExpr();
566 
567   QualType ResTy = msg.getResultType();
568 
569   SmallString<200> buf;
570   llvm::raw_svector_ostream os(buf);
571   os << "The receiver of message '";
572   ME->getSelector().print(os);
573   os << "' is nil";
574   if (ResTy->isReferenceType()) {
575     os << ", which results in forming a null reference";
576   } else {
577     os << " and returns a value of type '";
578     msg.getResultType().print(os, C.getLangOpts());
579     os << "' that will be garbage";
580   }
581 
582   auto report =
583       std::make_unique<PathSensitiveBugReport>(*BT_msg_ret, os.str(), N);
584   report->addRange(ME->getReceiverRange());
585   // FIXME: This won't track "self" in messages to super.
586   if (const Expr *receiver = ME->getInstanceReceiver()) {
587     bugreporter::trackExpressionValue(N, receiver, *report);
588   }
589   C.emitReport(std::move(report));
590 }
591 
592 static bool supportsNilWithFloatRet(const llvm::Triple &triple) {
593   return (triple.getVendor() == llvm::Triple::Apple &&
594           (triple.isiOS() || triple.isWatchOS() ||
595            !triple.isMacOSXVersionLT(10,5)));
596 }
597 
598 void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
599                                               ProgramStateRef state,
600                                               const ObjCMethodCall &Msg) const {
601   ASTContext &Ctx = C.getASTContext();
602   static CheckerProgramPointTag Tag(this, "NilReceiver");
603 
604   // Check the return type of the message expression.  A message to nil will
605   // return different values depending on the return type and the architecture.
606   QualType RetTy = Msg.getResultType();
607   CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
608   const LocationContext *LCtx = C.getLocationContext();
609 
610   if (CanRetTy->isStructureOrClassType()) {
611     // Structure returns are safe since the compiler zeroes them out.
612     SVal V = C.getSValBuilder().makeZeroVal(RetTy);
613     C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
614     return;
615   }
616 
617   // Other cases: check if sizeof(return type) > sizeof(void*)
618   if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
619                                   .isConsumedExpr(Msg.getOriginExpr())) {
620     // Compute: sizeof(void *) and sizeof(return type)
621     const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
622     const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);
623 
624     if (CanRetTy.getTypePtr()->isReferenceType()||
625         (voidPtrSize < returnTypeSize &&
626          !(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) &&
627            (Ctx.FloatTy == CanRetTy ||
628             Ctx.DoubleTy == CanRetTy ||
629             Ctx.LongDoubleTy == CanRetTy ||
630             Ctx.LongLongTy == CanRetTy ||
631             Ctx.UnsignedLongLongTy == CanRetTy)))) {
632       if (ExplodedNode *N = C.generateErrorNode(state, &Tag))
633         emitNilReceiverBug(C, Msg, N);
634       return;
635     }
636 
637     // Handle the safe cases where the return value is 0 if the
638     // receiver is nil.
639     //
640     // FIXME: For now take the conservative approach that we only
641     // return null values if we *know* that the receiver is nil.
642     // This is because we can have surprises like:
643     //
644     //   ... = [[NSScreens screens] objectAtIndex:0];
645     //
646     // What can happen is that [... screens] could return nil, but
647     // it most likely isn't nil.  We should assume the semantics
648     // of this case unless we have *a lot* more knowledge.
649     //
650     SVal V = C.getSValBuilder().makeZeroVal(RetTy);
651     C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag);
652     return;
653   }
654 
655   C.addTransition(state);
656 }
657 
658 void ento::registerCallAndMessageChecker(CheckerManager &mgr) {
659   mgr.registerChecker<CallAndMessageChecker>();
660 }
661 
662 bool ento::shouldRegisterCallAndMessageChecker(const CheckerManager &mgr) {
663   return true;
664 }
665 
666 #define REGISTER_CHECKER(name)                                                 \
667   void ento::register##name(CheckerManager &mgr) {                             \
668     CallAndMessageChecker *checker = mgr.getChecker<CallAndMessageChecker>();  \
669     checker->ChecksEnabled[CallAndMessageChecker::CK_##name] = true;           \
670                                                                                \
671   }                                                                            \
672                                                                                \
673   bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }
674 
675 REGISTER_CHECKER(CallAndMessageUnInitRefArg)
676