From 8c614e4f2b07741130e6c99a971a7093358fb9e4 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 24 Apr 2012 05:06:35 +0000 Subject: [PATCH] PR12629: Cope with parenthesized function types when attaching a delayed exception specification to a function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155424 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 12 ++++++++---- test/CXX/class/class.mem/p2.cpp | 11 ++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index b6395f5dcb..8645de1fcd 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -11315,11 +11315,9 @@ void Sema::actOnDelayedExceptionSpecification(Decl *MethodD, if (!Method) return; - // Dig out the prototype. This should never fail. + // Dig out the prototype, looking through only parens. This should never fail. const FunctionProtoType *Proto - = dyn_cast(Method->getType()); - if (!Proto) - return; + = cast(Method->getType().IgnoreParens()); // Check the exception specification. llvm::SmallVector Exceptions; @@ -11332,6 +11330,12 @@ void Sema::actOnDelayedExceptionSpecification(Decl *MethodD, Proto->arg_type_begin(), Proto->getNumArgs(), EPI); + + // Rebuild any parens around the function type. + for (const ParenType *PT = dyn_cast(Method->getType()); PT; + PT = dyn_cast(PT->getInnerType())) + T = Context.getParenType(T); + if (TypeSourceInfo *TSInfo = Method->getTypeSourceInfo()) { // FIXME: When we get proper type location information for exceptions, // we'll also have to rebuild the TypeSourceInfo. For now, we just patch diff --git a/test/CXX/class/class.mem/p2.cpp b/test/CXX/class/class.mem/p2.cpp index 0a823f4c1f..3e957df69d 100644 --- a/test/CXX/class/class.mem/p2.cpp +++ b/test/CXX/class/class.mem/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s // C++11 [class.mem]p2: // A class is considered a completely-defined object type (or @@ -56,3 +56,12 @@ namespace test3 { template struct A2; } + +namespace PR12629 { + struct S { + static int (f)() throw(); + static int ((((((g))))() throw(int))); + }; + static_assert(noexcept(S::f()), ""); + static_assert(!noexcept(S::g()), ""); +} -- 2.40.0