From: Richard Smith Date: Thu, 15 Nov 2012 22:54:20 +0000 (+0000) Subject: PR9903: Recover from a member functon declared with the 'typedef' specifier by X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6f9a445760992a6fbff2c0b08becf35ae9eafa71;p=clang PR9903: Recover from a member functon declared with the 'typedef' specifier by dropping the specifier, just like we do for non-member functions and function templates declared 'typedef'. Patch by Brian Brooks! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168108 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 4cb14e24f4..0d785af3ef 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1985,16 +1985,9 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_function_declared_typedef); - // This recovery skips the entire function body. It would be nice - // to simply call ParseCXXInlineMethodDef() below, however Sema - // assumes the declarator represents a function, not a typedef. - ConsumeBrace(); - SkipUntil(tok::r_brace, /*StopAtSemi*/false); - // Consume the optional ';' - if (Tok.is(tok::semi)) - ConsumeToken(); - return; + // Recover by treating the 'typedef' as spurious. + DS.ClearStorageClassSpecs(); } Decl *FunDecl = diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp index 290b947de2..5a4c9da0f6 100644 --- a/test/Parser/cxx-decl.cpp +++ b/test/Parser/cxx-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic %s +// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic -fcxx-exceptions -fexceptions %s const char const *x10; // expected-warning {{duplicate 'const' declaration specifier}} @@ -124,6 +124,14 @@ void CodeCompleteConsumer::() { // expected-error {{xpected unqualified-id}} // PR4111 void f(sqrgl); // expected-error {{unknown type name 'sqrgl'}} +// PR9903 +struct S { + typedef void a() { }; // expected-error {{function definition declared 'typedef'}} + typedef void c() try { } catch(...) { } // expected-error {{function definition declared 'typedef'}} + int n, m; + typedef S() : n(1), m(2) { } // expected-error {{function definition declared 'typedef'}} +}; + // PR8380 extern "" // expected-error {{unknown linkage language}} test6a { ;// expected-error {{C++ requires a type specifier for all declarations}} \ diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp index 3af73f95c7..3b883dc76c 100644 --- a/test/Parser/cxx0x-decl.cpp +++ b/test/Parser/cxx0x-decl.cpp @@ -34,3 +34,8 @@ struct MultiCV { }; static_assert(something, ""); // expected-error {{undeclared identifier}} + +// PR9903 +struct SS { + typedef void d() = default; // expected-error {{function definition declared 'typedef'}} expected-error {{only special member functions may be defaulted}} +};