Skip to content

Commit fb6383d

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:d9c31ee9568277e4303715736b40925e41503596 into amd-gfx:a79be10fda42
Local branch amd-gfx a79be10 Merged main:eac68447adac3852524c66acac7ab64d90205f47 into amd-gfx:b12f0cb54b03 Remote branch main d9c31ee Fix overflow flag for i128 USUBO
2 parents a79be10 + d9c31ee commit fb6383d

File tree

39 files changed

+647
-231
lines changed

39 files changed

+647
-231
lines changed

clang/docs/ClangFormatStyleOptions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6204,7 +6204,7 @@ the configuration (without a prefix: ``Auto``).
62046204

62056205
For example the configuration,
62066206

6207-
.. code-block:: c++
6207+
.. code-block:: yaml
62086208
62096209
TableGenBreakInsideDAGArg: BreakAll
62106210
TableGenBreakingDAGArgOperators: ['ins', 'outs']

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,8 @@ Arm and AArch64 Support
445445
like ``target_version`` or ``target_clones``.
446446
- Support has been added for the following processors (-mcpu identifiers in parenthesis):
447447
* Arm Cortex-A78AE (cortex-a78ae).
448+
* Arm Cortex-A520AE (cortex-a520ae).
449+
* Arm Cortex-A720AE (cortex-a720ae).
448450

449451
Android Support
450452
^^^^^^^^^^^^^^^

clang/include/clang/Analysis/FlowSensitive/RecordOps.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ namespace dataflow {
3131
///
3232
/// Requirements:
3333
///
34-
/// `Src` and `Dst` must have the same canonical unqualified type.
34+
/// Either:
35+
/// - `Src` and `Dest` must have the same canonical unqualified type, or
36+
/// - The type of `Src` must be derived from `Dest`, or
37+
/// - The type of `Dest` must be derived from `Src` (in this case, any fields
38+
/// that are only present in `Dest` are not overwritten).
3539
void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst,
3640
Environment &Env);
3741

clang/include/clang/Format/Format.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4735,7 +4735,7 @@ struct FormatStyle {
47354735
/// the specified identifiers.
47364736
///
47374737
/// For example the configuration,
4738-
/// \code
4738+
/// \code{.yaml}
47394739
/// TableGenBreakInsideDAGArg: BreakAll
47404740
/// TableGenBreakingDAGArgOperators: ['ins', 'outs']
47414741
/// \endcode

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3337,6 +3337,8 @@ template <class Emitter>
33373337
unsigned
33383338
ByteCodeExprGen<Emitter>::collectBaseOffset(const RecordType *BaseType,
33393339
const RecordType *DerivedType) {
3340+
assert(BaseType);
3341+
assert(DerivedType);
33403342
const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->getDecl());
33413343
const RecordDecl *CurDecl = DerivedType->getDecl();
33423344
const Record *CurRecord = getRecord(CurDecl);

clang/lib/AST/Interp/Disasm.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "FunctionPointer.h"
1717
#include "Integral.h"
1818
#include "IntegralAP.h"
19+
#include "InterpFrame.h"
1920
#include "Opcode.h"
2021
#include "PrimType.h"
2122
#include "Program.h"
@@ -206,3 +207,29 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const {
206207
if (isDummy())
207208
OS << " dummy";
208209
}
210+
211+
LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS,
212+
unsigned Indent) const {
213+
unsigned Spaces = Indent * 2;
214+
{
215+
ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
216+
OS.indent(Spaces);
217+
if (getCallee())
218+
describe(OS);
219+
else
220+
OS << "Frame (Depth: " << getDepth() << ")";
221+
OS << "\n";
222+
}
223+
OS.indent(Spaces) << "Function: " << getFunction();
224+
if (const Function *F = getFunction()) {
225+
OS << " (" << F->getName() << ")";
226+
}
227+
OS << "\n";
228+
OS.indent(Spaces) << "This: " << getThis() << "\n";
229+
OS.indent(Spaces) << "RVO: " << getRVOPtr() << "\n";
230+
231+
while (const InterpFrame *F = this->Caller) {
232+
F->dump(OS, Indent + 1);
233+
F = F->Caller;
234+
}
235+
}

