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