[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-10-05 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 557614.
to268 added a comment.

Fix arm buildbot issues


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1186,12 +1186,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  No
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 18
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+  signed auto a = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_complex_types(void) {
+  _Complex auto i = 12.0; // expected-error {{'_Complex auto' is invalid}}
+}
+
+void test_gnu_extensions(void) {
+  auto t = ({ // expected-warning {{use of GNU statement expression extension}}
+auto b = 12;
+b;
+  });
+  _Static_assert(_Generic(t, int : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with array in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(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";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
+  auto *str = "this is a string"; // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-10-05 Thread Aaron Ballman via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG5d78b78c8538: [C2X] N3007 Type inference for object 
definitions (authored by to268, committed by aaron.ballman).

Changed prior to commit:
  https://reviews.llvm.org/D133289?vs=557115=557610#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1186,12 +1186,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  No
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 18
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+  signed auto a = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_complex_types(void) {
+  _Complex auto i = 12.0; // expected-error {{'_Complex auto' is invalid}}
+}
+
+void test_gnu_extensions(void) {
+  auto t = ({ // expected-warning {{use of GNU statement expression extension}}
+auto b = 12;
+b;
+  });
+  _Static_assert(_Generic(t, int : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with array in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(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";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
+  auto *str 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-10-04 Thread Guillot Tony via Phabricator via cfe-commits
to268 added a comment.

> Do you need me to land this on your behalf? If so, I can fix up the NFC 
> changes I found for you, but what email address would you like me to use for 
> patch attribution?

It is probably the best thing to do, and yes I need you to land this on your 
behalf. `Guillot Tony `

> There are some outstanding issues that should be handled in a follow up

I will start to work on these issues, when the patch has been landed.

Thank you for the review!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-10-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

I spotted some minor issues, but this LGTM for the initial implementation. 
Thank you for all your effort on this project!!

There are some outstanding issues that should be handled in a follow up, 
however:

  void foo() {
 auto l = (struct S { int x, y; }){ 1, 2 }; // Underspecified declaration, 
should diagnose
  
_Atomic int i;
_Static_assert(_Generic(, _Atomic auto *: 1)); // Gets two errors instead 
of just 1
  
auto int i = 12; // At local and file scope, now gives: warning: 'auto' 
storage class specifier is not permitted in C++11, and will not be supported in 
future releases
  
auto __attribute__((mode(HI))) i = 12; // Gives confused diagnostics, but 
GCC also doesn't accept currently either
_Static_assert(_Generic(i, short : 1)); // But if we accepted the above, 
this should pass. 
  }

but these all seem minor enough to be handled in follow-up work.

Do you need me to land this on your behalf? If so, I can fix up the NFC changes 
I found for you, but what email address would you like me to use for patch 
attribution?




Comment at: clang/lib/Sema/DeclSpec.cpp:1367-1368
+  // specifier in a pre-C++11 dialect of C++ or in a pre-C23 dialect of C.
+  if ((!S.getLangOpts().CPlusPlus11 && !S.getLangOpts().C23) &&
+  TypeSpecType == TST_auto)
 S.Diag(TSTLoc, diag::ext_auto_type_specifier);





Comment at: clang/lib/Sema/SemaDecl.cpp:12869
+Diag(Range.getBegin(), diag::err_auto_not_allowed)
+<< (int)Deduced->getContainedAutoType()->getKeyword() << /* 'here' */ 
23
+<< Range;

`/*in array decl*/` instead of `here`



Comment at: clang/test/C/C2x/n3007.c:32
+
+  _Static_assert(_Generic(, _Atomic auto *: 1)); // expected-error {{_Atomic 
cannot be applied to type 'auto' which is not trivially copyable}} \
+  expected-error {{'auto' 
not allowed here}}

aaron.ballman wrote:
> The first error on this line isn't helpful; the second error is the only one 
> I'd expect to see here.
To be clear, I mean this example should have one diagnostic instead of two:
```
  _Static_assert(_Generic(, _Atomic auto *: 1)); // expected-error {{_Atomic 
cannot be applied to type 'auto' in C23}} \
  expected-error {{'auto' 
not allowed here}}
```




Comment at: clang/test/Sema/c2x-auto.c:110-111
+  _Static_assert(_Generic(str2, const char * : 1));
+  _Static_assert(_Generic(b, int * : 1));
+}
+




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-09-20 Thread Guillot Tony via Phabricator via cfe-commits
to268 added a comment.

I need thoughts about this.




Comment at: clang/lib/Sema/SemaTemplateDeduction.cpp:4805-4806
   if (!getLangOpts().CPlusPlus && InitList) {
-Diag(Init->getBeginLoc(), diag::err_auto_init_list_from_c);
+Diag(Init->getBeginLoc(), diag::err_auto_init_list_from_c)
+<< (int)AT->getKeyword() << getLangOpts().C23;
 return TDK_AlreadyDiagnosed;

It feels wrong to check if it's not C++ and changing the diagnostic if we are 
in C, I only emit the fixed diagnostic in C23 mode for now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-09-20 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 557115.
to268 added a comment.

Fixed the initializer list diagnotic


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1186,12 +1186,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  No
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 18
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+  signed auto a = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_complex_types(void) {
+  _Complex auto i = 12.0; // expected-error {{'_Complex auto' is invalid}}
+}
+
+void test_gnu_extensions(void) {
+  auto t = ({ // expected-warning {{use of GNU statement expression extension}}
+auto b = 12;
+b;
+  });
+  _Static_assert(_Generic(t, int : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with array in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(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";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
+  auto *str = "this is a string"; // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
+  const 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-09-06 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 556008.
to268 added a comment.

This updates fixes the `_Atomic auto` diagnostic, the previous diagnostic was 
confusing since it was referencing a C++ feature (std::is_trivially_copyable).
I have a few diagnostic issues remaining, some parts need to take place as 
earlier in the Parsing stage and be diagnosed in the Sema stage.
PS: I'll migrate this patch to GH at the end of September if I need to.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1191,12 +1191,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  No
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 18
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+  signed auto a = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_complex_types(void) {
+  _Complex auto i = 12.0; // expected-error {{'_Complex auto' is invalid}}
+}
+
+void test_gnu_extensions(void) {
+  auto t = ({ // expected-warning {{use of GNU statement expression extension}}
+auto b = 12;
+b;
+  });
+  _Static_assert(_Generic(t, int : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(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";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =   

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-08-16 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 550874.
to268 marked 4 inline comments as done.
to268 added a comment.

This update is mostly a followup of a change upstream that consist of renaming 
all C2x references to C23.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1191,12 +1191,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  No
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 18
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+  signed auto a = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_complex_types(void) {
+  _Complex auto i = 12.0; // expected-error {{'_Complex auto' is invalid}}
+}
+
+void test_gnu_extensions(void) {
+  auto t = ({ // expected-warning {{use of GNU statement expression extension}}
+auto b = 12;
+b;
+  });
+  _Static_assert(_Generic(t, int : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(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";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
+  auto *str = "this is a string"; // expected-warning {{type inference of a declaration other 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-07-18 Thread Guillot Tony via Phabricator via cfe-commits
to268 added inline comments.



Comment at: clang/test/Sema/c2x-auto.c:119
+  return x;
+}

aaron.ballman wrote:
> aaron.ballman wrote:
> > Some additional test cases to consider:
> > ```
> > _Complex auto i = 12.0; // Should be rejected because _Complex is a type 
> > specifier; however, 
> > // when auto becomes a type specifier, this should 
> > be accepted. GCC
> > // rejects but if we end up accepting, I won't be 
> > sad -- we'll need an
> > // extension warning in that case though.
> > 
> > void foo(void) {
> >   extern void foo(int a, int array[({ auto x = 12; x;})]); // This is a use 
> > of `auto` within function prototype
> >// scope, but 
> > should still be accepted.
> > }
> > ```
> The suggested comment I have isn't fully correct. It should be rejected 
> because _Complex is a type specifier, but when auto becomes a type specifier, 
> I think _Complex perhaps should still not deduce. Consider this analogous 
> case (which could be a fun test case as well):
> ```
> signed auto a = 1L;
> ```
> `signed` is a type specifier as well, and this is not accepted in C++ (so we 
> don't want to accept it in C either).
> ```
> void foo(void) {
>   extern void foo(int a, int array[({ auto x = 12; x;})]); // This is a use 
> of `auto` within function prototype
>// scope, but 
> should still be accepted.
> }
> ```

I think you made a mistake there by using the same function name as the outer 
one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-07-18 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 541538.
to268 marked 17 inline comments as done.
to268 added a comment.

Added recommendations from @aaron.ballman.
Adjusting diagnostic messages still need to be done.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1190,12 +1190,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  No
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,136 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+  signed auto a = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_complex_types(void) {
+  _Complex auto i = 12.0; // expected-error {{'_Complex auto' is invalid}}
+}
+
+void test_gnu_extensions(void) {
+  auto t = ({ // expected-warning {{use of GNU statement expression extension}}
+auto b = 12;
+b;
+  });
+  _Static_assert(_Generic(t, int : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  auto str2[] = "this is a string";
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
+  auto *str = "this is a string"; // expected-warning {{type inference of a declaration other than a plain identifier with optional trailing attributes is a Clang extension}}
+  const auto *str2 = "this is a string";  // expected-warning {{type 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-07-13 Thread Guillot Tony via Phabricator via cfe-commits
to268 marked an inline comment as done.
to268 added a comment.

Thank you for your feedback @aaron.ballman!
I really appreciate that you are pointing out all my formatting mistakes, and 
giving me more guidelines.
The direction of the patch is clearer now.

In D133289#4489883 , @aaron.ballman 
wrote:

> I think there's a typo in the patch summary:
>
>> auto in an compound statement
>
> I think you mean "as the type of a compound literal"?

Yes i was a mistake, I have edited the summary to fix that typo.

In D133289#4489883 , @aaron.ballman 
wrote:

> - We should have an extension warning for array use with string literals 
> `auto str[] = "testing";`

This makes sense, since auto arrays are prohibited in the standard.

In D133289#4497901 , @aaron.ballman 
wrote:

> The committee is discussing this again on the reflectors. Thus far, almost 
> everyone reads the standard the same way as GCC did with their 
> implementation, which matches what I suggest above. However, there are folks 
> who are claiming we should not be able to deduce the derived type because 
> `_Atomic` forms an entirely new type and thus isn't actually a qualifier (and 
> there are some words in the standard that could maybe be read as supporting 
> that). The most conservative approach is to reject using `_Atomic auto` for 
> right now so users don't build a reliance on it. Eventually WG14 will make a 
> decision and we can relax that diagnostic then if we need to. Sorry for the 
> confusion on this topic!

I was wondering about the support of `_Atomic auto`, i will add new error 
diagnostic to prohibit `_Atomic auto`, thank you for addressing that topic!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-07-13 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D133289#4489883 , @aaron.ballman 
wrote:

> - `_Atomic auto x = 12;` is now something we should be accepting and deduce 
> as an `_Atomic int`

The committee is discussing this again on the reflectors. Thus far, almost 
everyone reads the standard the same way as GCC did with their implementation, 
which matches what I suggest above. However, there are folks who are claiming 
we should not be able to deduce the derived type because `_Atomic` forms an 
entirely new type and thus isn't actually a qualifier (and there are some words 
in the standard that could maybe be read as supporting that). The most 
conservative approach is to reject using `_Atomic auto` for right now so users 
don't build a reliance on it. Eventually WG14 will make a decision and we can 
relax that diagnostic then if we need to. Sorry for the confusion on this topic!




Comment at: clang/test/Sema/c2x-auto.c:119
+  return x;
+}

aaron.ballman wrote:
> Some additional test cases to consider:
> ```
> _Complex auto i = 12.0; // Should be rejected because _Complex is a type 
> specifier; however, 
> // when auto becomes a type specifier, this should be 
> accepted. GCC
> // rejects but if we end up accepting, I won't be sad 
> -- we'll need an
> // extension warning in that case though.
> 
> void foo(void) {
>   extern void foo(int a, int array[({ auto x = 12; x;})]); // This is a use 
> of `auto` within function prototype
>// scope, but 
> should still be accepted.
> }
> ```
The suggested comment I have isn't fully correct. It should be rejected because 
_Complex is a type specifier, but when auto becomes a type specifier, I think 
_Complex perhaps should still not deduce. Consider this analogous case (which 
could be a fun test case as well):
```
signed auto a = 1L;
```
`signed` is a type specifier as well, and this is not accepted in C++ (so we 
don't want to accept it in C either).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-07-11 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

Thank you for your patience while WG14 finalized the feature and I wrapped my 
head around the moving parts involved. I think this is shaping up nicely, but 
there's still some diagnostic issues. The biggest ones are:

- We should have an extension warning for array use with string literals `auto 
str[] = "testing";`
- We should be careful about testing underspecified declarations in a way that 
give the impression they're an extension, so we should sprinkle more fixme 
comments around the tests
- `_Atomic auto x = 12;` is now something we should be accepting and deduce as 
an `_Atomic int`

I think there's a typo in the patch summary:

> auto in an compound statement

I think you mean "as the type of a compound literal"?




Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:240-242
+def ext_c2x_auto_pointer_declaration : Extension<
+  "explicit declaration of 'auto' pointers is a Clang extension">,
+  InGroup>;

I think we'll need this diagnostic for more than just `*` in a declaration. 
Consider a case like:
```
auto val = (struct X { int y; }){ 0 };
```
accepting this is also an extension because it declares `y`, which is not an 
"ordinary" identifier. See 6.7.9p2-3

Also, because this is about the syntax used, I think this might be a diagnostic 
that should live in DiagnosticParseKinds.td (but maybe it's correct here, I've 
not reviewed enough yet to see).



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:2417
 def err_auto_init_list_from_c : Error<
-  "cannot use __auto_type with initializer list in C">;
+  "cannot use %select{'auto'|'decltype(auto)'|'__auto_type'}0 with initializer 
list in C">;
 def err_auto_bitfield : Error<

I'm surprised to see `decltype(auto)` here as `decltype` isn't a keyword in C 
so it'd be invalid syntax; let's switch it to something that makes it obvious 
that we should never issue that particular part of the diagnostic in C.



Comment at: clang/lib/Sema/SemaDecl.cpp:12684-12685
 
+  // Diagnose auto array declarations in C2x,
+  // unless it's a char array or an initialiser list which is diagnosed later
+  if (getLangOpts().C2x && Type->isArrayType() &&

Comment can be re-flowed to 80 columns and the comment should end in a period. 
(Weirdly, Phabricator isn't letting me suggest edits just within this file.)



Comment at: clang/lib/Sema/SemaDecl.cpp:12687-12688
+  if (getLangOpts().C2x && Type->isArrayType() &&
+  !isa_and_nonnull(Init) &&
+  !isa_and_nonnull(Init)) {
+Diag(Range.getBegin(), diag::err_auto_not_allowed)

This can switch to using `!isa_and_present(Init)` 
(the `_and_nonnull` variant is quietly deprecated).



Comment at: clang/lib/Sema/SemaDecl.cpp:12690
+Diag(Range.getBegin(), diag::err_auto_not_allowed)
+<< (int)Deduced->getContainedAutoType()->getKeyword() << 23 << Range;
+return QualType();

Please add a `/* */` comment before `23` detailing what that magic number will 
be printing.



Comment at: clang/lib/Sema/SemaTemplateDeduction.cpp:4780
 
+  // Make sure that we treat 'char[]' equaly as 'char*' in C2x mode
+  auto *String = dyn_cast(Init);





Comment at: clang/lib/Sema/SemaTemplateDeduction.cpp:4789-4792
+  // Emit a warning if 'auto*' is used in pedantic and in C2x mode
+  if (getLangOpts().C2x && Type.getType()->isPointerType()) {
+Diag(Type.getBeginLoc(), diag::ext_c2x_auto_pointer_declaration);
+  }

I think this diagnostic should happen from the parser rather then when 
determining the concrete type; that ensures consistent diagnosis of the syntax 
regardless of whether we needed to deduce the type or not.



Comment at: clang/test/C/C2x/n3007.c:6-22
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression 
of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 
'int *' with an expression of type 'unsigned long *'}}

Adding one more test case for `restrict`-qualified pointers.



Comment at: clang/test/C/C2x/n3007.c:25
+void test_atomic(void) {
+  _Atomic auto i = 12;  // expected-error {{_Atomic cannot be applied to type 
'auto' which is not trivially copyable}}
+  _Atomic(auto) j = 12; // expected-error {{'auto' not allowed here}} \

What we finally landed on in WG14 is that this should be accepted. In this 
form, `_Atomic` is being used as a type qualifier (not a type specifier), and 
6.7.9p2 explicitly talks about qualifiers: "The inferred type of the declared 
object is the type of the assignment expression after lvalue, array to pointer 
or function to 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-07-05 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 537422.
to268 added a comment.

Minor code reformatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1190,12 +1190,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  Unknown
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  auto str2[] = "this is a string";
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  auto *str = "this is a string"; // expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  const auto *str2 = "this is a string";  // expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  auto *b =// expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  *b = // expected-error {{incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove &}}
+  auto nptr = nullptr;
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(ptr, int * : 1));
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, const char * : 1));
+  _Static_assert(_Generic(b, int * : 1));
+}
+
+void 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-07-05 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 537331.
to268 added a comment.

I have fixed the misleading diagnostic with auto array declarations.
The diagnostics now says that `'auto' is not allowed in array declarations`.

I am not sure with the way i have currently implemented it in ` SemaDecl.cpp`, 
maybe it can be done in a cleaner way.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1190,12 +1190,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  Unknown
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+
+  _Static_assert(_Generic(auto_int, int : 1));
+  _Static_assert(_Generic(auto_long, unsigned long : 1));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1));
+  _Static_assert(_Generic(double_cast, double : 1));
+  _Static_assert(_Generic(long_cast, long : 1));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1));
+  _Static_assert(_Generic(double_cl, double : 1));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1));
+  _Static_assert(_Generic(a, double * : 1));
+  _Static_assert(_Generic(b, double (*)[3] : 1));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1));
+  _Static_assert(_Generic(b, int : 1));
+  _Static_assert(_Generic(c, unsigned long : 1));
+  _Static_assert(_Generic(pa, int * : 1));
+  _Static_assert(_Generic(pb, const int * : 1));
+  _Static_assert(_Generic(pc, int * : 1));
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  auto str2[] = "this is a string";
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+
+  _Static_assert(_Generic(str, char * : 1));
+  _Static_assert(_Generic(str2, char * : 1));
+  _Static_assert(_Generic(str3, char * : 1));
+  _Static_assert(_Generic(str4, char * : 1));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  auto *str = "this is a string"; // expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  const auto *str2 = "this is a string";  // expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  auto *b =// expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  *b = // expected-error {{incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove &}}
+  auto nptr = nullptr;
+
+  

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-06-21 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 533214.
to268 marked 8 inline comments as done.
to268 added a comment.

I have updated and fixed all minors comments about the test cases.
I have added the diagnostic to warn users about using a Clang extension when 
declaring an explicit `auto*` in pedantic mode.
I need to debug more about the two remaining diagnostics to fix:

- Wrong diagnostic when using the `_Atomic` attribute
- Misleading diagnostic where it should say that `auto is not allowed` but says 
that `[...] requires an initializer`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1190,12 +1190,12 @@
 
   Underspecified object definitions
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3006.htm;>N3006
-  Unknown
+  Unknown
 
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -std=c2x -verify -pedantic -Wno-comments %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+
+  _Static_assert(_Generic(auto_int, int : 1, default : 0));
+  _Static_assert(_Generic(auto_long, unsigned long : 1, default : 0));
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cast, int : 1, default : 0));
+  _Static_assert(_Generic(double_cast, double : 1, default : 0));
+  _Static_assert(_Generic(long_cast, long : 1, default : 0));
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+
+  _Static_assert(_Generic(int_cl, int : 1, default : 0));
+  _Static_assert(_Generic(double_cl, double : 1, default : 0));
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+
+  _Static_assert(_Generic(array, double * : 1, default : 0));
+  _Static_assert(_Generic(a, double * : 1, default : 0));
+  _Static_assert(_Generic(b, double (*)[3] : 1, default : 0));
+}
+
+void test_typeof() {
+  int typeof_target();
+  auto result = (typeof(typeof_target())){12};
+
+  _Static_assert(_Generic(result, int : 1, default : 0));
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+  _Static_assert(_Generic(a, int : 1, default : 0));
+  _Static_assert(_Generic(b, int : 1, default : 0));
+  _Static_assert(_Generic(c, unsigned long : 1, default : 0));
+  _Static_assert(_Generic(pa, int * : 1, default : 0));
+  _Static_assert(_Generic(pb, const int * : 1, default : 0));
+  _Static_assert(_Generic(pc, int * : 1, default : 0));
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  auto str2[] = "this is a string";
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+
+  _Static_assert(_Generic(str, char * : 1, default : 0));
+  _Static_assert(_Generic(str2, char * : 1, default : 0));
+  _Static_assert(_Generic(str3, char * : 1, default : 0));
+  _Static_assert(_Generic(str4, char * : 1, default : 0));
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-warning {{explicit declaration of 'auto' pointers is a Clang extension}}
+  auto *str = "this is a string"; // expected-warning {{explicit declaration of 'auto' pointers is a 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-05-09 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

Thank you for the continued work on this! In general, I think the test coverage 
should verify the deduced type information more often. e.g., if we accept the 
code, there should probably be a `static_assert` nearby that ensures the 
deduced type is what we'd expect.

I applied the patch locally and tried out various things, and here's some test 
coverage I think we're lacking.

  // Important: these two declarations are at file scope, we're testing that 
the storage
  // class specifier is ignored because we're deducing the type.
  auto i = 12; // Ok, deduces int
  auto j = 12ull; // Ok, deduces unsigned long long
  
  // This is testing whether storage specifier order matters:
  void func() {
const auto static i = 12; // Ok, static variable of type const int
  }



In D133289#4279054 , @to268 wrote:

> I have *hopefully* fixed my broken patch.
> This is all the things in need to address:
>
>   auto str2[] = "string";
>   [[clang::overloadable]] auto test(auto x) { return x; }
>
> and maybe retry to support `auto` in compound literals,
> becaue i have seen heavy macro users that want compound literals to work.
>
> I think it's safe to say that we will not support all features from N3076 
>  in this patch.

My testing of your patch suggests those aren't issues left to address 
(perhaps). e.g.,

  auto test[] = "foo";
  static_assert(_Generic(test, char * : 1, default : 0));

this matches what I'd expect (no warning, no failed assertion; string literals 
have type `char []` in C, not `const char[]`.

My testing of `__attribute__((overloadable))` with your patch is that we 
currently reject use of `auto` in those functions. I think that's good initial 
behavior -- if we want to allow `auto` there, that's probably better left to a 
follow-up patch anyway because I'd expect there to be some debate around 
whether that's a good idea or not.

As for compound literals, I think we've determined they're not supported by C 
currently.




Comment at: clang/test/C/C2x/n3007.c:20
+void test_atomic(void) {
+  _Atomic auto i = 12;  // expected-error {{_Atomic cannot be applied to type 
'auto' which is not trivially copyable}}
+  _Atomic(auto) j = 12; // expected-error {{'auto' not allowed here}} \

This diagnostic is incorrect -- I believe this code should be accepted.



Comment at: clang/test/C/C2x/n3007.c:21
+  _Atomic auto i = 12;  // expected-error {{_Atomic cannot be applied to type 
'auto' which is not trivially copyable}}
+  _Atomic(auto) j = 12; // expected-error {{'auto' not allowed here}} \
+   expected-error {{a type specifier is required for 
all declarations}}

This diagnostic is correct.



Comment at: clang/test/C/C2x/n3007.c:31-32
+  double A[3] = { 0 };
+  auto pA = A;
+  auto qA = 
+  auto pi = 3.14;

We should test that the types match our expectations:
```
double A[3] = { 0 };
auto pA = A; // pA is double * due to array decay on A
static_assert(_Generic(pA, double * : 1, default : 0));
auto qA =  // qA is double (*)[3]
static_assert(_Generic(qA, double (*)[3] : 1, default : 0));
```



Comment at: clang/test/C/C2x/n3007.c:46
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  _Alignas(auto) auto b[4];   // expected-error {{declaration of variable 
'b' with deduced type 'auto[4]' requires an initializer}} \
+ expected-error {{expected expression}}

I think this would make it more clear that what's being tested is the 
`_Alignas` behavior.



Comment at: clang/test/C/C2x/n3007.c:56-57
+void test_initializer_list(void) {
+  // FIXME: as mentioned in N3076, it seems that intializer list are allowed
+  // even with an initializer list containing one item
+  auto a = {};// expected-error {{cannot use 'auto' with 
initializer list in C}}

