@@ -1103,8 +1103,27 @@ bool MicrosoftCXXABI::hasMostDerivedReturn(GlobalDecl GD) const {
1103
1103
return isDeletingDtor (GD);
1104
1104
}
1105
1105
1106
+ static bool fieldIsTrivialForMSVC (const FieldDecl *Field,
1107
+ const ASTContext &Context) {
1108
+ if (Field->getType ()->isReferenceType ())
1109
+ return false ;
1110
+
1111
+ const RecordType *RT =
1112
+ Context.getBaseElementType (Field->getType ())->getAs <RecordType>();
1113
+ if (!RT)
1114
+ return true ;
1115
+
1116
+ CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl ());
1117
+
1118
+ for (const FieldDecl *RDField : RD->fields ())
1119
+ if (!fieldIsTrivialForMSVC (RDField, Context))
1120
+ return false ;
1121
+
1122
+ return true ;
1123
+ }
1124
+
1106
1125
static bool isTrivialForMSVC (const CXXRecordDecl *RD, QualType Ty,
1107
- CodeGenModule &CGM) {
1126
+ CodeGenModule &CGM, const ASTContext &Context ) {
1108
1127
// On AArch64, HVAs that can be passed in registers can also be returned
1109
1128
// in registers. (Note this is using the MSVC definition of an HVA; see
1110
1129
// isPermittedToBeHomogeneousAggregate().)
@@ -1122,7 +1141,8 @@ static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
1122
1141
// No base classes
1123
1142
// No virtual functions
1124
1143
// Additionally, we need to ensure that there is a trivial copy assignment
1125
- // operator, a trivial destructor and no user-provided constructors.
1144
+ // operator, a trivial destructor, no user-provided constructors and no
1145
+ // non static data members of reference type.
1126
1146
if (RD->hasProtectedFields () || RD->hasPrivateFields ())
1127
1147
return false ;
1128
1148
if (RD->getNumBases () > 0 )
@@ -1136,6 +1156,9 @@ static bool isTrivialForMSVC(const CXXRecordDecl *RD, QualType Ty,
1136
1156
return false ;
1137
1157
if (RD->hasNonTrivialDestructor ())
1138
1158
return false ;
1159
+ for (const FieldDecl *Field : RD->fields ())
1160
+ if (!fieldIsTrivialForMSVC (Field, Context))
1161
+ return false ;
1139
1162
return true ;
1140
1163
}
1141
1164
@@ -1144,11 +1167,13 @@ bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
1144
1167
if (!RD)
1145
1168
return false ;
1146
1169
1147
- bool isTrivialForABI = RD->canPassInRegisters () &&
1148
- isTrivialForMSVC (RD, FI.getReturnType (), CGM);
1149
-
1150
1170
// MSVC always returns structs indirectly from C++ instance methods.
1151
- bool isIndirectReturn = !isTrivialForABI || FI.isInstanceMethod ();
1171
+ bool isIndirectReturn = FI.isInstanceMethod ();
1172
+ if (!isIndirectReturn) {
1173
+ isIndirectReturn =
1174
+ !(RD->canPassInRegisters () &&
1175
+ isTrivialForMSVC (RD, FI.getReturnType (), CGM, getContext ()));
1176
+ }
1152
1177
1153
1178
if (isIndirectReturn) {
1154
1179
CharUnits Align = CGM.getContext ().getTypeAlignInChars (FI.getReturnType ());
0 commit comments