https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/189722
>From d1cf27dc153aa32b5b76d4f1bc6fc1bfb21024e1 Mon Sep 17 00:00:00 2001 From: Tony Guillot <[email protected]> Date: Thu, 2 Apr 2026 17:38:08 +0200 Subject: [PATCH 1/4] Fixed C23 auto when an array type was specified for a `char *` --- clang/docs/ReleaseNotes.rst | 13 +++++++------ clang/lib/Sema/SemaTemplateDeduction.cpp | 10 ---------- clang/test/C/C23/n3007.c | 2 -- clang/test/CodeGen/auto.c | 1 - clang/test/Sema/c2x-auto.c | 17 ++++++++++++----- 5 files changed, 19 insertions(+), 24 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e36cffdd84647..08d4744953d82 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -113,7 +113,7 @@ Clang Python Bindings Potentially Breaking Changes ``locations`` argument are passed. Previousy, ``locations`` took precedence. - ``_CXUnsavedFile`` will be renamed to ``UnsavedFile`` for consistency. ``UnsavedFile`` is already available to use and existing uses should - be adapted to refer to it instead. ``_CXUnsavedFile`` will be removed in a + be adapted to refer to it instead. ``_CXUnsavedFile`` will be removed in a future release. What's New in Clang |release|? @@ -329,7 +329,7 @@ Improvements to Clang's diagnostics when accessing a member function on a past-the-end array element. (#GH179128) -- Added a missing space to the FixIt for the ``implicit-int`` group of diagnostics and +- 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) - Fixed the Fix-It insertion point for ``expected ';' after alias declaration`` @@ -342,7 +342,7 @@ Improvements to Clang's diagnostics - The ``-Wloop-analysis`` warning has been extended to catch more cases of variable modification inside lambda expressions (#GH132038). -- Clang now emits ``-Wsizeof-pointer-memaccess`` when snprintf/vsnprintf use the sizeof +- Clang now emits ``-Wsizeof-pointer-memaccess`` when snprintf/vsnprintf use the sizeof the destination buffer(dynamically allocated) in the len parameter(#GH162366) - Added ``-Wmodule-map-path-outside-directory`` (off by default) to warn on @@ -396,6 +396,7 @@ Bug Fixes in This Version with an explicit return type of void. The diagnostic now correctly refers to "lambda" instead of "block". (#GH188661) - Fixed a crash on _BitInt(N) arrays where 129 ≤ N ≤ 192 due to incorrect array filler lowering. (#GH189643) +- Fixed the behavior in C23 of ``auto``, by emitting an error when an array type is specified for a ``char *``. (#GH162694) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -418,7 +419,7 @@ Bug Fixes to C++ Support - Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741) - Fixed a crash when instantiating an invalid out-of-line static data member definition in a local class. (#GH176152) - Fixed a crash when pack expansions are used as arguments for non-pack parameters of built-in templates. (#GH180307) -- Fixed a bug where captured variables in non-mutable lambdas were incorrectly treated as mutable +- Fixed a bug where captured variables in non-mutable lambdas were incorrectly treated as mutable when used inside decltype in the return type. (#GH180460) - Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type vectors in ``constexpr``. (#GH180044) - Fixed a crash when `explicit(bool)` is used with an incomplete enumeration. (#GH183887) @@ -426,8 +427,8 @@ Bug Fixes to C++ Support - Fixed a crash when an immediate-invoked ``consteval`` lambda is used as an invalid initializer. (#GH185270) - Fixed an assertion failure when using a global destructor with a target with a non-default program address space. (#GH186484) -- Inherited constructors in ``dllexport`` classes are now exported for ABI-compatible cases, matching - MSVC behavior. Constructors with variadic arguments or callee-cleanup parameters are not yet supported +- Inherited constructors in ``dllexport`` classes are now exported for ABI-compatible cases, matching + MSVC behavior. Constructors with variadic arguments or callee-cleanup parameters are not yet supported and produce a warning. (#GH162640) - Fix initialization of GRO when GRO-return type mismatches, as part of CWG2563. (#GH98744) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index f18a34415ba43..696609d937850 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5224,16 +5224,6 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, return TemplateDeductionResult::Success; } - // Make sure that we treat 'char[]' equaly as 'char*' in C23 mode. - auto *String = dyn_cast<StringLiteral>(Init); - if (getLangOpts().C23 && String && Type.getType()->isArrayType()) { - Diag(Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier); - TypeLoc TL = TypeLoc(Init->getType(), Type.getOpaqueData()); - Result = SubstituteDeducedTypeTransform(*this, DependentResult).Apply(TL); - assert(!Result.isNull() && "substituting DependentTy can't fail"); - return TemplateDeductionResult::Success; - } - // Emit a warning if 'auto*' is used in pedantic and in C23 mode. if (getLangOpts().C23 && Type.getType()->isPointerType()) { Diag(Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier); diff --git a/clang/test/C/C23/n3007.c b/clang/test/C/C23/n3007.c index b8b84519fc19d..46bbfa48dda50 100644 --- a/clang/test/C/C23/n3007.c +++ b/clang/test/C/C23/n3007.c @@ -107,12 +107,10 @@ void test_misc(void) { auto something; // expected-error {{declaration of variable 'something' with deduced type 'auto' requires an initializer}} auto test_char = 'A'; auto test_char_ptr = "test"; - auto test_char_ptr2[] = "another test"; // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}} auto auto_size = sizeof(auto); // expected-error {{expected expression}} _Static_assert(_Generic(test_char, int : 1)); _Static_assert(_Generic(test_char_ptr, char * : 1)); - _Static_assert(_Generic(test_char_ptr2, char * : 1)); } void test_no_integer_promotions(void) { diff --git a/clang/test/CodeGen/auto.c b/clang/test/CodeGen/auto.c index e5bc1bf66138f..844fd37b309b9 100644 --- a/clang/test/CodeGen/auto.c +++ b/clang/test/CodeGen/auto.c @@ -7,7 +7,6 @@ void basic_types(void) { auto bl = true; // CHECK: alloca i8 auto chr = 'A'; // CHECK: alloca i{{8|32}} auto str = "Test"; // CHECK: alloca ptr - auto str2[] = "Test"; // CHECK: alloca [5 x i8] auto nptr = nullptr; // CHECK: alloca ptr } diff --git a/clang/test/Sema/c2x-auto.c b/clang/test/Sema/c2x-auto.c index 7d62db9ea6c28..6b92690003645 100644 --- a/clang/test/Sema/c2x-auto.c +++ b/clang/test/Sema/c2x-auto.c @@ -84,16 +84,16 @@ void test_qualifiers(const int y) { _Static_assert(_Generic(pc, int * : 1)); } -void test_strings(void) { +void test_parens(void) { auto str = "this is a string"; - auto str2[] = "this is a string"; // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}} - auto (str3) = "this is a string"; - auto (((str4))) = "this is a string"; + auto (str2) = "this is a string"; + auto (((str3))) = "this is a string"; + auto ((((x)))) = 12; _Static_assert(_Generic(str, char * : 1)); _Static_assert(_Generic(str2, char * : 1)); _Static_assert(_Generic(str3, char * : 1)); - _Static_assert(_Generic(str4, char * : 1)); + _Static_assert(_Generic(x, int : 1)); } void test_pointers(void) { @@ -137,3 +137,10 @@ void test_scopes(void) { expected-error {{'auto' not allowed in function return type}} return x; } + + +void test_incompatible_initializer(void) { + auto s1[] = "test"; // expected-error {{variable 's1' with type 'auto[]' has incompatible initializer of type 'char[5]'}} + auto s2[4] = "test"; // expected-error {{variable 's2' with type 'auto[4]' has incompatible initializer of type 'char[5]'}} + auto s3[5] = "test"; // expected-error {{variable 's3' with type 'auto[5]' has incompatible initializer of type 'char[5]'}} +} >From 7f9ebe63b43187a3aaa6569c9a5450e5cceb797b Mon Sep 17 00:00:00 2001 From: Tony Guillot <[email protected]> Date: Tue, 31 Mar 2026 19:39:49 +0200 Subject: [PATCH 2/4] Formatted ReleaseNotes --- clang/docs/ReleaseNotes.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 08d4744953d82..688f0a2c2bb75 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -113,7 +113,7 @@ Clang Python Bindings Potentially Breaking Changes ``locations`` argument are passed. Previousy, ``locations`` took precedence. - ``_CXUnsavedFile`` will be renamed to ``UnsavedFile`` for consistency. ``UnsavedFile`` is already available to use and existing uses should - be adapted to refer to it instead. ``_CXUnsavedFile`` will be removed in a + be adapted to refer to it instead. ``_CXUnsavedFile`` will be removed in a future release. What's New in Clang |release|? @@ -329,7 +329,7 @@ Improvements to Clang's diagnostics when accessing a member function on a past-the-end array element. (#GH179128) -- Added a missing space to the FixIt for the ``implicit-int`` group of diagnostics and +- 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) - Fixed the Fix-It insertion point for ``expected ';' after alias declaration`` @@ -342,7 +342,7 @@ Improvements to Clang's diagnostics - The ``-Wloop-analysis`` warning has been extended to catch more cases of variable modification inside lambda expressions (#GH132038). -- Clang now emits ``-Wsizeof-pointer-memaccess`` when snprintf/vsnprintf use the sizeof +- Clang now emits ``-Wsizeof-pointer-memaccess`` when snprintf/vsnprintf use the sizeof the destination buffer(dynamically allocated) in the len parameter(#GH162366) - Added ``-Wmodule-map-path-outside-directory`` (off by default) to warn on @@ -419,7 +419,7 @@ Bug Fixes to C++ Support - Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741) - Fixed a crash when instantiating an invalid out-of-line static data member definition in a local class. (#GH176152) - Fixed a crash when pack expansions are used as arguments for non-pack parameters of built-in templates. (#GH180307) -- Fixed a bug where captured variables in non-mutable lambdas were incorrectly treated as mutable +- Fixed a bug where captured variables in non-mutable lambdas were incorrectly treated as mutable when used inside decltype in the return type. (#GH180460) - Fixed a crash when evaluating uninitialized GCC vector/ext_vector_type vectors in ``constexpr``. (#GH180044) - Fixed a crash when `explicit(bool)` is used with an incomplete enumeration. (#GH183887) @@ -427,8 +427,8 @@ Bug Fixes to C++ Support - Fixed a crash when an immediate-invoked ``consteval`` lambda is used as an invalid initializer. (#GH185270) - Fixed an assertion failure when using a global destructor with a target with a non-default program address space. (#GH186484) -- Inherited constructors in ``dllexport`` classes are now exported for ABI-compatible cases, matching - MSVC behavior. Constructors with variadic arguments or callee-cleanup parameters are not yet supported +- Inherited constructors in ``dllexport`` classes are now exported for ABI-compatible cases, matching + MSVC behavior. Constructors with variadic arguments or callee-cleanup parameters are not yet supported and produce a warning. (#GH162640) - Fix initialization of GRO when GRO-return type mismatches, as part of CWG2563. (#GH98744) >From c5246d0c33b665583453e16311cb9d30c7344aef Mon Sep 17 00:00:00 2001 From: Tony Guillot <[email protected]> Date: Wed, 1 Apr 2026 14:39:57 +0200 Subject: [PATCH 3/4] Improved N3007 test case --- clang/test/C/C23/n3007.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/C/C23/n3007.c b/clang/test/C/C23/n3007.c index 46bbfa48dda50..881a7755f3467 100644 --- a/clang/test/C/C23/n3007.c +++ b/clang/test/C/C23/n3007.c @@ -107,6 +107,7 @@ void test_misc(void) { auto something; // expected-error {{declaration of variable 'something' with deduced type 'auto' requires an initializer}} auto test_char = 'A'; auto test_char_ptr = "test"; + auto test_char_ptr2[] = "another test"; // expected-error {{variable 'test_char_ptr2' with type 'auto[]' has incompatible initializer of type 'char[13]'}} auto auto_size = sizeof(auto); // expected-error {{expected expression}} _Static_assert(_Generic(test_char, int : 1)); >From 1e15ff29e0b727909682134e3f41ab1258d8a6db Mon Sep 17 00:00:00 2001 From: Tony Guillot <[email protected]> Date: Wed, 1 Apr 2026 22:42:47 +0200 Subject: [PATCH 4/4] Fixed diagnostic message --- clang/lib/Sema/SemaTemplateDeduction.cpp | 15 ++++++++------- clang/test/C/C23/n3006.c | 6 +++--- clang/test/C/C23/n3007.c | 10 +++++----- clang/test/Sema/auto-type.c | 9 +++++++++ clang/test/Sema/c2x-auto.c | 8 +++++--- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 696609d937850..c71c40526ccdc 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5224,18 +5224,19 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *Init, QualType &Result, return TemplateDeductionResult::Success; } - // Emit a warning if 'auto*' is used in pedantic and in C23 mode. - if (getLangOpts().C23 && Type.getType()->isPointerType()) { - Diag(Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier); - } - auto *InitList = dyn_cast<InitListExpr>(Init); - if (!getLangOpts().CPlusPlus && InitList) { + bool IsArrayType = Type.getType()->isArrayType(); + if (!getLangOpts().CPlusPlus && (InitList || IsArrayType)) { Diag(Init->getBeginLoc(), diag::err_auto_init_list_from_c) - << (int)AT->getKeyword() << getLangOpts().C23; + << (int)AT->getKeyword() << IsArrayType; return TemplateDeductionResult::AlreadyDiagnosed; } + // Emit a warning if 'auto*' is used in pedantic and in C23 mode. + if (getLangOpts().C23 && Type.getType()->isPointerType()) { + Diag(Type.getBeginLoc(), diag::ext_c23_auto_non_plain_identifier); + } + // Deduce type of TemplParam in Func(Init) SmallVector<DeducedTemplateArgument, 1> Deduced; Deduced.resize(1); diff --git a/clang/test/C/C23/n3006.c b/clang/test/C/C23/n3006.c index 14d73da9db49c..69674d8e8f4b2 100644 --- a/clang/test/C/C23/n3006.c +++ b/clang/test/C/C23/n3006.c @@ -11,7 +11,7 @@ void struct_test(void) { auto normal_struct2 = (struct S1) { .x = 1, .y = 2 }; auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 }; auto underspecified_struct_redef = (struct S1 { char x, y; }){ 'A', 'B'}; // expected-error {{type 'struct S1' has incompatible definitions}} \ - expected-error {{cannot use 'auto' with array in C}} \ + expected-error {{cannot use 'auto' with initializer list in C}} \ expected-note {{field 'x' has type 'char' here}} auto underspecified_empty_struct = (struct S3 { }){ }; auto zero_init_struct = (struct S4 { int x; }){ 0 }; @@ -25,7 +25,7 @@ void union_test(void) { auto normal_union_double = (union U1){ .b = 2.4 }; auto underspecified_union = (union U2 { int a; double b; }){ .a = 34 }; auto underspecified_union_redef = (union U1 { char a; double b; }){ .a = 'A' }; // expected-error {{type 'union U1' has incompatible definitions}} \ - expected-error {{cannot use 'auto' with array in C}} \ + expected-error {{cannot use 'auto' with initializer list in C}} \ expected-note {{field 'a' has type 'char' here}} auto underspecified_empty_union = (union U3 { }){ }; } @@ -37,7 +37,7 @@ void enum_test(void) { auto normal_enum_bar = (enum E1){ BAR }; auto underspecified_enum = (enum E2 { BAZ, QUX }){ BAZ }; auto underspecified_enum_redef = (enum E1 { ONE, TWO }){ ONE }; // expected-error {{type 'enum E1' has incompatible definitions}} \ - expected-error {{cannot use 'auto' with array in C}} \ + expected-error {{cannot use 'auto' with initializer list in C}} \ expected-note {{enumerator 'ONE' with value 0 here}} auto underspecified_empty_enum = (enum E3 { }){ }; // expected-error {{use of empty enum}} auto underspecified_undeclared_enum = (enum E4){ FOO }; // expected-error {{variable has incomplete type 'enum E4'}} \ diff --git a/clang/test/C/C23/n3007.c b/clang/test/C/C23/n3007.c index 881a7755f3467..fd81a6b9436b7 100644 --- a/clang/test/C/C23/n3007.c +++ b/clang/test/C/C23/n3007.c @@ -77,10 +77,10 @@ void test_arrary(void) { } void test_initializer_list(void) { - auto a = {}; // expected-error {{cannot use 'auto' with array in C}} - auto b = { 0 }; // expected-error {{cannot use 'auto' with array in C}} - auto c = { 1, }; // expected-error {{cannot use 'auto' with array in C}} - auto d = { 1 , 2 }; // expected-error {{cannot use 'auto' with array in C}} + auto a = {}; // expected-error {{cannot use 'auto' with initializer list in C}} + auto b = { 0 }; // expected-error {{cannot use 'auto' with initializer list in C}} + auto c = { 1, }; // expected-error {{cannot use 'auto' with initializer list in C}} + auto d = { 1 , 2 }; // expected-error {{cannot use 'auto' with initializer list in C}} auto e = (int [3]){ 1, 2, 3 }; } @@ -107,7 +107,7 @@ void test_misc(void) { auto something; // expected-error {{declaration of variable 'something' with deduced type 'auto' requires an initializer}} auto test_char = 'A'; auto test_char_ptr = "test"; - auto test_char_ptr2[] = "another test"; // expected-error {{variable 'test_char_ptr2' with type 'auto[]' has incompatible initializer of type 'char[13]'}} + auto test_char_ptr2[] = "another test"; // expected-error {{cannot use 'auto' with array in C}} auto auto_size = sizeof(auto); // expected-error {{expected expression}} _Static_assert(_Generic(test_char, int : 1)); diff --git a/clang/test/Sema/auto-type.c b/clang/test/Sema/auto-type.c index b66f58b923287..b80948d6db66f 100644 --- a/clang/test/Sema/auto-type.c +++ b/clang/test/Sema/auto-type.c @@ -89,3 +89,12 @@ void Issue55702(void) { (void)_Generic(v, long double : 0, double : 0, default : 1); // OK _Static_assert(_Generic(v, long double : 0, default : 1) == 1, "fail"); } + + +void incompatible_initializer(void) { + __auto_type s1[] = "test"; // expected-error {{cannot use '__auto_type' with array in C}} + __auto_type s2[4] = "test"; // expected-error {{cannot use '__auto_type' with array in C}} + __auto_type s3[5] = "test"; // expected-error {{cannot use '__auto_type' with array in C}} + __auto_type i = { 1 }; // expected-error {{cannot use '__auto_type' with initializer list in C}} + __auto_type i2 = { 1, 2 }; // expected-error {{cannot use '__auto_type' with initializer list in C}} +} diff --git a/clang/test/Sema/c2x-auto.c b/clang/test/Sema/c2x-auto.c index 6b92690003645..a11c42aa6fb49 100644 --- a/clang/test/Sema/c2x-auto.c +++ b/clang/test/Sema/c2x-auto.c @@ -140,7 +140,9 @@ void test_scopes(void) { void test_incompatible_initializer(void) { - auto s1[] = "test"; // expected-error {{variable 's1' with type 'auto[]' has incompatible initializer of type 'char[5]'}} - auto s2[4] = "test"; // expected-error {{variable 's2' with type 'auto[4]' has incompatible initializer of type 'char[5]'}} - auto s3[5] = "test"; // expected-error {{variable 's3' with type 'auto[5]' has incompatible initializer of type 'char[5]'}} + auto s1[] = "test"; // expected-error {{cannot use 'auto' with array in C}} + auto s2[4] = "test"; // expected-error {{cannot use 'auto' with array in C}} + auto s3[5] = "test"; // expected-error {{cannot use 'auto' with array in C}} + auto i = { 1 }; // expected-error {{cannot use 'auto' with initializer list in C}} + auto i2 = { 1, 2 }; // expected-error {{cannot use 'auto' with initializer list in C}} } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
