@@ -908,6 +908,69 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
908
908
incrementProfileCounter (&S);
909
909
}
910
910
911
+ bool CodeGenFunction::checkIfLoopMustProgress (const Expr *ControllingExpression,
912
+ bool HasEmptyBody) {
913
+ if (CGM.getCodeGenOpts ().getFiniteLoops () ==
914
+ CodeGenOptions::FiniteLoopsKind::Never)
915
+ return false ;
916
+
917
+ // Now apply rules for plain C (see 6.8.5.6 in C11).
918
+ // Loops with constant conditions do not have to make progress in any C
919
+ // version.
920
+ // As an extension, we consisider loops whose constant expression
921
+ // can be constant-folded.
922
+ Expr::EvalResult Result;
923
+ bool CondIsConstInt =
924
+ !ControllingExpression ||
925
+ (ControllingExpression->EvaluateAsInt (Result, getContext ()) &&
926
+ Result.Val .isInt ());
927
+
928
+ bool CondIsTrue = CondIsConstInt && (!ControllingExpression ||
929
+ Result.Val .getInt ().getBoolValue ());
930
+
931
+ // Loops with non-constant conditions must make progress in C11 and later.
932
+ if (getLangOpts ().C11 && !CondIsConstInt)
933
+ return true ;
934
+
935
+ // [C++26][intro.progress] (DR)
936
+ // The implementation may assume that any thread will eventually do one of the
937
+ // following:
938
+ // [...]
939
+ // - continue execution of a trivial infinite loop ([stmt.iter.general]).
940
+ if (CGM.getCodeGenOpts ().getFiniteLoops () ==
941
+ CodeGenOptions::FiniteLoopsKind::Always ||
942
+ getLangOpts ().CPlusPlus11 ) {
943
+ if (HasEmptyBody && CondIsTrue) {
944
+ CurFn->removeFnAttr (llvm::Attribute::MustProgress);
945
+ return false ;
946
+ }
947
+ return true ;
948
+ }
949
+ return false ;
950
+ }
951
+
952
+ // [C++26][stmt.iter.general] (DR)
953
+ // A trivially empty iteration statement is an iteration statement matching one
954
+ // of the following forms:
955
+ // - while ( expression ) ;
956
+ // - while ( expression ) { }
957
+ // - do ; while ( expression ) ;
958
+ // - do { } while ( expression ) ;
959
+ // - for ( init-statement expression(opt); ) ;
960
+ // - for ( init-statement expression(opt); ) { }
961
+ template <typename LoopStmt> static bool hasEmptyLoopBody (const LoopStmt &S) {
962
+ if constexpr (std::is_same_v<LoopStmt, ForStmt>) {
963
+ if (S.getInc ())
964
+ return false ;
965
+ }
966
+ const Stmt *Body = S.getBody ();
967
+ if (!Body || isa<NullStmt>(Body))
968
+ return true ;
969
+ if (const CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body))
970
+ return Compound->body_empty ();
971
+ return false ;
972
+ }
973
+
911
974
void CodeGenFunction::EmitWhileStmt (const WhileStmt &S,
912
975
ArrayRef<const Attr *> WhileAttrs) {
913
976
// Emit the header for the loop, which will also become
@@ -942,13 +1005,12 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
942
1005
// while(1) is common, avoid extra exit blocks. Be sure
943
1006
// to correctly handle break/continue though.
944
1007
llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
945
- bool CondIsConstInt = C != nullptr ;
946
- bool EmitBoolCondBranch = !CondIsConstInt || !C->isOne ();
1008
+ bool EmitBoolCondBranch = !C || !C->isOne ();
947
1009
const SourceRange &R = S.getSourceRange ();
948
1010
LoopStack.push (LoopHeader.getBlock (), CGM.getContext (), CGM.getCodeGenOpts (),
949
1011
WhileAttrs, SourceLocToDebugLoc (R.getBegin ()),
950
1012
SourceLocToDebugLoc (R.getEnd ()),
951
- checkIfLoopMustProgress (CondIsConstInt ));
1013
+ checkIfLoopMustProgress (S. getCond (), hasEmptyLoopBody (S) ));
952
1014
953
1015
// When single byte coverage mode is enabled, add a counter to loop condition.
954
1016
if (llvm::EnableSingleByteCoverage)
@@ -1059,14 +1121,13 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
1059
1121
// "do {} while (0)" is common in macros, avoid extra blocks. Be sure
1060
1122
// to correctly handle break/continue though.
1061
1123
llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal);
1062
- bool CondIsConstInt = C;
1063
1124
bool EmitBoolCondBranch = !C || !C->isZero ();
1064
1125
1065
1126
const SourceRange &R = S.getSourceRange ();
1066
1127
LoopStack.push (LoopBody, CGM.getContext (), CGM.getCodeGenOpts (), DoAttrs,
1067
1128
SourceLocToDebugLoc (R.getBegin ()),
1068
1129
SourceLocToDebugLoc (R.getEnd ()),
1069
- checkIfLoopMustProgress (CondIsConstInt ));
1130
+ checkIfLoopMustProgress (S. getCond (), hasEmptyLoopBody (S) ));
1070
1131
1071
1132
// As long as the condition is true, iterate the loop.
1072
1133
if (EmitBoolCondBranch) {
@@ -1109,15 +1170,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
1109
1170
llvm::BasicBlock *CondBlock = CondDest.getBlock ();
1110
1171
EmitBlock (CondBlock);
1111
1172
1112
- Expr::EvalResult Result;
1113
- bool CondIsConstInt =
1114
- !S.getCond () || S.getCond ()->EvaluateAsInt (Result, getContext ());
1115
-
1116
1173
const SourceRange &R = S.getSourceRange ();
1117
1174
LoopStack.push (CondBlock, CGM.getContext (), CGM.getCodeGenOpts (), ForAttrs,
1118
1175
SourceLocToDebugLoc (R.getBegin ()),
1119
1176
SourceLocToDebugLoc (R.getEnd ()),
1120
- checkIfLoopMustProgress (CondIsConstInt ));
1177
+ checkIfLoopMustProgress (S. getCond (), hasEmptyLoopBody (S) ));
1121
1178
1122
1179
// Create a cleanup scope for the condition variable cleanups.
1123
1180
LexicalScope ConditionScope (*this , S.getSourceRange ());
0 commit comments