Index: clang/lib/AST/Interp/ByteCodeExprGen.h =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -91,6 +91,8 @@ bool VisitPointerCompoundAssignOperator(const CompoundAssignOperator *E); bool VisitExprWithCleanups(const ExprWithCleanups *E); bool VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E); + bool VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *E); + bool VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E); bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E); bool VisitTypeTraitExpr(const TypeTraitExpr *E); bool VisitLambdaExpr(const LambdaExpr *E); Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -914,6 +914,24 @@ return false; } +template +bool ByteCodeExprGen::VisitCXXBindTemporaryExpr( + const CXXBindTemporaryExpr *E) { + + return this->visit(E->getSubExpr()); +} + +template +bool ByteCodeExprGen::VisitCXXTemporaryObjectExpr( + const CXXTemporaryObjectExpr *E) { + + if (std::optional LocalIndex = + allocateLocal(E, /*IsExtended=*/false)) { + return this->visitLocalInitializer(E, *LocalIndex); + } + return false; +} + template bool ByteCodeExprGen::VisitCompoundLiteralExpr( const CompoundLiteralExpr *E) { Index: clang/test/AST/Interp/records.cpp =================================================================== --- clang/test/AST/Interp/records.cpp +++ clang/test/AST/Interp/records.cpp @@ -314,16 +314,36 @@ int Pos = 0; { - auto T = Test(Arr, Pos); + Test(Arr, Pos); // End of scope, should destroy Test. } return Arr[Index]; } - static_assert(T(0) == 1); static_assert(T(1) == 2); static_assert(T(2) == 3); + + // Invalid destructor. + struct S { + constexpr S() {} + constexpr ~S() noexcept(false) { throw 12; } // expected-error {{cannot use 'throw'}} \ + // expected-note {{declared here}} \ + // ref-error {{cannot use 'throw'}} \ + // ref-error {{never produces a constant expression}} \ + // ref-note 2{{subexpression not valid}} + }; + + constexpr int f() { + S{}; // ref-note {{in call to '&S{}->~S()'}} + return 12; // expected-note {{undefined function '~S'}} + } + static_assert(f() == 12); // expected-error {{not an integral constant expression}} \ + // expected-note {{in call to 'f()'}} \ + // ref-error {{not an integral constant expression}} \ + // ref-note {{in call to 'f()'}} + + #endif }