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