clang/lib/AST/Interp/InterpFrame.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ class InterpFrame final : public Frame {
123123

124124
unsigned getDepth() const { return Depth; }
125125

126+
void dump() const { dump(llvm::errs(), 0); }
127+
void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const;
128+
126129
private:
127130
/// Returns an original argument from the stack.
128131
template <typename T> const T &stackRef(unsigned Offset) const {

clang/lib/Analysis/FlowSensitive/RecordOps.cpp

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,52 @@
1414

1515
#define DEBUG_TYPE "dataflow"
1616

17-
void clang::dataflow::copyRecord(RecordStorageLocation &Src,
18-
RecordStorageLocation &Dst, Environment &Env) {
17+
namespace clang::dataflow {
18+
19+
static void copyField(const ValueDecl &Field, StorageLocation *SrcFieldLoc,
20+
StorageLocation *DstFieldLoc, RecordStorageLocation &Dst,
21+
Environment &Env) {
22+
assert(Field.getType()->isReferenceType() ||
23+
(SrcFieldLoc != nullptr && DstFieldLoc != nullptr));
24+
25+
if (Field.getType()->isRecordType()) {
26+
copyRecord(cast<RecordStorageLocation>(*SrcFieldLoc),
27+
cast<RecordStorageLocation>(*DstFieldLoc), Env);
28+
} else if (Field.getType()->isReferenceType()) {
29+
Dst.setChild(Field, SrcFieldLoc);
30+
} else {
31+
if (Value *Val = Env.getValue(*SrcFieldLoc))
32+
Env.setValue(*DstFieldLoc, *Val);
33+
else
34+
Env.clearValue(*DstFieldLoc);
35+
}
36+
}
37+
38+
static void copySyntheticField(QualType FieldType, StorageLocation &SrcFieldLoc,
39+
StorageLocation &DstFieldLoc, Environment &Env) {
40+
if (FieldType->isRecordType()) {
41+
copyRecord(cast<RecordStorageLocation>(SrcFieldLoc),
42+
cast<RecordStorageLocation>(DstFieldLoc), Env);
43+
} else {
44+
if (Value *Val = Env.getValue(SrcFieldLoc))
45+
Env.setValue(DstFieldLoc, *Val);
46+
else
47+
Env.clearValue(DstFieldLoc);
48+
}
49+
}
50+
51+
void copyRecord(RecordStorageLocation &Src, RecordStorageLocation &Dst,
52+
Environment &Env) {
1953
auto SrcType = Src.getType().getCanonicalType().getUnqualifiedType();
2054
auto DstType = Dst.getType().getCanonicalType().getUnqualifiedType();
2155

2256
auto SrcDecl = SrcType->getAsCXXRecordDecl();
2357
auto DstDecl = DstType->getAsCXXRecordDecl();
2458

25-
bool compatibleTypes =
59+
[[maybe_unused]] bool compatibleTypes =
2660
SrcType == DstType ||
27-
(SrcDecl && DstDecl && SrcDecl->isDerivedFrom(DstDecl));
28-
(void)compatibleTypes;
61+
(SrcDecl != nullptr && DstDecl != nullptr &&
62+
(SrcDecl->isDerivedFrom(DstDecl) || DstDecl->isDerivedFrom(SrcDecl)));
2963

3064
LLVM_DEBUG({
3165
if (!compatibleTypes) {
@@ -35,45 +69,27 @@ void clang::dataflow::copyRecord(RecordStorageLocation &Src,
3569
});
3670
assert(compatibleTypes);
3771

38-
for (auto [Field, DstFieldLoc] : Dst.children()) {
39-
StorageLocation *SrcFieldLoc = Src.getChild(*Field);
40-
41-
assert(Field->getType()->isReferenceType() ||
42-
(SrcFieldLoc != nullptr && DstFieldLoc != nullptr));
43-
44-
if (Field->getType()->isRecordType()) {
45-
copyRecord(cast<RecordStorageLocation>(*SrcFieldLoc),
46-
cast<RecordStorageLocation>(*DstFieldLoc), Env);
47-
} else if (Field->getType()->isReferenceType()) {
48-
Dst.setChild(*Field, SrcFieldLoc);
49-
} else {
50-
if (Value *Val = Env.getValue(*SrcFieldLoc))
51-
Env.setValue(*DstFieldLoc, *Val);
52-
else
53-
Env.clearValue(*DstFieldLoc);
54-
}
55-
}
56-
57-
for (const auto &[Name, SynthFieldLoc] : Src.synthetic_fields()) {
58-
if (SynthFieldLoc->getType()->isRecordType()) {
59-
copyRecord(*cast<RecordStorageLocation>(SynthFieldLoc),
60-
cast<RecordStorageLocation>(Dst.getSyntheticField(Name)), Env);
61-
} else {
62-
if (Value *Val = Env.getValue(*SynthFieldLoc))
63-
Env.setValue(Dst.getSyntheticField(Name), *Val);
64-
else
65-
Env.clearValue(Dst.getSyntheticField(Name));
66-
}
72+
if (SrcType == DstType || (SrcDecl != nullptr && DstDecl != nullptr &&
73+
SrcDecl->isDerivedFrom(DstDecl))) {
74+
for (auto [Field, DstFieldLoc] : Dst.children())
75+
copyField(*Field, Src.getChild(*Field), DstFieldLoc, Dst, Env);
76+
for (const auto &[Name, DstFieldLoc] : Dst.synthetic_fields())
77+
copySyntheticField(DstFieldLoc->getType(), Src.getSyntheticField(Name),
78+
*DstFieldLoc, Env);
79+
} else {
80+
for (auto [Field, SrcFieldLoc] : Src.children())
81+
copyField(*Field, SrcFieldLoc, Dst.getChild(*Field), Dst, Env);
82+
for (const auto &[Name, SrcFieldLoc] : Src.synthetic_fields())
83+
copySyntheticField(SrcFieldLoc->getType(), *SrcFieldLoc,
84+
Dst.getSyntheticField(Name), Env);
6785
}
6886

6987
RecordValue *DstVal = &Env.create<RecordValue>(Dst);
7088
Env.setValue(Dst, *DstVal);
7189
}
7290

73-
bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1,
74-
const Environment &Env1,
75-
const RecordStorageLocation &Loc2,
76-
const Environment &Env2) {
91+
bool recordsEqual(const RecordStorageLocation &Loc1, const Environment &Env1,
92+
const RecordStorageLocation &Loc2, const Environment &Env2) {
7793
LLVM_DEBUG({
7894
if (Loc2.getType().getCanonicalType().getUnqualifiedType() !=
7995
Loc1.getType().getCanonicalType().getUnqualifiedType()) {
@@ -116,3 +132,5 @@ bool clang::dataflow::recordsEqual(const RecordStorageLocation &Loc1,
116132

117133
return true;
118134
}
135+
136+
} // namespace clang::dataflow

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -544,15 +544,6 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
544544
if (LocSrc == nullptr || LocDst == nullptr)
545545
return;
546546

547-
// The assignment operators are different from the type of the destination
548-
// in this model (i.e. in one of their base classes). This must be very
549-
// rare and we just bail.
550-
if (Method->getFunctionObjectParameterType()
551-
.getCanonicalType()
552-
.getUnqualifiedType() !=
553-
LocDst->getType().getCanonicalType().getUnqualifiedType())
554-
return;
555-
556547
copyRecord(*LocSrc, *LocDst, Env);
557548

558549
// If the expr is a glvalue, we can reasonably assume the operator is

clang/test/Driver/aarch64-mcpu.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@
5656
// CORTEX-A715: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a715"
5757
// RUN: %clang --target=aarch64 -mcpu=cortex-a720 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A720 %s
5858
// CORTEX-A720: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a720"
59+
// RUN: %clang --target=aarch64 -mcpu=cortex-a720ae -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A720AE %s
60+
// CORTEX-A720AE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a720ae"
5961
// RUN: %clang --target=aarch64 -mcpu=neoverse-e1 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-E1 %s
6062
// NEOVERSE-E1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-e1"
6163
// RUN: %clang --target=aarch64 -mcpu=neoverse-v1 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-V1 %s
@@ -70,6 +72,8 @@
7072
// NEOVERSE-512TVB: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-512tvb"
7173
// RUN: %clang --target=aarch64 -mcpu=cortex-a520 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A520 %s
7274
// CORTEX-A520: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a520"
75+
// RUN: %clang --target=aarch64 -mcpu=cortex-a520ae -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A520AE %s
76+
// CORTEX-A520AE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-a520ae"
7377

7478
// RUN: %clang --target=aarch64 -mcpu=cortex-r82 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEXR82 %s
7579
// CORTEXR82: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "cortex-r82"

clang/test/Misc/target-invalid-cpu-note.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55

66
// RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64
77
// AARCH64: error: unknown target CPU 'not-a-cpu'
8-
// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}
8+
// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}
99

1010
// RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE_AARCH64
1111
// TUNE_AARCH64: error: unknown target CPU 'not-a-cpu'
12-
// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}
12+
// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}
1313

1414
// RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86
1515
// X86: error: unknown target CPU 'not-a-cpu'

clang/unittests/Analysis/FlowSensitive/RecordOpsTest.cpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ TEST(RecordOpsTest, RecordsEqual) {
198198
});
199199
}
200200

201-
TEST(TransferTest, CopyRecordFromDerivedToBase) {
201+
TEST(TransferTest, CopyRecordBetweenDerivedAndBase) {
202202
std::string Code = R"(
203203
struct A {
204204
int i;
@@ -212,8 +212,23 @@ TEST(TransferTest, CopyRecordFromDerivedToBase) {
212212
// [[p]]
213213
}
214214
)";
215+
auto SyntheticFieldCallback = [](QualType Ty) -> llvm::StringMap<QualType> {
216+
CXXRecordDecl *ADecl = nullptr;
217+
if (Ty.getAsString() == "A")
218+
ADecl = Ty->getAsCXXRecordDecl();
219+
else if (Ty.getAsString() == "B")
220+
ADecl = Ty->getAsCXXRecordDecl()
221+
->bases_begin()
222+
->getType()
223+
->getAsCXXRecordDecl();
224+
else
225+
return {};
226+
QualType IntTy = getFieldNamed(ADecl, "i")->getType();
227+
return {{"synth_int", IntTy}};
228+
};
229+
// Test copying derived to base class.
215230
runDataflow(
216-
Code, /*SyntheticFieldCallback=*/{},
231+
Code, SyntheticFieldCallback,
217232
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
218233
ASTContext &ASTCtx) {
219234
Environment Env = getEnvironmentAtAnnotation(Results, "p").fork();
@@ -224,11 +239,38 @@ TEST(TransferTest, CopyRecordFromDerivedToBase) {
224239

225240
EXPECT_NE(Env.getValue(*A.getChild(*IDecl)),
226241
Env.getValue(*B.getChild(*IDecl)));
242+
EXPECT_NE(Env.getValue(A.getSyntheticField("synth_int")),
243+
Env.getValue(B.getSyntheticField("synth_int")));
227244

228245
copyRecord(B, A, Env);
229246

230247
EXPECT_EQ(Env.getValue(*A.getChild(*IDecl)),
231248
Env.getValue(*B.getChild(*IDecl)));
249+
EXPECT_EQ(Env.getValue(A.getSyntheticField("synth_int")),
250+
Env.getValue(B.getSyntheticField("synth_int")));
251+
});
252+
// Test copying base to derived class.
253+
runDataflow(
254+
Code, SyntheticFieldCallback,
255+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
256+
ASTContext &ASTCtx) {
257+
Environment Env = getEnvironmentAtAnnotation(Results, "p").fork();
258+
259+
const ValueDecl *IDecl = findValueDecl(ASTCtx, "i");
260+
auto &A = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "a");
261+
auto &B = getLocForDecl<RecordStorageLocation>(ASTCtx, Env, "b");
262+
263+
EXPECT_NE(Env.getValue(*A.getChild(*IDecl)),
264+
Env.getValue(*B.getChild(*IDecl)));
265+
EXPECT_NE(Env.getValue(A.getSyntheticField("synth_int")),
266+
Env.getValue(B.getSyntheticField("synth_int")));
267+
268+
copyRecord(A, B, Env);
269+
270+
EXPECT_EQ(Env.getValue(*A.getChild(*IDecl)),
271+
Env.getValue(*B.getChild(*IDecl)));
272+
EXPECT_EQ(Env.getValue(A.getSyntheticField("synth_int")),
273+
Env.getValue(B.getSyntheticField("synth_int")));
232274
});
233275
}
234276

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,8 +2313,6 @@ TEST(TransferTest, AssignmentOperator_ArgByValue) {
23132313
}
23142314

23152315
TEST(TransferTest, AssignmentOperatorFromBase) {
2316-
// This is a crash repro. We don't model the copy this case, so no
2317-
// expectations on the copied field of the base class are checked.
23182316
std::string Code = R"(
23192317
struct Base {
23202318
int base;
@@ -2326,14 +2324,33 @@ TEST(TransferTest, AssignmentOperatorFromBase) {
23262324
void target(Base B, Derived D) {
23272325
D.base = 1;
23282326
D.derived = 1;
2327+
// [[before]]
23292328
D = B;
2330-
// [[p]]
2329+
// [[after]]
23312330
}
23322331
)";
23332332
runDataflow(
23342333
Code,
23352334
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
2336-
ASTContext &ASTCtx) {});
2335+
ASTContext &ASTCtx) {
2336+
const Environment &EnvBefore =
2337+
getEnvironmentAtAnnotation(Results, "before");
2338+
const Environment &EnvAfter =
2339+
getEnvironmentAtAnnotation(Results, "after");
2340+
2341+
auto &BLoc =
2342+
getLocForDecl<RecordStorageLocation>(ASTCtx, EnvBefore, "B");
2343+
auto &DLoc =
2344+
getLocForDecl<RecordStorageLocation>(ASTCtx, EnvBefore, "D");
2345+
2346+
EXPECT_NE(getFieldValue(&BLoc, "base", ASTCtx, EnvBefore),
2347+
getFieldValue(&DLoc, "base", ASTCtx, EnvBefore));
2348+
EXPECT_EQ(getFieldValue(&BLoc, "base", ASTCtx, EnvAfter),
2349+
getFieldValue(&DLoc, "base", ASTCtx, EnvAfter));
2350+
2351+
EXPECT_EQ(getFieldValue(&DLoc, "derived", ASTCtx, EnvBefore),
2352+
getFieldValue(&DLoc, "derived", ASTCtx, EnvAfter));
2353+
});
23372354
}
23382355

23392356
TEST(TransferTest, AssignmentOperatorFromCallResult) {

0 commit comments

Comments
 (0)