diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 7970cb63484855..29069ba10bb86d 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1006,6 +1006,15 @@ bool ByteCodeExprGen::VisitCXXReinterpretCastExpr( return this->emitInvalidCast(CastKind::Reinterpret, E); } +template +bool ByteCodeExprGen::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) { + assert(E->getType()->isBooleanType()); + + if (DiscardResult) + return true; + return this->emitConstBool(E->getValue(), E); +} + template bool ByteCodeExprGen::discard(const Expr *E) { if (E->containsErrors()) return false; diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index c828f319cc04cd..6e134680d1fc5b 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -99,6 +99,7 @@ class ByteCodeExprGen : public ConstStmtVisitor, bool>, bool VisitPredefinedExpr(const PredefinedExpr *E); bool VisitCXXThrowExpr(const CXXThrowExpr *E); bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E); + bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E); protected: bool visitExpr(const Expr *E) override; diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index 25c40755c2d495..5a645621e2d756 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -910,3 +910,25 @@ namespace PredefinedExprs { static_assert(heh(2) == 'h', ""); #endif } + +namespace NE { + constexpr int foo() noexcept { + return 1; + } + static_assert(noexcept(foo()), ""); + constexpr int foo2() { + return 1; + } + static_assert(!noexcept(foo2()), ""); + +#if __cplusplus > 201402L + constexpr int a() { + int b = 0; + (void)noexcept(++b); // expected-warning {{expression with side effects has no effect in an unevaluated context}} \ + // ref-warning {{expression with side effects has no effect in an unevaluated context}} + + return b; + } + static_assert(a() == 0, ""); +#endif +} diff --git a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp index f4911541d1d336..6afeeefec40da8 100644 --- a/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp +++ b/clang/test/SemaCXX/cxx0x-noexcept-expression.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s -fexceptions -fcxx-exceptions -Wno-unevaluated-expression +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2a %s -fexceptions -fcxx-exceptions -Wno-unevaluated-expression -fexperimental-new-constant-interpreter void f(); // expected-note {{possible target for call}} void f(int); // expected-note {{possible target for call}}