r303398 - When a type-id is unexpectedly given a name, assume that the name is unrelated

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu May 18 18:55:00 PDT 2017


Author: rsmith
Date: Thu May 18 20:54:59 2017
New Revision: 303398

URL: http://llvm.org/viewvc/llvm-project?rev=303398&view=rev
Log:
When a type-id is unexpectedly given a name, assume that the name is unrelated
syntax unless we have a reason to think otherwise.

This improves error recovery in a couple of cases.

Modified:
    cfe/trunk/include/clang/Sema/DeclSpec.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/test/Parser/cxx-template-argument.cpp
    cfe/trunk/test/Parser/cxx0x-decl.cpp
    cfe/trunk/test/Sema/block-args.c

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=303398&r1=303397&r2=303398&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu May 18 20:54:59 2017
@@ -1999,41 +1999,6 @@ public:
     llvm_unreachable("unknown context kind!");
   }
 
-  /// diagnoseIdentifier - Return true if the identifier is prohibited and
-  /// should be diagnosed (because it cannot be anything else).
-  bool diagnoseIdentifier() const {
-    switch (Context) {
-    case FileContext:
-    case KNRTypeListContext:
-    case MemberContext:
-    case BlockContext:
-    case ForContext:
-    case InitStmtContext:
-    case ConditionContext:
-    case PrototypeContext:
-    case LambdaExprParameterContext:
-    case TemplateParamContext:
-    case CXXCatchContext:
-    case ObjCCatchContext:
-    case TypeNameContext:
-    case FunctionalCastContext:
-    case ConversionIdContext:
-    case ObjCParameterContext:
-    case ObjCResultContext:
-    case BlockLiteralContext:
-    case CXXNewContext:
-    case LambdaExprContext:
-      return false;
-
-    case AliasDeclContext:
-    case AliasTemplateContext:
-    case TemplateTypeArgContext:
-    case TrailingReturnContext:
-      return true;
-    }
-    llvm_unreachable("unknown context kind!");
-  }
-
   /// Return true if the context permits a C++17 decomposition declarator.
   bool mayHaveDecompositionDeclarator() const {
     switch (Context) {

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=303398&r1=303397&r2=303398&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu May 18 20:54:59 2017
@@ -5542,11 +5542,28 @@ void Parser::ParseDirectDeclarator(Decla
     D.SetRangeEnd(Tok.getLocation());
     ConsumeToken();
     goto PastIdentifier;
-  } else if (Tok.is(tok::identifier) && D.diagnoseIdentifier()) {
-    // A virt-specifier isn't treated as an identifier if it appears after a
-    // trailing-return-type.
-    if (D.getContext() != Declarator::TrailingReturnContext ||
-        !isCXX11VirtSpecifier(Tok)) {
+  } else if (Tok.is(tok::identifier) && !D.mayHaveIdentifier()) {
+    // We're not allowed an identifier here, but we got one. Try to figure out
+    // if the user was trying to attach a name to the type, or whether the name
+    // is some unrelated trailing syntax.
+    bool DiagnoseIdentifier = false;
+    if (D.hasGroupingParens())
+      // An identifier within parens is unlikely to be intended to be anything
+      // other than a name being "declared".
+      DiagnoseIdentifier = true;
+    else if (D.getContext() == Declarator::TemplateTypeArgContext)
+      // T<int N> is an accidental identifier; T<int N indicates a missing '>'.
+      DiagnoseIdentifier =
+          NextToken().isOneOf(tok::comma, tok::greater, tok::greatergreater);
+    else if (D.getContext() == Declarator::AliasDeclContext ||
+             D.getContext() == Declarator::AliasTemplateContext)
+      // The most likely error is that the ';' was forgotten.
+      DiagnoseIdentifier = NextToken().isOneOf(tok::comma, tok::semi);
+    else if (D.getContext() == Declarator::TrailingReturnContext &&
+             !isCXX11VirtSpecifier(Tok))
+      DiagnoseIdentifier = NextToken().isOneOf(
+          tok::comma, tok::semi, tok::equal, tok::l_brace, tok::kw_try);
+    if (DiagnoseIdentifier) {
       Diag(Tok.getLocation(), diag::err_unexpected_unqualified_id)
         << FixItHint::CreateRemoval(Tok.getLocation());
       D.SetIdentifier(nullptr, Tok.getLocation());

Modified: cfe/trunk/test/Parser/cxx-template-argument.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-argument.cpp?rev=303398&r1=303397&r2=303398&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-template-argument.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-argument.cpp Thu May 18 20:54:59 2017
@@ -10,7 +10,7 @@ template<typename T> struct A {};
 // Check for template argument lists followed by junk
 // FIXME: The diagnostics here aren't great...
 A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}}
-A<int x; // expected-error {{type-id cannot have a name}} expected-error {{expected '>'}}
+A<int x; // expected-error {{expected '>'}}
 
 // PR8912
 template <bool> struct S {};

Modified: cfe/trunk/test/Parser/cxx0x-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-decl.cpp?rev=303398&r1=303397&r2=303398&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-decl.cpp Thu May 18 20:54:59 2017
@@ -137,6 +137,9 @@ namespace AliasDeclEndLocation {
     >\
 > // expected-error {{expected ';' after alias declaration}}
     ;
+  using D = AliasDeclEndLocation::A<int
+    > // expected-error {{expected ';' after alias declaration}}
+  B something_else;
 }
 
 struct Base { virtual void f() = 0; virtual void g() = 0; virtual void h() = 0; };

Modified: cfe/trunk/test/Sema/block-args.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-args.c?rev=303398&r1=303397&r2=303398&view=diff
==============================================================================
--- cfe/trunk/test/Sema/block-args.c (original)
+++ cfe/trunk/test/Sema/block-args.c Thu May 18 20:54:59 2017
@@ -37,7 +37,7 @@ void f0() {
 
 // rdar://problem/8962770
 void test4() {
-  int (^f)() = ^((x)) { }; // expected-error {{expected ')'}} expected-warning {{type specifier missing}} expected-note {{to match this}}
+  int (^f)() = ^((x)) { }; // expected-warning {{type specifier missing}} expected-error {{type-id cannot have a name}}
 }
 
 // rdar://problem/9170609




More information about the cfe-commits mailing list