https://github.com/KFAFSP updated 
https://github.com/llvm/llvm-project/pull/179356

>From 07d3efd799ae7cf0e2636a7dcd68a7f409dd996c Mon Sep 17 00:00:00 2001
From: Karl Friebel <[email protected]>
Date: Mon, 9 Feb 2026 15:47:24 +0100
Subject: [PATCH] [Clang] Fixes for implicit-int diagnostics.

When encountering a declaration without a type
specifier, in contexts where they could reasonably
be assumed to default to int, clang emits a
diagnostic with FixIt. This FixIt does not produce
working code.

This patch corrects the SemaType FixIts inserting
an int type specifier (missing whitespace). In
addition, the diagnostic is now emitted only on
the first declarator of a comma-separated group.
The patch also adds test coverage for the FixIts.

Fixes #179354
---
 clang/docs/ReleaseNotes.rst | 12 +++++++++---
 clang/lib/Sema/SemaType.cpp | 31 ++++++++++++++++++++-----------
 clang/test/FixIt/fixit.c    | 21 +++++++++++++++++++++
 3 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a1bb1bd2467b7..dfd0de3e2fd85 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -227,6 +227,12 @@ Improvements to Clang's diagnostics
   when accessing a member function on a past-the-end array element.
   (#GH179128)
 
+- Fixed the FixIt for the ``implicit-int`` group of diagnostics. (#GH179354)
+
+- Changed the ``implicit-int`` diagnostics such that only one will be emitted
+  per comma-separated declaration group. Previously, one was generated for each
+  declarator in the group.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
@@ -360,7 +366,7 @@ AST Matchers
 
 clang-format
 ------------
-- Add ``ObjCSpaceAfterMethodDeclarationPrefix`` option to control space 
between the 
+- Add ``ObjCSpaceAfterMethodDeclarationPrefix`` option to control space 
between the
   '-'/'+' and the return type in Objective-C method declarations
 
 libclang
@@ -395,8 +401,8 @@ Python Binding Changes
   Affected methods: ``isKindOptional``, ``isKindTypedText``, 
``isKindPlaceHolder``,
   ``isKindInformative`` and ``isKindResultType``.
 - Add a deprecation warning to ``CodeCompletionResults.results``.
-  This property will become an implementation detail with changed behavior in 
a 
-  future release and should not be used directly.. Existing uses of 
+  This property will become an implementation detail with changed behavior in a
+  future release and should not be used directly.. Existing uses of
   ``CodeCompletionResults.results`` should be changed to directly use
   ``CodeCompletionResults``: it nows supports ``__len__`` and ``__getitem__``,
   so it can be used the same as ``CodeCompletionResults.results``.
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 348823ab2e9ca..a6d4b989cae3d 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -978,17 +978,24 @@ static QualType ConvertDeclSpecToType(TypeProcessingState 
&state) {
     // parser already though by it pretending to have seen an 'int' in this
     // case.
     if (S.getLangOpts().isImplicitIntRequired()) {
-      S.Diag(DeclLoc, diag::warn_missing_type_specifier)
-          << DS.getSourceRange()
-          << FixItHint::CreateInsertion(DS.getBeginLoc(), "int");
+      // Only emit the diagnostic for the first declarator in a DeclGroup, as
+      // the warning is always implied for all subsequent declarators, and the
+      // fix must only be applied exactly once as well.
+      if (declarator.isFirstDeclarator()) {
+        S.Diag(DeclLoc, diag::warn_missing_type_specifier)
+            << DS.getSourceRange()
+            << FixItHint::CreateInsertion(DS.getBeginLoc(), "int ");
+      }
     } else if (!DS.hasTypeSpecifier()) {
       // C99 and C++ require a type specifier.  For example, C99 6.7.2p2 says:
       // "At least one type specifier shall be given in the declaration
-      // specifiers in each declaration, and in the specifier-qualifier list in
-      // each struct declaration and type name."
+      // specifiers in each declaration, and in the specifier-qualifier list
+      // in each struct declaration and type name."
       if (!S.getLangOpts().isImplicitIntAllowed() && !DS.isTypeSpecPipe()) {
-        S.Diag(DeclLoc, diag::err_missing_type_specifier)
-            << DS.getSourceRange();
+        if (declarator.isFirstDeclarator()) {
+          S.Diag(DeclLoc, diag::err_missing_type_specifier)
+              << DS.getSourceRange();
+        }
 
         // When this occurs, often something is very broken with the value
         // being declared, poison it as invalid so we don't get chains of
@@ -996,15 +1003,17 @@ static QualType 
ConvertDeclSpecToType(TypeProcessingState &state) {
         declarator.setInvalidType(true);
       } else if (S.getLangOpts().getOpenCLCompatibleVersion() >= 200 &&
                  DS.isTypeSpecPipe()) {
-        S.Diag(DeclLoc, diag::err_missing_actual_pipe_type)
-            << DS.getSourceRange();
+        if (declarator.isFirstDeclarator()) {
+          S.Diag(DeclLoc, diag::err_missing_actual_pipe_type)
+              << DS.getSourceRange();
+        }
         declarator.setInvalidType(true);
-      } else {
+      } else if (declarator.isFirstDeclarator()) {
         assert(S.getLangOpts().isImplicitIntAllowed() &&
                "implicit int is disabled?");
         S.Diag(DeclLoc, diag::ext_missing_type_specifier)
             << DS.getSourceRange()
-            << FixItHint::CreateInsertion(DS.getBeginLoc(), "int");
+            << FixItHint::CreateInsertion(DS.getBeginLoc(), "int ");
       }
     }
 
diff --git a/clang/test/FixIt/fixit.c b/clang/test/FixIt/fixit.c
index 0e86d454a0e10..a9d9686380630 100644
--- a/clang/test/FixIt/fixit.c
+++ b/clang/test/FixIt/fixit.c
@@ -27,6 +27,27 @@ struct s s0 = { y: 5 }; // expected-warning {{GNU old-style}}
 // CHECK: int array0[5] = { [3] = 3 };
 int array0[5] = { [3] 3 }; // expected-warning {{GNU 'missing ='}}
 
+// CHECK: int imp0[4],imp1,imp2=5;
+imp0[4],imp1,imp2=5; // expected-error {{type specifier missing, defaults to 
'int'}}
+
+// CHECK: int const imp3;
+const imp3; // expected-error {{type specifier missing, defaults to 'int'}}
+// CHECK: int static imp4;
+static imp4; // expected-error {{type specifier missing, defaults to 'int'}}
+// CHECK: int static const imp5;
+static const imp5; // expected-error {{type specifier missing, defaults to 
'int'}}
+// CHECK: int volatile __attribute__ ((aligned (16))) imp6;
+volatile __attribute__ ((aligned (16))) imp6; // expected-error {{type 
specifier missing, defaults to 'int'}}
+
+// CHECK-LABEL: int f2(void)
+f2(void) // expected-error {{type specifier missing, defaults to 'int'}}
+{
+  // CHECK: register __attribute__ ((uninitialized)) i;
+  register __attribute__ ((uninitialized)) i; // expected-error {{type 
specifier missing, defaults to 'int'}}
+  return 0;
+}
+
+// CHECK-LABEL: void f1(x, y)
 // CHECK: int x
 // CHECK: int y
 void f1(x, y) // expected-error 2{{was not declared, defaults to 'int'; ISO 
C99 and later do not support implicit int}}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to