This should now be resolved in N3096  so the FIXME comment can be removed.



Comment at: clang/test/C/C2x/n3007.c:66
+void test_structs(void) {
+  auto a = (struct { int a; } *)0;
+  struct B { auto b; };   // expected-error {{'auto' not allowed in struct 
member}}

This is awfully close to the examples from the paper (6.7.9p3):
```
auto p1 = (struct { int a; } *)0; // error expected

struct s;
auto p2 = (struct s { int a; } *)0; // error expected
```
They are expected to be diagnosed due to changes in N3006 (underspecified 
object definitions), so I think it's fine to add a FIXME comment with the test 
cases instead of trying to also implement N3006 at the same time. We currently 
list that as `unknown` in our status page, but I think it's clearly a `no` now.



Comment at: clang/test/C/C2x/n3007.c:100
+  auto d = 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-05-08 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 520447.
to268 added a comment.

Fixed auto char arrays with explicit brackets

  c
  auto foo[] = "bar";


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1195,7 +1195,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  auto str2[] = "this is a string";
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr = 
+  auto *str = "this is a string";
+  const auto *str2 = "this is a string";
+  auto *b = 
+  *b =  // expected-error {{incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove &}}
+  auto nptr = nullptr;
+}
+
+void test_scopes(void) {
+  double a = 7;
+  double b = 9;
+  {
+auto a = a * a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
+   expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  }
+  {
+auto b = a * a;
+auto a = b;
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+  int a;
+  auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  union {
+char c;
+auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  } u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto basic_usage(auto auto) {   // c2x-error {{'auto' not allowed in function prototype}} \
+   c2x-error {{'auto' not allowed in function return type}} \
+   c2x-error {{cannot combine with 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-04-18 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 514789.
to268 added a comment.

I have *hopefully* fixed my broken patch.
This is all the things in need to address:

  auto str2[] = "string";
  [[clang::overloadable]] auto test(auto x) { return x; }

and maybe retry to support `auto` in compound literals,
becaue i have seen heavy macro users that want compound literals to work.

I think it's safe to say that we will not support all features from N3076 
 in this patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1195,7 +1195,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  // FIXME: This should work for char*
+  auto str2[] = "this is a string"; // expected-error {{variable 'str2' with type 'auto[]' has incompatible initializer of type 'char[17]'}}
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+}
+
+void test_pointers(void) {
+  // FIXME: as mentioned in N3076, it seems that auto* is allowed
+  auto a = 12;
+  auto *ptr = 
+  auto *str = "this is a string";
+  const auto *str2 = "this is a string";
+  auto *b = 
+  *b =  // expected-error {{incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove &}}
+  auto nptr = nullptr;
+}
+
+void test_scopes(void) {
+  double a = 7;
+  double b = 9;
+  {
+auto a = a * a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
+   expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  }
+  {
+auto b = a * a;
+auto a = b;
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+  int a;
+  auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  union {
+char c;
+auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-04-16 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 514051.
to268 added a comment.

I have improved some diagnostics and i am now testing `nullptr` with `auto`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1195,7 +1195,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with
+  // deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto); // expected-error {{expected expression}}
+  typeof(auto) tpof = 4; // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = {
+  1, 2,
+  3}; // expected-error {{cannot use 'auto' with initializer list in C}}
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13}; // expected-error {{expected expression}}
+}
+
+void test_array_pointers(void) {
+  double array[3] = {0};
+  auto a = array;
+  auto b = 
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int *pa =  // expected-warning {{initializing 'int *' with an expression of
+// type 'const int *' discards qualifiers}}
+  const int *pb = 
+  int *pc =  // expected-warning {{incompatible pointer types initializing
+// 'int *' with an expression of type 'unsigned long *'}}
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  // FIXME: This should work for char*
+  auto str2[] =
+  "this is a string"; // expected-error {{variable 'str2' with type 'auto[]'
+  // has incompatible initializer of type 'char[17]'}}
+  auto(str3) = "this is a string";
+  auto(((str4))) = "this is a string";
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr = 
+  auto *str = "this is a string";
+  const auto *str2 = "this is a string";
+  auto *b = 
+  *b =  // expected-error {{incompatible pointer to integer conversion
+   // assigning to 'int' from 'int *'; remove &}}
+  auto nptr = nullptr;
+}
+
+void test_scopes(void) {
+  double a = 7;
+  double b = 9;
+  {
+auto a =
+a *
+a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
+   expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  }
+  {
+auto b = a * a;
+auto a = b;
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+  int a;
+  auto b; // c2x-error {{'auto' not allowed in struct member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  union {
+char c;
+auto smth; // c2x-error {{'auto' not allowed in union member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  } u;
+};
+
+enum E : auto{ // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-03-11 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 504381.
to268 added a comment.

Patch update: Reverting `auto` as a type specifier.
I am currently figuring out what behavior the `auto` keyword need to match.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1195,7 +1195,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 17
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  // FIXME: This should work for char*
+  auto str2[] = "this is a string"; // expected-error {{str2' declared as array of 'auto'}}
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+}
+
+void test_pointers(void) {
+  // FIXME: as mentioned in N3076, it seems that auto* is allowed
+  auto a = 12;
+  auto *ptr = 
+  auto *str = "this is a string";
+  const auto *str2 = "this is a string";
+  auto *b = 
+  *b =  // expected-error {{incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove &}}
+}
+
+void test_scopes(void) {
+  double a = 7;
+  double b = 9;
+  {
+auto a = a * a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
+   expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  }
+  {
+auto b = a * a;
+auto a = b;
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+  int a;
+  auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  union {
+char c;
+auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+   c17-error {{type name does not allow storage class to be specified}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+  } u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto basic_usage(auto auto) {   // c2x-error {{'auto' not allowed in function prototype}} \
+   c2x-error {{'auto' not allowed in function 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-02-01 Thread Thorsten via Phabricator via cfe-commits
tschuett added a comment.

In D133289#4096588 , @aaron.ballman 
wrote:

> In D133289#4037180 , @tschuett 
> wrote:
>
>> It surprised me that there are no type inference messages? The type of this 
>> auto is double. I only found warnings of misuse of auto and codegen tests.
>
> Can you give a code example of what you expected to see a diagnostic for but 
> aren't getting one?

This is probably only for testing and not for Clang users:

  auto Float = 3.0; // note that Float is a float


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-02-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D133289#4037180 , @tschuett wrote:

> It surprised me that there are no type inference messages? The type of this 
> auto is double. I only found warnings of misuse of auto and codegen tests.

Can you give a code example of what you expected to see a diagnostic for but 
aren't getting one?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-02-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D133289#4036529 , @aaron.ballman 
wrote:

> I spoke with @to268 during office hours about the current status of the NB 
> comments for this feature in the C committee. For the moment, he's going to 
> pause work on this patch until the C committee weighs in on whether `auto` is 
> a type specifier or not. The committee meets the week of Jan 23, so we should 
> have a better understanding of direction by the week of Jan 30. If the C 
> committee turns `auto` into a type specifier, we may go back to the original 
> implementation of this feature which exposes the C++ feature in C (and add 
> diagnostics around the things that need to be constrained in C such as use in 
> a function signature).

The minutes from last week's meeting aren't available yet, but I can give an 
update from my personal notes. Alex Gilding wrote a proposal to change the 
specification mechanisms away from "storage class specifier with no type 
specifier" and to an actual type specifier in WG14 N3076 
(https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3076.pdf). WG14 briefly 
looked at the paper, but given how late in the cycle we are, we did not want to 
adopt new specification wording that is so drastically different from the 
existing wording. So we repaired the national body comments with WG14 N3079 
(https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3079.htm) instead.

> Does WG14 want something along the lines of N3076 in a future revision of the 
> standard? 10 (for)/0 (against)/7 (abstain) -- consensus

So we now have sufficient support within WG14 for Clang to expose our C++ 
implementation of `auto` in C (with additional diagnostics for functionality C 
doesn't yet support like `auto` in function signatures) instead of implementing 
it from scratch as a weird storage class specifier/missing type specifier. 
However, we did make some other repairs to the feature so the current wording 
in the working draft (WG14 N3054) is not the latest. Specifically, we adopted 
US-122 and US-123 changes from WG14 N3079.

WG14 is expecting to have another week of meetings to work on NB comments (week 
of Feb 13) and we are expecting to have a second round of NB comments. I think 
it's okay for us to restart work on this patch now that we have a direction, 
but we might want to hold off on landing the patch until after we have a better 
idea of the final form of the specification. If there are no comments about it 
in CD2, then we're fine, but it's possible for CD2 to make breaking changes to 
the feature, so it's mostly about being aware of that situation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-01-09 Thread Thorsten via Phabricator via cfe-commits
tschuett added a comment.

It surprised me that there are no type inference messages? The type of this 
auto is double. I only found warnings of misuse of auto and codegen tests.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-01-09 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

I spoke with @to268 during office hours about the current status of the NB 
comments for this feature in the C committee. For the moment, he's going to 
pause work on this patch until the C committee weighs in on whether `auto` is a 
type specifier or not. The committee meets the week of Jan 23, so we should 
have a better understanding of direction by the week of Jan 30. If the C 
committee turns `auto` into a type specifier, we may go back to the original 
implementation of this feature which exposes the C++ feature in C (and add 
diagnostics around the things that need to be constrained in C such as use in a 
function signature).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2023-01-09 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 487427.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1192,7 +1192,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  // FIXME: This should work for char*
+  auto str2[] = "this is a string"; // expected-error {{str2' declared as array of 'auto'}}
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+}
+
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-error {{cannot declare 'ptr' as an explcit 'auto*' in C2x}}
+  auto *str = "this is a string"; // expected-error {{cannot declare 'str' as an explcit 'auto*' in C2x}}
+  const auto *str2 = "this is a string";  // expected-error {{cannot declare 'str2' as an explcit 'auto*' in C2x}}
+  auto *b =// expected-error {{cannot declare 'b' as an explcit 'auto*' in C2x}}
+  *b = 
+}
+
+void test_scopes(void) {
+  double a = 7;
+  double b = 9;
+  {
+auto a = a * a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
+   expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  }
+  {
+auto b = a * a;
+auto a = b;
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+union {
+  char c;
+  auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto basic_usage(auto auto) {   // 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-12-08 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 481339.
to268 added a comment.

Removed compound literal diagnostic in ParseExpr


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1192,7 +1192,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  // FIXME: This should work for char*
+  auto str2[] = "this is a string"; // expected-error {{str2' declared as array of 'auto'}}
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+}
+
+// FIXME: All these statements should fails (cannot declare a variable as a auto*)
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-error {{cannot declare 'ptr' as an explcit 'auto*' in C2x}}
+  auto *str = "this is a string"; // expected-error {{cannot declare 'str' as an explcit 'auto*' in C2x}}
+  const auto *str2 = "this is a string";  // expected-error {{cannot declare 'str2' as an explcit 'auto*' in C2x}}
+  auto *b =// expected-error {{cannot declare 'b' as an explcit 'auto*' in C2x}}
+  *b = 
+}
+
+void test_scopes(void) {
+  double a = 7;
+  double b = 9;
+  {
+auto a = a * a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
+   expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  }
+  {
+auto b = a * a;
+auto a = b;
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+union {
+  char c;
+  auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-11-27 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 478113.
to268 marked 5 inline comments as done.
to268 added a comment.

Added test cases and added an explicit `auto*` diagnostic


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1192,7 +1192,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{'auto' is not allowed in a compound literal}}
+}
+
+void test_array_pointers(void) {
+  double array[3] = { 0 };
+  auto a = array;
+  auto b = 
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  // FIXME: This should work for char*
+  auto str2[] = "this is a string"; // expected-error {{str2' declared as array of 'auto'}}
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+}
+
+// FIXME: All these statements should fails (cannot declare a variable as a auto*)
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr =  // expected-error {{cannot declare 'ptr' as an explcit 'auto*' in C2x}}
+  auto *str = "this is a string"; // expected-error {{cannot declare 'str' as an explcit 'auto*' in C2x}}
+  const auto *str2 = "this is a string";  // expected-error {{cannot declare 'str2' as an explcit 'auto*' in C2x}}
+  auto *b =// expected-error {{cannot declare 'b' as an explcit 'auto*' in C2x}}
+  *b = 
+}
+
+void test_scopes(void) {
+  double a = 7;
+  double b = 9;
+  {
+auto a = a * a; // expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}} \
+   expected-error {{variable 'a' declared with deduced type 'auto' cannot appear in its own initializer}}
+  }
+  {
+auto b = a * a;
+auto a = b;
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+union {
+  char c;
+  auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-11-13 Thread Guillot Tony via Phabricator via cfe-commits
to268 marked 7 inline comments as done.
to268 added a comment.

This is a status update of the patch.




Comment at: clang/lib/Parse/ParseExpr.cpp:1526
+// This is a temporary fix while we don't support C2x 6.5.2.5p4
+if (getLangOpts().C2x && GetLookAheadToken(2).getKind() == tok::l_brace) {
+  Diag(Tok, diag::err_c2x_auto_compound_literal_not_allowed);

aaron.ballman wrote:
> I don't think this is quite right; I suspect we're going to need more 
> complicated logic here. Consider a case like: `(auto const){ 12 }` or `(auto 
> *){ nullptr }` where two tokens ahead is `)` and not `{`. (Note, these type 
> specifications can be pretty arbitrarily complex.)
> 
> Given that this is a temporary workaround for a lack of support for storage 
> class specifiers in compound literals, perhaps another approach is to not try 
> to catch uses in compound literals. Instead, we could add tests with FIXME 
> comments to demonstrate the behavior we get with compound literals now, and 
> when we do that storage class specifier work, we will (hopefully) break those 
> tests and come back to make them correct.
I think it's better to make a test of the actual behavior than trying to 
correct this case. 



Comment at: clang/lib/Parse/ParseExpr.cpp:1530-1531
+}
+  }
+[[fallthrough]];
+

aaron.ballman wrote:
> This looks a bit less visually jarring to me (the indentation differences 
> were distracting). WDYT?
That's better but i remember that `clang-format` has failed on that.



Comment at: clang/test/C/C2x/n3007.c:13
+  int* pc =  // expected-warning {{incompatible pointer types initializing 
'int *' with an expression of type 'unsigned long *'}}
+
+  const int ci = 12;

aaron.ballman wrote:
> I'd also like a test for:
> ```
> _Atomic auto i = 12;
> _Atomic(auto) j = 12;
> 
> _Atomic(int) foo(void);
> auto k = foo(); // Do we get _Atomic(int) or just int?
> ```
The _Atomic qualifier is dropped so the type of k is an `int`



Comment at: clang/test/C/C2x/n3007.c:40-41
+void test_arrary(void) {
+  auto a[4];  // expected-error {{'a' declared as array of 'auto'}}
+  auto b[] = {1, 2};  // expected-error {{'b' declared as array of 'auto'}}
+}

aaron.ballman wrote:
> I think other array cases we want to test are:
> ```
> auto a = { 1 , 2 }; // Error
> auto b = { 1, }; // OK
> auto c = (int [3]){ 1, 2, 3 }; // OK
> ```
These statements are not working:
```
auto b = { 1, }; // Not valid
auto d = { 1 };  // Not valid
```
I think it's related to the compound literal.




Comment at: clang/test/C/C2x/n3007.c:56
+
+  _Static_assert(_Generic(test_char_ptr, const char * : 1, char * : 2) == 2, 
"C is weird");
+}

aaron.ballman wrote:
> I'd also like to ensure we reject:
> ```
> typedef auto (*fp)(void);
> typedef void (*fp)(auto);
> 
> _Generic(0, auto : 1);
> ```
> and we should ensure we properly get integer promotions:
> ```
> short s;
> auto a = s;
> _Generic(a, int : 1);
> ```
> and a test for use of an explicit pointer declarator (which is UB that we can 
> define if we want to):
> ```
> int a;
> auto *ptr =  // Okay?
> auto *ptr = a; // Error
> ```
```
> and we should ensure we properly get integer promotions:
> ```
> short s;
> auto a = s;
> _Generic(a, int : 1);
> ```
I got the error `controlling expression type 'short' not compatible with any 
generic association type` so we don't promote from `short` to `int`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-11-01 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

Thank you for the update to this!




Comment at: clang/lib/Parse/ParseExpr.cpp:1526
+// This is a temporary fix while we don't support C2x 6.5.2.5p4
+if (getLangOpts().C2x && GetLookAheadToken(2).getKind() == tok::l_brace) {
+  Diag(Tok, diag::err_c2x_auto_compound_literal_not_allowed);

I don't think this is quite right; I suspect we're going to need more 
complicated logic here. Consider a case like: `(auto const){ 12 }` or `(auto 
*){ nullptr }` where two tokens ahead is `)` and not `{`. (Note, these type 
specifications can be pretty arbitrarily complex.)

Given that this is a temporary workaround for a lack of support for storage 
class specifiers in compound literals, perhaps another approach is to not try 
to catch uses in compound literals. Instead, we could add tests with FIXME 
comments to demonstrate the behavior we get with compound literals now, and 
when we do that storage class specifier work, we will (hopefully) break those 
tests and come back to make them correct.



Comment at: clang/lib/Parse/ParseExpr.cpp:1530-1531
+}
+  }
+[[fallthrough]];
+

This looks a bit less visually jarring to me (the indentation differences were 
distracting). WDYT?



Comment at: clang/lib/Sema/DeclSpec.cpp:1362
   // type specifier.
   if (S.getLangOpts().CPlusPlus &&
   TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {

to268 wrote:
> Do we need to include C2x just in case?
I don't think so -- we're in a language where the type specifier *is* optional 
for C2x.



Comment at: clang/lib/Sema/DeclSpec.cpp:1370-1372
+  // specifier in a pre-C++11 dialect of C++
+  if ((!S.getLangOpts().CPlusPlus11 && !S.getLangOpts().C2x) &&
+  TypeSpecType == TST_auto)





Comment at: clang/test/C/C2x/n3007.c:13
+  int* pc =  // expected-warning {{incompatible pointer types initializing 
'int *' with an expression of type 'unsigned long *'}}
+
+  const int ci = 12;

I'd also like a test for:
```
_Atomic auto i = 12;
_Atomic(auto) j = 12;

_Atomic(int) foo(void);
auto k = foo(); // Do we get _Atomic(int) or just int?
```



Comment at: clang/test/C/C2x/n3007.c:36
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  _Alignas(4) auto b[4];  // expected-error {{'b' declared as array of 
'auto'}}
+}

I think this test should be `_Alignas(auto)` right?



Comment at: clang/test/C/C2x/n3007.c:40-41
+void test_arrary(void) {
+  auto a[4];  // expected-error {{'a' declared as array of 'auto'}}
+  auto b[] = {1, 2};  // expected-error {{'b' declared as array of 'auto'}}
+}

I think other array cases we want to test are:
```
auto a = { 1 , 2 }; // Error
auto b = { 1, }; // OK
auto c = (int [3]){ 1, 2, 3 }; // OK
```



Comment at: clang/test/C/C2x/n3007.c:56
+
+  _Static_assert(_Generic(test_char_ptr, const char * : 1, char * : 2) == 2, 
"C is weird");
+}

I'd also like to ensure we reject:
```
typedef auto (*fp)(void);
typedef void (*fp)(auto);

_Generic(0, auto : 1);
```
and we should ensure we properly get integer promotions:
```
short s;
auto a = s;
_Generic(a, int : 1);
```
and a test for use of an explicit pointer declarator (which is UB that we can 
define if we want to):
```
int a;
auto *ptr =  // Okay?
auto *ptr = a; // Error
```



Comment at: clang/test/Sema/c2x-auto.c:27
+  auto auto_cl = (auto){13};  // expected-error {{'auto' is not allowed in a 
compound literal}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 
'auto'}}
+}

This one should not be accepted -- the grammar productions for the 
initialization allow for `{0}` and `{0,}` but no more than one element in the 
braces.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-10-28 Thread Guillot Tony via Phabricator via cfe-commits
to268 added a comment.

Also i'm not sure if must add C2x to this condition just in case (falling back 
or add an assertion)




Comment at: clang/lib/Sema/DeclSpec.cpp:1362
   // type specifier.
   if (S.getLangOpts().CPlusPlus &&
   TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {

Do we need to include C2x just in case?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-10-28 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 471535.
to268 added a comment.

Reworked the parsing side of the patch


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1184,7 +1184,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{'auto' is not allowed in a compound literal}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(const int y) {
+  const auto a = 12;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+
+}
+
+void test_strings(void) {
+  auto str = "this is a string";
+  // FIXME: This should work for char*
+  auto str2[] = "this is a string"; // expected-error {{str2' declared as array of 'auto'}}
+  auto (str3) = "this is a string";
+  auto (((str4))) = "this is a string";
+}
+
+// FIXME: All these statements should fails (cannot declare a variable as a auto*)
+void test_pointers(void) {
+  auto a = 12;
+  auto *ptr = 
+  auto *str = "this is a string";
+  const auto *str2 = "this is a string";
+  auto *b = 
+  *b =   // expected-error {{incompatible pointer to integer conversion assigning to 'int' from 'int *'; remove &}}
+}
+
+void test_scopes(void) {
+  {
+auto a = 7;
+auto b = 9;
+auto c = a + b;
+  }
+  {
+auto d = a * b;   // expected-error {{use of undeclared identifier 'a'}} \
+ expected-error {{use of undeclared identifier 'b'}}
+{
+  auto e = d + c; // expected-error {{use of undeclared identifier 'c'}}
+}
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+union {
+  char c;
+  auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto basic_usage(auto auto) {   // c2x-error {{'auto' not allowed in function prototype}} \
+   c2x-error {{'auto' not allowed in function return type}} \
+   c2x-error {{cannot combine with previous 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-10-05 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 465312.
to268 added a comment.

Added a check to not diagnose a missing type specifier in C2x mode


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1184,7 +1184,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{'auto' is not allowed in a compound literal}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
+
+void test_scopes(void) {
+  {
+auto a = 7;
+auto b = 9;
+auto c = a + b;
+  }
+  {
+auto d = a * b;   // expected-error {{use of undeclared identifier 'a'}} \
+ expected-error {{use of undeclared identifier 'b'}}
+{
+  auto e = d + c; // expected-error {{use of undeclared identifier 'c'}}
+}
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+union {
+  char c;
+  auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto basic_usage(auto auto) {   // c2x-error {{'auto' not allowed in function prototype}} \
+   c2x-error {{'auto' not allowed in function return type}} \
+   c2x-error {{cannot combine with previous 'auto' declaration specifier}} \
+   c17-error {{invalid storage class specifier in function declarator}} \
+   c17-error {{illegal storage class on function}} \
+   c17-warning {{duplicate 'auto' declaration specifier}} \
+   c17-warning {{omitting the parameter name in a function definition is a C2x extension}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-10-04 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 465280.
to268 added a comment.

Added a check to not diagnose a missing type specifier in C2x mode


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1184,7 +1184,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{'auto' is not allowed in a compound literal}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
+
+void test_scopes(void) {
+  {
+auto a = 7;
+auto b = 9;
+auto c = a + b;
+  }
+  {
+auto d = a * b;   // expected-error {{use of undeclared identifier 'a'}} \
+ expected-error {{use of undeclared identifier 'b'}}
+{
+  auto e = d + c; // expected-error {{use of undeclared identifier 'c'}}
+}
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+union {
+  char c;
+  auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto basic_usage(auto auto) {   // c2x-error {{'auto' not allowed in function prototype}} \
+   c2x-error {{'auto' not allowed in function return type}} \
+   c2x-error {{cannot combine with previous 'auto' declaration specifier}} \
+   c17-error {{invalid storage class specifier in function declarator}} \
+   c17-error {{illegal storage class on function}} \
+   c17-warning {{duplicate 'auto' declaration specifier}} \
+   c17-warning {{omitting the parameter name in a function definition is a C2x extension}} \
+   c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-28 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/lib/Parse/ParseExpr.cpp:1515
+// This is a temporary fix while we don't support C2x 6.5.2.5p4
+if (getLangOpts().C2x && GetLookAheadToken(2).getKind() == tok::l_brace) {
+  Diag(Tok, diag::err_c2x_auto_compound_literal_not_allowed);

to268 wrote:
> to268 wrote:
> > aaron.ballman wrote:
> > > Why would this not be handled from `Sema::ActOnCompoundLiteral()`?
> > You're right, it's better to handle this in `Sema::ActOnCompoundLiteral()`
> > The problem is that right now, the usage of the `auto` keyword in a 
> > compound literal isn't parsed as a compound literal. 
> > This compound literal is unable to reach `Sema::ActOnCompoundLiteral()` 
> > because the parser emits that it's an invalid expression.
> > 
> > To summarize, i'm unable to handle handle a compound literal that uses the 
> > `auto` keyword inside `Sema::ActOnCompoundLiteral()`
> > if it's never going to be called.
> > ```
> > int test_ncl = (int){12};   // Parsed as a CL
> > auto test_cl = (auto){12};  // Not parsed as a CL and emits 
> > "expected expression"
> > /*
> >  * |-DeclStmt 0x562180ede8b0 
> >  * | `-VarDecl 0x562180ede730  col:9 test_ncl 'int' cinit
> >  * |   `-ImplicitCastExpr 0x562180ede898  'int' 
> > 
> >  * | `-CompoundLiteralExpr 0x562180ede870  'int' lvalue
> >  * |   `-InitListExpr 0x562180ede828  'int'
> >  * | `-IntegerLiteral 0x562180ede7b0  'int' 12
> >  * |-DeclStmt 0x562180ede970 
> >  * | `-VarDecl 0x562180ede908  col:10 invalid test_cl 'auto'
> >  * `-ReturnStmt 0x562180ede9a8 
> >  *   `-IntegerLiteral 0x562180ede988  'int' 0
> >  */
> > ```
> When we are parsing an expression between parentheses in 
> `Parser::ParseParenExpression()` line 2972,
> we are calling `Parser::isTypeIdInParens()` which when using C will return 
> `true` if it's a type specifier,
> which is not the case for the `auto` keyword.
> 
> Ultimately, we fall into the conditional block of 
> `Parser::ParseParenExpression()` line 3191,
> which will return an `ExprError()` (AKA: a parsing error).
> 
> This is why we are unable to forbid a compound literal using the `auto` 
> keyword at the 
> Semantic Analysis stage and why this feature is not working out of the box in 
> the first place.
> When we are parsing an expression between parentheses in 
> Parser::ParseParenExpression() line 2972,
we are calling Parser::isTypeIdInParens() which when using C will return true 
if it's a type specifier,
which is not the case for the auto keyword.

A, that makes a lot of sense!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-27 Thread Guillot Tony via Phabricator via cfe-commits
to268 added a comment.

Here are all the details that i've said earlier




Comment at: clang/lib/Parse/ParseExpr.cpp:1515
+// This is a temporary fix while we don't support C2x 6.5.2.5p4
+if (getLangOpts().C2x && GetLookAheadToken(2).getKind() == tok::l_brace) {
+  Diag(Tok, diag::err_c2x_auto_compound_literal_not_allowed);

aaron.ballman wrote:
> Why would this not be handled from `Sema::ActOnCompoundLiteral()`?
You're right, it's better to handle this in `Sema::ActOnCompoundLiteral()`
The problem is that right now, the usage of the `auto` keyword in a compound 
literal isn't parsed as a compound literal. 
This compound literal is unable to reach `Sema::ActOnCompoundLiteral()` because 
the parser emits that it's an invalid expression.

To summarize, i'm unable to handle handle a compound literal that uses the 
`auto` keyword inside `Sema::ActOnCompoundLiteral()`
if it's never going to be called.
```
int test_ncl = (int){12};   // Parsed as a CL
auto test_cl = (auto){12};  // Not parsed as a CL and emits "expected 
expression"
/*
 * |-DeclStmt 0x562180ede8b0 
 * | `-VarDecl 0x562180ede730  col:9 test_ncl 'int' cinit
 * |   `-ImplicitCastExpr 0x562180ede898  'int' 
 * | `-CompoundLiteralExpr 0x562180ede870  'int' lvalue
 * |   `-InitListExpr 0x562180ede828  'int'
 * | `-IntegerLiteral 0x562180ede7b0  'int' 12
 * |-DeclStmt 0x562180ede970 
 * | `-VarDecl 0x562180ede908  col:10 invalid test_cl 'auto'
 * `-ReturnStmt 0x562180ede9a8 
 *   `-IntegerLiteral 0x562180ede988  'int' 0
 */
```



Comment at: clang/lib/Parse/ParseExpr.cpp:1515
+// This is a temporary fix while we don't support C2x 6.5.2.5p4
+if (getLangOpts().C2x && GetLookAheadToken(2).getKind() == tok::l_brace) {
+  Diag(Tok, diag::err_c2x_auto_compound_literal_not_allowed);

to268 wrote:
> aaron.ballman wrote:
> > Why would this not be handled from `Sema::ActOnCompoundLiteral()`?
> You're right, it's better to handle this in `Sema::ActOnCompoundLiteral()`
> The problem is that right now, the usage of the `auto` keyword in a compound 
> literal isn't parsed as a compound literal. 
> This compound literal is unable to reach `Sema::ActOnCompoundLiteral()` 
> because the parser emits that it's an invalid expression.
> 
> To summarize, i'm unable to handle handle a compound literal that uses the 
> `auto` keyword inside `Sema::ActOnCompoundLiteral()`
> if it's never going to be called.
> ```
> int test_ncl = (int){12};   // Parsed as a CL
> auto test_cl = (auto){12};  // Not parsed as a CL and emits "expected 
> expression"
> /*
>  * |-DeclStmt 0x562180ede8b0 
>  * | `-VarDecl 0x562180ede730  col:9 test_ncl 'int' cinit
>  * |   `-ImplicitCastExpr 0x562180ede898  'int' 
> 
>  * | `-CompoundLiteralExpr 0x562180ede870  'int' lvalue
>  * |   `-InitListExpr 0x562180ede828  'int'
>  * | `-IntegerLiteral 0x562180ede7b0  'int' 12
>  * |-DeclStmt 0x562180ede970 
>  * | `-VarDecl 0x562180ede908  col:10 invalid test_cl 'auto'
>  * `-ReturnStmt 0x562180ede9a8 
>  *   `-IntegerLiteral 0x562180ede988  'int' 0
>  */
> ```
When we are parsing an expression between parentheses in 
`Parser::ParseParenExpression()` line 2972,
we are calling `Parser::isTypeIdInParens()` which when using C will return 
`true` if it's a type specifier,
which is not the case for the `auto` keyword.

Ultimately, we fall into the conditional block of 
`Parser::ParseParenExpression()` line 3191,
which will return an `ExprError()` (AKA: a parsing error).

This is why we are unable to forbid a compound literal using the `auto` keyword 
at the 
Semantic Analysis stage and why this feature is not working out of the box in 
the first place.



Comment at: clang/test/C/C2x/n3007.c:7
+void test_qualifiers(int x, const int y) {
+  // TODO: prohibit cont auto
+  const auto a = x;

aaron.ballman wrote:
> Why? My reading of the grammar is that `const auto` is valid. `const` is a 
> type-specifier-qualifier declaration-specifier, and `auto` is a 
> storage-class-specifier declaration-specifier, and a declaration is allowed 
> to use a sequence of declaration-specifiers.
It's a mistake, i don't remember why i've added this comment in the first place 
and i've forgot his existence


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-27 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 463415.
to268 marked 3 inline comments as done.
to268 added a comment.

I've fixed the diagnostic message and all of the bad TODOs comments from the 
Sema test.
I've explained in details why i'm only able to handle `auto` in compound 
literals.

In D133289#3784117 , @aaron.ballman 
wrote:

> One thought that occurred to me is that the way C has this specified is 
> awfully effectively the same way implicit int worked. It may be worth 
> exploring a change to our implicit int functionality to instead generate an 
> implicit `auto` type when in C2x mode.

That's something is was trying to do a few weeks earlier, so i'll work on that 
too.

In D133289#3784117 , @aaron.ballman 
wrote:

> I've been thinking about this more and I'm starting to make myself a bit 
> uncomfortable with the current approach, at least in terms of how we're 
> handling it on the parsing side of things. I think it's reasonable for us to 
> form an `AutoType` when we eventually get down to forming the type. But I'm 
> uncomfortable with not modeling the language when parsing. e.g., I think we 
> want to parse `auto` as a storage class specifier rather than a type 
> specifier, and we want to rely on the lack of a type specifier coupled with 
> use of `auto` as a storage class specifier to determine the situations where 
> we want to infer a type. The resulting semantics should be basically 
> equivalent, but this ensures that we're properly parsing as the language 
> expects which helps us be forwards-compatible with future changes in C that 
> build on top of this being a storage class specifier rather than a type.

I agree, that's a better approach to design it like that, i'll change my 
approach when i'll be able to generate an implicit `auto`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1193,7 +1193,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{'auto' is not allowed in a compound literal}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
+
+void test_scopes(void) {
+  {
+auto a = 7;
+auto b = 9;
+auto c = a + b;
+  }
+  {
+auto d = a * b;   // expected-error {{use of undeclared identifier 'a'}} \
+ expected-error {{use of undeclared identifier 'b'}}
+{
+  auto e = d + c; // expected-error {{use of undeclared identifier 'c'}}
+}
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-21 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added inline comments.



Comment at: clang/test/Sema/c2x-auto.c:49
+auto b = 9;
+auto c = a + b;
+  }

aaron.ballman wrote:
> to268 wrote:
> > shafik wrote:
> > > When I made the comment about the example from the proposal, this was 
> > > what I was thinking about.
> > Do i need to treat shadowing when using `auto` as invalid?
> You shouldn't need to do anything special there, I think. It should naturally 
> fall out that you cannot use a variable in its own initialization. Note, you 
> don't even need an inner scope for that: https://godbolt.org/z/EYa3fMxqx 
> (example is compiled in C++ mode).
The scope of the identifier begins after its `declarator` so `a` is being used 
in it's own deduction which can not be.

e.g.

```
  double a = 1.0;
{
int a = a*a; // undefined behavior a is used uninitialized within it's 
own initialization
}
```



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-21 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added reviewers: sammccall, rjmccall, efriedma.
aaron.ballman added a comment.

In D133289#3784117 , @aaron.ballman 
wrote:

> One thought that occurred to me is that the way C has this specified is 
> awfully effectively the same way implicit int worked. It may be worth 
> exploring a change to our implicit int functionality to instead generate an 
> implicit `auto` type when in C2x mode.

I've been thinking about this more and I'm starting to make myself a bit 
uncomfortable with the current approach, at least in terms of how we're 
handling it on the parsing side of things. I think it's reasonable for us to 
form an `AutoType` when we eventually get down to forming the type. But I'm 
uncomfortable with not modeling the language when parsing. e.g., I think we 
want to parse `auto` as a storage class specifier rather than a type specifier, 
and we want to rely on the lack of a type specifier coupled with use of `auto` 
as a storage class specifier to determine the situations where we want to infer 
a type. The resulting semantics should be basically equivalent, but this 
ensures that we're properly parsing as the language expects which helps us be 
forwards-compatible with future changes in C that build on top of this being a 
storage class specifier rather than a type.

Adding a few more reviewers for some extra opinions on this.




Comment at: clang/include/clang/Basic/DiagnosticParseKinds.td:374
+def err_c2x_auto_compound_literal_not_allowed: Error<
+  "'auto' is not allowed in compound litterals">;
 def ext_auto_type : Extension<





Comment at: clang/lib/Parse/ParseExpr.cpp:1515
+// This is a temporary fix while we don't support C2x 6.5.2.5p4
+if (getLangOpts().C2x && GetLookAheadToken(2).getKind() == tok::l_brace) {
+  Diag(Tok, diag::err_c2x_auto_compound_literal_not_allowed);

Why would this not be handled from `Sema::ActOnCompoundLiteral()`?



Comment at: clang/test/C/C2x/n3007.c:7
+void test_qualifiers(int x, const int y) {
+  // TODO: prohibit cont auto
+  const auto a = x;

Why? My reading of the grammar is that `const auto` is valid. `const` is a 
type-specifier-qualifier declaration-specifier, and `auto` is a 
storage-class-specifier declaration-specifier, and a declaration is allowed to 
use a sequence of declaration-specifiers.



Comment at: clang/test/C/C2x/n3007.c:15
+
+  // TODO: prohibit cont auto
+  const int ci = 12;





Comment at: clang/test/Sema/c2x-auto.c:49
+auto b = 9;
+auto c = a + b;
+  }

to268 wrote:
> shafik wrote:
> > When I made the comment about the example from the proposal, this was what 
> > I was thinking about.
> Do i need to treat shadowing when using `auto` as invalid?
You shouldn't need to do anything special there, I think. It should naturally 
fall out that you cannot use a variable in its own initialization. Note, you 
don't even need an inner scope for that: https://godbolt.org/z/EYa3fMxqx 
(example is compiled in C++ mode).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-20 Thread Guillot Tony via Phabricator via cfe-commits
to268 added a comment.

Also i have found that we don't parse the compound literal with the `auto` 
keyword correctly in `ParseExpr.cpp` between line 939 to 973 which is the 
beginning of `Parser::ParseCastExpression(...)`

  int test_cl = (int){12};  // Compound literal is detected
  auto test_cl2 = (auto){12};   // Compound literal is not detected

I've haven't dig deeper yet but maybe it's because we are not including `auto` 
when trying to guess if it's a compound literal due to the fact that `auto` is 
a `storage-class-specifier`




Comment at: clang/test/Sema/c2x-auto.c:49
+auto b = 9;
+auto c = a + b;
+  }

shafik wrote:
> When I made the comment about the example from the proposal, this was what I 
> was thinking about.
Do i need to treat shadowing when using `auto` as invalid?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-20 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 461790.
to268 marked 2 inline comments as done.
to268 added a comment.

I've added more test cases, added a diagnostic when using `auto` in compound 
literals and advised fixes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2x/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1193,7 +1193,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Clang 16
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_sizeof_typeof(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  typeof(auto) tpof = 4;  // expected-error {{expected expression}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+
+  // FIXME: This should be accepted per C2x 6.5.2.5p4
+  auto auto_cl = (auto){13};  // expected-error {{'auto' is not allowed in compound litterals}}
+
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
+
+void test_scopes(void) {
+  {
+auto a = 7;
+auto b = 9;
+auto c = a + b;
+  }
+  {
+auto d = a * b;   // expected-error {{use of undeclared identifier 'a'}} \
+ expected-error {{use of undeclared identifier 'b'}}
+{
+  auto e = d + c; // expected-error {{use of undeclared identifier 'c'}}
+}
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,123 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+auto b;   // c2x-error {{'auto' not allowed in struct member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+union {
+  char c;
+  auto smth;  // c2x-error {{'auto' not allowed in union member}} \
+ c17-error {{type name does not allow storage class to be specified}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto basic_usage(auto auto) {   // c2x-error {{'auto' not allowed in function prototype}} \
+   c2x-error {{'auto' not allowed in function return type}} \
+   c2x-error {{cannot combine with previous 'auto' declaration specifier}} \
+   c17-error {{invalid storage class specifier in function declarator}} \
+   c17-error {{illegal storage class on function}} \
+   c17-warning {{duplicate 'auto' declaration specifier}} \
+   c17-warning {{omitting the parameter name in a function definition is a C2x extension}} \
+   c17-error 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-14 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In D133289#3788655 , @to268 wrote:

> In D133289#3784042 , @aaron.ballman 
> wrote:
>
>>   auto auto k = 12; // 99% this is intended to be accepted; first `auto` is 
>> the storage class specifier, second `auto` is a redundant storage class 
>> specifier
>
> It seems that specifying `auto` twice isn't supported at the time being, so i 
> think i should fix that too.
>
>   auto auto test = 12; // error: cannot combine with previous 'auto' 
> declaration specifier

Yup! I just learned yesterday that the error there is correct and intended, at 
least according to the author of WG N3007.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-13 Thread Guillot Tony via Phabricator via cfe-commits
to268 marked 6 inline comments as done.
to268 added a comment.

In D133289#3784042 , @aaron.ballman 
wrote:

>   auto auto k = 12; // 99% this is intended to be accepted; first `auto` is 
> the storage class specifier, second `auto` is a redundant storage class 
> specifier

It seems that specifying `auto` twice isn't supported at the time being

  auto auto test = 12; // error: cannot combine with previous 'auto' 
declaration specifier




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

One thought that occurred to me is that the way C has this specified is awfully 
effectively the same way implicit int worked. It may be worth exploring a 
change to our implicit int functionality to instead generate an implicit `auto` 
type when in C2x mode.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

FYI: regarding `auto auto`, I've heard back from the author of N3007 and the 
intent was to disallow this construct ("others" was meant to exclude `auto` and 
"except typedef" was meant to add onto the list of exclusions).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-12 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added inline comments.



Comment at: clang/test/Sema/c2x-auto.c:49
+auto b = 9;
+auto c = a + b;
+  }

When I made the comment about the example from the proposal, this was what I 
was thinking about.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

This is awesome, thank you for working on it! @to268 and I had a really good 
discussion during my office hours and what we decided for next steps were:

0) Next time you upload a patch, please use `-U` to give the patch more 
context for reviewers to see.

1. Need to handle function pointers: `auto (*)(void)` and `void (*)(auto)` 
should both be rejected - you may want to consider adding logic to 
`Sema::BuildPointerType()` to semantically restrict forming such a function 
pointer type.
2. Need a ton of random tests:

  auto file_scope_1 = 12;
  // This  be something we accept because the redundant storage class 
specifier is not
  // specifying automatic storage duration due to the lack of a type specifier, 
or we might reject
  // because of the redundant storage class specifier. I have a question out to 
the author to clarify.
  auto auto file_scope_2 = 12;
  
  void func(void) {
int i;
_Generic(i, auto : 0); // Should reject auto in an association
_Alignof(auto); // Should also reject
_Alignas(auto); // Should also reject
  
  
auto j = ({ auto x = 12; x; }); // Should work, x and j should both be int
auto auto k = 12; // 99% this is intended to be accepted; first `auto` is 
the storage class specifier, second `auto` is a redundant storage class 
specifier
  
const int ci = 12;
auto yup = ci;
yup = 12; // Okay, the type of yup is int, not const int
  
_Atomic(auto) atom1 = 12; // Should reject, asking WG14 about it
_Atomic auto atom2 = 12; // Should also reject
  }
  `

It's worth noting that `auto` in C is a very, very strange beast. It's a 
storage-class-specifier, not a type-name. If there's a storage class specifier 
and NO TYPE NAME, then the type is inferred. So grammar productions that use 
type-name without also using `storage-class-specifier` should reject any use of 
`auto` because that's not a valid type name.




Comment at: clang/test/C/C2X/n3007.c:6
+ */
+#include 
+

Rather than include the system header, you should use `_Alignas` and `_Alignof` 
spellings.



Comment at: clang/test/C/C2X/n3007.c:45
+  struct B { auto b; };   // expected-error {{'auto' not allowed in struct 
member}}
+  typedef auto auto_type; // expected-error {{'auto' not allowed in typedef}}
+}

Heh, this doesn't have much to do with structs. :-)



Comment at: clang/test/C/C2X/n3007.c:50
+  auto test_char = 'A';
+  auto test_char_ptr = "test";
+  auto something; // expected-error {{declaration of variable 'something' with 
deduced type 'auto' requires an initializer}}

An additional tests here that's interesting is:
```
_Static_assert(_Generic(test_char_ptr, const char * : 1, char * : 2) == 2, "C 
is weird");
```



Comment at: clang/test/Parser/c2x-auto.c:9
+int a;
+int b;
+union {

Should also test a structure member just to have the coverage.



Comment at: clang/test/Sema/c2x-auto.c:3
+
+#include 
+

Same suggestion here as above.



Comment at: clang/test/Sema/c2x-auto.c:11-20
+void test_structs(void) {
+  struct s_auto { auto a; };  // expected-error {{'auto' not allowed in 
struct member}}
+  auto s_int = (struct { int a; } *)0;
+  typedef auto auto_type; // expected-error {{'auto' not allowed in 
typedef}}
+}
+
+void test_sizeof_alignas(void) {

This seems to be duplicated from the parser tests -- there is only a need to 
test this once (and in each of these cases it seems to be a parsing 
restriction, so the tests should live in Parser).



Comment at: clang/test/Sema/c2x-auto.c:32
+  auto double_cl = (double){2.5};
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 
'auto'}}

This should have a FIXME comment -- we should produce a better diagnostic here. 
That we give an error is correct though!

C2x 6.5.2.5p4 specifies that compound literal is rewritten as if it were a 
declaration: `SC typeof(T) ID = { IL };` (where SC is the storage class, T is 
the type, ID is a program-wide unique ID, and IL is the initializer list).

C2x 6.7.2.5p1 only allows `typeof` on an `expression` or a `type-name`, and 
`type-name` does not include `auto` as an option.

So the rewrite makes this invalid.



Comment at: clang/www/c_status.html:1196
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Yes
 

This should use class `unreleased` and specify `Clang 16` instead of `Yes` 
("Yes" basically means "we have no idea when we started supporting something, 
we've probably supported this forever")


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-07 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

In D133289#3773708 , @to268 wrote:

> Also @aaron.ballman said me that he was thinking about maybe adding an 
> extension to add support for `auto` in a function return or in a parameter 
> list.

I think extensions are best left to a separate pr, if at all.
Supporting deduced return type sounds fine, with a warning.
Supporting auto template parameters... Not so much, as it would in effect bring 
function templates, overloading and mangling into C... I don't think we want to 
go there.

I think we should consider supporting auto in older language modes though.

Or at least, improving the diagnostics for auto in older language modes.

> type specifier missing, defaults to 'int'.

The probability that someone tries to use auto as a storage specifier and want 
an implicit int at the same time is about 0.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-06 Thread Guillot Tony via Phabricator via cfe-commits
to268 added a comment.

Also @aaron.ballman said me that he was thinking about maybe adding an 
extension to add support for `auto` in a function return or in a parameter list.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-06 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 458358.
to268 added a comment.

I've added a test case with scopes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2X/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1193,7 +1193,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Yes
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+#include 
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_structs(void) {
+  struct s_auto { auto a; };  // expected-error {{'auto' not allowed in struct member}}
+  auto s_int = (struct { int a; } *)0;
+  typedef auto auto_type; // expected-error {{'auto' not allowed in typedef}}
+}
+
+void test_sizeof_alignas(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  alignas(4) auto b[4];   // expected-error {{'b' declared as array of 'auto'}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
+
+void test_scopes(void) {
+  {
+auto a = 7;
+auto b = 9;
+auto c = a + b;
+  }
+  {
+auto d = a * b;   // expected-error {{use of undeclared identifier 'a'}} \
+ expected-error {{use of undeclared identifier 'b'}}
+{
+  auto e = d + c; // expected-error {{use of undeclared identifier 'c'}}
+}
+  }
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+int b;
+union {
+  char c;
+  auto smth; // c2x-error {{'auto' not allowed in union member}} \
+c17-error {{type name does not allow storage class to be specified}} \
+c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto auto_usage(auto auto) {  // c2x-error {{'auto' not allowed in function prototype}} \
+ c2x-error {{'auto' not allowed in function return type}} \
+ c2x-error {{cannot combine with previous 'auto' declaration specifier}} \
+ c17-error {{invalid storage class specifier in function declarator}} \
+ c17-error {{illegal storage class on function}} \
+ c17-warning {{duplicate 'auto' declaration specifier}} \
+ c17-warning {{omitting the parameter name in a function definition is a C2x extension}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+
+  auto = 4;   // expected-error {{expected 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-06 Thread Shafik Yaghmour via Phabricator via cfe-commits
shafik added a comment.

The proposal has several nice tests and I don't they are all covered here e.g.:

  {
double a = 7;
double b = 9;
{
  double b = b * b;   // undefined, uses uninitialized variable without 
address


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-05 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 458092.
to268 added a comment.

Fixed `DeclSpec.cpp` formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2X/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1193,7 +1193,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Yes
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+#include 
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_structs(void) {
+  struct s_auto { auto a; };  // expected-error {{'auto' not allowed in struct member}}
+  auto s_int = (struct { int a; } *)0;
+  typedef auto auto_type; // expected-error {{'auto' not allowed in typedef}}
+}
+
+void test_sizeof_alignas(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  alignas(4) auto b[4];   // expected-error {{'b' declared as array of 'auto'}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+int b;
+union {
+  char c;
+  auto smth; // c2x-error {{'auto' not allowed in union member}} \
+c17-error {{type name does not allow storage class to be specified}} \
+c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto auto_usage(auto auto) {  // c2x-error {{'auto' not allowed in function prototype}} \
+ c2x-error {{'auto' not allowed in function return type}} \
+ c2x-error {{cannot combine with previous 'auto' declaration specifier}} \
+ c17-error {{invalid storage class specifier in function declarator}} \
+ c17-error {{illegal storage class on function}} \
+ c17-warning {{duplicate 'auto' declaration specifier}} \
+ c17-warning {{omitting the parameter name in a function definition is a C2x extension}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+
+  auto = 4;   // expected-error {{expected identifier or '('}}
+
+  auto a = 4; // c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+
+  auto b[4];  // c2x-error {{'b' declared as array of 'auto'}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support 

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-05 Thread Guillot Tony via Phabricator via cfe-commits
to268 updated this revision to Diff 458089.
to268 added a comment.

I have fixed my CodeGen test with the windows platform.
(Linux uses an i64 for the long type instead windows is using an i32)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D133289/new/

https://reviews.llvm.org/D133289

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2X/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1193,7 +1193,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Yes
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+#include 
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_structs(void) {
+  struct s_auto { auto a; };  // expected-error {{'auto' not allowed in struct member}}
+  auto s_int = (struct { int a; } *)0;
+  typedef auto auto_type; // expected-error {{'auto' not allowed in typedef}}
+}
+
+void test_sizeof_alignas(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  alignas(4) auto b[4];   // expected-error {{'b' declared as array of 'auto'}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+int b;
+union {
+  char c;
+  auto smth; // c2x-error {{'auto' not allowed in union member}} \
+c17-error {{type name does not allow storage class to be specified}} \
+c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto auto_usage(auto auto) {  // c2x-error {{'auto' not allowed in function prototype}} \
+ c2x-error {{'auto' not allowed in function return type}} \
+ c2x-error {{cannot combine with previous 'auto' declaration specifier}} \
+ c17-error {{invalid storage class specifier in function declarator}} \
+ c17-error {{illegal storage class on function}} \
+ c17-warning {{duplicate 'auto' declaration specifier}} \
+ c17-warning {{omitting the parameter name in a function definition is a C2x extension}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+
+  auto = 4;   // expected-error {{expected identifier or '('}}
+
+  auto a = 4; // c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+
+  auto b[4];  // c2x-error {{'b' declared as array of 'auto'}} \
+

[PATCH] D133289: [C2X] N3007 Type inference for object definitions

2022-09-05 Thread Guillot Tony via Phabricator via cfe-commits
to268 created this revision.
to268 added reviewers: aaron.ballman, clang-language-wg, jyknight.
Herald added a project: All.
to268 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This patches implements the `auto` keyword from the N3007 
 standard 
specification.
This allows deducing the type of the variable like in C++

  auto nb = 1;
  auto chr = 'A';
  auto str = "String";


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133289

Files:
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/test/C/C2X/n3007.c
  clang/test/CodeGen/auto.c
  clang/test/Parser/c2x-auto.c
  clang/test/Sema/c2x-auto.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -1193,7 +1193,7 @@
 
   Type inference for object declarations
   https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3007.htm;>N3007
-  No
+  Yes
 
 
   constexpr for object definitions
Index: clang/test/Sema/c2x-auto.c
===
--- /dev/null
+++ clang/test/Sema/c2x-auto.c
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c2x %s
+
+#include 
+
+void test_basic_types(void) {
+  auto undefined; // expected-error {{declaration of variable 'undefined' with deduced type 'auto' requires an initializer}}
+  auto auto_int = 4;
+  auto auto_long = 4UL;
+}
+
+void test_structs(void) {
+  struct s_auto { auto a; };  // expected-error {{'auto' not allowed in struct member}}
+  auto s_int = (struct { int a; } *)0;
+  typedef auto auto_type; // expected-error {{'auto' not allowed in typedef}}
+}
+
+void test_sizeof_alignas(void) {
+  auto auto_size = sizeof(auto);  // expected-error {{expected expression}}
+  alignas(4) auto b[4];   // expected-error {{'b' declared as array of 'auto'}}
+}
+
+void test_casts(void) {
+  auto int_cast = (int)(4 + 3);
+  auto double_cast = (double)(1 / 3);
+  auto long_cast = (long)(4UL + 3UL);
+  auto auto_cast = (auto)(4 + 3); // expected-error {{expected expression}}
+}
+
+void test_compound_literral(void) {
+  auto int_cl = (int){13};
+  auto double_cl = (double){2.5};
+  auto auto_cl = (auto){13};  // expected-error {{expected expression}}
+  auto array[] = { 1, 2, 3 }; // expected-error {{'array' declared as array of 'auto'}}
+}
+
+void test_qualifiers(int x, const int y) {
+  const auto a = x;
+  auto b = y;
+  static auto c = 1UL;
+  int* pa =  // expected-warning {{initializing 'int *' with an expression of type 'const int *' discards qualifiers}}
+  const int* pb = 
+  int* pc =  // expected-warning {{incompatible pointer types initializing 'int *' with an expression of type 'unsigned long *'}}
+}
Index: clang/test/Parser/c2x-auto.c
===
--- /dev/null
+++ clang/test/Parser/c2x-auto.c
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c2x -std=c2x %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,c17 -std=c17 %s
+
+#define AUTO_MACRO(_NAME, ARG, ARG2, ARG3) \
+  auto _NAME = ARG + (ARG2 / ARG3);
+
+struct S {
+int a;
+int b;
+union {
+  char c;
+  auto smth; // c2x-error {{'auto' not allowed in union member}} \
+c17-error {{type name does not allow storage class to be specified}} \
+c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+} u;
+};
+
+enum E : auto { // c2x-error {{'auto' not allowed here}} \
+   c17-error {{expected a type}} \
+   c17-error {{type name does not allow storage class to be specified}}
+  One,
+  Two,
+  Tree,
+};
+
+auto auto_usage(auto auto) {  // c2x-error {{'auto' not allowed in function prototype}} \
+ c2x-error {{'auto' not allowed in function return type}} \
+ c2x-error {{cannot combine with previous 'auto' declaration specifier}} \
+ c17-error {{invalid storage class specifier in function declarator}} \
+ c17-error {{illegal storage class on function}} \
+ c17-warning {{duplicate 'auto' declaration specifier}} \
+ c17-warning {{omitting the parameter name in a function definition is a C2x extension}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} \
+ c17-error {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}}
+
+  auto = 4;   // expected-error {{expected identifier or '('}}
+
+  auto a = 4;