From 359ddfd9d9388c5ec570def90d519d736a32fc73 Mon Sep 17 00:00:00 2001 From: "John F. Carr" Date: Fri, 10 Jan 2025 13:46:25 -0500 Subject: [PATCH 1/2] Test that the C++20 init statement works with range Cilk for --- clang/test/Cilk/cilkfor-init.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 clang/test/Cilk/cilkfor-init.cpp diff --git a/clang/test/Cilk/cilkfor-init.cpp b/clang/test/Cilk/cilkfor-init.cpp new file mode 100644 index 000000000000..40492c5949e4 --- /dev/null +++ b/clang/test/Cilk/cilkfor-init.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 %s -std=c++20 -triple x86_64-unknown-linux-gnu -fopencilk -disable-llvm-passes -verify -emit-llvm -o - | FileCheck %s +// Make sure the C++20 init-statement works with cilk_for. + +extern bool *getarray(unsigned long size); + +extern unsigned int global[1000]; + +// CHECK-LABEL: _Z4scanv +void scan() { + + // This syntax is new in C++20. + _Cilk_for (bool *array = getarray(666); unsigned int i : global) { + // expected-warning@-1{{experimental}} + // CHECK: %[[ARRAY:.+]] = call noundef ptr @_Z8getarraym(i64 noundef 666) + // CHECK-NEXT: store ptr %[[ARRAY]], ptr %array, align 8 + // CHECK: pfor.body: + // CHECK: %[[ARRAY2:.+]] = load ptr, ptr %array + // CHECK: %[[ELEMENT:.+]] = getelementptr inbounds i8, ptr %[[ARRAY2]] + // CHECK: store i8 1, ptr %[[ELEMENT]] + // CHECK-NEXT: br label + array[i] = true; + } + + // CHECK: ret void + +} From 637e62317d33d6cc0e1f35e6b156e93838645b25 Mon Sep 17 00:00:00 2001 From: "John F. Carr" Date: Fri, 10 Jan 2025 14:46:46 -0500 Subject: [PATCH 2/2] Report a clearer error for non-integral iterator differences --- clang/lib/Sema/SemaStmt.cpp | 2 +- clang/test/Cilk/cilkfor-range-error.cpp | 36 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 clang/test/Cilk/cilkfor-range-error.cpp diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 691758ecd76b..f274ca406270 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4002,7 +4002,7 @@ StmtResult Sema::BuildCilkForRangeStmt(CXXForRangeStmt *ForRange) { } ExprResult LimitExpr = ActOnBinOp(S, ForRange->getColonLoc(), tok::minus, EndRef.get(), BeginRef.get()); - if (LimitExpr.isInvalid()) { + if (LimitExpr.isInvalid() || !LimitExpr.get()->getType()->isIntegerType()) { // CilkForRange currently only supports random access iterators. Diag(ForRange->getForLoc(), diag::err_cilk_for_range_end_minus_begin); return StmtError(); diff --git a/clang/test/Cilk/cilkfor-range-error.cpp b/clang/test/Cilk/cilkfor-range-error.cpp new file mode 100644 index 000000000000..a897400e82f8 --- /dev/null +++ b/clang/test/Cilk/cilkfor-range-error.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 %s -std=c++20 -triple x86_64-unknown-linux-gnu -fopencilk -fsyntax-only -verify + +template +struct Iterator { + void *data; + Iterator operator+(long); + bool operator!=(const Iterator &) const; + Iterator &operator++(); + Datum &operator*(); + Datum *operator->(); +}; + +struct S { + int data; + struct I : public Iterator { + float operator-(const I &) const; + }; + I begin(), end(); +}; + +struct T { + int data; + struct I : public Iterator { + long operator-(const I &) const; + }; + I begin(), end(); +}; + +void sum(S &s, T &t) { + _Cilk_for (auto i : s) { // expected-warning{{experimental}} + // expected-error@-1{{cannot determine length}} + } + _Cilk_for (auto i : _Cilk_spawn t) { // expected-warning{{experimental}} + // expected-error@-1{{'cilk_spawn' not allowed in this scope}} + } +}