llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (serge-sans-paille) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/114095.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaChecking.cpp (+4-3) - (modified) clang/test/SemaCXX/warn-memaccess.cpp (+21-4) ``````````diff diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 3308b898a5b68f..577218ac4f0ab2 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -8900,7 +8900,8 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call, << Call->getCallee()->getSourceRange()); else if (const auto *RT = PointeeTy->getAs<RecordType>()) { - bool IsTriviallyCopyableCXXRecord = + bool MayBeTriviallyCopyableCXXRecord = + RT->isIncompleteType() || RT->desugar().isTriviallyCopyableType(Context); if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) && @@ -8910,7 +8911,7 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call, << ArgIdx << FnName << PointeeTy << 0); SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *this); } else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) && - !IsTriviallyCopyableCXXRecord && ArgIdx == 0) { + !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) { // FIXME: Limiting this warning to dest argument until we decide // whether it's valid for source argument too. DiagRuntimeBehavior(Dest->getExprLoc(), Dest, @@ -8923,7 +8924,7 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call, << ArgIdx << FnName << PointeeTy << 1); SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *this); } else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) && - !IsTriviallyCopyableCXXRecord && ArgIdx == 0) { + !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) { // FIXME: Limiting this warning to dest argument until we decide // whether it's valid for source argument too. DiagRuntimeBehavior(Dest->getExprLoc(), Dest, diff --git a/clang/test/SemaCXX/warn-memaccess.cpp b/clang/test/SemaCXX/warn-memaccess.cpp index b4b7f6a6905b23..070b44891a91aa 100644 --- a/clang/test/SemaCXX/warn-memaccess.cpp +++ b/clang/test/SemaCXX/warn-memaccess.cpp @@ -7,12 +7,17 @@ extern "C" void *memcpy(void *s1, const void *s2, unsigned n); class TriviallyCopyable {}; class NonTriviallyCopyable { NonTriviallyCopyable(const NonTriviallyCopyable&);}; +struct Incomplete; void test_bzero(TriviallyCopyable* tc, - NonTriviallyCopyable *ntc) { + NonTriviallyCopyable *ntc, + Incomplete* i) { // OK bzero(tc, sizeof(*tc)); + // OK + bzero(i, 10); + // expected-warning@+2{{first argument in call to 'bzero' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}} // expected-note@+1{{explicitly cast the pointer to silence this warning}} bzero(ntc, sizeof(*ntc)); @@ -22,10 +27,14 @@ void test_bzero(TriviallyCopyable* tc, } void test_memset(TriviallyCopyable* tc, - NonTriviallyCopyable *ntc) { + NonTriviallyCopyable *ntc, + Incomplete* i) { // OK memset(tc, 0, sizeof(*tc)); + // OK + memset(i, 0, 10); + // expected-warning@+2{{first argument in call to 'memset' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}} // expected-note@+1{{explicitly cast the pointer to silence this warning}} memset(ntc, 0, sizeof(*ntc)); @@ -36,10 +45,14 @@ void test_memset(TriviallyCopyable* tc, void test_memcpy(TriviallyCopyable* tc0, TriviallyCopyable* tc1, - NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1) { + NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1, + Incomplete *i0, Incomplete *i1) { // OK memcpy(tc0, tc1, sizeof(*tc0)); + // OK + memcpy(i0, i1, 10); + // expected-warning@+2{{first argument in call to 'memcpy' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}} // expected-note@+1{{explicitly cast the pointer to silence this warning}} memcpy(ntc0, ntc1, sizeof(*ntc0)); @@ -52,10 +65,14 @@ void test_memcpy(TriviallyCopyable* tc0, TriviallyCopyable* tc1, } void test_memmove(TriviallyCopyable* tc0, TriviallyCopyable* tc1, - NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1) { + NonTriviallyCopyable *ntc0, NonTriviallyCopyable *ntc1, + Incomplete *i0, Incomplete *i1) { // OK memmove(tc0, tc1, sizeof(*tc0)); + // OK + memmove(i0, i1, 10); + // expected-warning@+2{{first argument in call to 'memmove' is a pointer to non-trivially copyable type 'NonTriviallyCopyable'}} // expected-note@+1{{explicitly cast the pointer to silence this warning}} memmove(ntc0, ntc1, sizeof(*ntc0)); `````````` </details> https://github.com/llvm/llvm-project/pull/114095 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits