Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -99,6 +99,7 @@ def DeleteIncomplete : DiagGroup<"delete-incomplete">; def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">; def AbstractFinalClass : DiagGroup<"abstract-final-class">; +def AggregateCtors : DiagGroup<"aggregate-ctors">; def CXX11CompatDeprecatedWritableStr : DiagGroup<"c++11-compat-deprecated-writable-strings">; Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -6466,6 +6466,9 @@ def warn_jump_out_of_seh_finally : Warning< "jump out of __finally block has undefined behavior">, InGroup>; +def warn_aggregate_with_user_declared_constructor : Warning< + "aggregate type has user-declared constructors">, + InGroup; def warn_non_virtual_dtor : Warning< "%0 has virtual functions but non-virtual destructor">, InGroup, DefaultIgnore; Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -5907,6 +5907,10 @@ diag::warn_non_virtual_dtor) << Context.getRecordType(Record); } + if (Record->isAggregate() && Record->hasUserDeclaredConstructor()) { + Diag(Record->getLocation(), diag::warn_aggregate_with_user_declared_constructor); + } + if (Record->isAbstract()) { if (FinalAttr *FA = Record->getAttr()) { Diag(Record->getLocation(), diag::warn_abstract_final_class)