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.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,12 @@ operator int(); }; +struct ID1 { + // Small trivally copy constructor, but no trivally copy assignment + // operator. + 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 +461,23 @@ // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:17-[[@LINE-3]]:18}:" " } +void test11() { + Container C; + + for (const ID1 &x : C) {} + // No warning + + for (const ID1& x : C) {} + // No warning + + for (const ID1 & x : C) {} + // No warning + + for (const ID1&x : C) {} + // No warning +} + + template void test_template_function() { // In a template instantiation the diagnostics should not be emitted for