Skip to content

Commit d5807d3

Browse files
[clang] Fix 7131569 in presence of incomplete types
Incomplete types are not considered trivially copyable by clang but we don't want to warn about invalid argument for memcpy / memset in that case because we cannot prove they are not Trivially Copyable.
1 parent a9c417c commit d5807d3

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8900,7 +8900,8 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
89008900
<< Call->getCallee()->getSourceRange());
89018901
else if (const auto *RT = PointeeTy->getAs<RecordType>()) {
89028902

8903-
bool IsTriviallyCopyableCXXRecord =
8903+
bool MayBeTriviallyCopyableCXXRecord =
8904+
RT->isIncompleteType() ||
89048905
RT->desugar().isTriviallyCopyableType(Context);
89058906

89068907
if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
@@ -8910,7 +8911,7 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
89108911
<< ArgIdx << FnName << PointeeTy << 0);
89118912
SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *this);
89128913
} else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
8913-
!IsTriviallyCopyableCXXRecord && ArgIdx == 0) {
8914+
!MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
89148915
// FIXME: Limiting this warning to dest argument until we decide
89158916
// whether it's valid for source argument too.
89168917
DiagRuntimeBehavior(Dest->getExprLoc(), Dest,
@@ -8923,7 +8924,7 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
89238924
<< ArgIdx << FnName << PointeeTy << 1);
89248925
SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *this);
89258926
} else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
8926-
!IsTriviallyCopyableCXXRecord && ArgIdx == 0) {
8927+
!MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
89278928
// FIXME: Limiting this warning to dest argument until we decide
89288929
// whether it's valid for source argument too.
89298930
DiagRuntimeBehavior(Dest->getExprLoc(), Dest,

clang/test/SemaCXX/warn-memaccess.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@ extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
77

88
class TriviallyCopyable {};
99
class NonTriviallyCopyable { NonTriviallyCopyable(const NonTriviallyCopyable&);};
10+
struct Incomplete;
1011

1112
void test_bzero(TriviallyCopyable* tc,
12-
NonTriviallyCopyable *ntc) {
13+
NonTriviallyCopyable *ntc,
14+
Incomplete* i) {
1315
// OK
1416
bzero(tc, sizeof(*tc));
1517

18+
// OK
19+
bzero(i, 10);
20+
1621
// expected-warning@+2{{first argument in call to 'bzero' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}}
1722
// expected-note@+1{{explicitly cast the pointer to silence this warning}}
1823
bzero(ntc, sizeof(*ntc));
@@ -22,10 +27,14 @@ void test_bzero(TriviallyCopyable* tc,
2227
}
2328

2429
void test_memset(TriviallyCopyable* tc,
25-
NonTriviallyCopyable *ntc) {
30+
NonTriviallyCopyable *ntc,
31+
Incomplete* i) {
2632
// OK
2733
memset(tc, 0, sizeof(*tc));
2834

35+
// OK
36+
memset(i, 0, 10);
37+
2938
// expected-warning@+2{{first argument in call to 'memset' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}}
3039
// expected-note@+1{{explicitly cast the pointer to silence this warning}}
3140
memset(ntc, 0, sizeof(*ntc));
@@ -36,10 +45,14 @@ void test_memset(TriviallyCopyable* tc,
3645

3746

3847
void test_memcpy(TriviallyCopyable* tc0, TriviallyCopyable* tc1,
39-
NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1) {
48+
NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1,
49+
Incomplete *i0, Incomplete *i1) {
4050
// OK
4151
memcpy(tc0, tc1, sizeof(*tc0));
4252

53+
// OK
54+
memcpy(i0, i1, 10);
55+
4356
// expected-warning@+2{{first argument in call to 'memcpy' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}}
4457
// expected-note@+1{{explicitly cast the pointer to silence this warning}}
4558
memcpy(ntc0, ntc1, sizeof(*ntc0));
@@ -52,10 +65,14 @@ void test_memcpy(TriviallyCopyable* tc0, TriviallyCopyable* tc1,
5265
}
5366

5467
void test_memmove(TriviallyCopyable* tc0, TriviallyCopyable* tc1,
55-
NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1) {
68+
NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1,
69+
Incomplete *i0, Incomplete *i1) {
5670
// OK
5771
memmove(tc0, tc1, sizeof(*tc0));
5872

73+
// OK
74+
memmove(i0, i1, 10);
75+
5976
// expected-warning@+2{{first argument in call to 'memmove' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}}
6077
// expected-note@+1{{explicitly cast the pointer to silence this warning}}
6178
memmove(ntc0, ntc1, sizeof(*ntc0));

0 commit comments

Comments
 (0)