Skip to content

Commit d29f7f1

Browse files
danlark1zygoloid
authored andcommitted
[clang] Fix ternary operator in the second for loop statement
Fix ternary operator in for loop argument, it was by mistake not set as CanBeForRangeDecl and led to incorrect codegen. It fixes https://bugs.llvm.org/show_bug.cgi?id=50038. I don't have commit rights. Danila Kutenin. [email protected] Reviewed By: rsmith Differential Revision: https://reviews.llvm.org/D102502
1 parent d1a7630 commit d29f7f1

File tree

5 files changed

+58
-1
lines changed

5 files changed

+58
-1
lines changed

clang/lib/Parse/ParseExprCXX.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,6 +2033,8 @@ Sema::ConditionResult Parser::ParseCXXCondition(StmtResult *InitStmt,
20332033
DeclGroupPtrTy DG = ParseSimpleDeclaration(DeclaratorContext::ForInit,
20342034
DeclEnd, attrs, false, FRI);
20352035
FRI->LoopVar = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
2036+
assert((FRI->ColonLoc.isValid() || !DG) &&
2037+
"cannot find for range declaration");
20362038
return Sema::ConditionResult();
20372039
}
20382040

clang/lib/Parse/ParseTentative.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,8 @@ struct Parser::ConditionDeclarationOrInitStatementState {
353353
if (CanBeForRangeDecl) {
354354
// Skip until we hit a ')', ';', or a ':' with no matching '?'.
355355
// The final case is a for range declaration, the rest are not.
356+
unsigned QuestionColonDepth = 0;
356357
while (true) {
357-
unsigned QuestionColonDepth = 0;
358358
P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
359359
StopBeforeMatch);
360360
if (P.Tok.is(tok::question))
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s
3+
4+
// CHECK-LABEL: @_Z1fv(
5+
// CHECK-NEXT: entry:
6+
// CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
7+
// CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
8+
// CHECK-NEXT: [[X:%.*]] = alloca i32, align 4
9+
// CHECK-NEXT: store i32 0, i32* [[I]], align 4
10+
// CHECK-NEXT: br label [[FOR_COND:%.*]]
11+
// CHECK: for.cond:
12+
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[I]], align 4
13+
// CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP0]], 2
14+
// CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[CMP]] to i64
15+
// CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 1, i32 0
16+
// CHECK-NEXT: store i32 [[COND]], i32* [[X]], align 4
17+
// CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4
18+
// CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0
19+
// CHECK-NEXT: br i1 [[TOBOOL]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
20+
// CHECK: for.body:
21+
// CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[X]], align 4
22+
// CHECK-NEXT: store i32 [[TMP3]], i32* [[RETVAL]], align 4
23+
// CHECK-NEXT: br label [[RETURN:%.*]]
24+
// CHECK: for.inc:
25+
// CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[I]], align 4
26+
// CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP4]], 1
27+
// CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4
28+
// CHECK-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
29+
// CHECK: for.end:
30+
// CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4
31+
// CHECK-NEXT: br label [[RETURN]]
32+
// CHECK: return:
33+
// CHECK-NEXT: [[TMP5:%.*]] = load i32, i32* [[RETVAL]], align 4
34+
// CHECK-NEXT: ret i32 [[TMP5]]
35+
//
36+
int f() {
37+
for (int i = 0; int x = i < 2 ? 1 : 0; i++) {
38+
return x;
39+
}
40+
return 0;
41+
}
42+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang_cc1 -emit-pch -o %t %s
2+
// RUN: %clang_cc1 -x ast -ast-print %t | FileCheck %s
3+
4+
int f() {
5+
// CHECK: for (int i = 0; x; i++) {
6+
for (int i = 0; int x = i < 2 ? 1 : 0; i++) {
7+
return x;
8+
}
9+
return 0;
10+
}
11+

clang/test/Parser/cxx2a-init-statement.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ void f() {
1515
int A<0>::*arr2[3];
1616
for (int n = 5; int A<true ? 0 : 1>::*x : arr2) {}
1717

18+
for (int i = 0; int x = i < 2 ? 1 : 0; i++) {}
19+
1820
F (*arr3[3])(int);
1921
for (int n = 5; F (*p)(int n) : arr3) {}
2022
for (int n = 5; F (*p)(int (n)) : arr3) {}

0 commit comments

Comments
 (0)