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 @@ -99,6 +99,7 @@ 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/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 @@ -1006,6 +1006,15 @@ 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/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -910,3 +910,25 @@ 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 --- 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}}