Skip to content

Commit 2acda98

Browse files
committed
Trivial infinite loops are considered infinite,
even in the presence of -ffinite-loops
1 parent d97c458 commit 2acda98

File tree

6 files changed

+37
-35
lines changed

6 files changed

+37
-35
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ Modified Compiler Flags
297297
- Carved out ``-Wformat`` warning about scoped enums into a subwarning and
298298
make it controlled by ``-Wformat-pedantic``. Fixes #GH88595.
299299

300+
- Trivial infinite loops (i.e loops with a constant controlling expresion
301+
evaluating to ``true`` and an empty body such as ``while(1);``)
302+
are considered infinite, even when the ``-ffinite-loop`` flag is set.
303+
300304
Removed Compiler Flags
301305
-------------------------
302306

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3971,7 +3971,7 @@ def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>,
39713971
def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>,
39723972
HelpText<"Turn off loop unroller">, Visibility<[ClangOption, CC1Option]>;
39733973
def ffinite_loops: Flag<["-"], "ffinite-loops">, Group<f_Group>,
3974-
HelpText<"Assume all loops are finite.">, Visibility<[ClangOption, CC1Option]>;
3974+
HelpText<"Assume all non-trivial loops are finite.">, Visibility<[ClangOption, CC1Option]>;
39753975
def fno_finite_loops: Flag<["-"], "fno-finite-loops">, Group<f_Group>,
39763976
HelpText<"Do not assume that any loop is finite.">,
39773977
Visibility<[ClangOption, CC1Option]>;

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -909,15 +909,11 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
909909
}
910910

