diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2855,8 +2855,14 @@ // 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; + const CXXRecordDecl *ClassDecl = nullptr; + if (const auto *RT = VariableType->getAs()) { + ClassDecl = dyn_cast(RT->getDecl()); + } if (Ctx.getTypeSize(VariableType) <= 64 * 8 && (VariableType.isTriviallyCopyableType(Ctx) || + // Fix https://bugs.llvm.org/show_bug.cgi?id=48011 + (ClassDecl && !ClassDecl->hasNonTrivialCopyConstructor()) || hasTrivialABIAttr(VariableType))) return; diff --git a/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp b/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp --- a/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp +++ b/clang/test/SemaCXX/warn-range-loop-analysis-trivially-copyable.cpp @@ -55,8 +55,6 @@ int b; }; - // 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; diff --git a/clang/test/SemaCXX/warn-range-loop-analysis.cpp b/clang/test/SemaCXX/warn-range-loop-analysis.cpp --- a/clang/test/SemaCXX/warn-range-loop-analysis.cpp +++ b/clang/test/SemaCXX/warn-range-loop-analysis.cpp @@ -29,6 +29,13 @@ operator int(); }; +struct ID1 { + // Small trivally copy constructor, but no trivally copy assignment + // operator. + ID1(ID1 const&) = default; + ID1& operator=(ID1 const& other) { return *this; } +}; + // Testing notes: // test0 checks that the full text of the warnings and notes is correct. The // rest of the tests checks a smaller portion of the text. @@ -455,6 +462,14 @@ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:" " } +void test11() { + Container C; + + for (const ID1 x : C) {} + // No warning +} + + template void test_template_function() { // In a template instantiation the diagnostics should not be emitted for