xref: /llvm-project/clang/lib/Analysis/FlowSensitive/Transfer.cpp (revision 68761a9e05693bd3986e46628e401c80a27e945d)
1 //===-- Transfer.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 file defines transfer functions that evaluate program statements and
10 //  update an environment accordingly.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Analysis/FlowSensitive/Transfer.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/OperationKinds.h"
21 #include "clang/AST/Stmt.h"
22 #include "clang/AST/StmtVisitor.h"
23 #include "clang/Analysis/FlowSensitive/ASTOps.h"
24 #include "clang/Analysis/FlowSensitive/AdornedCFG.h"
25 #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
26 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
27 #include "clang/Analysis/FlowSensitive/NoopAnalysis.h"
28 #include "clang/Analysis/FlowSensitive/RecordOps.h"
29 #include "clang/Analysis/FlowSensitive/Value.h"
30 #include "clang/Basic/Builtins.h"
31 #include "clang/Basic/OperatorKinds.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/Debug.h"
34 #include <assert.h>
35 #include <cassert>
36 
37 #define DEBUG_TYPE "dataflow"
38 
39 namespace clang {
40 namespace dataflow {
41 
42 const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const {
43   auto BlockIt = ACFG.getStmtToBlock().find(&ignoreCFGOmittedNodes(S));
44   if (BlockIt == ACFG.getStmtToBlock().end()) {
45     assert(false);
46     // Return null to avoid dereferencing the end iterator in non-assert builds.
47     return nullptr;
48   }
49   if (!ACFG.isBlockReachable(*BlockIt->getSecond()))
50     return nullptr;
51   if (BlockIt->getSecond()->getBlockID() == CurBlockID)
52     return &CurState.Env;
53   const auto &State = BlockToState[BlockIt->getSecond()->getBlockID()];
54   if (!(State))
55     return nullptr;
56   return &State->Env;
57 }
58 
59 static BoolValue &evaluateBooleanEquality(const Expr &LHS, const Expr &RHS,
60                                           Environment &Env) {
61   Value *LHSValue = Env.getValue(LHS);
62   Value *RHSValue = Env.getValue(RHS);
63 
64   if (LHSValue == RHSValue)
65     return Env.getBoolLiteralValue(true);
66 
67   if (auto *LHSBool = dyn_cast_or_null<BoolValue>(LHSValue))
68     if (auto *RHSBool = dyn_cast_or_null<BoolValue>(RHSValue))
69       return Env.makeIff(*LHSBool, *RHSBool);
70 
71   if (auto *LHSPtr = dyn_cast_or_null<PointerValue>(LHSValue))
72     if (auto *RHSPtr = dyn_cast_or_null<PointerValue>(RHSValue))
73       // If the storage locations are the same, the pointers definitely compare
74       // the same. If the storage locations are different, they may still alias,
75       // so we fall through to the case below that returns an atom.
76       if (&LHSPtr->getPointeeLoc() == &RHSPtr->getPointeeLoc())
77         return Env.getBoolLiteralValue(true);
78 
79   return Env.makeAtomicBoolValue();
80 }
81 
82 static BoolValue &unpackValue(BoolValue &V, Environment &Env) {
83   if (auto *Top = llvm::dyn_cast<TopBoolValue>(&V)) {
84     auto &A = Env.getDataflowAnalysisContext().arena();
85     return A.makeBoolValue(A.makeAtomRef(Top->getAtom()));
86   }
87   return V;
88 }
89 
90 // Unpacks the value (if any) associated with `E` and updates `E` to the new
91 // value, if any unpacking occured. Also, does the lvalue-to-rvalue conversion,
92 // by skipping past the reference.
93 static Value *maybeUnpackLValueExpr(const Expr &E, Environment &Env) {
94   auto *Loc = Env.getStorageLocation(E);
95   if (Loc == nullptr)
96     return nullptr;
97   auto *Val = Env.getValue(*Loc);
98 
99   auto *B = dyn_cast_or_null<BoolValue>(Val);
100   if (B == nullptr)
101     return Val;
102 
103   auto &UnpackedVal = unpackValue(*B, Env);
104   if (&UnpackedVal == Val)
105     return Val;
106   Env.setValue(*Loc, UnpackedVal);
107   return &UnpackedVal;
108 }
109 
110 static void propagateValue(const Expr &From, const Expr &To, Environment &Env) {
111   if (From.getType()->isRecordType())
112     return;
113   if (auto *Val = Env.getValue(From))
114     Env.setValue(To, *Val);
115 }
116 
117 static void propagateStorageLocation(const Expr &From, const Expr &To,
118                                      Environment &Env) {
119   if (auto *Loc = Env.getStorageLocation(From))
120     Env.setStorageLocation(To, *Loc);
121 }
122 
123 // Propagates the value or storage location of `From` to `To` in cases where
124 // `From` may be either a glvalue or a prvalue. `To` must be a glvalue iff
125 // `From` is a glvalue.
126 static void propagateValueOrStorageLocation(const Expr &From, const Expr &To,
127                                             Environment &Env) {
128   assert(From.isGLValue() == To.isGLValue());
129   if (From.isGLValue())
130     propagateStorageLocation(From, To, Env);
131   else
132     propagateValue(From, To, Env);
133 }
134 
135 namespace {
136 
137 class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
138 public:
139   TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env,
140                   Environment::ValueModel &Model)
141       : StmtToEnv(StmtToEnv), Env(Env), Model(Model) {}
142 
143   void VisitBinaryOperator(const BinaryOperator *S) {
144     const Expr *LHS = S->getLHS();
145     assert(LHS != nullptr);
146 
147     const Expr *RHS = S->getRHS();
148     assert(RHS != nullptr);
149 
150     switch (S->getOpcode()) {
151     case BO_Assign: {
152       auto *LHSLoc = Env.getStorageLocation(*LHS);
153       if (LHSLoc == nullptr)
154         break;
155 
156       auto *RHSVal = Env.getValue(*RHS);
157       if (RHSVal == nullptr)
158         break;
159 
160       // Assign a value to the storage location of the left-hand side.
161       Env.setValue(*LHSLoc, *RHSVal);
162 
163       // Assign a storage location for the whole expression.
164       Env.setStorageLocation(*S, *LHSLoc);
165       break;
166     }
167     case BO_LAnd:
168     case BO_LOr: {
169       BoolValue &LHSVal = getLogicOperatorSubExprValue(*LHS);
170       BoolValue &RHSVal = getLogicOperatorSubExprValue(*RHS);
171 
172       if (S->getOpcode() == BO_LAnd)
173         Env.setValue(*S, Env.makeAnd(LHSVal, RHSVal));
174       else
175         Env.setValue(*S, Env.makeOr(LHSVal, RHSVal));
176       break;
177     }
178     case BO_NE:
179     case BO_EQ: {
180       auto &LHSEqRHSValue = evaluateBooleanEquality(*LHS, *RHS, Env);
181       Env.setValue(*S, S->getOpcode() == BO_EQ ? LHSEqRHSValue
182                                                : Env.makeNot(LHSEqRHSValue));
183       break;
184     }
185     case BO_Comma: {
186       propagateValueOrStorageLocation(*RHS, *S, Env);
187       break;
188     }
189     default:
190       break;
191     }
192   }
193 
194   void VisitDeclRefExpr(const DeclRefExpr *S) {
195     const ValueDecl *VD = S->getDecl();
196     assert(VD != nullptr);
197 
198     // Some `DeclRefExpr`s aren't glvalues, so we can't associate them with a
199     // `StorageLocation`, and there's also no sensible `Value` that we can
200     // assign to them. Examples:
201     // - Non-static member variables
202     // - Non static member functions
203     //   Note: Member operators are an exception to this, but apparently only
204     //   if the `DeclRefExpr` is used within the callee of a
205     //   `CXXOperatorCallExpr`. In other cases, for example when applying the
206     //   address-of operator, the `DeclRefExpr` is a prvalue.
207     if (!S->isGLValue())
208       return;
209 
210     auto *DeclLoc = Env.getStorageLocation(*VD);
211     if (DeclLoc == nullptr)
212       return;
213 
214     Env.setStorageLocation(*S, *DeclLoc);
215   }
216 
217   void VisitDeclStmt(const DeclStmt *S) {
218     // Group decls are converted into single decls in the CFG so the cast below
219     // is safe.
220     const auto &D = *cast<VarDecl>(S->getSingleDecl());
221 
222     ProcessVarDecl(D);
223   }
224 
225   void ProcessVarDecl(const VarDecl &D) {
226     // Static local vars are already initialized in `Environment`.
227     if (D.hasGlobalStorage())
228       return;
229 
230     // If this is the holding variable for a `BindingDecl`, we may already
231     // have a storage location set up -- so check. (See also explanation below
232     // where we process the `BindingDecl`.)
233     if (D.getType()->isReferenceType() && Env.getStorageLocation(D) != nullptr)
234       return;
235 
236     assert(Env.getStorageLocation(D) == nullptr);
237 
238     Env.setStorageLocation(D, Env.createObject(D));
239 
240     // `DecompositionDecl` must be handled after we've interpreted the loc
241     // itself, because the binding expression refers back to the
242     // `DecompositionDecl` (even though it has no written name).
243     if (const auto *Decomp = dyn_cast<DecompositionDecl>(&D)) {
244       // If VarDecl is a DecompositionDecl, evaluate each of its bindings. This
245       // needs to be evaluated after initializing the values in the storage for
246       // VarDecl, as the bindings refer to them.
247       // FIXME: Add support for ArraySubscriptExpr.
248       // FIXME: Consider adding AST nodes used in BindingDecls to the CFG.
249       for (const auto *B : Decomp->bindings()) {
250         if (auto *ME = dyn_cast_or_null<MemberExpr>(B->getBinding())) {
251           auto *DE = dyn_cast_or_null<DeclRefExpr>(ME->getBase());
252           if (DE == nullptr)
253             continue;
254 
255           // ME and its base haven't been visited because they aren't included
256           // in the statements of the CFG basic block.
257           VisitDeclRefExpr(DE);
258           VisitMemberExpr(ME);
259 
260           if (auto *Loc = Env.getStorageLocation(*ME))
261             Env.setStorageLocation(*B, *Loc);
262         } else if (auto *VD = B->getHoldingVar()) {
263           // Holding vars are used to back the `BindingDecl`s of tuple-like
264           // types. The holding var declarations appear after the
265           // `DecompositionDecl`, so we have to explicitly process them here
266           // to know their storage location. They will be processed a second
267           // time when we visit their `VarDecl`s, so we have code that protects
268           // against this above.
269           ProcessVarDecl(*VD);
270           auto *VDLoc = Env.getStorageLocation(*VD);
271           assert(VDLoc != nullptr);
272           Env.setStorageLocation(*B, *VDLoc);
273         }
274       }
275     }
276   }
277 
278   void VisitImplicitCastExpr(const ImplicitCastExpr *S) {
279     const Expr *SubExpr = S->getSubExpr();
280     assert(SubExpr != nullptr);
281 
282     switch (S->getCastKind()) {
283     case CK_IntegralToBoolean: {
284       // This cast creates a new, boolean value from the integral value. We
285       // model that with a fresh value in the environment, unless it's already a
286       // boolean.
287       if (auto *SubExprVal =
288               dyn_cast_or_null<BoolValue>(Env.getValue(*SubExpr)))
289         Env.setValue(*S, *SubExprVal);
290       else
291         // FIXME: If integer modeling is added, then update this code to create
292         // the boolean based on the integer model.
293         Env.setValue(*S, Env.makeAtomicBoolValue());
294       break;
295     }
296 
297     case CK_LValueToRValue: {
298       // When an L-value is used as an R-value, it may result in sharing, so we
299       // need to unpack any nested `Top`s.
300       auto *SubExprVal = maybeUnpackLValueExpr(*SubExpr, Env);
301       if (SubExprVal == nullptr)
302         break;
303 
304       Env.setValue(*S, *SubExprVal);
305       break;
306     }
307 
308     case CK_IntegralCast:
309       // FIXME: This cast creates a new integral value from the
310       // subexpression. But, because we don't model integers, we don't
311       // distinguish between this new value and the underlying one. If integer
312       // modeling is added, then update this code to create a fresh location and
313       // value.
314     case CK_UncheckedDerivedToBase:
315     case CK_ConstructorConversion:
316     case CK_UserDefinedConversion:
317       // FIXME: Add tests that excercise CK_UncheckedDerivedToBase,
318       // CK_ConstructorConversion, and CK_UserDefinedConversion.
319     case CK_NoOp: {
320       // FIXME: Consider making `Environment::getStorageLocation` skip noop
321       // expressions (this and other similar expressions in the file) instead
322       // of assigning them storage locations.
323       propagateValueOrStorageLocation(*SubExpr, *S, Env);
324       break;
325     }
326     case CK_NullToPointer: {
327       auto &NullPointerVal =
328           Env.getOrCreateNullPointerValue(S->getType()->getPointeeType());
329       Env.setValue(*S, NullPointerVal);
330       break;
331     }
332     case CK_NullToMemberPointer:
333       // FIXME: Implement pointers to members. For now, don't associate a value
334       // with this expression.
335       break;
336     case CK_FunctionToPointerDecay: {
337       StorageLocation *PointeeLoc = Env.getStorageLocation(*SubExpr);
338       if (PointeeLoc == nullptr)
339         break;
340 
341       Env.setValue(*S, Env.create<PointerValue>(*PointeeLoc));
342       break;
343     }
344     case CK_BuiltinFnToFnPtr:
345       // Despite its name, the result type of `BuiltinFnToFnPtr` is a function,
346       // not a function pointer. In addition, builtin functions can only be
347       // called directly; it is not legal to take their address. We therefore
348       // don't need to create a value or storage location for them.
349       break;
350     default:
351       break;
352     }
353   }
354 
355   void VisitUnaryOperator(const UnaryOperator *S) {
356     const Expr *SubExpr = S->getSubExpr();
357     assert(SubExpr != nullptr);
358 
359     switch (S->getOpcode()) {
360     case UO_Deref: {
361       const auto *SubExprVal = Env.get<PointerValue>(*SubExpr);
362       if (SubExprVal == nullptr)
363         break;
364 
365       Env.setStorageLocation(*S, SubExprVal->getPointeeLoc());
366       break;
367     }
368     case UO_AddrOf: {
369       // FIXME: Model pointers to members.
370       if (S->getType()->isMemberPointerType())
371         break;
372 
373       if (StorageLocation *PointeeLoc = Env.getStorageLocation(*SubExpr))
374         Env.setValue(*S, Env.create<PointerValue>(*PointeeLoc));
375       break;
376     }
377     case UO_LNot: {
378       auto *SubExprVal = dyn_cast_or_null<BoolValue>(Env.getValue(*SubExpr));
379       if (SubExprVal == nullptr)
380         break;
381 
382       Env.setValue(*S, Env.makeNot(*SubExprVal));
383       break;
384     }
385     case UO_PreInc:
386     case UO_PreDec:
387       // Propagate the storage location, but don't create a new value; to
388       // avoid generating unnecessary values, we leave it to the specific
389       // analysis to do this if desired.
390       propagateStorageLocation(*S->getSubExpr(), *S, Env);
391       break;
392     case UO_PostInc:
393     case UO_PostDec:
394       // Propagate the old value, but don't create a new value; to avoid
395       // generating unnecessary values, we leave it to the specific analysis
396       // to do this if desired.
397       propagateValue(*S->getSubExpr(), *S, Env);
398       break;
399     default:
400       break;
401     }
402   }
403 
404   void VisitCXXThisExpr(const CXXThisExpr *S) {
405     auto *ThisPointeeLoc = Env.getThisPointeeStorageLocation();
406     if (ThisPointeeLoc == nullptr)
407       // Unions are not supported yet, and will not have a location for the
408       // `this` expression's pointee.
409       return;
410 
411     Env.setValue(*S, Env.create<PointerValue>(*ThisPointeeLoc));
412   }
413 
414   void VisitCXXNewExpr(const CXXNewExpr *S) {
415     if (Value *Val = Env.createValue(S->getType()))
416       Env.setValue(*S, *Val);
417   }
418 
419   void VisitCXXDeleteExpr(const CXXDeleteExpr *S) {
420     // Empty method.
421     // We consciously don't do anything on deletes.  Diagnosing double deletes
422     // (for example) should be done by a specific analysis, not by the
423     // framework.
424   }
425 
426   void VisitReturnStmt(const ReturnStmt *S) {
427     if (!Env.getDataflowAnalysisContext().getOptions().ContextSensitiveOpts)
428       return;
429 
430     auto *Ret = S->getRetValue();
431     if (Ret == nullptr)
432       return;
433 
434     if (Ret->isPRValue()) {
435       if (Ret->getType()->isRecordType())
436         return;
437 
438       auto *Val = Env.getValue(*Ret);
439       if (Val == nullptr)
440         return;
441 
442       // FIXME: Model NRVO.
443       Env.setReturnValue(Val);
444     } else {
445       auto *Loc = Env.getStorageLocation(*Ret);
446       if (Loc == nullptr)
447         return;
448 
449       // FIXME: Model NRVO.
450       Env.setReturnStorageLocation(Loc);
451     }
452   }
453 
454   void VisitMemberExpr(const MemberExpr *S) {
455     ValueDecl *Member = S->getMemberDecl();
456     assert(Member != nullptr);
457 
458     // FIXME: Consider assigning pointer values to function member expressions.
459     if (Member->isFunctionOrFunctionTemplate())
460       return;
461 
462     // FIXME: if/when we add support for modeling enums, use that support here.
463     if (isa<EnumConstantDecl>(Member))
464       return;
465 
466     if (auto *D = dyn_cast<VarDecl>(Member)) {
467       if (D->hasGlobalStorage()) {
468         auto *VarDeclLoc = Env.getStorageLocation(*D);
469         if (VarDeclLoc == nullptr)
470           return;
471 
472         Env.setStorageLocation(*S, *VarDeclLoc);
473         return;
474       }
475     }
476 
477     RecordStorageLocation *BaseLoc = getBaseObjectLocation(*S, Env);
478     if (BaseLoc == nullptr)
479       return;
480 
481     auto *MemberLoc = BaseLoc->getChild(*Member);
482     if (MemberLoc == nullptr)
483       return;
484     Env.setStorageLocation(*S, *MemberLoc);
485   }
486 
487   void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *S) {
488     const Expr *ArgExpr = S->getExpr();
489     assert(ArgExpr != nullptr);
490     propagateValueOrStorageLocation(*ArgExpr, *S, Env);
491 
492     if (S->isPRValue() && S->getType()->isRecordType()) {
493       auto &Loc = Env.getResultObjectLocation(*S);
494       Env.initializeFieldsWithValues(Loc);
495     }
496   }
497 
498   void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *S) {
499     const Expr *InitExpr = S->getExpr();
500     assert(InitExpr != nullptr);
501 
502     // If this is a prvalue of record type, the handler for `*InitExpr` (if one
503     // exists) will initialize the result object; there is no value to propgate
504     // here.
505     if (S->getType()->isRecordType() && S->isPRValue())
506       return;
507 
508     propagateValueOrStorageLocation(*InitExpr, *S, Env);
509   }
510 
511   void VisitCXXConstructExpr(const CXXConstructExpr *S) {
512     const CXXConstructorDecl *ConstructorDecl = S->getConstructor();
513     assert(ConstructorDecl != nullptr);
514 
515     // `CXXConstructExpr` can have array type if default-initializing an array
516     // of records. We don't handle this specifically beyond potentially inlining
517     // the call.
518     if (!S->getType()->isRecordType()) {
519       transferInlineCall(S, ConstructorDecl);
520       return;
521     }
522 
523     RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);
524 
525     if (ConstructorDecl->isCopyOrMoveConstructor()) {
526       // It is permissible for a copy/move constructor to have additional
527       // parameters as long as they have default arguments defined for them.
528       assert(S->getNumArgs() != 0);
529 
530       const Expr *Arg = S->getArg(0);
531       assert(Arg != nullptr);
532 
533       auto *ArgLoc = Env.get<RecordStorageLocation>(*Arg);
534       if (ArgLoc == nullptr)
535         return;
536 
537       // Even if the copy/move constructor call is elidable, we choose to copy
538       // the record in all cases (which isn't wrong, just potentially not
539       // optimal).
540       copyRecord(*ArgLoc, Loc, Env);
541       return;
542     }
543 
544     Env.initializeFieldsWithValues(Loc, S->getType());
545 
546     transferInlineCall(S, ConstructorDecl);
547   }
548 
549   void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
550     if (S->getOperator() == OO_Equal) {
551       assert(S->getNumArgs() == 2);
552 
553       const Expr *Arg0 = S->getArg(0);
554       assert(Arg0 != nullptr);
555 
556       const Expr *Arg1 = S->getArg(1);
557       assert(Arg1 != nullptr);
558 
559       // Evaluate only copy and move assignment operators.
560       const auto *Method =
561           dyn_cast_or_null<CXXMethodDecl>(S->getDirectCallee());
562       if (!Method)
563         return;
564       if (!Method->isCopyAssignmentOperator() &&
565           !Method->isMoveAssignmentOperator())
566         return;
567 
568       RecordStorageLocation *LocSrc = nullptr;
569       if (Arg1->isPRValue()) {
570         LocSrc = &Env.getResultObjectLocation(*Arg1);
571       } else {
572         LocSrc = Env.get<RecordStorageLocation>(*Arg1);
573       }
574       auto *LocDst = Env.get<RecordStorageLocation>(*Arg0);
575 
576       if (LocSrc == nullptr || LocDst == nullptr)
577         return;
578 
579       copyRecord(*LocSrc, *LocDst, Env);
580 
581       // The assignment operator can have an arbitrary return type. We model the
582       // return value only if the return type is the same as or a base class of
583       // the destination type.
584       if (S->getType().getCanonicalType().getUnqualifiedType() !=
585           LocDst->getType().getCanonicalType().getUnqualifiedType()) {
586         auto ReturnDecl = S->getType()->getAsCXXRecordDecl();
587         auto DstDecl = LocDst->getType()->getAsCXXRecordDecl();
588         if (ReturnDecl == nullptr || DstDecl == nullptr)
589           return;
590         if (!DstDecl->isDerivedFrom(ReturnDecl))
591           return;
592       }
593 
594       if (S->isGLValue())
595         Env.setStorageLocation(*S, *LocDst);
596       else
597         copyRecord(*LocDst, Env.getResultObjectLocation(*S), Env);
598 
599       return;
600     }
601 
602     // `CXXOperatorCallExpr` can be a prvalue. Call `VisitCallExpr`() to
603     // initialize the prvalue's fields with values.
604     VisitCallExpr(S);
605   }
606 
607   void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *RBO) {
608     propagateValue(*RBO->getSemanticForm(), *RBO, Env);
609   }
610 
611   void VisitCallExpr(const CallExpr *S) {
612     // Of clang's builtins, only `__builtin_expect` is handled explicitly, since
613     // others (like trap, debugtrap, and unreachable) are handled by CFG
614     // construction.
615     if (S->isCallToStdMove()) {
616       assert(S->getNumArgs() == 1);
617 
618       const Expr *Arg = S->getArg(0);
619       assert(Arg != nullptr);
620 
621       auto *ArgLoc = Env.getStorageLocation(*Arg);
622       if (ArgLoc == nullptr)
623         return;
624 
625       Env.setStorageLocation(*S, *ArgLoc);
626     } else if (S->getDirectCallee() != nullptr &&
627                S->getDirectCallee()->getBuiltinID() ==
628                    Builtin::BI__builtin_expect) {
629       assert(S->getNumArgs() > 0);
630       assert(S->getArg(0) != nullptr);
631       auto *ArgVal = Env.getValue(*S->getArg(0));
632       if (ArgVal == nullptr)
633         return;
634       Env.setValue(*S, *ArgVal);
635     } else if (const FunctionDecl *F = S->getDirectCallee()) {
636       transferInlineCall(S, F);
637 
638       // If this call produces a prvalue of record type, initialize its fields
639       // with values.
640       if (S->getType()->isRecordType() && S->isPRValue()) {
641         RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);
642         Env.initializeFieldsWithValues(Loc);
643       }
644     }
645   }
646 
647   void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *S) {
648     const Expr *SubExpr = S->getSubExpr();
649     assert(SubExpr != nullptr);
650 
651     StorageLocation &Loc = Env.createStorageLocation(*S);
652     Env.setStorageLocation(*S, Loc);
653 
654     if (SubExpr->getType()->isRecordType())
655       // Nothing else left to do -- we initialized the record when transferring
656       // `SubExpr`.
657       return;
658 
659     if (Value *SubExprVal = Env.getValue(*SubExpr))
660       Env.setValue(Loc, *SubExprVal);
661   }
662 
663   void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *S) {
664     const Expr *SubExpr = S->getSubExpr();
665     assert(SubExpr != nullptr);
666 
667     propagateValue(*SubExpr, *S, Env);
668   }
669 
670   void VisitCXXStaticCastExpr(const CXXStaticCastExpr *S) {
671     if (S->getCastKind() == CK_NoOp) {
672       const Expr *SubExpr = S->getSubExpr();
673       assert(SubExpr != nullptr);
674 
675       propagateValueOrStorageLocation(*SubExpr, *S, Env);
676     }
677   }
678 
679   void VisitConditionalOperator(const ConditionalOperator *S) {
680     const Environment *TrueEnv = StmtToEnv.getEnvironment(*S->getTrueExpr());
681     const Environment *FalseEnv = StmtToEnv.getEnvironment(*S->getFalseExpr());
682 
683     if (TrueEnv == nullptr || FalseEnv == nullptr) {
684       // If the true or false branch is dead, we may not have an environment for
685       // it. We could handle this specifically by forwarding the value or
686       // location of the live branch, but this case is rare enough that this
687       // probably isn't worth the additional complexity.
688       return;
689     }
690 
691     if (S->isGLValue()) {
692       StorageLocation *TrueLoc = TrueEnv->getStorageLocation(*S->getTrueExpr());
693       StorageLocation *FalseLoc =
694           FalseEnv->getStorageLocation(*S->getFalseExpr());
695       if (TrueLoc == FalseLoc && TrueLoc != nullptr)
696         Env.setStorageLocation(*S, *TrueLoc);
697     } else if (!S->getType()->isRecordType()) {
698       // The conditional operator can evaluate to either of the values of the
699       // two branches. To model this, join these two values together to yield
700       // the result of the conditional operator.
701       // Note: Most joins happen in `computeBlockInputState()`, but this case is
702       // different:
703       // - `computeBlockInputState()` (which in turn calls `Environment::join()`
704       //   joins values associated with the _same_ expression or storage
705       //   location, then associates the joined value with that expression or
706       //   storage location. This join has nothing to do with transfer --
707       //   instead, it joins together the results of performing transfer on two
708       //   different blocks.
709       // - Here, we join values associated with _different_ expressions (the
710       //   true and false branch), then associate the joined value with a third
711       //   expression (the conditional operator itself). This join is what it
712       //   means to perform transfer on the conditional operator.
713       if (Value *Val = Environment::joinValues(
714               S->getType(), TrueEnv->getValue(*S->getTrueExpr()), *TrueEnv,
715               FalseEnv->getValue(*S->getFalseExpr()), *FalseEnv, Env, Model))
716         Env.setValue(*S, *Val);
717     }
718   }
719 
720   void VisitInitListExpr(const InitListExpr *S) {
721     QualType Type = S->getType();
722 
723     if (!Type->isRecordType()) {
724       // Until array initialization is implemented, we skip arrays and don't
725       // need to care about cases where `getNumInits() > 1`.
726       if (!Type->isArrayType() && S->getNumInits() == 1)
727         propagateValueOrStorageLocation(*S->getInit(0), *S, Env);
728       return;
729     }
730 
731     // If the initializer list is transparent, there's nothing to do.
732     if (S->isSemanticForm() && S->isTransparent())
733       return;
734 
735     RecordStorageLocation &Loc = Env.getResultObjectLocation(*S);
736 
737     // Initialization of base classes and fields of record type happens when we
738     // visit the nested `CXXConstructExpr` or `InitListExpr` for that base class
739     // or field. We therefore only need to deal with fields of non-record type
740     // here.
741 
742     RecordInitListHelper InitListHelper(S);
743 
744     for (auto [Field, Init] : InitListHelper.field_inits()) {
745       if (Field->getType()->isRecordType())
746         continue;
747       if (Field->getType()->isReferenceType()) {
748         assert(Field->getType().getCanonicalType()->getPointeeType() ==
749                Init->getType().getCanonicalType());
750         Loc.setChild(*Field, &Env.createObject(Field->getType(), Init));
751         continue;
752       }
753       assert(Field->getType().getCanonicalType().getUnqualifiedType() ==
754              Init->getType().getCanonicalType().getUnqualifiedType());
755       StorageLocation *FieldLoc = Loc.getChild(*Field);
756       // Locations for non-reference fields must always be non-null.
757       assert(FieldLoc != nullptr);
758       Value *Val = Env.getValue(*Init);
759       if (Val == nullptr && isa<ImplicitValueInitExpr>(Init) &&
760           Init->getType()->isPointerType())
761         Val =
762             &Env.getOrCreateNullPointerValue(Init->getType()->getPointeeType());
763       if (Val == nullptr)
764         Val = Env.createValue(Field->getType());
765       if (Val != nullptr)
766         Env.setValue(*FieldLoc, *Val);
767     }
768 
769     for (const auto &[FieldName, FieldLoc] : Loc.synthetic_fields()) {
770       QualType FieldType = FieldLoc->getType();
771       if (FieldType->isRecordType()) {
772         Env.initializeFieldsWithValues(*cast<RecordStorageLocation>(FieldLoc));
773       } else {
774         if (Value *Val = Env.createValue(FieldType))
775           Env.setValue(*FieldLoc, *Val);
776       }
777     }
778 
779     // FIXME: Implement array initialization.
780   }
781 
782   void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *S) {
783     Env.setValue(*S, Env.getBoolLiteralValue(S->getValue()));
784   }
785 
786   void VisitIntegerLiteral(const IntegerLiteral *S) {
787     Env.setValue(*S, Env.getIntLiteralValue(S->getValue()));
788   }
789 
790   void VisitParenExpr(const ParenExpr *S) {
791     // The CFG does not contain `ParenExpr` as top-level statements in basic
792     // blocks, however manual traversal to sub-expressions may encounter them.
793     // Redirect to the sub-expression.
794     auto *SubExpr = S->getSubExpr();
795     assert(SubExpr != nullptr);
796     Visit(SubExpr);
797   }
798 
799   void VisitExprWithCleanups(const ExprWithCleanups *S) {
800     // The CFG does not contain `ExprWithCleanups` as top-level statements in
801     // basic blocks, however manual traversal to sub-expressions may encounter
802     // them. Redirect to the sub-expression.
803     auto *SubExpr = S->getSubExpr();
804     assert(SubExpr != nullptr);
805     Visit(SubExpr);
806   }
807 
808 private:
809   /// Returns the value for the sub-expression `SubExpr` of a logic operator.
810   BoolValue &getLogicOperatorSubExprValue(const Expr &SubExpr) {
811     // `SubExpr` and its parent logic operator might be part of different basic
812     // blocks. We try to access the value that is assigned to `SubExpr` in the
813     // corresponding environment.
814     if (const Environment *SubExprEnv = StmtToEnv.getEnvironment(SubExpr))
815       if (auto *Val =
816               dyn_cast_or_null<BoolValue>(SubExprEnv->getValue(SubExpr)))
817         return *Val;
818 
819     // The sub-expression may lie within a basic block that isn't reachable,
820     // even if we need it to evaluate the current (reachable) expression
821     // (see https://discourse.llvm.org/t/70775). In this case, visit `SubExpr`
822     // within the current environment and then try to get the value that gets
823     // assigned to it.
824     if (Env.getValue(SubExpr) == nullptr)
825       Visit(&SubExpr);
826     if (auto *Val = dyn_cast_or_null<BoolValue>(Env.getValue(SubExpr)))
827       return *Val;
828 
829     // If the value of `SubExpr` is still unknown, we create a fresh symbolic
830     // boolean value for it.
831     return Env.makeAtomicBoolValue();
832   }
833 
834   // If context sensitivity is enabled, try to analyze the body of the callee
835   // `F` of `S`. The type `E` must be either `CallExpr` or `CXXConstructExpr`.
836   template <typename E>
837   void transferInlineCall(const E *S, const FunctionDecl *F) {
838     const auto &Options = Env.getDataflowAnalysisContext().getOptions();
839     if (!(Options.ContextSensitiveOpts &&
840           Env.canDescend(Options.ContextSensitiveOpts->Depth, F)))
841       return;
842 
843     const AdornedCFG *ACFG = Env.getDataflowAnalysisContext().getAdornedCFG(F);
844     if (!ACFG)
845       return;
846 
847     // FIXME: We don't support context-sensitive analysis of recursion, so
848     // we should return early here if `F` is the same as the `FunctionDecl`
849     // holding `S` itself.
850 
851     auto ExitBlock = ACFG->getCFG().getExit().getBlockID();
852 
853     auto CalleeEnv = Env.pushCall(S);
854 
855     // FIXME: Use the same analysis as the caller for the callee. Note,
856     // though, that doing so would require support for changing the analysis's
857     // ASTContext.
858     auto Analysis = NoopAnalysis(ACFG->getDecl().getASTContext(),
859                                  DataflowAnalysisOptions{Options});
860 
861     auto BlockToOutputState =
862         dataflow::runDataflowAnalysis(*ACFG, Analysis, CalleeEnv);
863     assert(BlockToOutputState);
864     assert(ExitBlock < BlockToOutputState->size());
865 
866     auto &ExitState = (*BlockToOutputState)[ExitBlock];
867     assert(ExitState);
868 
869     Env.popCall(S, ExitState->Env);
870   }
871 
872   const StmtToEnvMap &StmtToEnv;
873   Environment &Env;
874   Environment::ValueModel &Model;
875 };
876 
877 } // namespace
878 
879 void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env,
880               Environment::ValueModel &Model) {
881   TransferVisitor(StmtToEnv, Env, Model).Visit(&S);
882 }
883 
884 } // namespace dataflow
885 } // namespace clang
886