diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 17f95e7f3cac0d..b07c57ab86d9ad 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1186,11 +1186,21 @@ bool ByteCodeExprGen::visitInitList(ArrayRef Inits, if (!this->visit(Init)) return false; - if (!this->emitInitElem(ElemT, InitIndex, E)) - return false; - ++InitIndex; + // If the initializer is of vector type itself, we have to deconstruct + // that and initialize all the target fields from the initializer fields. + if (const auto *InitVecT = Init->getType()->getAs()) { + if (!this->emitCopyArray(ElemT, 0, InitIndex, InitVecT->getNumElements(), E)) + return false; + InitIndex += InitVecT->getNumElements(); + } else { + if (!this->emitInitElem(ElemT, InitIndex, E)) + return false; + ++InitIndex; + } } + assert(InitIndex <= NumVecElements); + // Fill the rest with zeroes. for (; InitIndex != NumVecElements; ++InitIndex) { if (!this->visitZeroInitializer(ElemT, ElemQT, E)) diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 2b650d684be9c4..66d30cc3fbaaba 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -2090,6 +2090,24 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) { return true; } +template ::T> +inline bool CopyArray(InterpState &S, CodePtr OpPC, uint32_t SrcIndex, uint32_t DestIndex, uint32_t Size) { + const auto &SrcPtr = S.Stk.pop(); + const auto &DestPtr = S.Stk.peek(); + + for (uint32_t I = 0; I != Size; ++I) { + const Pointer &SP = SrcPtr.atIndex(SrcIndex + I); + + if (!CheckLoad(S, OpPC, SP)) + return false; + + const Pointer &DP = DestPtr.atIndex(DestIndex + I); + DP.deref() = SP.deref(); + DP.initialize(); + } + return true; +} + /// Just takes a pointer and checks if it's an incomplete /// array type. inline bool ArrayDecay(InterpState &S, CodePtr OpPC) { diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 2a97b978b52325..cfbd7f93c32de8 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -376,7 +376,11 @@ def ArrayElem : Opcode { let HasGroup = 1; } - +def CopyArray : Opcode { + let Args = [ArgUint32, ArgUint32, ArgUint32]; + let Types = [AllTypeClass]; + let HasGroup = 1; +} //===----------------------------------------------------------------------===// // Direct field accessors diff --git a/clang/test/AST/Interp/opencl.cl b/clang/test/AST/Interp/opencl.cl index e7b9ec5caf2b1e..fd7756fff7c11e 100644 --- a/clang/test/AST/Interp/opencl.cl +++ b/clang/test/AST/Interp/opencl.cl @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -verify=ref,both %s -// RUN: %clang_cc1 -fsyntax-only -verify=expected,both %s -fexperimental-new-constant-interpreter +// RUN: %clang_cc1 -fsyntax-only -cl-std=CL2.0 -verify=ref,both %s +// RUN: %clang_cc1 -fsyntax-only -cl-std=CL2.0 -verify=expected,both %s -fexperimental-new-constant-interpreter // both-no-diagnostics @@ -33,3 +33,6 @@ void foo(int3 arg1, int8 arg2) { void negativeShift32(int a,int b) { char array0[((int)1)<<40]; } + +int2 A = {1,2}; +int4 B = {(int2)(1,2), (int2)(3,4)};