diff options
author | Mark de Wever <koraq@xs4all.nl> | 2020-01-11 10:16:40 +0100 |
---|---|---|
committer | Mark de Wever <koraq@xs4all.nl> | 2020-01-11 15:34:02 +0100 |
commit | 9c74fb402e1b7aad4a509a49ab4792154b8ba2c8 (patch) | |
tree | 132e905be5a2a736ac7f1a9f6944e6b4e6d14eb6 /clang/lib/Sema | |
parent | 08275a52d83e623f0347fd9396c18f4d21a15c90 (diff) | |
download | bcm5719-llvm-9c74fb402e1b7aad4a509a49ab4792154b8ba2c8.tar.gz bcm5719-llvm-9c74fb402e1b7aad4a509a49ab4792154b8ba2c8.zip |
[Sema] Improve -Wrange-loop-analysis warnings.
No longer generate a diagnostic when a small trivially copyable type is
used without a reference. Before the test looked for a POD type and had no
size restriction. Since the range-based for loop is only available in
C++11 and POD types are trivially copyable in C++11 it's not required to
test for a POD type.
Since copying a large object will be expensive its size has been
restricted. 64 bytes is a common size of a cache line and if the object is
aligned the copy will be cheap. No performance impact testing has been
done.
Differential Revision: https://reviews.llvm.org/D72212
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 1e7cc503d8c..d6c3af9e84c 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2779,6 +2779,15 @@ static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, } } +/// Determines whether the @p VariableType's declaration is a record with the +/// clang::trivial_abi attribute. +static bool hasTrivialABIAttr(QualType VariableType) { + if (CXXRecordDecl *RD = VariableType->getAsCXXRecordDecl()) + return RD->hasAttr<TrivialABIAttr>(); + + return false; +} + // Warns when the loop variable can be changed to a reference type to // prevent a copy. For instance, if given "for (const Foo x : Range)" suggest // "for (const Foo &x : Range)" if this form does not make a copy. @@ -2800,10 +2809,13 @@ static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef, return; } - // TODO: Determine a maximum size that a POD type can be before a diagnostic - // should be emitted. Also, only ignore POD types with trivial copy - // constructors. - if (VariableType.isPODType(SemaRef.Context)) + // Small trivially copyable types are cheap to copy. Do not emit the + // diagnostic for these instances. 64 bytes is a common size of a cache line. + // (The function `getTypeSize` returns the size in bits.) + ASTContext &Ctx = SemaRef.Context; + if (Ctx.getTypeSize(VariableType) <= 64 * 8 && + (VariableType.isTriviallyCopyableType(Ctx) || + hasTrivialABIAttr(VariableType))) return; // Suggest changing from a const variable to a const reference variable |