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

>From de0a68f7ab3beb5eff5c108f87ab58918a94658d Mon Sep 17 00:00:00 2001
From: Karl Friebel <[email protected]>
Date: Mon, 9 Feb 2026 15:47:24 +0100
Subject: [PATCH 1/4] [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 |  6 ++++++
 clang/lib/Sema/SemaType.cpp | 31 ++++++++++++++++++++-----------
 clang/test/FixIt/fixit.c    | 21 +++++++++++++++++++++
 3 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a1bb1bd2467b7..d955eeebf5131 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
 ----------------------------------
 
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..2cd5b7ae020ba 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: int 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}}

>From ef569e0d6506eb929f7b36e6d1c4e66525ce771a Mon Sep 17 00:00:00 2001
From: Karl Friebel <[email protected]>
Date: Mon, 9 Feb 2026 18:21:18 +0100
Subject: [PATCH 2/4] Merged release notes.

Co-authored-by: Sirraide <[email protected]>
---
 clang/docs/ReleaseNotes.rst | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d955eeebf5131..a75e159732d0b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -227,11 +227,8 @@ 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.
+- Added a missing space to the FixIt for the ``implicit-int`` group of 
diagnostics and 
+  made sure that only one such diagnostic and FixIt is emitted per declaration 
group. (#GH179354)
 
 Improvements to Clang's time-trace
 ----------------------------------

>From 7b9f2017207df3a544c9e76e23f89ec8eb397ee9 Mon Sep 17 00:00:00 2001
From: Karl Friebel <[email protected]>
Date: Tue, 10 Feb 2026 00:56:43 +0100
Subject: [PATCH 3/4] Added missing-type-spec test suite and C90 FixIt.

This commit moves the implicit-int fixit checks
from fixit.c into fixit-missing-type-spec.c and
adds the appropriate tests for C90, C99 and C23.

In addition, this commit adds a FixIt for the
warning emitted on function declarations without
a type specifier in C90 mode for consistency.
---
 clang/lib/Parse/Parser.cpp                 |  3 +-
 clang/test/FixIt/fixit-missing-type-spec.c | 57 ++++++++++++++++++++++
 clang/test/FixIt/fixit.c                   | 21 --------
 3 files changed, 59 insertions(+), 22 deletions(-)
 create mode 100644 clang/test/FixIt/fixit-missing-type-spec.c

diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index be9e0a39a3781..5d18414b1a746 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1188,7 +1188,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator 
&D,
   // declaration-specifiers are completely optional in the grammar.
   if (getLangOpts().isImplicitIntRequired() && D.getDeclSpec().isEmpty()) {
     Diag(D.getIdentifierLoc(), diag::warn_missing_type_specifier)
-        << D.getDeclSpec().getSourceRange();
+        << D.getDeclSpec().getSourceRange()
+        << FixItHint::CreateInsertion(D.getDeclSpec().getBeginLoc(), "int ");
     const char *PrevSpec;
     unsigned DiagID;
     const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
diff --git a/clang/test/FixIt/fixit-missing-type-spec.c 
b/clang/test/FixIt/fixit-missing-type-spec.c
new file mode 100644
index 0000000000000..5d1eecfcb1f7a
--- /dev/null
+++ b/clang/test/FixIt/fixit-missing-type-spec.c
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -verify=c90 -x c %s
+// RUN: cp %s %t
+// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -fixit %t
+// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -Werror -x c %t
+// RUN: cat %t | FileCheck %s
+// RUN: %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype 
-verify=c99 -x c %s
+// RUN: cp %s %t
+// RUN: not %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype -fixit 
%t
+// RUN: %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype -Werror -x 
c %t
+// RUN: cat %t | FileCheck %s
+// RUN: %clang_cc1 -std=c23 -pedantic -verify=c23 -x c %s
+
+// CHECK: int imp0[4],imp1,imp2=5;
+imp0[4],imp1,imp2=5;
+// c90-warning@-1 {{type specifier missing, defaults to 'int'}}
+// c99-error@-2 {{type specifier missing, defaults to 'int'}}
+// c23-error@-3 {{a type specifier is required for all declarations}}
+// c23-error@-4 {{expected ';' after top level declarator}}
+
+// CHECK: int const imp3;
+const imp3;
+// c90-warning@-1 {{type specifier missing, defaults to 'int'}}
+// c99-error@-2 {{type specifier missing, defaults to 'int'}}
+// c23-error@-3 {{a type specifier is required for all declarations}}
+
+// CHECK: int static imp4;
+static imp4;
+// c90-warning@-1 {{type specifier missing, defaults to 'int'}}
+// c99-error@-2 {{type specifier missing, defaults to 'int'}}
+// c23-error@-3 {{a type specifier is required for all declarations}}
+
+// CHECK: int static const imp5;
+static const imp5;
+// c90-warning@-1 {{type specifier missing, defaults to 'int'}}
+// c99-error@-2 {{type specifier missing, defaults to 'int'}}
+// c23-error@-3 {{a type specifier is required for all declarations}}
+
+// CHECK: int volatile __attribute__ ((aligned (16))) imp6;
+volatile __attribute__ ((aligned (16))) imp6;
+// c90-warning@-1 {{type specifier missing, defaults to 'int'}}
+// c99-error@-2 {{type specifier missing, defaults to 'int'}}
+// c23-error@-3 {{a type specifier is required for all declarations}}
+
+// CHECK-LABEL: int f2(void)
+f2(void)
+// c90-warning@-1 {{type specifier missing, defaults to 'int'}}
+// c99-error@-2 {{type specifier missing, defaults to 'int'}}
+// c23-error@-3 {{a type specifier is required for all declarations}}
+{
+  // CHECK: int register __attribute__ ((uninitialized)) i;
+  register __attribute__ ((uninitialized)) i;
+  // c90-warning@-1 {{type specifier missing, defaults to 'int'}}
+  // c99-error@-2 {{type specifier missing, defaults to 'int'}}
+  // c23-error@-3 {{a type specifier is required for all declarations}}
+
+  return 0;
+}
diff --git a/clang/test/FixIt/fixit.c b/clang/test/FixIt/fixit.c
index 2cd5b7ae020ba..0e86d454a0e10 100644
--- a/clang/test/FixIt/fixit.c
+++ b/clang/test/FixIt/fixit.c
@@ -27,27 +27,6 @@ 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: int 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}}

>From 9267ec4a7430cf80422705dc6b7dd7d9d09e8496 Mon Sep 17 00:00:00 2001
From: Karl Friebel <[email protected]>
Date: Tue, 10 Feb 2026 19:25:50 +0100
Subject: [PATCH 4/4] Applied suggestions to fixit-missing-type-spec.c

- Added an empty line between every lang standard
- Added -fsyntax-only where appropriate
- Made C90 exfail using -Werror for consistency
---
 clang/test/FixIt/fixit-missing-type-spec.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/clang/test/FixIt/fixit-missing-type-spec.c 
b/clang/test/FixIt/fixit-missing-type-spec.c
index 5d1eecfcb1f7a..a8804593bc496 100644
--- a/clang/test/FixIt/fixit-missing-type-spec.c
+++ b/clang/test/FixIt/fixit-missing-type-spec.c
@@ -1,14 +1,18 @@
-// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -verify=c90 -x c %s
+// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -fsyntax-only -verify=c90 -x c %s
 // RUN: cp %s %t
-// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -fixit %t
-// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -Werror -x c %t
+// RUN: not %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -Werror -fixit %t
+// RUN: %clang_cc1 -std=c90 -pedantic -Wno-comment 
-Wno-deprecated-non-prototype -Wimplicit-int -fsyntax-only -verify -x c %t
 // RUN: cat %t | FileCheck %s
-// RUN: %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype 
-verify=c99 -x c %s
+//
+// RUN: %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype 
-fsyntax-only -verify=c99 -x c %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype -fixit 
%t
-// RUN: %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype -Werror -x 
c %t
+// RUN: %clang_cc1 -std=c99 -pedantic -Wno-deprecated-non-prototype 
-fsyntax-only -verify -x c %t
 // RUN: cat %t | FileCheck %s
-// RUN: %clang_cc1 -std=c23 -pedantic -verify=c23 -x c %s
+//
+// RUN: %clang_cc1 -std=c23 -pedantic -fsyntax-only -verify=c23 -x c %s
+
+// expected-no-diagnostics
 
 // CHECK: int imp0[4],imp1,imp2=5;
 imp0[4],imp1,imp2=5;

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

Reply via email to