]> git.eshelyaron.com Git - emacs.git/commitdiff
CC Mode: Prevent "const" inside an identifier being recognized as the keyword
authorAlan Mackenzie <acm@muc.de>
Tue, 2 Feb 2021 20:34:42 +0000 (20:34 +0000)
committerAlan Mackenzie <acm@muc.de>
Tue, 2 Feb 2021 20:34:42 +0000 (20:34 +0000)
This fixes bug #45560.

* lisp/progmodes/cc-engine.el (c-forward-declarator)
(c-forward-decl-or-cast-1): Amend certain regexp match numbers on account of
the change below.  Surround some looking-at calls with save-match-data.

* lisp/progmodes/cc-langs.el (c-type-decl-prefix-keywords-key): New lang
const.
(c-type-decl-prefix-key): Reformulate to match operators and keywords
separately, using the new lang const (above).

lisp/progmodes/cc-engine.el
lisp/progmodes/cc-langs.el

index 3fce7dbafae0713452fb9fc55232a55daa76749f..484624b866481f13a6c1603bc7350a8193cf208b 100644 (file)
@@ -9021,14 +9021,15 @@ point unchanged and return nil."
                    (c-forward-noise-clause))
                   ((and (looking-at c-type-decl-prefix-key)
                         (if (and (c-major-mode-is 'c++-mode)
-                                 (match-beginning 3))
+                                 (match-beginning 4)) ; Was 3 - 2021-01-01
                             ;; If the third submatch matches in C++ then
                             ;; we're looking at an identifier that's a
                             ;; prefix only if it specifies a member pointer.
                             (progn
                               (setq id-start (point))
                               (c-forward-name)
-                              (if (looking-at "\\(::\\)")
+                              (if (save-match-data
+                                    (looking-at "\\(::\\)"))
                                   ;; We only check for a trailing "::" and
                                   ;; let the "*" that should follow be
                                   ;; matched in the next round.
@@ -9038,13 +9039,15 @@ point unchanged and return nil."
                                 (setq got-identifier t)
                                 nil))
                           t))
-                   (if (looking-at c-type-decl-operator-prefix-key)
+                   (if (save-match-data
+                         (looking-at c-type-decl-operator-prefix-key))
                        (setq decorated t))
                    (if (eq (char-after) ?\()
                        (progn
                          (setq paren-depth (1+ paren-depth))
                          (forward-char))
-                     (goto-char (match-end 1)))
+                     (goto-char (or (match-end 1)
+                                    (match-end 2))))
                    (c-forward-syntactic-ws)
                    t)))
 
@@ -9721,14 +9724,15 @@ This function might do hidden buffer changes."
              (setq after-paren-pos (point))))
        (while (and (looking-at c-type-decl-prefix-key)
                    (if (and (c-major-mode-is 'c++-mode)
-                            (match-beginning 3))
-                       ;; If the third submatch matches in C++ then
+                            (match-beginning 4))
+                       ;; If the fourth submatch matches in C++ then
                        ;; we're looking at an identifier that's a
                        ;; prefix only if it specifies a member pointer.
                        (when (progn (setq pos (point))
                                     (setq got-identifier (c-forward-name)))
                          (setq name-start pos)
-                         (if (looking-at "\\(::\\)")
+                         (if (save-match-data
+                               (looking-at "\\(::\\)"))
                              ;; We only check for a trailing "::" and
                              ;; let the "*" that should follow be
                              ;; matched in the next round.
@@ -9749,7 +9753,8 @@ This function might do hidden buffer changes."
            (when (save-match-data
                    (looking-at c-type-decl-operator-prefix-key))
              (setq got-function-name-prefix t))
-           (goto-char (match-end 1)))
+           (goto-char (or (match-end 1)
+                          (match-end 2))))
          (c-forward-syntactic-ws)))
 
       (setq got-parens (> paren-depth 0))
index f4dcbcda962c75271f5b51ae752cdd388ca3a6ce..07479389c621f4269bb088492a68ae93c0457534 100644 (file)
@@ -3433,41 +3433,47 @@ possible for good performance."
   t (c-make-bare-char-alt (c-lang-const c-block-prefix-disallowed-chars) t))
 (c-lang-defvar c-block-prefix-charset (c-lang-const c-block-prefix-charset))
 
-(c-lang-defconst c-type-decl-prefix-key
-  "Regexp matching any declarator operator that might precede the
-identifier in a declaration, e.g. the \"*\" in \"char *argv\".  This
-regexp should match \"(\" if parentheses are valid in declarators.
-The end of the first submatch is taken as the end of the operator.
-Identifier syntax is in effect when this is matched (see
-`c-identifier-syntax-table')."
+(c-lang-defconst c-type-decl-prefix-keywords-key
+  ;; Regexp matching any keyword operator that might precede the identifier in
+  ;; a declaration, e.g. "const" or nil.  It doesn't test there is no "_"
+  ;; following the keyword.
   t (if (or (c-lang-const c-type-modifier-kwds) (c-lang-const c-modifier-kwds))
-        (concat
+       (concat
         (regexp-opt (c--delete-duplicates
                      (append (c-lang-const c-type-modifier-kwds)
                              (c-lang-const c-modifier-kwds))
                      :test 'string-equal)
                     t)
-        "\\>")
-      ;; Default to a regexp that never matches.
-      regexp-unmatchable)
+        "\\>")))
+
+(c-lang-defconst c-type-decl-prefix-key
+  "Regexp matching any declarator operator that might precede the
+identifier in a declaration, e.g. the \"*\" in \"char *argv\".  This
+regexp should match \"(\" if parentheses are valid in declarators.
+The operator found is either the first submatch (if it is not a
+keyword) or the second submatch (if it is)."
+  t (if (c-lang-const c-type-decl-prefix-keywords-key)
+       (concat "\\(\\`a\\`\\)\\|"      ; 1 - will never match.
+               (c-lang-const c-type-decl-prefix-keywords-key) ; 2
+               "\\([^_]\\|$\\)")                              ; 3
+      "\\`a\\`") ;; Default to a regexp that never matches.
   ;; Check that there's no "=" afterwards to avoid matching tokens
   ;; like "*=".
-  (c objc) (concat "\\("
+  (c objc) (concat "\\("               ; 1
                   "[*(]"
-                  "\\|"
-                  (c-lang-const c-type-decl-prefix-key)
-                  "\\)"
-                  "\\([^=]\\|$\\)")
-  c++  (concat "\\("
+                  "\\)\\|"
+                  (c-lang-const c-type-decl-prefix-keywords-key) ; 2
+                  "\\([^=_]\\|$\\)")   ; 3
+  c++  (concat "\\("                   ; 1
               "&&"
               "\\|"
               "\\.\\.\\."
               "\\|"
               "[*(&~]"
+              "\\)\\|\\("                                    ; 2
+              (c-lang-const c-type-decl-prefix-keywords-key) ; 3
               "\\|"
-              (c-lang-const c-type-decl-prefix-key)
-              "\\|"
-              (concat "\\("   ; 3
+              (concat "\\("   ; 4
                       ;; If this matches there's special treatment in
                       ;; `c-font-lock-declarators' and
                       ;; `c-font-lock-declarations' that check for a
@@ -3475,8 +3481,9 @@ Identifier syntax is in effect when this is matched (see
                       (c-lang-const c-identifier-start)
                       "\\)")
               "\\)"
-              "\\([^=]\\|$\\)")
+              "\\([^=_]\\|$\\)")       ; 5
   pike "\\(\\*\\)\\([^=]\\|$\\)")
+
 (c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
   'dont-doc)