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
2418
2418
2419
2419
bool isObjCAvailabilityCheck () const ;
2420
2420
2421
+ bool isObjCAvailabilityCheckWithDomainName () const ;
2422
+
2421
2423
SourceLocation getBeginLoc () const { return getIfLoc (); }
2422
2424
SourceLocation getEndLoc () const LLVM_READONLY {
2423
2425
if (getElse ())
Original file line number Diff line number Diff line change @@ -1004,6 +1004,13 @@ bool IfStmt::isObjCAvailabilityCheck() const {
1004
1004
return isa<ObjCAvailabilityCheckExpr>(getCond ());
1005
1005
}
1006
1006
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
+
1007
1014
std::optional<Stmt *> IfStmt::getNondiscardedCase (const ASTContext &Ctx) {
1008
1015
if (!isConstexpr () || getCond ()->isValueDependent ())
1009
1016
return std::nullopt;
Original file line number Diff line number Diff line change @@ -556,6 +556,8 @@ class ScalarExprEmitter
556
556
auto DomainName = E->getDomainName ();
557
557
ASTContext::AvailabilityDomainInfo Info =
558
558
CGF.getContext ().getFeatureAvailInfo (DomainName);
559
+ assert ((Info.Kind == FeatureAvailKind::Dynamic && Info.Call ) &&
560
+ " ObjCAvailabilityCheckExpr should have been constant evaluated" );
559
561
return CGF.EmitScalarExpr (Info.Call );
560
562
}
561
563
Original file line number Diff line number Diff line change @@ -818,7 +818,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
818
818
// the condition and the dead arm of the if/else.
819
819
bool CondConstant;
820
820
if (ConstantFoldsToSimpleInteger (S.getCond (), CondConstant,
821
- S.isConstexpr ())) {
821
+ ( S.isConstexpr () || S. isObjCAvailabilityCheckWithDomainName () ))) {
822
822
// Figure out which block (then or else) is executed.
823
823
const Stmt *Executed = S.getThen ();
824
824
const Stmt *Skipped = S.getElse ();
@@ -827,7 +827,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
827
827
828
828
// If the skipped block has no labels in it, just emit the executed block.
829
829
// This avoids emitting dead code and simplifies the CFG substantially.
830
- if (S.isConstexpr () || !ContainsLabel (Skipped)) {
830
+ if (( S.isConstexpr () || S. isObjCAvailabilityCheckWithDomainName () ) || !ContainsLabel (Skipped)) {
831
831
if (CondConstant)
832
832
incrementProfileCounter (&S);
833
833
if (Executed) {
Original file line number Diff line number Diff line change @@ -83,13 +83,6 @@ class DiagnoseUnguardedFeatureAvailability
83
83
return true ;
84
84
}
85
85
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
-
93
86
bool VisitTypeLoc (TypeLoc Ty);
94
87
95
88
void IssueDiagnostics () {
Original file line number Diff line number Diff line change @@ -106,4 +106,22 @@ void test4(void) {
106
106
107
107
#endif
108
108
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
+
109
127
#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
175
175
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}}
176
176
}
177
177
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 :
183
185
;
186
+ } else {
187
+ if (c > 80 )
188
+ goto label2 ;
189
+ label1 :
190
+ ;
191
+ label2 :
192
+ ;
193
+ }
184
194
}
185
195
186
196
void test6 (void ) {
You can’t perform that action at this time.
0 commit comments