File tree Expand file tree Collapse file tree 7 files changed +46
-14
lines changed Expand file tree Collapse file tree 7 files changed +46
-14
lines changed Original file line number Diff line number Diff line change @@ -2418,6 +2418,8 @@ class IfStmt final
24182418
24192419 bool isObjCAvailabilityCheck () const ;
24202420
2421+ bool isObjCAvailabilityCheckWithDomainName () const ;
2422+
24212423 SourceLocation getBeginLoc () const { return getIfLoc (); }
24222424 SourceLocation getEndLoc () const LLVM_READONLY {
24232425 if (getElse ())
Original file line number Diff line number Diff line change @@ -1004,6 +1004,13 @@ bool IfStmt::isObjCAvailabilityCheck() const {
10041004 return isa<ObjCAvailabilityCheckExpr>(getCond ());
10051005}
10061006
1007+ bool IfStmt::isObjCAvailabilityCheckWithDomainName () const {
1008+ if (auto *ACE = dyn_cast<ObjCAvailabilityCheckExpr>(getCond ());
1009+ ACE && ACE->hasDomainName ())
1010+ return true ;
1011+ return false ;
1012+ }
1013+
10071014std::optional<Stmt *> IfStmt::getNondiscardedCase (const ASTContext &Ctx) {
10081015 if (!isConstexpr () || getCond ()->isValueDependent ())
10091016 return std::nullopt ;
Original file line number Diff line number Diff line change @@ -556,6 +556,8 @@ class ScalarExprEmitter
556556 auto DomainName = E->getDomainName ();
557557 ASTContext::AvailabilityDomainInfo Info =
558558 CGF.getContext ().getFeatureAvailInfo (DomainName);
559+ assert ((Info.Kind == FeatureAvailKind::Dynamic && Info.Call ) &&
560+ " ObjCAvailabilityCheckExpr should have been constant evaluated" );
559561 return CGF.EmitScalarExpr (Info.Call );
560562 }
561563
Original file line number Diff line number Diff line change @@ -818,7 +818,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
818818 // the condition and the dead arm of the if/else.
819819 bool CondConstant;
820820 if (ConstantFoldsToSimpleInteger (S.getCond (), CondConstant,
821- S.isConstexpr ())) {
821+ ( S.isConstexpr () || S. isObjCAvailabilityCheckWithDomainName () ))) {
822822 // Figure out which block (then or else) is executed.
823823 const Stmt *Executed = S.getThen ();
824824 const Stmt *Skipped = S.getElse ();
@@ -827,7 +827,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
827827
828828 // If the skipped block has no labels in it, just emit the executed block.
829829 // This avoids emitting dead code and simplifies the CFG substantially.
830- if (S.isConstexpr () || !ContainsLabel (Skipped)) {
830+ if (( S.isConstexpr () || S. isObjCAvailabilityCheckWithDomainName () ) || !ContainsLabel (Skipped)) {
831831 if (CondConstant)
832832 incrementProfileCounter (&S);
833833 if (Executed) {
Original file line number Diff line number Diff line change @@ -83,13 +83,6 @@ class DiagnoseUnguardedFeatureAvailability
8383 return true ;
8484 }
8585
86- bool VisitLabelStmt (LabelStmt *LS) {
87- if (isConditionallyGuardedByFeature ())
88- SemaRef.Diag (LS->getBeginLoc (),
89- diag::err_label_in_conditionally_guarded_feature);
90- return true ;
91- }
92-
9386 bool VisitTypeLoc (TypeLoc Ty);
9487
9588 void IssueDiagnostics () {
Original file line number Diff line number Diff line change @@ -106,4 +106,22 @@ void test4(void) {
106106
107107#endif
108108
109+ // CHECK-LABEL: define void @test5()
110+ // CHECK: br label %[[L1:.*]]
111+ // CHECK: [[L1]]:
112+ // CHECK-NEXT: call i32 @func0()
113+ // CHECK-NEXT: ret void
114+
115+ void test5 (void ) {
116+ if (__builtin_available (domain :feature1 )) {
117+ goto L1 ;
118+ L1 :
119+ func0 ();
120+ } else {
121+ goto L2 ;
122+ L2 :
123+ func2 ();
124+ }
125+ }
126+
109127#endif /* HEADER */
Original file line number Diff line number Diff line change @@ -175,12 +175,22 @@ void test4(struct S0 *s0) { // expected-error {{use of 'S0' requires feature 'fe
175175 g11 .i0 = 0 ; // expected-error {{use of 'g11' requires feature 'feature1' to be available}} expected-error {{use of 'i0' requires feature 'feature1' to be available}}
176176}
177177
178- void test5 (void ) {
179- if (__builtin_available (domain :feature1 ))
180- label0 : // expected-error {{labels cannot appear in regions conditionally guarded by features}}
181- ;
182- label1 :
178+ void test5 (int c ) {
179+ if (c > 100 )
180+ goto label0 ; // expected-error {{cannot jump from this goto statement to its label}}
181+ else if (c > 50 )
182+ goto label1 ; // expected-error {{cannot jump from this goto statement to its label}}
183+ if (__builtin_available (domain :feature1 )) { // expected-note 2 {{jump enters controlled statement of if available}}
184+ label0 :
183185 ;
186+ } else {
187+ if (c > 80 )
188+ goto label2 ;
189+ label1 :
190+ ;
191+ label2 :
192+ ;
193+ }
184194}
185195
186196void test6 (void ) {
You can’t perform that action at this time.
0 commit comments