Author: Danila Kutenin
Date: 2021-05-16T10:42:52-07:00
New Revision: d29f7f1a7b47345289d63318e7b2a28cc56e169d

URL: 
https://github.com/llvm/llvm-project/commit/d29f7f1a7b47345289d63318e7b2a28cc56e169d
DIFF: 
https://github.com/llvm/llvm-project/commit/d29f7f1a7b47345289d63318e7b2a28cc56e169d.diff

LOG: [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. kutdan...@yandex.ru

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D102502

Added: 
    clang/test/CodeGenCXX/for-loop-init-ternary-operator-statement.cpp
    clang/test/PCH/for-loop-init-ternary-operator-statement.cpp

Modified: 
    clang/lib/Parse/ParseExprCXX.cpp
    clang/lib/Parse/ParseTentative.cpp
    clang/test/Parser/cxx2a-init-statement.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Parse/ParseExprCXX.cpp 
b/clang/lib/Parse/ParseExprCXX.cpp
index 644df55bf46e8..93f578edc09e6 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -2033,6 +2033,8 @@ Sema::ConditionResult 
Parser::ParseCXXCondition(StmtResult *InitStmt,
     DeclGroupPtrTy DG = ParseSimpleDeclaration(DeclaratorContext::ForInit,
                                                DeclEnd, attrs, false, FRI);
     FRI->LoopVar = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
+    assert((FRI->ColonLoc.isValid() || !DG) &&
+           "cannot find for range declaration");
     return Sema::ConditionResult();
   }
 

diff  --git a/clang/lib/Parse/ParseTentative.cpp 
b/clang/lib/Parse/ParseTentative.cpp
index 3bf2bc455bfe8..c0bfbbde40ac8 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -353,8 +353,8 @@ struct Parser::ConditionDeclarationOrInitStatementState {
       if (CanBeForRangeDecl) {
         // Skip until we hit a ')', ';', or a ':' with no matching '?'.
         // The final case is a for range declaration, the rest are not.
+        unsigned QuestionColonDepth = 0;
         while (true) {
-          unsigned QuestionColonDepth = 0;
           P.SkipUntil({tok::r_paren, tok::semi, tok::question, tok::colon},
                       StopBeforeMatch);
           if (P.Tok.is(tok::question))

diff  --git 
a/clang/test/CodeGenCXX/for-loop-init-ternary-operator-statement.cpp 
b/clang/test/CodeGenCXX/for-loop-init-ternary-operator-statement.cpp
new file mode 100644
index 0000000000000..a40898b0e84d1
--- /dev/null
+++ b/clang/test/CodeGenCXX/for-loop-init-ternary-operator-statement.cpp
@@ -0,0 +1,42 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | 
FileCheck %s
+
+// CHECK-LABEL: @_Z1fv(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[RETVAL:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[X:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i32 0, i32* [[I]], align 4
+// CHECK-NEXT:    br label [[FOR_COND:%.*]]
+// CHECK:       for.cond:
+// CHECK-NEXT:    [[TMP0:%.*]] = load i32, i32* [[I]], align 4
+// CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[TMP0]], 2
+// CHECK-NEXT:    [[TMP1:%.*]] = zext i1 [[CMP]] to i64
+// CHECK-NEXT:    [[COND:%.*]] = select i1 [[CMP]], i32 1, i32 0
+// CHECK-NEXT:    store i32 [[COND]], i32* [[X]], align 4
+// CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[X]], align 4
+// CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP2]], 0
+// CHECK-NEXT:    br i1 [[TOBOOL]], label [[FOR_BODY:%.*]], label 
[[FOR_END:%.*]]
+// CHECK:       for.body:
+// CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[X]], align 4
+// CHECK-NEXT:    store i32 [[TMP3]], i32* [[RETVAL]], align 4
+// CHECK-NEXT:    br label [[RETURN:%.*]]
+// CHECK:       for.inc:
+// CHECK-NEXT:    [[TMP4:%.*]] = load i32, i32* [[I]], align 4
+// CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP4]], 1
+// CHECK-NEXT:    store i32 [[INC]], i32* [[I]], align 4
+// CHECK-NEXT:    br label [[FOR_COND]], !llvm.loop [[LOOP2:![0-9]+]]
+// CHECK:       for.end:
+// CHECK-NEXT:    store i32 0, i32* [[RETVAL]], align 4
+// CHECK-NEXT:    br label [[RETURN]]
+// CHECK:       return:
+// CHECK-NEXT:    [[TMP5:%.*]] = load i32, i32* [[RETVAL]], align 4
+// CHECK-NEXT:    ret i32 [[TMP5]]
+//
+int f() {
+  for (int i = 0; int x = i < 2 ? 1 : 0; i++) {
+    return x;
+  }
+  return 0;
+}
+

diff  --git a/clang/test/PCH/for-loop-init-ternary-operator-statement.cpp 
b/clang/test/PCH/for-loop-init-ternary-operator-statement.cpp
new file mode 100644
index 0000000000000..50819e79e6f6f
--- /dev/null
+++ b/clang/test/PCH/for-loop-init-ternary-operator-statement.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -emit-pch -o %t %s
+// RUN: %clang_cc1 -x ast -ast-print %t | FileCheck %s
+
+int f() {
+  // CHECK: for (int i = 0; x; i++) {
+  for (int i = 0; int x = i < 2 ? 1 : 0; i++) {
+    return x;
+  }
+  return 0;
+}
+

diff  --git a/clang/test/Parser/cxx2a-init-statement.cpp 
b/clang/test/Parser/cxx2a-init-statement.cpp
index 727ee63d1b927..116e38506d9d2 100644
--- a/clang/test/Parser/cxx2a-init-statement.cpp
+++ b/clang/test/Parser/cxx2a-init-statement.cpp
@@ -15,6 +15,8 @@ void f() {
   int A<0>::*arr2[3];
   for (int n = 5; int A<true ? 0 : 1>::*x : arr2) {}
 
+  for (int i = 0; int x = i < 2 ? 1 : 0; i++) {}
+
   F (*arr3[3])(int);
   for (int n = 5; F (*p)(int n) : arr3) {}
   for (int n = 5; F (*p)(int (n)) : arr3) {}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to