Skip to content

Changed Checks from TriviallyCopyable to TriviallyCopyConstructible #77194

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3c8dfcf
Changed Checks from TriviallyCopyable to TriviallyCopyConstructible
11happy Jan 1, 2024
57b50cb
Added tests
11happy Jan 1, 2024
c346904
implemented static non member
11happy Jan 4, 2024
81daac9
Committing local changes before revert
11happy Jan 4, 2024
723b9fd
Revert "implemented static non member"
11happy Jan 4, 2024
d3483b5
Revert "Committing local changes before revert"
11happy Jan 4, 2024
6c0936c
Internal Static member
11happy Jan 4, 2024
41cfb32
Internal static member
11happy Jan 4, 2024
a2b208c
Formatted the code
11happy Jan 4, 2024
c5847f7
IsCopyConstructible
11happy Jan 5, 2024
5a03096
Formatted the code
11happy Jan 5, 2024
7a44b58
Added Release notes
11happy Jan 5, 2024
7382376
Minor Fix
11happy Jan 6, 2024
658ea09
Changed Checks from TriviallyCopyable to TriviallyCopyConstructible
11happy Jan 1, 2024
31d1de1
Added tests
11happy Jan 1, 2024
c917059
implemented static non member
11happy Jan 4, 2024
bd4b449
Committing local changes before revert
11happy Jan 4, 2024
a7ac895
Revert "implemented static non member"
11happy Jan 4, 2024
51659f6
Revert "Committing local changes before revert"
11happy Jan 4, 2024
b841647
Internal Static member
11happy Jan 4, 2024
8c3f1e1
Internal static member
11happy Jan 4, 2024
50054da
Formatted the code
11happy Jan 4, 2024
cbf03e2
IsCopyConstructible
11happy Jan 5, 2024
158d239
Formatted the code
11happy Jan 5, 2024
07d8bbf
Added Release notes
11happy Jan 5, 2024
d4b3eba
Minor Fix
11happy Jan 6, 2024
878c9b1
Rebased
11happy Jan 6, 2024
ad8f8e8
Rebase1
11happy Jan 6, 2024
a5938af
Corrected Release Notes
11happy Jan 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,9 @@ Bug Fixes to AST Handling
- Fixed a bug where RecursiveASTVisitor fails to visit the
initializer of a bitfield.
`Issue 64916 <https://github.com/llvm/llvm-project/issues/64916>`_
- Fixed a bug where range-loop-analysis checks for trivial copyability,
rather than trivial copy-constructibility
`Issue 47355 <https://github.com/llvm/llvm-project/issues/47355>`_
- Fixed a bug where Template Instantiation failed to handle Lambda Expressions
with certain types of Attributes.
(`#76521 <https://github.com/llvm/llvm-project/issues/76521>`_)
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/DeclCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,9 @@ class CXXRecordDecl : public RecordDecl {
/// (C++11 [class]p6).
bool isTriviallyCopyable() const;

/// Determine whether this class is considered trivially copyable per
bool isTriviallyCopyConstructible() const;

/// Determine whether this class is considered trivial.
///
/// C++11 [class]p6:
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,9 @@ class QualType {
/// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
bool isTriviallyCopyableType(const ASTContext &Context) const;

/// Return true if this is a trivially copyable type
bool isTriviallyCopyConstructibleType(const ASTContext &Context) const;

/// Return true if this is a trivially relocatable type.
bool isTriviallyRelocatableType(const ASTContext &Context) const;

Expand Down
13 changes: 13 additions & 0 deletions clang/lib/AST/DeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,19 @@ bool CXXRecordDecl::isTriviallyCopyable() const {
return true;
}

bool CXXRecordDecl::isTriviallyCopyConstructible() const {

// A trivially copy constructible class is a class that:
// -- has no non-trivial copy constructors,
if (hasNonTrivialCopyConstructor())
return false;
// -- has a trivial destructor.
if (!hasTrivialDestructor())
return false;

return true;
}

void CXXRecordDecl::markedVirtualFunctionPure() {
// C++ [class.abstract]p2:
// A class is abstract if it has at least one pure virtual function.
Expand Down
34 changes: 25 additions & 9 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2604,19 +2604,22 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
return false;
}

bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
if ((*this)->isArrayType())
return Context.getBaseElementType(*this).isTriviallyCopyableType(Context);
static bool isTriviallyCopyableTypeImpl(const QualType &type,
const ASTContext &Context,
bool IsCopyConstructible) {
if (type->isArrayType())
return isTriviallyCopyableTypeImpl(Context.getBaseElementType(type),
Context, IsCopyConstructible);

if (hasNonTrivialObjCLifetime())
if (type.hasNonTrivialObjCLifetime())
return false;

// C++11 [basic.types]p9 - See Core 2094
// Scalar types, trivially copyable class types, arrays of such types, and
// cv-qualified versions of these types are collectively
// called trivially copyable types.
// called trivially copy constructible types.

QualType CanonicalType = getCanonicalType();
QualType CanonicalType = type.getCanonicalType();
if (CanonicalType->isDependentType())
return false;

Expand All @@ -2634,16 +2637,29 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {

if (const auto *RT = CanonicalType->getAs<RecordType>()) {
if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
if (!ClassDecl->isTriviallyCopyable()) return false;
if (IsCopyConstructible) {
return ClassDecl->isTriviallyCopyConstructible();
} else {
return ClassDecl->isTriviallyCopyable();
}
}

return true;
}

// No other types can match.
return false;
}

bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
return isTriviallyCopyableTypeImpl(*this, Context,
/*IsCopyConstructible=*/false);
}

bool QualType::isTriviallyCopyConstructibleType(
const ASTContext &Context) const {
return isTriviallyCopyableTypeImpl(*this, Context,
/*IsCopyConstructible=*/true);
}

bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {
QualType BaseElementType = Context.getBaseElementType(*this);

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3200,7 +3200,7 @@ static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef,
// (The function `getTypeSize` returns the size in bits.)
ASTContext &Ctx = SemaRef.Context;
if (Ctx.getTypeSize(VariableType) <= 64 * 8 &&
(VariableType.isTriviallyCopyableType(Ctx) ||
(VariableType.isTriviallyCopyConstructibleType(Ctx) ||
hasTrivialABIAttr(VariableType)))
return;

Expand Down
25 changes: 25 additions & 0 deletions clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ void test_TriviallyCopyable_64_bytes() {
for (const auto r : records)
(void)r;
}
void test_TriviallyCopyConstructible_64_bytes() {
struct Record {
char a[64];
Record& operator=(Record const& other){return *this;};

};

Record records[8];
for (const auto r : records)
(void)r;
}

void test_TriviallyCopyable_65_bytes() {
struct Record {
Expand All @@ -47,6 +58,19 @@ void test_TriviallyCopyable_65_bytes() {
(void)r;
}

void test_TriviallyCopyConstructible_65_bytes() {
struct Record {
char a[65];
Record& operator=(Record const& other){return *this;};

};
// expected-warning@+3 {{loop variable 'r' creates a copy from type 'const Record'}}
// expected-note@+2 {{use reference type 'const Record &' to prevent copying}}
Record records[8];
for (const auto r : records)
(void)r;
}

void test_NonTriviallyCopyable() {
struct Record {
Record() {}
Expand Down Expand Up @@ -87,3 +111,4 @@ void test_TrivialABI_65_bytes() {
for (const auto r : records)
(void)r;
}