@@ -3042,6 +3042,7 @@ class ObjCImplementationChecker {
3042
3042
WrongDeclKind,
3043
3043
WrongType,
3044
3044
WrongWritability,
3045
+ WrongRequiredAttr,
3045
3046
3046
3047
Match,
3047
3048
MatchWithExplicitObjCName,
@@ -3339,6 +3340,10 @@ class ObjCImplementationChecker {
3339
3340
!cast<AbstractStorageDecl>(cand)->isSettable (nullptr ))
3340
3341
return MatchOutcome::WrongWritability;
3341
3342
3343
+ if (auto reqCtor = dyn_cast<ConstructorDecl>(req))
3344
+ if (reqCtor->isRequired () != cast<ConstructorDecl>(cand)->isRequired ())
3345
+ return MatchOutcome::WrongRequiredAttr;
3346
+
3342
3347
// If we got here, everything matched. But at what quality?
3343
3348
if (explicitObjCName)
3344
3349
return MatchOutcome::MatchWithExplicitObjCName;
@@ -3426,6 +3431,22 @@ class ObjCImplementationChecker {
3426
3431
diagnose (cand, diag::objc_implementation_must_be_settable,
3427
3432
cand->getDescriptiveKind (), cand, req->getDescriptiveKind ());
3428
3433
return ;
3434
+
3435
+ case MatchOutcome::WrongRequiredAttr: {
3436
+ bool shouldBeRequired = cast<ConstructorDecl>(req)->isRequired ();
3437
+
3438
+ auto diag =
3439
+ diagnose (cand, diag::objc_implementation_required_attr_mismatch,
3440
+ cand->getDescriptiveKind (), cand, shouldBeRequired);
3441
+
3442
+ if (shouldBeRequired)
3443
+ diag.fixItInsert (cand->getAttributeInsertionLoc (/* forModifier=*/ true ),
3444
+ " required " );
3445
+ else
3446
+ diag.fixItRemove (cand->getAttrs ().getAttribute <RequiredAttr>()
3447
+ ->getLocation ());
3448
+ return ;
3449
+ }
3429
3450
}
3430
3451
3431
3452
llvm_unreachable (" Unknown MatchOutcome" );
0 commit comments