hokein created this revision.
hokein added a reviewer: sammccall.
Herald added a project: clang.

Previously, clang emitted a less-usefull diagnostic and didnt recover
well when the keywords is used as identifier in function paramter.

  void foo(int case, int x); // previously we drop all parameters after
  `int case`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77633

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/test/Parser/cxx-keyword-identifiers.cpp


Index: clang/test/Parser/cxx-keyword-identifiers.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/cxx-keyword-identifiers.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+
+int foo(int case, int throw, int y) { // expected-error {{using keyword 'case' 
as an identifier is not permitted}} \
+                                         expected-error {{using keyword 
'throw' as}}
+  // Trailing parameters should be recovered.
+  y = 1;
+}
+
+void test() {
+  // FIXME: we shoud improve the dianostics for the following cases.
+  int case; // expected-error {{expected unqualified-id}}
+  struct X {
+    int case; // expected-error {{expected member name or ';'}}
+  };
+}
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6869,6 +6869,13 @@
         }
       }
 
+      // Recovery if a keyword is used as an identifier.
+      if (Tok.getIdentifierInfo() &&
+          Tok.getIdentifierInfo()->isKeyword(getLangOpts())) {
+        Diag(Tok, diag::err_keyword_as_ident) << PP.getSpelling(Tok);
+        // Consume the keyword.
+        ConsumeToken();
+      }
       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
                                           ParmDeclarator.getIdentifierLoc(),
                                           Param, std::move(DefArgToks)));
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -591,6 +591,8 @@
 def warn_empty_init_statement : Warning<
   "empty initialization statement of '%select{if|switch|range-based for}0' "
   "has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
+def err_keyword_as_ident : Error <
+  "using keyword '%0' as an identifier is not permitted">;
 
 // C++ derived classes
 def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;


Index: clang/test/Parser/cxx-keyword-identifiers.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/cxx-keyword-identifiers.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+
+int foo(int case, int throw, int y) { // expected-error {{using keyword 'case' as an identifier is not permitted}} \
+                                         expected-error {{using keyword 'throw' as}}
+  // Trailing parameters should be recovered.
+  y = 1;
+}
+
+void test() {
+  // FIXME: we shoud improve the dianostics for the following cases.
+  int case; // expected-error {{expected unqualified-id}}
+  struct X {
+    int case; // expected-error {{expected member name or ';'}}
+  };
+}
Index: clang/lib/Parse/ParseDecl.cpp
===================================================================
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -6869,6 +6869,13 @@
         }
       }
 
+      // Recovery if a keyword is used as an identifier.
+      if (Tok.getIdentifierInfo() &&
+          Tok.getIdentifierInfo()->isKeyword(getLangOpts())) {
+        Diag(Tok, diag::err_keyword_as_ident) << PP.getSpelling(Tok);
+        // Consume the keyword.
+        ConsumeToken();
+      }
       ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII,
                                           ParmDeclarator.getIdentifierLoc(),
                                           Param, std::move(DefArgToks)));
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -591,6 +591,8 @@
 def warn_empty_init_statement : Warning<
   "empty initialization statement of '%select{if|switch|range-based for}0' "
   "has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore;
+def err_keyword_as_ident : Error <
+  "using keyword '%0' as an identifier is not permitted">;
 
 // C++ derived classes
 def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to