Author: rsmith Date: Fri Feb 2 14:24:54 2018 New Revision: 324151 URL: http://llvm.org/viewvc/llvm-project?rev=324151&view=rev Log: Add missing direct-init / parameter-declaration-clause disambiguation when parsing a trailing-return-type of a (function pointer) variable declaration.
Modified: cfe/trunk/include/clang/Parse/Parser.h cfe/trunk/include/clang/Sema/DeclSpec.h cfe/trunk/lib/Parse/ParseDecl.cpp cfe/trunk/lib/Parse/ParseDeclCXX.cpp cfe/trunk/lib/Parse/ParseExprCXX.cpp cfe/trunk/lib/Parse/ParseTentative.cpp cfe/trunk/lib/Sema/SemaType.cpp cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp cfe/trunk/test/Parser/cxx0x-decl.cpp Modified: cfe/trunk/include/clang/Parse/Parser.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/include/clang/Parse/Parser.h (original) +++ cfe/trunk/include/clang/Parse/Parser.h Fri Feb 2 14:24:54 2018 @@ -1644,7 +1644,8 @@ private: //===--------------------------------------------------------------------===// // C++0x 8: Function declaration trailing-return-type - TypeResult ParseTrailingReturnType(SourceRange &Range); + TypeResult ParseTrailingReturnType(SourceRange &Range, + bool MayBeFollowedByDirectInit); //===--------------------------------------------------------------------===// // C++ 2.13.5: C++ Boolean Literals @@ -2158,7 +2159,8 @@ private: TPResult TryParsePtrOperatorSeq(); TPResult TryParseOperatorId(); TPResult TryParseInitDeclaratorList(); - TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier=true); + TPResult TryParseDeclarator(bool mayBeAbstract, bool mayHaveIdentifier = true, + bool mayHaveDirectInit = false); TPResult TryParseParameterDeclarationClause(bool *InvalidAsDeclaration = nullptr, bool VersusTemplateArg = false); Modified: cfe/trunk/include/clang/Sema/DeclSpec.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) +++ cfe/trunk/include/clang/Sema/DeclSpec.h Fri Feb 2 14:24:54 2018 @@ -1731,6 +1731,7 @@ enum class DeclaratorContext { LambdaExprParameterContext, // Lambda-expression parameter declarator. ConversionIdContext, // C++ conversion-type-id. TrailingReturnContext, // C++11 trailing-type-specifier. + TrailingReturnVarContext, // C++11 trailing-type-specifier for variable. TemplateTypeArgContext, // Template type argument. AliasDeclContext, // C++11 alias-declaration. AliasTemplateContext // C++11 alias-declaration template. @@ -1950,6 +1951,7 @@ public: case DeclaratorContext::ConversionIdContext: case DeclaratorContext::TemplateTypeArgContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: return true; } llvm_unreachable("unknown context kind!"); @@ -1986,6 +1988,7 @@ public: case DeclaratorContext::ConversionIdContext: case DeclaratorContext::TemplateTypeArgContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: return false; } llvm_unreachable("unknown context kind!"); @@ -2026,6 +2029,7 @@ public: case DeclaratorContext::ConversionIdContext: case DeclaratorContext::TemplateTypeArgContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: return false; } llvm_unreachable("unknown context kind!"); @@ -2052,6 +2056,7 @@ public: case DeclaratorContext::BlockContext: case DeclaratorContext::ForContext: case DeclaratorContext::InitStmtContext: + case DeclaratorContext::TrailingReturnVarContext: return true; case DeclaratorContext::ConditionContext: @@ -2288,6 +2293,7 @@ public: case DeclaratorContext::ConversionIdContext: case DeclaratorContext::TemplateTypeArgContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: return false; } llvm_unreachable("unknown context kind!"); @@ -2319,6 +2325,7 @@ public: case DeclaratorContext::LambdaExprContext: case DeclaratorContext::ConversionIdContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: return false; case DeclaratorContext::BlockContext: Modified: cfe/trunk/lib/Parse/ParseDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) +++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Feb 2 14:24:54 2018 @@ -2671,7 +2671,8 @@ Parser::getDeclSpecContextFromDeclarator return DeclSpecContext::DSC_template_param; if (Context == DeclaratorContext::TemplateTypeArgContext) return DeclSpecContext::DSC_template_type_arg; - if (Context == DeclaratorContext::TrailingReturnContext) + if (Context == DeclaratorContext::TrailingReturnContext || + Context == DeclaratorContext::TrailingReturnVarContext) return DeclSpecContext::DSC_trailing; if (Context == DeclaratorContext::AliasDeclContext || Context == DeclaratorContext::AliasTemplateContext) @@ -5627,7 +5628,8 @@ void Parser::ParseDirectDeclarator(Decla D.getContext() == DeclaratorContext::AliasTemplateContext) // The most likely error is that the ';' was forgotten. DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi); - else if (D.getContext() == DeclaratorContext::TrailingReturnContext && + else if ((D.getContext() == DeclaratorContext::TrailingReturnContext || + D.getContext() == DeclaratorContext::TrailingReturnVarContext) && !isCXX11VirtSpecifier(Tok)) DiagnoseIdentifier = NextToken().isOneOf( tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try); @@ -5641,6 +5643,18 @@ void Parser::ParseDirectDeclarator(Decla } if (Tok.is(tok::l_paren)) { + // If this might be an abstract-declarator followed by a direct-initializer, + // check whether this is a valid declarator chunk. If it can't be, assume + // that it's an initializer instead. + if (D.mayOmitIdentifier() && D.mayBeFollowedByCXXDirectInit()) { + RevertingTentativeParsingAction PA(*this); + if (TryParseDeclarator(true, D.mayHaveIdentifier(), true) == + TPResult::False) { + D.SetIdentifier(nullptr, Tok.getLocation()); + goto PastIdentifier; + } + } + // direct-declarator: '(' declarator ')' // direct-declarator: '(' attributes declarator ')' // Example: 'char (*X)' or 'int (*XX)(void)' @@ -6111,7 +6125,8 @@ void Parser::ParseFunctionDeclarator(Dec StartLoc = D.getDeclSpec().getTypeSpecTypeLoc(); LocalEndLoc = Tok.getLocation(); SourceRange Range; - TrailingReturnType = ParseTrailingReturnType(Range); + TrailingReturnType = + ParseTrailingReturnType(Range, D.mayBeFollowedByCXXDirectInit()); EndLoc = Range.getEnd(); } } else if (standardAttributesAllowed()) { Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Feb 2 14:24:54 2018 @@ -3706,12 +3706,15 @@ ExceptionSpecificationType Parser::Parse /// ParseTrailingReturnType - Parse a trailing return type on a new-style /// function declaration. -TypeResult Parser::ParseTrailingReturnType(SourceRange &Range) { +TypeResult Parser::ParseTrailingReturnType(SourceRange &Range, + bool MayBeFollowedByDirectInit) { assert(Tok.is(tok::arrow) && "expected arrow"); ConsumeToken(); - return ParseTypeName(&Range, DeclaratorContext::TrailingReturnContext); + return ParseTypeName(&Range, MayBeFollowedByDirectInit + ? DeclaratorContext::TrailingReturnVarContext + : DeclaratorContext::TrailingReturnContext); } /// \brief We have just started parsing the definition of a new class, Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri Feb 2 14:24:54 2018 @@ -1183,7 +1183,8 @@ ExprResult Parser::ParseLambdaExpression if (Tok.is(tok::arrow)) { FunLocalRangeEnd = Tok.getLocation(); SourceRange Range; - TrailingReturnType = ParseTrailingReturnType(Range); + TrailingReturnType = + ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false); if (Range.getEnd().isValid()) DeclEndLoc = Range.getEnd(); } @@ -1253,7 +1254,8 @@ ExprResult Parser::ParseLambdaExpression // Parse the return type, if there is one. if (Tok.is(tok::arrow)) { SourceRange Range; - TrailingReturnType = ParseTrailingReturnType(Range); + TrailingReturnType = + ParseTrailingReturnType(Range, /*MayBeFollowedByDirectInit*/ false); if (Range.getEnd().isValid()) DeclEndLoc = Range.getEnd(); } Modified: cfe/trunk/lib/Parse/ParseTentative.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParseTentative.cpp (original) +++ cfe/trunk/lib/Parse/ParseTentative.cpp Fri Feb 2 14:24:54 2018 @@ -873,7 +873,8 @@ Parser::TPResult Parser::TryParseOperato /// template-id [TODO] /// Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, - bool mayHaveIdentifier) { + bool mayHaveIdentifier, + bool mayHaveDirectInit) { // declarator: // direct-declarator // ptr-operator declarator @@ -930,6 +931,9 @@ Parser::TPResult Parser::TryParseDeclara return TPResult::False; } + if (mayHaveDirectInit) + return TPResult::Ambiguous; + while (1) { TPResult TPR(TPResult::Ambiguous); Modified: cfe/trunk/lib/Sema/SemaType.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaType.cpp (original) +++ cfe/trunk/lib/Sema/SemaType.cpp Fri Feb 2 14:24:54 2018 @@ -2859,6 +2859,7 @@ static QualType GetDeclSpecTypeForDeclar Error = 12; // Type alias break; case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: if (!SemaRef.getLangOpts().CPlusPlus14 || !IsCXXAutoType) Error = 13; // Function return type break; @@ -2961,6 +2962,7 @@ static QualType GetDeclSpecTypeForDeclar unsigned DiagID = 0; switch (D.getContext()) { case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: // Class and enumeration definitions are syntactically not allowed in // trailing return types. llvm_unreachable("parser should not have allowed this"); @@ -3914,6 +3916,7 @@ static TypeSourceInfo *GetFullTypeForDec case DeclaratorContext::ObjCResultContext: case DeclaratorContext::PrototypeContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: isFunctionOrMethod = true; LLVM_FALLTHROUGH; @@ -4954,6 +4957,7 @@ static TypeSourceInfo *GetFullTypeForDec case DeclaratorContext::LambdaExprContext: case DeclaratorContext::ConversionIdContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::TrailingReturnVarContext: case DeclaratorContext::TemplateTypeArgContext: // FIXME: We may want to allow parameter packs in block-literal contexts // in the future. Modified: cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp (original) +++ cfe/trunk/test/Parser/cxx-ambig-decl-expr.cpp Fri Feb 2 14:24:54 2018 @@ -11,3 +11,7 @@ void f() { unknown *p = 0; // expected-error {{unknown type name 'unknown'}} unknown * p + 0; // expected-error {{undeclared identifier 'unknown'}} } + +auto (*p)() -> int(nullptr); +auto (*q)() -> int(*)(unknown); // expected-error {{unknown type name 'unknown'}} +auto (*r)() -> int(*)(unknown + 1); // expected-error {{undeclared identifier 'unknown'}} Modified: cfe/trunk/test/Parser/cxx0x-decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-decl.cpp?rev=324151&r1=324150&r2=324151&view=diff ============================================================================== --- cfe/trunk/test/Parser/cxx0x-decl.cpp (original) +++ cfe/trunk/test/Parser/cxx0x-decl.cpp Fri Feb 2 14:24:54 2018 @@ -79,7 +79,7 @@ enum E namespace PR5066 { using T = int (*f)(); // expected-error {{type-id cannot have a name}} template<typename T> using U = int (*f)(); // expected-error {{type-id cannot have a name}} - auto f() -> int (*f)(); // expected-error {{type-id cannot have a name}} + auto f() -> int (*f)(); // expected-error {{only variables can be initialized}} expected-error {{expected ';'}} auto g = []() -> int (*f)() {}; // expected-error {{type-id cannot have a name}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits