From: Douglas Gregor Date: Sun, 9 Oct 2011 18:31:23 +0000 (+0000) Subject: After instantiating a 'noexcept' expression, be sure to convert it to X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c340e803ed2e384ff47f3e560df253515c92e1e;p=clang After instantiating a 'noexcept' expression, be sure to convert it to a boolean value and check that it is a constant expression. Fixes PR11084. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141511 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 4fea4002cb..c8628dbd49 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2286,7 +2286,21 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs); if (E.isUsable()) + E = SemaRef.CheckBooleanCondition(E.get(), E.get()->getLocStart()); + + if (E.isUsable()) { + SourceLocation ErrLoc; + llvm::APSInt NoexceptVal; NoexceptExpr = E.take(); + if (!NoexceptExpr->isTypeDependent() && + !NoexceptExpr->isValueDependent() && + !NoexceptExpr->isIntegerConstantExpr(NoexceptVal, SemaRef.Context, + &ErrLoc, /*evaluated=*/false)){ + SemaRef.Diag(ErrLoc, diag::err_noexcept_needs_constant_expression) + << NoexceptExpr->getSourceRange(); + NoexceptExpr = 0; + } + } } // Rebuild the function type diff --git a/test/CXX/except/except.spec/p1.cpp b/test/CXX/except/except.spec/p1.cpp index 86924bb49d..b45580a21c 100644 --- a/test/CXX/except/except.spec/p1.cpp +++ b/test/CXX/except/except.spec/p1.cpp @@ -60,14 +60,22 @@ namespace noex { } namespace noexcept_unevaluated { - template void f(T) { + template bool f(T) { T* x = 1; } template - void g(T x) noexcept((f(x), sizeof(T) == 4)) { } + void g(T x) noexcept((sizeof(T) == sizeof(int)) || f(x)) { } void h() { g(1); } } + +namespace PR11084 { + template struct A { + static int f() noexcept(1/X) { return 10; } // expected-error{{argument to noexcept specifier must be a constant expression}} + }; + + void g() { A<0>::f(); } // expected-note{{in instantiation of template class 'PR11084::A<0>' requested here}} +}