diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -75,6 +75,7 @@ bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E); bool VisitUnaryOperator(const UnaryOperator *E); bool VisitDeclRefExpr(const DeclRefExpr *E); + bool VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E); protected: bool visitExpr(const Expr *E) override; diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -223,6 +223,14 @@ return this->bail(BO); } +template +bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) { + if (Optional T = classify(E)) + return this->emitZero(*T, E); + + return false; +} + template bool ByteCodeExprGen::discard(const Expr *E) { OptionScope Scope(this, /*NewDiscardResult=*/true); diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -203,6 +203,7 @@ // [] -> [Integer] def Zero : Opcode { let Types = [AluTypeClass]; + let HasGroup = 1; } // [] -> [Pointer] diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp new file mode 100644 --- /dev/null +++ b/clang/test/AST/Interp/arrays.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s +// RUN: %clang_cc1 -verify=ref %s + + +/// expected-no-diagnostics +/// ref-no-diagnostics + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc99-extensions" +#pragma clang diagnostic ignored "-Winitializer-overrides" +/// FIXME: The example below tests ImplicitValueInitExprs, but we can't +/// currently evaluate other parts of it. +#if 0 +struct fred { + char s [6]; + int n; +}; + +struct fred y [] = { [0] = { .s[0] = 'q' } }; +#endif +#pragma clang diagnostic pop