clang: include/clang/Analysis/FlowSensitive/DataflowEnvironment.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
16#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWENVIRONMENT_H
17
29#include "llvm/ADT/DenseMap.h"
30#include "llvm/ADT/DenseSet.h"
31#include "llvm/ADT/MapVector.h"
32#include "llvm/Support/Compiler.h"
33#include "llvm/Support/ErrorHandling.h"
34#include
35#include
36#include <type_traits>
37#include
38#include
39
41namespace dataflow {
42
43
48};
49
50
52
54
55
57};
58
59
60
61
62
63
64
66public:
67
68
70 public:
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
90
91
93 }
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
145
146
147 switch (compare(Type, Prev, PrevEnv, Current, CurrentEnv)) {
149 return std::nullopt;
154 }
155 llvm_unreachable("all cases in switch covered");
156 }
157 };
158
159
160
162 : DACtx(&DACtx),
163 FlowConditionToken(DACtx.arena().makeFlowConditionToken()) {}
164
165
166
168 InitialTargetStmt = &S;
169 }
170
171
172
173
174
175
176
177
181 InitialTargetFunc = &FD;
182 }
183
184
186
189
190
191
192
193
194
196
197
198
199
200
201
202
203
204
206
207
208
209
210
211
212
213
214
215
216
217
220
221
222
225
226
227
228
229
230
231
232
233
234
235
238
239
240
241
245 };
246
247
248
249
250
251
252
253
257
258
259
260
261
262
263
264
265
266
267
272
273
274
275
276
277
278
279
282
283
284
285
286
287
288
289
290
291
293
294
295
296
298
299
300
301
303
304
305
306
307
308
310
311
312
314
315
317
318
319
320
321
322
323
324
326
327
328
329
330
331
332
334
335
336
337
338
339
340 template
341 std::enable_if_t<std::is_base_of_v<StorageLocation, T>, T *>
344 }
345 template
346 std::enable_if_t<std::is_base_of_v<StorageLocation, T>, T *>
349 }
350
351
352
353
355 return ThisPointeeLoc;
356 }
357
358
359
361 ThisPointeeLoc = &Loc;
362 }
363
364
365
366
367
368
369
370
371
372
373
374
375
378
379
380
381
382
383
384
385
386
387
390 ()->getReturnType()->isReferenceType());
391 return ReturnVal;
392 }
393
394
395
396
397
398
399
400
403 getCurrentFunc()->getReturnType()->isReferenceType());
404 return ReturnLoc;
405 }
406
407
408
409
410
411
414 ()->getReturnType()->isReferenceType());
415 ReturnVal = Val;
416 }
417
418
419
420
421
422
423
426 getCurrentFunc()->getReturnType()->isReferenceType());
427 ReturnLoc = Loc;
428 }
429
430
431
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
451
452
453
454
455
457 return createObjectInternal(nullptr, Ty, InitExpr);
458 }
459
460
461
462
463
464
466 return createObjectInternal(&D, D.getType(), D.getInit());
467 }
468
469
470
471
472
473
475 return createObjectInternal(&D, D.getType(), InitExpr);
476 }
477
478
479
480
481
482
483
484
488 }
489
490
491
492
493
494
496
497
499
500
501
502
503
504
505
507
508
509
510
511
512
513
515
516
517
518
519
520
521
523
524
525
527
528
529
530
531
532
533 template
534 std::enable_if_t<std::is_base_of_v<Value, T>, T *>
537 }
538 template
539 std::enable_if_t<std::is_base_of_v<Value, T>, T *>
541 return cast_or_null(getValue(D));
542 }
543 template
544 std::enable_if_t<std::is_base_of_v<Value, T>, T *> get(const Expr &E) const {
545 return cast_or_null(getValue(E));
546 }
547
548
549
550
551
552
553
554
555 template <typename T, typename... Args>
556 std::enable_if_t<std::is_base_of<Value, T>::value, T &>
558 return arena().create<T>(std::forward(args)...);
559 }
560
561
562
565 }
566
567
568
571 }
572
573
576 }
577
578
581 }
582
583
584
585
586
590 }
591
592
593
594
595
599 }
600
601
602
605 }
606
607
608
609
610
614 }
615
616
617
618
619
623 }
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
640
641
643
644
645
646
647
648
649
650
651
652
654
655
656
657
659
660
661
663 return CallStack.empty() ? InitialTargetFunc : CallStack.back();
664 }
665
666
667
669
670
671
672
673
675
676
678
680
681 LLVM_DUMP_METHOD void dump() const;
682 LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
683
684private:
685 using PrValueToResultObject =
686 llvm::DenseMap<const Expr *, RecordStorageLocation *>;
687
688
690
691
692
693
694
695
696
697
698
699
700
701
703 llvm::DenseSet &Visited,
704 int Depth, int &CreatedValuesCount);
705
706
707
708
709
711 llvm::DenseSet &Visited,
712 int Depth, int &CreatedValuesCount);
713
714
715
716
717
718
719
721 llvm::DenseSet &Visited, int Depth,
722 int &CreatedValuesCount);
723
724
725
727 const Expr *InitExpr);
728
729
730
731
732 void pushCallInternal(const FunctionDecl *FuncDecl,
734
735
736
737 void initFieldsGlobalsAndFuncs(const ReferencedDecls &Referenced);
738
739 static PrValueToResultObject
744
745 static PrValueToResultObject
749
750
752
753
754
755
756
757
758
759 std::vector<const FunctionDecl *> CallStack;
760
761
762
763 const FunctionDecl *InitialTargetFunc = nullptr;
764
765
766
767
768 Stmt *InitialTargetStmt = nullptr;
769
770
771
772
773
774
775
776
777 std::shared_ptr ResultObjectMap;
778
779
780
781
782
783 Value *ReturnVal = nullptr;
784
785
787
788
789
791
792
793
795
796
797
798
799
800 llvm::DenseMap<const ValueDecl *, StorageLocation *> DeclToLoc;
801 llvm::DenseMap<const Expr *, StorageLocation *> ExprToLoc;
802
803
804
805
806 llvm::MapVector<const Expr *, Value *> ExprToVal;
807 llvm::MapVector<const StorageLocation *, Value *> LocToVal;
808
809 Atom FlowConditionToken;
810};
811
812
813
814
815
817 const Environment &Env);
818
819
820
821
823 const Environment &Env);
824
825}
826}
827
828#endif
llvm::DenseSet< const void * > Visited
C Language Family Type Representation.
Represents a call to a C++ constructor.
Represents a call to a member function that may be written either with member call syntax (e....
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
This represents one expression.
Represents a function declaration or definition.
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A (possibly-)qualified type.
Stmt - This represents one statement.
The base class of the type hierarchy.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
The Arena owns the objects that model data within an analysis.
IntegerValue & makeIntLiteral(llvm::APInt Value)
Returns a symbolic integer value that models an integer literal equal to Value.
TopBoolValue & makeTopValue()
Creates a fresh Top boolean value.
BoolValue & makeBoolValue(const Formula &)
Creates a BoolValue wrapping a particular formula.
AtomicBoolValue & makeAtomValue()
Creates a fresh atom and wraps in in an AtomicBoolValue.
std::enable_if_t< std::is_base_of< StorageLocation, T >::value, T & > create(Args &&...args)
Creates a T (some subclass of StorageLocation), forwarding args to the constructor,...
const Formula & formula() const
Owns objects that encompass the state of a program and stores context that is used during dataflow an...
Supplements Environment with non-standard comparison and join operations.
virtual std::optional< WidenResult > widen(QualType Type, Value &Prev, const Environment &PrevEnv, Value &Current, Environment &CurrentEnv)
This function may widen the current value – replace it with an approximation that can reach a fixed p...
virtual ~ValueModel()=default
virtual void join(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2, Value &JoinedVal, Environment &JoinedEnv)
Modifies JoinedVal to approximate both Val1 and Val2.
virtual ComparisonResult compare(QualType Type, const Value &Val1, const Environment &Env1, const Value &Val2, const Environment &Env2)
Returns: Same: Val1 is equivalent to Val2, according to the model.
Holds the state of the program (store and heap) at a given program point.
bool allows(const Formula &) const
Returns true if the formula may be true when this point is reached.
void initializeFieldsWithValues(RecordStorageLocation &Loc)
LatticeEffect widen(const Environment &PrevEnv, Environment::ValueModel &Model)
Widens the environment point-wise, using PrevEnv as needed to inform the approximation.
PointerValue & getOrCreateNullPointerValue(QualType PointeeType)
Returns a pointer value that represents a null pointer.
BoolValue & makeAnd(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value that represents the conjunction of LHS and RHS.
std::enable_if_t< std::is_base_of_v< Value, T >, T * > get(const StorageLocation &Loc) const
Returns the result of casting getValue(...) to a subclass of Value (using cast_or_null).
RecordStorageLocation * getThisPointeeStorageLocation() const
Returns the storage location assigned to the this pointee in the environment or null if the this poin...
BoolValue & makeIff(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value represents LHS <=> RHS.
Environment pushCall(const CallExpr *Call) const
Creates and returns an environment to use for an inline analysis of the callee.
void clearValue(const StorageLocation &Loc)
Clears any association between Loc and a value in the environment.
StorageLocation * getStorageLocation(const ValueDecl &D) const
Returns the storage location assigned to D in the environment, or null if D isn't assigned a storage ...
LLVM_DUMP_METHOD void dump() const
Environment(DataflowAnalysisContext &DACtx, Stmt &S)
Creates an environment that uses DACtx to store objects that encompass the state of a program,...
void setReturnValue(Value *Val)
Sets the return value of the function currently being analyzed.
Environment(Environment &&Other)=default
BoolValue & makeTopBoolValue() const
Returns a unique instance of boolean Top.
StorageLocation & createObject(const VarDecl &D)
Creates an object for the variable declaration D.
void initializeFieldsWithValues(RecordStorageLocation &Loc, QualType Type)
Initializes the fields (including synthetic fields) of Loc with values, unless values of the field ty...
StorageLocation & createStorageLocation(QualType Type)
Creates a storage location appropriate for Type.
Value * getReturnValue() const
Returns the return value of the function currently being analyzed.
Environment fork() const
Returns a new environment that is a copy of this one.
void popCall(const CallExpr *Call, const Environment &CalleeEnv)
Moves gathered information back into this from a CalleeEnv created via pushCall.
Environment(DataflowAnalysisContext &DACtx)
Creates an environment that uses DACtx to store objects that encompass the state of a program.
bool equivalentTo(const Environment &Other, Environment::ValueModel &Model) const
Returns true if and only if the environment is equivalent to Other, i.e the two environments:
BoolValue & makeAtomicBoolValue() const
Returns an atomic boolean value.
std::enable_if_t< std::is_base_of_v< Value, T >, T * > get(const ValueDecl &D) const
bool proves(const Formula &) const
Returns true if the formula is always true when this point is reached.
Value * getValue(const StorageLocation &Loc) const
Returns the value assigned to Loc in the environment or null if Loc isn't assigned a value in the env...
Environment & operator=(const Environment &Other)=delete
const FunctionDecl * getCurrentFunc() const
Returns the function currently being analyzed, or null if the code being analyzed isn't part of a fun...
BoolValue & getBoolLiteralValue(bool Value) const
Returns a symbolic boolean value that models a boolean literal equal to Value
StorageLocation & createObject(QualType Ty, const Expr *InitExpr=nullptr)
Creates an object (i.e.
void assume(const Formula &)
Record a fact that must be true if this point in the program is reached.
DataflowAnalysisContext & getDataflowAnalysisContext() const
Returns the DataflowAnalysisContext used by the environment.
static Value * joinValues(QualType Ty, Value *Val1, const Environment &Env1, Value *Val2, const Environment &Env2, Environment &JoinedEnv, Environment::ValueModel &Model)
Returns a value that approximates both Val1 and Val2, or null if no such value can be produced.
void setStorageLocation(const ValueDecl &D, StorageLocation &Loc)
Assigns Loc as the storage location of D in the environment.
void removeDecl(const ValueDecl &D)
Removes the location assigned to D in the environment (if any).
RecordStorageLocation & getResultObjectLocation(const Expr &RecordPRValue) const
Returns the location of the result object for a record-type prvalue.
std::enable_if_t< std::is_base_of_v< StorageLocation, T >, T * > get(const Expr &E) const
ExprJoinBehavior
How to treat expression state (ExprToLoc and ExprToVal) in a join.
static Environment join(const Environment &EnvA, const Environment &EnvB, Environment::ValueModel &Model, ExprJoinBehavior ExprBehavior)
Joins two environments by taking the intersection of storage locations and values that are stored in ...
Value * createValue(QualType Type)
Creates a value appropriate for Type, if Type is supported, otherwise returns null.
void setValue(const StorageLocation &Loc, Value &Val)
Assigns Val as the value of Loc in the environment.
IntegerValue & getIntLiteralValue(llvm::APInt Value) const
Returns a symbolic integer value that models an integer literal equal to Value
Environment & operator=(Environment &&Other)=default
void setThisPointeeStorageLocation(RecordStorageLocation &Loc)
Sets the storage location assigned to the this pointee in the environment.
Atom getFlowConditionToken() const
Returns a boolean variable that identifies the flow condition (FC).
Environment(DataflowAnalysisContext &DACtx, const FunctionDecl &FD)
Creates an environment that uses DACtx to store objects that encompass the state of a program,...
StorageLocation & createObject(const ValueDecl &D, const Expr *InitExpr)
Creates an object for the variable declaration D.
BoolValue & makeNot(BoolValue &Val) const
Returns a boolean value that represents the negation of Val.
size_t callStackSize() const
Returns the size of the call stack, not counting the initial analysis target.
bool canDescend(unsigned MaxDepth, const FunctionDecl *Callee) const
Returns whether this Environment can be extended to analyze the given Callee (i.e.
std::enable_if_t< std::is_base_of_v< StorageLocation, T >, T * > get(const ValueDecl &D) const
Returns the result of casting getStorageLocation(...) to a subclass of StorageLocation (using cast_or...
void initialize()
Assigns storage locations and values to all parameters, captures, global variables,...
BoolValue & makeOr(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value that represents the disjunction of LHS and RHS.
std::enable_if_t< std::is_base_of< Value, T >::value, T & > create(Args &&...args)
Creates a T (some subclass of Value), forwarding args to the constructor, and returns a reference to ...
void setReturnStorageLocation(StorageLocation *Loc)
Sets the storage location for the reference returned by the function currently being analyzed.
StorageLocation * getReturnStorageLocation() const
Returns the storage location for the reference returned by the function currently being analyzed.
std::enable_if_t< std::is_base_of_v< Value, T >, T * > get(const Expr &E) const
BoolValue & makeImplication(BoolValue &LHS, BoolValue &RHS) const
Returns a boolean value represents LHS => RHS.
Models a symbolic pointer. Specifically, any value of type T*.
A storage location for a record (struct, class, or union).
Base class for elements of the local variable store and of the heap.
Base class for all values computed by abstract interpretation.
Atom
Identifies an atomic boolean variable such as "V1".
ComparisonResult
Indicates the result of a tentative comparison.
RecordStorageLocation * getImplicitObjectLocation(const CXXMemberCallExpr &MCE, const Environment &Env)
Returns the storage location for the implicit object of a CXXMemberCallExpr, or null if none is defin...
RecordStorageLocation * getBaseObjectLocation(const MemberExpr &ME, const Environment &Env)
Returns the storage location for the base object of a MemberExpr, or null if none is defined in the e...
LatticeEffect
Effect indicating whether a lattice operation resulted in a new value.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
@ Other
Other implicit parameter.
A collection of several types of declarations, all referenced from the same function.
The result of a widen operation.
LatticeEffect Effect
Whether V represents a "change" (that is, a different value) with respect to the previous value in th...
Value * V
Non-null pointer to a potentially widened version of the input value.