tbaeder updated this revision to Diff 469243. tbaeder marked 3 inline comments as done.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D135013/new/ https://reviews.llvm.org/D135013 Files: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/arrays.cpp Index: clang/test/AST/Interp/arrays.cpp =================================================================== --- clang/test/AST/Interp/arrays.cpp +++ clang/test/AST/Interp/arrays.cpp @@ -117,3 +117,15 @@ // expected-error {{must be initialized by a constant expression}} \ // expected-note {{cannot refer to element -2 of array of 10}} }; + +namespace DefaultInit { + template <typename T, unsigned N> + struct B { + T a[N]; + }; + + int f() { + constexpr B<int,10> arr = {}; + constexpr int x = arr.a[0]; + } +}; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -721,6 +721,27 @@ if (!this->emitPopPtr(Initializer)) return false; } + return true; + } else if (const auto *IVIE = dyn_cast<ImplicitValueInitExpr>(Initializer)) { + const ArrayType *ArrayType = IVIE->getType()->getAsArrayTypeUnsafe(); + assert(ArrayType); + const auto *CAT = cast<ConstantArrayType>(ArrayType); + size_t NumElems = CAT->getSize().getZExtValue(); + + if (Optional<PrimType> ElemT = classify(CAT->getElementType())) { + // TODO(perf): For int and bool types, we can probably just skip this + // since we memset our Block*s to 0 and so we have the desired value + // without this. + for (size_t I = 0; I != NumElems; ++I) { + if (!this->emitZero(*ElemT, Initializer)) + return false; + if (!this->emitInitElem(*ElemT, I, Initializer)) + return false; + } + } else { + assert(false && "default initializer for non-primitive type"); + } + return true; }
Index: clang/test/AST/Interp/arrays.cpp =================================================================== --- clang/test/AST/Interp/arrays.cpp +++ clang/test/AST/Interp/arrays.cpp @@ -117,3 +117,15 @@ // expected-error {{must be initialized by a constant expression}} \ // expected-note {{cannot refer to element -2 of array of 10}} }; + +namespace DefaultInit { + template <typename T, unsigned N> + struct B { + T a[N]; + }; + + int f() { + constexpr B<int,10> arr = {}; + constexpr int x = arr.a[0]; + } +}; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -721,6 +721,27 @@ if (!this->emitPopPtr(Initializer)) return false; } + return true; + } else if (const auto *IVIE = dyn_cast<ImplicitValueInitExpr>(Initializer)) { + const ArrayType *ArrayType = IVIE->getType()->getAsArrayTypeUnsafe(); + assert(ArrayType); + const auto *CAT = cast<ConstantArrayType>(ArrayType); + size_t NumElems = CAT->getSize().getZExtValue(); + + if (Optional<PrimType> ElemT = classify(CAT->getElementType())) { + // TODO(perf): For int and bool types, we can probably just skip this + // since we memset our Block*s to 0 and so we have the desired value + // without this. + for (size_t I = 0; I != NumElems; ++I) { + if (!this->emitZero(*ElemT, Initializer)) + return false; + if (!this->emitInitElem(*ElemT, I, Initializer)) + return false; + } + } else { + assert(false && "default initializer for non-primitive type"); + } + return true; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits