30
30
#include " llvm/ADT/MapVector.h"
31
31
#include " llvm/Support/Compiler.h"
32
32
#include " llvm/Support/ErrorHandling.h"
33
- #include < memory>
34
33
#include < type_traits>
35
34
#include < utility>
36
35
@@ -345,6 +344,17 @@ class Environment {
345
344
// / location of the result object to pass in `this`, even though prvalues are
346
345
// / otherwise not associated with storage locations.
347
346
// /
347
+ // / FIXME: Currently, this simply returns a stable storage location for `E`,
348
+ // / but this doesn't do the right thing in scenarios like the following:
349
+ // / ```
350
+ // / MyClass c = some_condition()? MyClass(foo) : MyClass(bar);
351
+ // / ```
352
+ // / Here, `MyClass(foo)` and `MyClass(bar)` will have two different storage
353
+ // / locations, when in fact their storage locations should be the same.
354
+ // / Eventually, we want to propagate storage locations from result objects
355
+ // / down to the prvalues that initialize them, similar to the way that this is
356
+ // / done in Clang's CodeGen.
357
+ // /
348
358
// / Requirements:
349
359
// / `E` must be a prvalue of record type.
350
360
RecordStorageLocation &
@@ -452,13 +462,7 @@ class Environment {
452
462
// / Initializes the fields (including synthetic fields) of `Loc` with values,
453
463
// / unless values of the field type are not supported or we hit one of the
454
464
// / limits at which we stop producing values.
455
- // / If `Type` is provided, initializes only those fields that are modeled for
456
- // / `Type`; this is intended for use in cases where `Loc` is a derived type
457
- // / and we only want to initialize the fields of a base type.
458
- void initializeFieldsWithValues (RecordStorageLocation &Loc, QualType Type);
459
- void initializeFieldsWithValues (RecordStorageLocation &Loc) {
460
- initializeFieldsWithValues (Loc, Loc.getType ());
461
- }
465
+ void initializeFieldsWithValues (RecordStorageLocation &Loc);
462
466
463
467
// / Assigns `Val` as the value of `Loc` in the environment.
464
468
void setValue (const StorageLocation &Loc, Value &Val);
@@ -649,9 +653,6 @@ class Environment {
649
653
LLVM_DUMP_METHOD void dump (raw_ostream &OS) const ;
650
654
651
655
private:
652
- using PrValueToResultObject =
653
- llvm::DenseMap<const Expr *, RecordStorageLocation *>;
654
-
655
656
// The copy-constructor is for use in fork() only.
656
657
Environment (const Environment &) = default ;
657
658
@@ -681,10 +682,8 @@ class Environment {
681
682
// / Initializes the fields (including synthetic fields) of `Loc` with values,
682
683
// / unless values of the field type are not supported or we hit one of the
683
684
// / limits at which we stop producing values (controlled by `Visited`,
684
- // / `Depth`, and `CreatedValuesCount`). If `Type` is different from
685
- // / `Loc.getType()`, initializes only those fields that are modeled for
686
- // / `Type`.
687
- void initializeFieldsWithValues (RecordStorageLocation &Loc, QualType Type,
685
+ // / `Depth`, and `CreatedValuesCount`).
686
+ void initializeFieldsWithValues (RecordStorageLocation &Loc,
688
687
llvm::DenseSet<QualType> &Visited, int Depth,
689
688
int &CreatedValuesCount);
690
689
@@ -703,45 +702,22 @@ class Environment {
703
702
// / and functions referenced in `FuncDecl`. `FuncDecl` must have a body.
704
703
void initFieldsGlobalsAndFuncs (const FunctionDecl *FuncDecl);
705
704
706
- static PrValueToResultObject
707
- buildResultObjectMap (DataflowAnalysisContext *DACtx,
708
- const FunctionDecl *FuncDecl,
709
- RecordStorageLocation *ThisPointeeLoc,
710
- RecordStorageLocation *LocForRecordReturnVal);
711
-
712
705
// `DACtx` is not null and not owned by this object.
713
706
DataflowAnalysisContext *DACtx;
714
707
715
- // FIXME: move the fields `CallStack`, `ResultObjectMap `, `ReturnVal`,
716
- // `ReturnLoc` and ` ThisPointeeLoc` into a separate call-context object,
717
- // shared between environments in the same call.
708
+ // FIXME: move the fields `CallStack`, `ReturnVal `, `ReturnLoc` and
709
+ // `ThisPointeeLoc` into a separate call-context object, shared between
710
+ // environments in the same call.
718
711
// https://github.com/llvm/llvm-project/issues/59005
719
712
720
713
// `DeclContext` of the block being analysed if provided.
721
714
std::vector<const DeclContext *> CallStack;
722
715
723
- // Maps from prvalues of record type to their result objects. Shared between
724
- // all environments for the same function.
725
- // FIXME: It's somewhat unsatisfactory that we have to use a `shared_ptr`
726
- // here, though the cost is acceptable: The overhead of a `shared_ptr` is
727
- // incurred when it is copied, and this happens only relatively rarely (when
728
- // we fork the environment). The need for a `shared_ptr` will go away once we
729
- // introduce a shared call-context object (see above).
730
- std::shared_ptr<PrValueToResultObject> ResultObjectMap;
731
-
732
- // The following three member variables handle various different types of
733
- // return values.
734
- // - If the return type is not a reference and not a record: Value returned
735
- // by the function.
716
+ // Value returned by the function (if it has non-reference return type).
736
717
Value *ReturnVal = nullptr ;
737
- // - If the return type is a reference: Storage location of the reference
738
- // returned by the function .
718
+ // Storage location of the reference returned by the function (if it has
719
+ // reference return type) .
739
720
StorageLocation *ReturnLoc = nullptr ;
740
- // - If the return type is a record or the function being analyzed is a
741
- // constructor: Storage location into which the return value should be
742
- // constructed.
743
- RecordStorageLocation *LocForRecordReturnVal = nullptr ;
744
-
745
721
// The storage location of the `this` pointee. Should only be null if the
746
722
// function being analyzed is only a function and not a method.
747
723
RecordStorageLocation *ThisPointeeLoc = nullptr ;
0 commit comments