diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 5d81205137988c143ad97cd670fe25e0a5548c63..4671a87423020f3e2afc8433128b51e407ebe730 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6933,8 +6933,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, // explicit assignments, do so. This optimization only applies for arrays // of scalars and arrays of class type with trivial copy-assignment // operators. - if (FieldType->isArrayType() && - BaseType.hasTrivialCopyAssignment(Context)) { + if (FieldType->isArrayType() && !FieldType.isVolatileQualified() + && BaseType.hasTrivialCopyAssignment(Context)) { // Compute the size of the memory buffer to be copied. QualType SizeType = Context.getSizeType(); llvm::APInt Size(Context.getTypeSize(SizeType), diff --git a/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp b/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb13503fdc3f814f0517c21e5dee1aea8e044317 --- /dev/null +++ b/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// rdar://9894548 + +typedef unsigned long word_t; +typedef unsigned long u64_t; +typedef unsigned int u32_t; + +class ioapic_redir_t { +public: + union { + struct { + word_t vector : 8; + + word_t delivery_mode : 3; + word_t dest_mode : 1; + + word_t delivery_status : 1; + word_t polarity : 1; + word_t irr : 1; + word_t trigger_mode : 1; + + word_t mask : 1; + word_t _pad0 : 15; + + word_t dest : 8; + }; + volatile u32_t raw[2]; + volatile u64_t raw64; + }; +}; + +struct ioapic_shadow_struct +{ + ioapic_redir_t redirs[24]; +} ioapic_shadow[16]; + +void init_ioapic(unsigned long ioapic_id) +{ + ioapic_redir_t entry; + ioapic_shadow[ioapic_id].redirs[3] = entry; +} + +// CHECK: call void @llvm.memcpy