@@ -1393,12 +1393,17 @@ static void inferDynamic(ASTContext &ctx, ValueDecl *D) {
1393
1393
(D->getOverriddenDecl () &&
1394
1394
D->getOverriddenDecl ()->hasClangNode ());
1395
1395
1396
+ bool overridesDyanmic =
1397
+ (D->getOverriddenDecl () &&
1398
+ D->getOverriddenDecl ()->isDynamic ());
1399
+
1396
1400
bool isNSManaged = D->getAttrs ().hasAttribute <NSManagedAttr>();
1397
1401
1398
1402
bool isExtension = isa<ExtensionDecl>(D->getDeclContext ());
1399
1403
1400
1404
// We only infer 'dynamic' in these three cases.
1401
- if (!isExtension && !isNSManaged && !overridesImportedMethod)
1405
+ if (!isExtension && !isNSManaged && !overridesImportedMethod &&
1406
+ !overridesDyanmic)
1402
1407
return ;
1403
1408
1404
1409
// The presence of 'final' blocks the inference of 'dynamic'.
@@ -2904,6 +2909,19 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2904
2909
}
2905
2910
}
2906
2911
2912
+ if (!checkOverrides (TC, VD)) {
2913
+ // If a property has an override attribute but does not override
2914
+ // anything, complain.
2915
+ auto overridden = VD->getOverriddenDecl ();
2916
+ if (auto *OA = VD->getAttrs ().getAttribute <OverrideAttr>()) {
2917
+ if (!overridden) {
2918
+ TC.diagnose (VD, diag::property_does_not_override)
2919
+ .highlight (OA->getLocation ());
2920
+ OA->setInvalid ();
2921
+ }
2922
+ }
2923
+ }
2924
+
2907
2925
TC.checkDeclAttributes (VD);
2908
2926
2909
2927
triggerAccessorSynthesis (TC, VD);
@@ -3049,6 +3067,18 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3049
3067
AccessControlChecker::checkAccessControl (TC, SD);
3050
3068
UsableFromInlineChecker::checkUsableFromInline (TC, SD);
3051
3069
3070
+ if (!checkOverrides (TC, SD)) {
3071
+ // If a subscript has an override attribute but does not override
3072
+ // anything, complain.
3073
+ if (auto *OA = SD->getAttrs ().getAttribute <OverrideAttr>()) {
3074
+ if (!SD->getOverriddenDecl ()) {
3075
+ TC.diagnose (SD, diag::subscript_does_not_override)
3076
+ .highlight (OA->getLocation ());
3077
+ OA->setInvalid ();
3078
+ }
3079
+ }
3080
+ }
3081
+
3052
3082
triggerAccessorSynthesis (TC, SD);
3053
3083
}
3054
3084
@@ -3539,6 +3569,18 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3539
3569
AccessControlChecker::checkAccessControl (TC, FD);
3540
3570
UsableFromInlineChecker::checkUsableFromInline (TC, FD);
3541
3571
3572
+ if (!checkOverrides (TC, FD)) {
3573
+ // If a method has an 'override' keyword but does not
3574
+ // override anything, complain.
3575
+ if (auto *OA = FD->getAttrs ().getAttribute <OverrideAttr>()) {
3576
+ if (!FD->getOverriddenDecl ()) {
3577
+ TC.diagnose (FD, diag::method_does_not_override)
3578
+ .highlight (OA->getLocation ());
3579
+ OA->setInvalid ();
3580
+ }
3581
+ }
3582
+ }
3583
+
3542
3584
if (FD->hasBody ()) {
3543
3585
// Record the body.
3544
3586
TC.definedFunctions .push_back (FD);
@@ -3668,6 +3710,61 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
3668
3710
void visitConstructorDecl (ConstructorDecl *CD) {
3669
3711
TC.validateDecl (CD);
3670
3712
3713
+ // Check whether this initializer overrides an initializer in its
3714
+ // superclass.
3715
+ if (!checkOverrides (TC, CD)) {
3716
+ // If an initializer has an override attribute but does not override
3717
+ // anything or overrides something that doesn't need an 'override'
3718
+ // keyword (e.g., a convenience initializer), complain.
3719
+ // anything, or overrides something that complain.
3720
+ if (auto *attr = CD->getAttrs ().getAttribute <OverrideAttr>()) {
3721
+ if (!CD->getOverriddenDecl ()) {
3722
+ TC.diagnose (CD, diag::initializer_does_not_override)
3723
+ .highlight (attr->getLocation ());
3724
+ attr->setInvalid ();
3725
+ } else if (attr->isImplicit ()) {
3726
+ // Don't diagnose implicit attributes.
3727
+ } else if (!overrideRequiresKeyword (CD->getOverriddenDecl ())) {
3728
+ // Special case: we are overriding a 'required' initializer, so we
3729
+ // need (only) the 'required' keyword.
3730
+ if (cast<ConstructorDecl>(CD->getOverriddenDecl ())->isRequired ()) {
3731
+ if (CD->getAttrs ().hasAttribute <RequiredAttr>()) {
3732
+ TC.diagnose (CD, diag::required_initializer_override_keyword)
3733
+ .fixItRemove (attr->getLocation ());
3734
+ } else {
3735
+ TC.diagnose (CD, diag::required_initializer_override_wrong_keyword)
3736
+ .fixItReplace (attr->getLocation (), " required" );
3737
+ CD->getAttrs ().add (
3738
+ new (TC.Context ) RequiredAttr (/* IsImplicit=*/ true ));
3739
+ }
3740
+
3741
+ TC.diagnose (findNonImplicitRequiredInit (CD->getOverriddenDecl ()),
3742
+ diag::overridden_required_initializer_here);
3743
+ } else {
3744
+ // We tried to override a convenience initializer.
3745
+ TC.diagnose (CD, diag::initializer_does_not_override)
3746
+ .highlight (attr->getLocation ());
3747
+ TC.diagnose (CD->getOverriddenDecl (),
3748
+ diag::convenience_init_override_here);
3749
+ }
3750
+ }
3751
+ }
3752
+
3753
+ // A failable initializer cannot override a non-failable one.
3754
+ // This would normally be diagnosed by the covariance rules;
3755
+ // however, those are disabled so that we can provide a more
3756
+ // specific diagnostic here.
3757
+ if (CD->getFailability () != OTK_None &&
3758
+ CD->getOverriddenDecl () &&
3759
+ CD->getOverriddenDecl ()->getFailability () == OTK_None) {
3760
+ TC.diagnose (CD, diag::failable_initializer_override,
3761
+ CD->getFullName ());
3762
+ TC.diagnose (CD->getOverriddenDecl (),
3763
+ diag::nonfailable_initializer_override_here,
3764
+ CD->getOverriddenDecl ()->getFullName ());
3765
+ }
3766
+ }
3767
+
3671
3768
// If this initializer overrides a 'required' initializer, it must itself
3672
3769
// be marked 'required'.
3673
3770
if (!CD->getAttrs ().hasAttribute <RequiredAttr>()) {
@@ -4440,19 +4537,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
4440
4537
checkDeclAttributesEarly (VD);
4441
4538
validateAttributes (*this , VD);
4442
4539
4443
- if (!checkOverrides (*this , VD)) {
4444
- // If a property has an override attribute but does not override
4445
- // anything, complain.
4446
- auto overridden = VD->getOverriddenDecl ();
4447
- if (auto *OA = VD->getAttrs ().getAttribute <OverrideAttr>()) {
4448
- if (!overridden) {
4449
- diagnose (VD, diag::property_does_not_override)
4450
- .highlight (OA->getLocation ());
4451
- OA->setInvalid ();
4452
- }
4453
- }
4454
- }
4455
-
4456
4540
// Properties need some special validation logic.
4457
4541
if (auto *nominalDecl = VD->getDeclContext ()
4458
4542
->getAsNominalTypeOrNominalTypeExtensionContext ()) {
@@ -4731,18 +4815,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
4731
4815
4732
4816
// Member functions need some special validation logic.
4733
4817
if (FD->getDeclContext ()->isTypeContext ()) {
4734
- if (!checkOverrides (*this , FD)) {
4735
- // If a method has an 'override' keyword but does not
4736
- // override anything, complain.
4737
- if (auto *OA = FD->getAttrs ().getAttribute <OverrideAttr>()) {
4738
- if (!FD->getOverriddenDecl ()) {
4739
- diagnose (FD, diag::method_does_not_override)
4740
- .highlight (OA->getLocation ());
4741
- OA->setInvalid ();
4742
- }
4743
- }
4744
- }
4745
-
4746
4818
if (FD->isOperator ())
4747
4819
checkMemberOperator (*this , FD);
4748
4820
@@ -4929,59 +5001,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
4929
5001
4930
5002
validateAttributes (*this , CD);
4931
5003
4932
- // Check whether this initializer overrides an initializer in its
4933
- // superclass.
4934
- if (!checkOverrides (*this , CD)) {
4935
- // If an initializer has an override attribute but does not override
4936
- // anything or overrides something that doesn't need an 'override'
4937
- // keyword (e.g., a convenience initializer), complain.
4938
- // anything, or overrides something that complain.
4939
- if (auto *attr = CD->getAttrs ().getAttribute <OverrideAttr>()) {
4940
- if (!CD->getOverriddenDecl ()) {
4941
- diagnose (CD, diag::initializer_does_not_override)
4942
- .highlight (attr->getLocation ());
4943
- attr->setInvalid ();
4944
- } else if (!overrideRequiresKeyword (CD->getOverriddenDecl ())) {
4945
- // Special case: we are overriding a 'required' initializer, so we
4946
- // need (only) the 'required' keyword.
4947
- if (cast<ConstructorDecl>(CD->getOverriddenDecl ())->isRequired ()) {
4948
- if (CD->getAttrs ().hasAttribute <RequiredAttr>()) {
4949
- diagnose (CD, diag::required_initializer_override_keyword)
4950
- .fixItRemove (attr->getLocation ());
4951
- } else {
4952
- diagnose (CD, diag::required_initializer_override_wrong_keyword)
4953
- .fixItReplace (attr->getLocation (), " required" );
4954
- CD->getAttrs ().add (
4955
- new (Context) RequiredAttr (/* IsImplicit=*/ true ));
4956
- }
4957
-
4958
- diagnose (findNonImplicitRequiredInit (CD->getOverriddenDecl ()),
4959
- diag::overridden_required_initializer_here);
4960
- } else {
4961
- // We tried to override a convenience initializer.
4962
- diagnose (CD, diag::initializer_does_not_override)
4963
- .highlight (attr->getLocation ());
4964
- diagnose (CD->getOverriddenDecl (),
4965
- diag::convenience_init_override_here);
4966
- }
4967
- }
4968
- }
4969
-
4970
- // A failable initializer cannot override a non-failable one.
4971
- // This would normally be diagnosed by the covariance rules;
4972
- // however, those are disabled so that we can provide a more
4973
- // specific diagnostic here.
4974
- if (CD->getFailability () != OTK_None &&
4975
- CD->getOverriddenDecl () &&
4976
- CD->getOverriddenDecl ()->getFailability () == OTK_None) {
4977
- diagnose (CD, diag::failable_initializer_override,
4978
- CD->getFullName ());
4979
- diagnose (CD->getOverriddenDecl (),
4980
- diag::nonfailable_initializer_override_here,
4981
- CD->getOverriddenDecl ()->getFullName ());
4982
- }
4983
- }
4984
-
4985
5004
// An initializer is ObjC-compatible if it's explicitly @objc or a member
4986
5005
// of an ObjC-compatible class.
4987
5006
if (CD->getDeclContext ()->isTypeContext ()) {
@@ -5123,18 +5142,6 @@ void TypeChecker::validateDecl(ValueDecl *D) {
5123
5142
new (C) ImplicitlyUnwrappedOptionalAttr (/* implicit= */ true ));
5124
5143
}
5125
5144
5126
- if (!checkOverrides (*this , SD)) {
5127
- // If a subscript has an override attribute but does not override
5128
- // anything, complain.
5129
- if (auto *OA = SD->getAttrs ().getAttribute <OverrideAttr>()) {
5130
- if (!SD->getOverriddenDecl ()) {
5131
- diagnose (SD, diag::subscript_does_not_override)
5132
- .highlight (OA->getLocation ());
5133
- OA->setInvalid ();
5134
- }
5135
- }
5136
- }
5137
-
5138
5145
// Member subscripts need some special validation logic.
5139
5146
if (dc->isTypeContext ()) {
5140
5147
// If this is a class member, mark it final if the class is final.
0 commit comments