[clang] Changed Checks from TriviallyCopyable to TriviallyCopyConstructible (PR #76680)
Bhuminjay Soni via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 4 06:40:40 PST 2024
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/76680
>From 3c8dfcf96e732f4546f8019c0111fd873b233162 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Mon, 1 Jan 2024 19:53:45 +0530
Subject: [PATCH 1/3] Changed Checks from TriviallyCopyable to
TriviallyCopyConstructible
Signed-off-by: 11happy <soni5happy at gmail.com>
---
clang/include/clang/AST/DeclCXX.h | 3 +++
clang/include/clang/AST/Type.h | 3 +++
clang/lib/AST/DeclCXX.cpp | 13 ++++++++++
clang/lib/AST/Type.cpp | 43 +++++++++++++++++++++++++++++++
clang/lib/Sema/SemaStmt.cpp | 2 +-
5 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 432293583576b5..3ac0d6a9e083cd 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -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:
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 1afa693672860f..bce2256f96a828 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -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;
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index c944862fcefeee..98b0a6dc28ea2f 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -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.
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 160a725939ccd4..9c8b25798a0a95 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2644,6 +2644,49 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
return false;
}
+bool QualType::isTriviallyCopyConstructibleType(
+ const ASTContext &Context) const {
+ if ((*this)->isArrayType())
+ return Context.getBaseElementType(*this).isTriviallyCopyConstructibleType(
+ Context);
+
+ if (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 copy constructible types.
+
+ QualType CanonicalType = getCanonicalType();
+ if (CanonicalType->isDependentType())
+ return false;
+
+ if (CanonicalType->isSizelessBuiltinType())
+ return true;
+
+ // Return false for incomplete types after skipping any incomplete array types
+ // which are expressly allowed by the standard and thus our API.
+ if (CanonicalType->isIncompleteType())
+ return false;
+
+ // As an extension, Clang treats vector types as Scalar types.
+ if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
+ return true;
+
+ if (const auto *RT = CanonicalType->getAs<RecordType>()) {
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (!ClassDecl->isTriviallyCopyConstructible())
+ return false;
+ }
+
+ return true;
+ }
+
+ // No other types can match.
+ return false;
+}
+
bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {
QualType BaseElementType = Context.getBaseElementType(*this);
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index f0b03db690843a..21efe25ed84a3d 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -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;
>From 57b50cb0fc242d994558ddcb8226c3a785763e87 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Mon, 1 Jan 2024 21:46:17 +0530
Subject: [PATCH 2/3] Added tests
Signed-off-by: 11happy <soni5happy at gmail.com>
---
...range-loop-analysis-trivially-copyable.cpp | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp b/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp
index e345ef40aed9ca..8fa387908c3658 100644
--- a/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp
+++ b/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp
@@ -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 {
@@ -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 at +3 {{loop variable 'r' creates a copy from type 'const Record'}}
+ // expected-note at +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() {}
@@ -87,3 +111,4 @@ void test_TrivialABI_65_bytes() {
for (const auto r : records)
(void)r;
}
+
>From c346904caff1bf97605d84bdd0120cefe1ca35f4 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Thu, 4 Jan 2024 20:10:04 +0530
Subject: [PATCH 3/3] implemented static non member
Signed-off-by: 11happy <soni5happy at gmail.com>
---
clang/include/clang/AST/Type.h | 3 ++
clang/lib/AST/Type.cpp | 59 ++++++++--------------------------
2 files changed, 16 insertions(+), 46 deletions(-)
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index bce2256f96a828..4532cfe63ebb1b 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -766,6 +766,8 @@ class QualType {
bool UseExcessPrecision(const ASTContext &Ctx);
+ static bool isTriviallyCopyableTypeImpl(const QualType &type, const ASTContext &Context,bool copy_constructible);
+
/// Retrieves a pointer to the underlying (unqualified) type.
///
/// This function requires that the type not be NULL. If the type might be
@@ -911,6 +913,7 @@ class QualType {
/// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account.
bool isCXX11PODType(const ASTContext &Context) const;
+
/// Return true if this is a trivial type per (C++0x [basic.types]p9)
bool isTrivialType(const ASTContext &Context) const;
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 9c8b25798a0a95..964df0bd1c97bf 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2605,52 +2605,18 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
}
bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
- if ((*this)->isArrayType())
- return Context.getBaseElementType(*this).isTriviallyCopyableType(Context);
-
- if (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.
-
- QualType CanonicalType = getCanonicalType();
- if (CanonicalType->isDependentType())
- return false;
-
- if (CanonicalType->isSizelessBuiltinType())
- return true;
-
- // Return false for incomplete types after skipping any incomplete array types
- // which are expressly allowed by the standard and thus our API.
- if (CanonicalType->isIncompleteType())
- return false;
-
- // As an extension, Clang treats vector types as Scalar types.
- if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
- return true;
-
- if (const auto *RT = CanonicalType->getAs<RecordType>()) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- if (!ClassDecl->isTriviallyCopyable()) return false;
- }
-
- return true;
- }
+ return isTriviallyCopyableTypeImpl(*this,Context,false);
+}
- // No other types can match.
- return false;
+bool QualType::isTriviallyCopyConstructibleType(const ASTContext &Context) const {
+ return isTriviallyCopyableTypeImpl(*this,Context,true);
}
-bool QualType::isTriviallyCopyConstructibleType(
- const ASTContext &Context) const {
- if ((*this)->isArrayType())
- return Context.getBaseElementType(*this).isTriviallyCopyConstructibleType(
- Context);
+bool QualType::isTriviallyCopyableTypeImpl(const QualType &type, const ASTContext &Context,bool copy_constructible){
+ if (type->isArrayType())
+ return Context.getBaseElementType(type).isTriviallyCopyableTypeImpl(type,Context,copy_constructible);
- if (hasNonTrivialObjCLifetime())
+ if (type.hasNonTrivialObjCLifetime())
return false;
// C++11 [basic.types]p9 - See Core 2094
@@ -2658,7 +2624,7 @@ bool QualType::isTriviallyCopyConstructibleType(
// cv-qualified versions of these types are collectively
// called trivially copy constructible types.
- QualType CanonicalType = getCanonicalType();
+ QualType CanonicalType = type.getCanonicalType();
if (CanonicalType->isDependentType())
return false;
@@ -2676,13 +2642,14 @@ bool QualType::isTriviallyCopyConstructibleType(
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- if (!ClassDecl->isTriviallyCopyConstructible())
- return false;
+ if (copy_constructible)
+ return ClassDecl->isTriviallyCopyConstructible();
+ else
+ return ClassDecl->isTriviallyCopyable();
}
return true;
}
-
// No other types can match.
return false;
}
More information about the cfe-commits
mailing list