return EmitUnaryOpLValue(cast<UnaryOperator>(E));
case Expr::ArraySubscriptExprClass:
return EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E));
- case Expr::OMPArraySectionExprClass:
- return EmitOMPArraySectionExpr(cast<OMPArraySectionExpr>(E));
case Expr::ExtVectorElementExprClass:
return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
case Expr::MemberExprClass:
return LV;
}
-LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E,
- bool LowerBound) {
- LValue Base;
- if (auto *ASE =
- dyn_cast<OMPArraySectionExpr>(E->getBase()->IgnoreParenImpCasts()))
- Base = EmitOMPArraySectionExpr(ASE, LowerBound);
- else
- Base = EmitLValue(E->getBase());
- QualType BaseTy = Base.getType();
- llvm::Value *Idx;
- QualType ResultExprTy;
- if (auto *AT = getContext().getAsArrayType(BaseTy))
- ResultExprTy = AT->getElementType();
- else
- ResultExprTy = BaseTy->getPointeeType();
- if (LowerBound) {
- Idx = E->getLowerBound()
- ? Builder.CreateIntCast(EmitScalarExpr(E->getLowerBound()),
- IntPtrTy,
- E->getLowerBound()
- ->getType()
- ->hasSignedIntegerRepresentation())
- : llvm::ConstantInt::getNullValue(IntPtrTy);
- } else {
- auto &C = CGM.getContext();
- auto *Length = E->getLength();
- if (Length || E->getColonLoc().isInvalid()) {
- // Idx = LowerBound + Length - 1;
- auto *One = llvm::ConstantInt::get(IntPtrTy, /*V=*/1);
- if (Length) {
- Idx = Builder.CreateIntCast(
- EmitScalarExpr(Length), IntPtrTy,
- Length->getType()->hasSignedIntegerRepresentation());
- }
- auto *LowerBound = E->getLowerBound();
- llvm::APSInt ConstLowerBound;
- if (LowerBound && LowerBound->isIntegerConstantExpr(ConstLowerBound, C))
- LowerBound = nullptr;
- if (LowerBound && ConstLowerBound.getZExtValue() != 0) {
- auto *LowerBoundVal = Builder.CreateIntCast(
- EmitScalarExpr(LowerBound), IntPtrTy,
- LowerBound->getType()->hasSignedIntegerRepresentation());
- if (E->getColonLoc().isValid()) {
- if (getLangOpts().isSignedOverflowDefined())
- Idx = Builder.CreateAdd(Idx, LowerBoundVal);
- else
- Idx = Builder.CreateNSWAdd(Idx, LowerBoundVal);
- } else
- Idx = LowerBoundVal;
- }
- if (E->getColonLoc().isValid()) {
- if (getLangOpts().isSignedOverflowDefined())
- Idx = Builder.CreateSub(Idx, One);
- else
- Idx = Builder.CreateNSWSub(Idx, One);
- }
- } else if (auto *VAT = C.getAsVariableArrayType(BaseTy)) {
- // Idx = ArrSize - 1;
- Length = VAT->getSizeExpr();
- Idx = Builder.CreateIntCast(
- EmitScalarExpr(Length), IntPtrTy,
- Length->getType()->hasSignedIntegerRepresentation());
- auto *One = llvm::ConstantInt::get(IntPtrTy, /*V=*/1);
- if (getLangOpts().isSignedOverflowDefined())
- Idx = Builder.CreateSub(Idx, One);
- else
- Idx = Builder.CreateNSWSub(Idx, One);
- } else {
- // Idx = ArrSize - 1;
- auto *CAT = C.getAsConstantArrayType(BaseTy);
- Idx = llvm::ConstantInt::get(IntPtrTy, CAT->getSize().getZExtValue() - 1);
- }
- }
-
- llvm::Value *Address;
- CharUnits ArrayAlignment;
- if (auto *VLA = getContext().getAsVariableArrayType(ResultExprTy)) {
- // The element count here is the total number of non-VLA elements.
- llvm::Value *numElements = getVLASize(VLA).first;
-
- // Effectively, the multiply by the VLA size is part of the GEP.
- // GEP indexes are signed, and scaling an index isn't permitted to
- // signed-overflow, so we use the same semantics for our explicit
- // multiply. We suppress this if overflow is not undefined behavior.
- if (getLangOpts().isSignedOverflowDefined()) {
- Idx = Builder.CreateMul(Idx, numElements);
- Address = Builder.CreateGEP(Base.getAddress(), Idx, "arrayidx");
- } else {
- Idx = Builder.CreateNSWMul(Idx, numElements);
- Address = Builder.CreateInBoundsGEP(Base.getAddress(), Idx, "arrayidx");
- }
- } else if (BaseTy->isConstantArrayType()) {
- llvm::Value *ArrayPtr = Base.getAddress();
- llvm::Value *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
- llvm::Value *Args[] = {Zero, Idx};
-
- // Propagate the alignment from the array itself to the result.
- ArrayAlignment = Base.getAlignment();
-
- if (getLangOpts().isSignedOverflowDefined())
- Address = Builder.CreateGEP(ArrayPtr, Args, "arrayidx");
- else
- Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, "arrayidx");
- } else {
- // The base must be a pointer, which is not an aggregate. Emit it.
- if (getLangOpts().isSignedOverflowDefined())
- Address = Builder.CreateGEP(Base.getAddress(), Idx, "arrayidx");
- else
- Address = Builder.CreateInBoundsGEP(Base.getAddress(), Idx, "arrayidx");
- }
-
- // Limit the alignment to that of the result type.
- LValue LV;
- if (!ArrayAlignment.isZero()) {
- CharUnits Align = getContext().getTypeAlignInChars(ResultExprTy);
- ArrayAlignment = std::min(Align, ArrayAlignment);
- LV = MakeAddrLValue(Address, ResultExprTy, ArrayAlignment);
- } else
- LV = MakeNaturalAlignAddrLValue(Address, ResultExprTy);
-
- LV.getQuals().setAddressSpace(BaseTy.getAddressSpace());
-
- return LV;
-}
-
LValue CodeGenFunction::
EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
// Emit the base vector as an l-value.
// CHECK: [[S:%.+]] = alloca [2 x [[STRUCT_S]]]
char b;
S s[2];
- int arr[10][a];
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T]]* @{{.+}})
// CHECK: [[B_REF:%.+]] = getelementptr inbounds [[STRUCT_SHAREDS]], [[STRUCT_SHAREDS]]* [[CAPTURES:%.+]], i32 0, i32 0
// CHECK: store i8* [[B]], i8** [[B_REF]]
// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[SHAREDS_REF]], i8* [[BITCAST]], i64 8, i32 8, i1 false)
// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]], [[KMP_TASK_T]]* [[TASK_PTR]], i32 0, i32 3
// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
-// CHECK: getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: store i64 ptrtoint (i32* @{{.+}} to i64), i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1
// CHECK: store i64 4, i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 1, i8*
-// CHECK: getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 1
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: ptrtoint i8* [[B]] to i64
// CHECK: store i64 %{{[^,]+}}, i64*
// CHECK: store i64 1, i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 1, i8*
-// CHECK: getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 2
+// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: ptrtoint [2 x [[STRUCT_S]]]* [[S]] to i64
// CHECK: store i64 %{{[^,]+}}, i64*
// CHECK: store i64 8, i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 1, i8*
-// CHECK: [[IDX1:%.+]] = mul nsw i64 0, [[A_VAL:%.+]]
-// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[IDX1:%.+]] = mul nsw i64 9, [[A_VAL]]
-// CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[END1:%.+]] = getelementptr i32, i32* [[END]], i32 1
-// CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START]] to i64
-// CHECK: [[END_INT:%.+]] = ptrtoint i32* [[END1]] to i64
-// CHECK: [[SIZEOF:%.+]] = sub nuw i64 [[END_INT]], [[START_INT]]
-// CHECK: getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 3
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
-// CHECK: ptrtoint i32* [[START]] to i64
-// CHECK: store i64 %{{[^,]+}}, i64*
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1
-// CHECK: store i64 [[SIZEOF]], i64*
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
-// CHECK: store i8 1, i8*
-// CHECK: getelementptr inbounds [4 x [[KMP_DEPEND_INFO]]], [4 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8*
-// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 4, i8* %{{[^,]+}}, i32 0, i8* null)
-#pragma omp task shared(a, s) depend(in : a, b, s, arr[:])
+// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 3, i8* %{{[^,]+}}, i32 0, i8* null)
+#pragma omp task shared(a, s) depend(in : a, b, s)
{
a = 15;
s[1].a = 10;
// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3
// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
// CHECK: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i32 0, i64 0
-// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [1 x [[KMP_DEPEND_INFO]]], [1 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: ptrtoint [[STRUCT_S]]* %{{.+}} to i64
// CHECK: store i64 %{{[^,]+}}, i64*
// CHECK: store i64 4, i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 2, i8*
-// CHECK: [[IDX1:%.+]] = mul nsw i64 4, [[A_VAL]]
-// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]
-// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64
-// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 [[IDX2]]
-// CHECK: [[IDX1:%.+]] = mul nsw i64 9, [[A_VAL]]
-// CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[B_VAL:%.+]] = load i8, i8* [[B]]
-// CHECK: [[IDX2:%.+]] = sext i8 [[B_VAL]] to i64
-// CHECK: [[END1:%.+]] = getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]]
-// CHECK: [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1
-// CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64
-// CHECK: [[END_INT:%.+]] = ptrtoint i32* [[END2]] to i64
-// CHECK: [[SIZEOF:%.+]] = sub nuw i64 [[END_INT]], [[START_INT]]
-// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 1
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
-// CHECK: ptrtoint i32* [[START1]] to i64
-// CHECK: store i64 %{{[^,]+}}, i64*
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1
-// CHECK: store i64 [[SIZEOF]], i64*
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
-// CHECK: store i8 2, i8*
-// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [1 x [[KMP_DEPEND_INFO]]], [1 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8*
-// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 2, i8* %{{[^,]+}}, i32 0, i8* null)
-#pragma omp task untied depend(out : s[0], arr[4:][b])
+// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 1, i8* %{{[^,]+}}, i32 0, i8* null)
+#pragma omp task untied depend(out : s[0])
{
a = 1;
}
// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 3, i64 32, i64 1,
// CHECK: [[DESTRUCTORS_REF_PTR:%.+]] = getelementptr inbounds [[KMP_TASK_T]]{{.*}}* {{%.+}}, i32 0, i32 3
// CHECK: store i32 (i32, i8*)* null, i32 (i32, i8*)** [[DESTRUCTORS_REF_PTR]]
-// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: store i64 ptrtoint (i32* @{{.+}} to i64), i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 3, i8*
// CHECK: getelementptr inbounds [2 x [[STRUCT_S]]], [2 x [[STRUCT_S]]]* [[S]], i32 0, i64 1
-// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 1
+// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 1
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: ptrtoint [[STRUCT_S]]* %{{.+}} to i64
// CHECK: store i64 %{{[^,]+}}, i64*
// CHECK: store i64 4, i64*
// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
// CHECK: store i8 3, i8*
-// CHECK: [[IDX1:%.+]] = mul nsw i64 0, [[A_VAL]]
-// CHECK: [[START:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[START1:%.+]] = getelementptr inbounds i32, i32* [[START]], i64 3
-// CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}},
-// CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64
-// CHECK: [[SUB:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1
-// CHECK: [[IDX1:%.+]] = mul nsw i64 [[SUB]], [[A_VAL]]
-// CHECK: [[END:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[NEW_A_VAL:%.+]] = load i32, i32* @{{.+}},
-// CHECK: [[NEW_A_VAL_I64:%.+]] = sext i32 [[NEW_A_VAL]] to i64
-// CHECK: [[IDX2:%.+]] = sub nsw i64 [[NEW_A_VAL_I64]], 1
-// CHECK: [[END1:%.+]] = getelementptr inbounds i32, i32* [[END]], i64 [[IDX2]]
-// CHECK: [[END2:%.+]] = getelementptr i32, i32* [[END1]], i32 1
-// CHECK: [[START_INT:%.+]] = ptrtoint i32* [[START1]] to i64
-// CHECK: [[END_INT:%.+]] = ptrtoint i32* [[END2]] to i64
-// CHECK: [[SIZEOF:%.+]] = sub nuw i64 [[END_INT]], [[START_INT]]
-// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 2
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 0
-// CHECK: ptrtoint i32* [[START1]] to i64
-// CHECK: store i64 %{{[^,]+}}, i64*
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 1
-// CHECK: store i64 [[SIZEOF]], i64*
-// CHECK: getelementptr inbounds [[KMP_DEPEND_INFO]], [[KMP_DEPEND_INFO]]* %{{[^,]+}}, i32 0, i32 2
-// CHECK: store i8 3, i8*
-// CHECK: getelementptr inbounds [3 x [[KMP_DEPEND_INFO]]], [3 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
+// CHECK: getelementptr inbounds [2 x [[KMP_DEPEND_INFO]]], [2 x [[KMP_DEPEND_INFO]]]* %{{[^,]+}}, i32 0, i32 0
// CHECK: bitcast [[KMP_DEPEND_INFO]]* %{{.+}} to i8*
-// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 3, i8* %{{[^,]+}}, i32 0, i8* null)
-#pragma omp task final(true) depend(inout: a, s[1], arr[:a][3:])
+// CHECK: call i32 @__kmpc_omp_task_with_deps([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]], i32 2, i8* %{{[^,]+}}, i32 0, i8* null)
+#pragma omp task final(true) depend(inout: a, s[1])
{
a = 2;
}