ricejasonf updated this revision to Diff 368962. ricejasonf added a comment.
I moved the test to CodeGenCXX and actually test output with FileCheck. I used the code from a non-template function as the expected output. Some minor formatting changes are also addressed. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D108482/new/ https://reviews.llvm.org/D108482 Files: clang/lib/Sema/SemaInit.cpp clang/lib/Sema/TreeTransform.h clang/test/CodeGenCXX/pr45964-decomp-transform.cpp Index: clang/test/CodeGenCXX/pr45964-decomp-transform.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/pr45964-decomp-transform.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++1z -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s + +int a[1]; +// CHECK: @a = global [1 x i32] zeroinitializer +template <int> +void test_transform() { + auto [b] = a; +} +void (*d)(){test_transform<0>}; +// CHECK-LABEL: define {{.*}} @_Z14test_transformILi0EEvv +// CHECK: [[ENTRY:.*]]: +// CHECK-NEXT: [[ARR:%.*]] = alloca [1 x i32] +// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[ARR]], i64 0, i64 0 +// CHECK-NEXT: br label %[[BODY:.*]] +// CHECK-EMPTY: +// CHECK-NEXT: [[BODY]]: +// CHECK-NEXT: [[CUR:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[NEXT:%.*]], %[[BODY]] ] +// CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i32, i32* [[BEGIN]], i64 [[CUR]] +// CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* @a, i64 0, i64 [[CUR]] +// CHECK-NEXT: [[X:%.*]] = load i32, i32* [[SRC]] +// CHECK-NEXT: store i32 [[X]], i32* [[DEST]] +// CHECK-NEXT: [[NEXT]] = add nuw i64 [[CUR]], 1 +// CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[NEXT]], 1 +// CHECK-NEXT: br i1 [[EQ]], label %[[FIN:.*]], label %[[BODY]] +// CHECK-EMPTY: +// CHECK-NEXT: [[FIN]]: +// CHECK-NEXT: ret void Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -10511,7 +10511,18 @@ TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) { assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) && "opaque value expression requires transformation"); - return E; + + // Note that SourceExpr can be nullptr. + ExprResult SourceExpr = TransformExpr(E->getSourceExpr()); + if (SourceExpr.isInvalid()) + return ExprError(); + if (SourceExpr.get() == E->getSourceExpr() && !getDerived().AlwaysRebuild()) + return E; + + OpaqueValueExpr *New = new (SemaRef.Context) + OpaqueValueExpr(E->getExprLoc(), E->getType(), E->getValueKind(), + E->getObjectKind(), SourceExpr.get()); + return New; } template<typename Derived> Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -8643,9 +8643,13 @@ case SK_ArrayLoopIndex: { Expr *Cur = CurInit.get(); - Expr *BaseExpr = new (S.Context) - OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(), - Cur->getValueKind(), Cur->getObjectKind(), Cur); + // Prevent nested OpaqueValueExprs. + Expr *BaseExpr = dyn_cast<OpaqueValueExpr>(Cur); + if (!BaseExpr) { + BaseExpr = new (S.Context) + OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(), + Cur->getValueKind(), Cur->getObjectKind(), Cur); + } Expr *IndexExpr = new (S.Context) ArrayInitIndexExpr(S.Context.getSizeType()); CurInit = S.CreateBuiltinArraySubscriptExpr(
Index: clang/test/CodeGenCXX/pr45964-decomp-transform.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/pr45964-decomp-transform.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -std=c++1z -triple x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s + +int a[1]; +// CHECK: @a = global [1 x i32] zeroinitializer +template <int> +void test_transform() { + auto [b] = a; +} +void (*d)(){test_transform<0>}; +// CHECK-LABEL: define {{.*}} @_Z14test_transformILi0EEvv +// CHECK: [[ENTRY:.*]]: +// CHECK-NEXT: [[ARR:%.*]] = alloca [1 x i32] +// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* [[ARR]], i64 0, i64 0 +// CHECK-NEXT: br label %[[BODY:.*]] +// CHECK-EMPTY: +// CHECK-NEXT: [[BODY]]: +// CHECK-NEXT: [[CUR:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[NEXT:%.*]], %[[BODY]] ] +// CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i32, i32* [[BEGIN]], i64 [[CUR]] +// CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds [1 x i32], [1 x i32]* @a, i64 0, i64 [[CUR]] +// CHECK-NEXT: [[X:%.*]] = load i32, i32* [[SRC]] +// CHECK-NEXT: store i32 [[X]], i32* [[DEST]] +// CHECK-NEXT: [[NEXT]] = add nuw i64 [[CUR]], 1 +// CHECK-NEXT: [[EQ:%.*]] = icmp eq i64 [[NEXT]], 1 +// CHECK-NEXT: br i1 [[EQ]], label %[[FIN:.*]], label %[[BODY]] +// CHECK-EMPTY: +// CHECK-NEXT: [[FIN]]: +// CHECK-NEXT: ret void Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -10511,7 +10511,18 @@ TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) { assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) && "opaque value expression requires transformation"); - return E; + + // Note that SourceExpr can be nullptr. + ExprResult SourceExpr = TransformExpr(E->getSourceExpr()); + if (SourceExpr.isInvalid()) + return ExprError(); + if (SourceExpr.get() == E->getSourceExpr() && !getDerived().AlwaysRebuild()) + return E; + + OpaqueValueExpr *New = new (SemaRef.Context) + OpaqueValueExpr(E->getExprLoc(), E->getType(), E->getValueKind(), + E->getObjectKind(), SourceExpr.get()); + return New; } template<typename Derived> Index: clang/lib/Sema/SemaInit.cpp =================================================================== --- clang/lib/Sema/SemaInit.cpp +++ clang/lib/Sema/SemaInit.cpp @@ -8643,9 +8643,13 @@ case SK_ArrayLoopIndex: { Expr *Cur = CurInit.get(); - Expr *BaseExpr = new (S.Context) - OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(), - Cur->getValueKind(), Cur->getObjectKind(), Cur); + // Prevent nested OpaqueValueExprs. + Expr *BaseExpr = dyn_cast<OpaqueValueExpr>(Cur); + if (!BaseExpr) { + BaseExpr = new (S.Context) + OpaqueValueExpr(Cur->getExprLoc(), Cur->getType(), + Cur->getValueKind(), Cur->getObjectKind(), Cur); + } Expr *IndexExpr = new (S.Context) ArrayInitIndexExpr(S.Context.getSizeType()); CurInit = S.CreateBuiltinArraySubscriptExpr(
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits