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