911911
bool CodeGenFunction::checkIfLoopMustProgress(const Expr *ControllingExpression,
912-
bool IsTrivialCXXLoop) {
912+
bool HasEmptyBody) {
913913
if (CGM.getCodeGenOpts().getFiniteLoops() ==
914914
CodeGenOptions::FiniteLoopsKind::Never)
915915
return false;
916916

917-
if (CGM.getCodeGenOpts().getFiniteLoops() ==
918-
CodeGenOptions::FiniteLoopsKind::Always &&
919-
!getLangOpts().CPlusPlus11)
920-
return true;
921917
// Now apply rules for plain C (see 6.8.5.6 in C11).
922918
// Loops with constant conditions do not have to make progress in any C
923919
// version.
@@ -944,8 +940,10 @@ bool CodeGenFunction::checkIfLoopMustProgress(const Expr *ControllingExpression,
944940
// following:
945941
// [...]
946942
// - continue execution of a trivial infinite loop ([stmt.iter.general]).
947-
if (getLangOpts().CPlusPlus11) {
948-
if (IsTrivialCXXLoop && CondIsTrue) {
943+
if (CGM.getCodeGenOpts().getFiniteLoops() ==
944+
CodeGenOptions::FiniteLoopsKind::Always ||
945+
getLangOpts().CPlusPlus11) {
946+
if (HasEmptyBody && CondIsTrue) {
949947
CurFn->removeFnAttr(llvm::Attribute::MustProgress);
950948
return false;
951949
}

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ class CodeGenFunction : public CodeGenTypeCache {
636636
/// Returns true if a loop must make progress, which means the mustprogress
637637
/// attribute can be added. \p HasConstantCond indicates whether the branch
638638
/// condition is a known constant.
639-
bool checkIfLoopMustProgress(const Expr *, bool IsTrivialCXXLoop);
639+
bool checkIfLoopMustProgress(const Expr *, bool HasEmptyBody);
640640

641641
const CodeGen::CGBlockInfo *BlockInfo = nullptr;
642642
llvm::Value *BlockPointer = nullptr;

clang/test/CodeGen/attr-mustprogress.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ int b = 0;
3030
// CHECK: for.cond:
3131
// C99-NOT: br {{.*}}!llvm.loop
3232
// C11-NOT: br {{.*}}!llvm.loop
33-
// FINITE-NEXT: br {{.*}}!llvm.loop
33+
// FINITE-NOR: br {{.*}}!llvm.loop
3434
//
3535
void f0(void) {
3636
for (; ;) ;
@@ -45,7 +45,7 @@ void f0(void) {
4545
// CHECK: for.body:
4646
// C99-NOT: br {{.*}}, !llvm.loop
4747
// C11-NOT: br {{.*}}, !llvm.loop
48-
// FINITE-NEXT: br {{.*}}, !llvm.loop
48+
// FINITE-NOT: br {{.*}}, !llvm.loop
4949
// CHECK: for.end:
5050
// CHECK-NEXT: ret void
5151
//
@@ -84,7 +84,7 @@ void f2(void) {
8484
// CHECK: for.body:
8585
// C99-NOT: br {{.*}}, !llvm.loop
8686
// C11-NOT: br {{.*}}, !llvm.loop
87-
// FINITE-NEXT: br {{.*}}, !llvm.loop
87+
// FINITE-NOT: br {{.*}}, !llvm.loop
8888
// CHECK: for.end:
8989
// CHECK-NEXT: br label %for.cond1
9090
// CHECK: for.cond1:
@@ -113,7 +113,7 @@ void F(void) {
113113
// CHECK: while.body:
114114
// C99-NOT: br {{.*}}, !llvm.loop
115115
// C11-NOT: br {{.*}}, !llvm.loop
116-
// FINITE-NEXT: br {{.*}}, !llvm.loop
116+
// FINITE-NOT: br {{.*}}, !llvm.loop
117117
//
118118
void w1(void) {
119119
while (1) {
@@ -159,7 +159,7 @@ void w2(void) {
159159
// CHECK: while.body2:
160160
// C99-NOT: br {{.*}} !llvm.loop
161161
// C11-NOT: br {{.*}} !llvm.loop
162-
// FINITE-NEXT: br {{.*}} !llvm.loop
162+
// FINITE-NOT: br {{.*}} !llvm.loop
163163
//
164164
void W(void) {
165165
while (a == b) {
@@ -177,7 +177,7 @@ void W(void) {
177177
// CHECK: do.cond:
178178
// C99-NOT: br {{.*}}, !llvm.loop
179179
// C11-NOT: br {{.*}}, !llvm.loop
180-
// FINITE-NEXT: br {{.*}}, !llvm.loop
180+
// FINITE-NOT: br {{.*}}, !llvm.loop
181181
// CHECK: do.end:
182182
// CHECK-NEXT: ret void
183183
//

clang/test/CodeGenCXX/attr-mustprogress.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ int b = 0;
3232
// CHECK: for.cond:
3333
// CXX98-NOT: br {{.*}} llvm.loop
3434
// CXX11-NOT: br {{.*}} llvm.loop
35-
// FINITE-NEXT: br label %for.cond, !llvm.loop [[LOOP1:!.*]]
35+
// FINITE-NOT: br {{.*}} llvm.loop
3636
void f0() {
3737
for (; ;) ;
3838
}
@@ -48,7 +48,7 @@ void f0() {
4848
// CHECK: for.body:
4949
// CXX98-NOT: br {{.*}}, !llvm.loop
5050
// CXX11-NOT: br {{.*}} llvm.loop
51-
// FINITE-NEXT: br label %for.cond, !llvm.loop [[LOOP2:!.*]]
51+
// FINITE-NOT: br {{.*}} llvm.loop
5252
// CHECK: for.end:
5353
// CHECK-NEXT: ret void
5454
//
@@ -91,7 +91,7 @@ void f2() {
9191
// CHECK: for.body:
9292
// CXX98-NOT: br {{.*}}, !llvm.loop
9393
// CXX11-NOT: br {{.*}}, !llvm.loop
94-
// FINITE-NEXT: br label %for.cond, !llvm.loop [[LOOP4:!.*]]
94+
// FINITE-NOT: br {{.*}}, !llvm.loop
9595
// CHECK: for.end:
9696
// CHECK-NEXT: br label %for.cond1
9797
// CHECK: for.cond1:
@@ -135,7 +135,7 @@ void F() {
135135
// CHECK: for.body2:
136136
// CXX98-NOT: br {{.*}}, !llvm.loop
137137
// CXX11-NOT: br {{.*}}, !llvm.loop
138-
// FINITE-NEXT: br label %for.cond1, !llvm.loop [[LOOP7:!.*]]
138+
// FINITE-NOT: br {{.*}}, !llvm.loop
139139
// CHECK: for.end3:
140140
// CHECK-NEXT: ret void
141141
//
@@ -155,7 +155,7 @@ void F2() {
155155
// CHECK: while.body:
156156
// CXX98-NOT: br {{.*}}, !llvm.loop
157157
// CXX11-NOT: br {{.*}}, !llvm.loop
158-
// FINITE-NEXT: br label %while.body, !llvm.loop [[LOOP8:!.*]]
158+
// FINITE-NOT: br {{.*}}, !llvm.loop
159159
//
160160
void w1() {
161161
while (1)
@@ -205,7 +205,7 @@ void w2() {
205205
// CHECK: while.body2:
206206
// CXX98-NOT: br {{.*}}, !llvm.loop
207207
// CXX11-NOT: br {{.*}}, !llvm.loop
208-
// FINITE-NEXT: br label %while.body2, !llvm.loop [[LOOP11:!.*]]
208+
// FINITE-NOT: br {{.*}}, !llvm.loop
209209
//
210210
void W() {
211211
while (a == b)
@@ -223,7 +223,7 @@ void W() {
223223
// CHECK: while.body:
224224
// CXX98-NOT: br {{.*}}, !llvm.loop
225225
// CXX11-NOT: br {{.*}}, !llvm.loop
226-
// FINITE-NEXT: br label %while.body, !llvm.loop [[LOOP12:!.*]]
226+
// FINITE-NOT: br {{.*}}, !llvm.loop
227227
//
228228
void W2() {
229229
while (1)
@@ -243,7 +243,7 @@ void W2() {
243243
// CHECK: do.cond:
244244
// CXX98-NOT: br {{.*}}, !llvm.loop
245245
// CXX11-NOT: br {{.*}}, !llvm.loop
246-
// FINITE-NEXT: br i1 true, label %do.body, label %do.end, !llvm.loop [[LOOP13:!.*]]
246+
// FINITE-NOT: br {{.*}}, !llvm.loop
247247
// CHECK: do.end:
248248
// CHECK-NEXT: ret void
249249
//
@@ -288,7 +288,7 @@ void d2() {
288288
// CHECK: do.cond:
289289
// CXX98-NOT: br {{.*}}, !llvm.loop
290290
// CXX11-NOT: br {{.*}}, !llvm.loop
291-
// FINITE-NEXT: br i1 true, label %do.body, label %do.end, !llvm.loop [[LOOP15:!.*]]
291+
// FINITE-NOT: br {{.*}}, !llvm.loop
292292
// CHECK: do.end:
293293
// CHECK-NEXT: br label %do.body1
294294
// CHECK: do.body1:
@@ -334,7 +334,7 @@ void D() {
334334
// CHECK: do.cond2:
335335
// CXX98-NOT: br {{.*}}, !llvm.loop
336336
// CXX11-NOT: br {{.*}}, !llvm.loop
337-
// FINITE-NEXT: br i1 true, label %do.body1, label %do.end3, !llvm.loop [[LOOP18:!.*]]
337+
// FINITE-NOT: br {{.*}}, !llvm.loop
338338
// CHECK: do.end3:
339339
// CHECK-NEXT: ret void
340340
//
@@ -354,9 +354,9 @@ void D2() {
354354
// CHECK-NEXT: entry:
355355
// CHECK-NEXT: br label %for.cond
356356
// CHECK: for.cond:
357-
// CXX98-NOT: br {{.*}} llvm.loop
358-
// CXX11-NOT: br {{.*}} llvm.loop
359-
// FINITE-NEXT: br label %for.cond, !llvm.loop [[LOOP19:!.*]]
357+
// CXX98-NOT: br {{.*}}, !llvm.loop
358+
// CXX11-NOT: br {{.*}}, !llvm.loop
359+
// FINITE-NOT: br {{.*}}, !llvm.loop
360360
void compound0() {
361361
for (; ;) {}
362362
}
@@ -368,9 +368,9 @@ void compound0() {
368368
// CHECK-NEXT: entry:
369369
// CHECK-NEXT: br label %for.cond
370370
// CHECK: for.cond:
371-
// CXX98-NOT: br {{.*}} llvm.loop
372-
// CXX11-NOT: br {{.*}} llvm.loop
373-
// FINITE-NEXT: br label %for.cond, !llvm.loop [[LOOP20:!.*]]
371+
// CXX98-NOT: br {{.*}}, llvm.loop
372+
// CXX11-NOT: br {{.*}}, llvm.loop
373+
// FINITE-NOT: br {{.*}}, !llvm.loop
374374
void compound1() {
375375
for (; ;) {/*! */}
376376
}
@@ -384,9 +384,9 @@ void compound1() {
384384
// CHECK: do.body:
385385
// CHECK-NEXT: br label %do.cond
386386
// CHECK: do.cond:
387-
// CXX98-NOT: br {{.*}}, !llvm.loop
388-
// CXX11-NOT: br {{.*}}, !llvm.loop
389-
// FINITE-NEXT: br i1 true, label %do.body, label %do.end, !llvm.loop [[LOOP21:!.*]]
387+
// CXX98-NOT: br {{.*}}, !llvm.loop
388+
// CXX11-NOT: br {{.*}}, !llvm.loop
389+
// FINITE-NOT: br {{.*}}, !llvm.loop
390390
// CHECK: do.end:
391391
// CHECK-NEXT: ret void
392392
//
@@ -396,7 +396,7 @@ void compound2() {
396396

397397
// CXX98-NOT: mustprogress
398398
// CXX11 : mustprogress
399-
// FINITE-NOT: mustprogress
399+
// FINITE : mustprogress
400400
// CHECK-LABEL: @_Z5Falsev(
401401
// CHECK-NEXT: entry:
402402
// CHECK-NEXT: br label %do.body

0 commit comments

Comments
 (0)