Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
[ghstack-poisoned]
  • Loading branch information
smeenai committed Dec 3, 2024
1 parent d497eb9 commit aff8c66
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
17 changes: 4 additions & 13 deletions clang/lib/CIR/CodeGen/CIRGenClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,20 +429,11 @@ class AssignmentMemcpyizer : public FieldMemcpyizer {
}
return nullptr;
} else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
if (!(MD && isMemcpyEquivalentSpecialMember(MD)))
return nullptr;
MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
if (!IOA)
return nullptr;
FieldDecl *Field = dyn_cast<FieldDecl>(IOA->getMemberDecl());
if (!Field || !isMemcpyableField(Field))
return nullptr;
MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->getMemberDecl()))
return nullptr;
return Field;
// We want to represent all calls explicitly for analysis purposes.
return nullptr;
} else if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
// TODO(cir): https://github.com/llvm/clangir/issues/1177: This can result
// in memcpys instead of calls to trivial member functions.
FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
if (!FD || FD->getBuiltinID() != Builtin::BI__builtin_memcpy)
return nullptr;
Expand Down
30 changes: 30 additions & 0 deletions clang/test/CIR/CodeGen/assign-operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,33 @@ struct Trivial {
void copyTrivial(Trivial &a, Trivial &b) {
a = b;
}

struct ContainsTrivial {
Trivial t1;
Trivial t2;
ContainsTrivial &operator=(const ContainsTrivial &);
};

// We should explicitly call operator= even for trivial types.
// CHECK-LABEL: cir.func @_ZN15ContainsTrivialaSERKS_(
// CHECK: cir.call @_ZN7TrivialaSERKS_(
// CHECK: cir.call @_ZN7TrivialaSERKS_(
ContainsTrivial &ContainsTrivial::operator=(const ContainsTrivial &) = default;

struct ContainsTrivialArray {
Trivial arr[2];
ContainsTrivialArray &operator=(const ContainsTrivialArray &);
};

// We should be calling operator= here but don't currently.
// CHECK-LABEL: cir.func @_ZN20ContainsTrivialArrayaSERKS_(
// CHECK: %[[#THIS_LOAD:]] = cir.load deref %[[#]]
// CHECK-NEXT: %[[#THIS_ARR:]] = cir.get_member %[[#THIS_LOAD]][0] {name = "arr"}
// CHECK-NEXT: %[[#THIS_ARR_CAST:]] = cir.cast(bitcast, %[[#THIS_ARR]] : !cir.ptr<!cir.array<!ty_Trivial x 2>>), !cir.ptr<!void>
// CHECK-NEXT: %[[#OTHER_LOAD:]] = cir.load %[[#]]
// CHECK-NEXT: %[[#OTHER_ARR:]] = cir.get_member %[[#OTHER_LOAD]][0] {name = "arr"}
// CHECK-NEXT: %[[#OTHER_ARR_CAST:]] = cir.cast(bitcast, %[[#OTHER_ARR]] : !cir.ptr<!cir.array<!ty_Trivial x 2>>), !cir.ptr<!void>
// CHECK-NEXT: %[[#MEMCPY_SIZE:]] = cir.const #cir.int<80> : !u64i
// CHECK-NEXT: cir.libc.memcpy %[[#MEMCPY_SIZE]] bytes from %[[#OTHER_ARR_CAST]] to %[[#THIS_ARR_CAST]]
ContainsTrivialArray &
ContainsTrivialArray::operator=(const ContainsTrivialArray &) = default;

0 comments on commit aff8c66

Please sign in to comment.