llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Tony Guillot (to268)

<details>
<summary>Changes</summary>

At the time of the implementation of 
[N3007](https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm) in Clang, 
when an array type was specified, an error was emitted unless the deduced type 
was a `char *`.
After further inspection in the C standard, it turns out that the inferred type 
of an `char[]` should be deduced to a `char *`, which should emit an error if 
an array type is specified with `auto`.

This now invalidates the following cases:
```c
auto s1[] = "test";
auto s2[4] = "test";
auto s3[5] = "test";
```

Fixes #<!-- -->162694

---
Full diff: https://github.com/llvm/llvm-project/pull/189722.diff


5 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (-10) 
- (modified) clang/test/C/C23/n3007.c (-2) 
- (modified) clang/test/CodeGen/auto.c (-1) 
- (modified) clang/test/Sema/c2x-auto.c (+12-5) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index bbbd3a34e01d6..cb69dbef3d2e5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -384,6 +384,7 @@ Bug Fixes in This Version
 - Correctly diagnosing and no longer crashing when ``export module foo``
   (without a semicolon) are the final tokens in a module file. (#GH187771)
 - Fixed a crash in duplicate attribute checking caused by comparing constant 
arguments with different integer signedness. (#GH188259)
+- 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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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]'}}
+}

``````````

</details>


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

Reply via email to