[openmp] [lldb] [llvm] [libcxx] [libc] [clang-tools-extra] [compiler-rt] [lld] [flang] [libcxxabi] [clang] [mlir] [libunwind] [C23] Implement N3018: The constexpr specifier for object definitions (PR

2023-12-11 Thread Guillot Tony via cfe-commits


@@ -0,0 +1,287 @@
+// RUN: %clang_cc1 -std=c2x -verify -triple x86_64 -pedantic -Wno-conversion 
-Wno-constant-conversion -Wno-div-by-zero %s
+
+// Check that constexpr only applies to variables.
+constexpr void f0() {} // expected-error {{'constexpr' can only be used in 
variable declarations}}
+constexpr const int f1() { return 0; } // expected-error {{'constexpr' can 
only be used in variable declarations}}
+
+constexpr struct S1 { int f; }; //expected-error {{struct cannot be marked 
constexpr}}
+constexpr struct S2 ; // expected-error {{struct cannot be marked constexpr}}
+constexpr union U1; // expected-error {{union cannot be marked constexpr}}
+constexpr union U2 {int a; float b;}; // expected-error {{union cannot be 
marked constexpr}}
+constexpr enum E1 {A = 1, B = 2} ; // expected-error {{enum cannot be marked 
constexpr}}
+struct S3 {
+  static constexpr int f = 0; // expected-error {{type name does not allow 
storage class}}
+  // expected-error@-1 {{type name does not allow constexpr}}
+  // expected-error@-2 {{expected ';' at end}}
+  constexpr int f1 = 0;
+  // expected-error@-1 {{type name does not allow constexpr}}
+  // expected-error@-2 {{expected ';' at end}}
+};
+
+constexpr; // expected-error {{'constexpr' can only be used in variable 
declarations}}
+constexpr int V1 = 3;
+constexpr float V2 = 7.0;
+int V3 = (constexpr)3; // expected-error {{expected expression}}
+
+void f2() {
+  constexpr int a = 0;
+  constexpr float b = 1.7f;
+}
+
+// Check how constexpr works with other storage-class specifiers.
+constexpr auto V4 = 1;
+constexpr static auto V5 = 1;
+constexpr static const auto V6 = 1;
+constexpr static const int V7 = 1;
+constexpr static int V8 = 1;

to268 wrote:

I would preferably suggest to add a couple of `constexpr auto` tests, theses 
cases bellow should be enough to make sure that no divergence has been 
introduced.
```c
constexpr auto Ulong = 1L;
constexpr auto CompoundLiterral = (int){13};
constexpr auto DoubleCast = (double)(1 / 3);
constexpr auto String = "this is a string";
constexpr signed auto Long = 1L; // expected-error {{'auto' cannot be signed or 
unsigned}}
```

Adding some `_Static_assert` would be better to also make sure that the `auto` 
keyword is on par when adding the `constexpr` keyword.
```c
_Static_assert(_Generic(Ulong, long : 1));
_Static_assert(_Generic(CompoundLiterral, int : 1));
_Static_assert(_Generic(DoubleCast, double : 1));
_Static_assert(_Generic(String, char* : 1));
```

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[mlir] [libc] [lld] [libcxxabi] [compiler-rt] [lldb] [llvm] [clang-tools-extra] [libunwind] [libcxx] [clang] [openmp] [flang] [C23] Implement N3018: The constexpr specifier for object definitions (PR

2023-12-11 Thread Guillot Tony via cfe-commits

to268 wrote:

I have found no major issues with the C23 `auto` keyword.
There is a minor improvement that I've found in the test cases.

Concerning N3006 (AKA: Underspecified object declarations), I haven't reviewed 
yet the compatibility with the `constexpr` keyword, since I haven't work much 
on it yet.  
 

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

2023-11-22 Thread Guillot Tony via cfe-commits

to268 wrote:

That's probably because I have still not commit access, but I'll take a look.

https://github.com/llvm/llvm-project/pull/73099
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-03-18 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From f463907db6a68422c2f28d08593ab21e42c6a497 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Mon, 29 Jan 2024 15:14:32 +0100
Subject: [PATCH 1/3] Implementation base of N3006 Underspecified object
 declarations

---
 clang/docs/ReleaseNotes.rst   |  3 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/Sema/SemaExpr.cpp   | 27 +++
 clang/test/C/C2x/n3006.c  | 27 +++
 clang/test/Parser/c2x-underspecified-decls.c  | 12 +
 clang/www/c_status.html   |  2 +-
 6 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/C/C2x/n3006.c
 create mode 100644 clang/test/Parser/c2x-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 125d51c42d507f..3b4a9291b6f7f0 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -163,6 +163,9 @@ C23 Feature Support
 - Clang now supports `N3018 The constexpr specifier for object definitions`
   `_.
 
+- Clang now diagnoses `N3006 Underspecified object declarations
+  `_.
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8e97902564af08..b336b5f63367c1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7685,6 +7685,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8725b09f8546cf..6395690e0edeb9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7813,6 +7813,33 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
diag::err_variable_object_no_init))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(),
+   diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind()
+  << Tag->getDecl()->getName() << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
  RequireCompleteType(LParenLoc, literalType,
diag::err_typecheck_decl_incomplete_type,
diff --git a/clang/test/C/C2x/n3006.c b/clang/test/C/C2x/n3006.c
new file mode 100644
index 00..15efc0ccd6d323
--- /dev/null
+++ b/clang/test/C/C2x/n3006.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous definition is 
here}}
+union U1 { int a; double b; };  // expected-note {{previous definition is 
here}}
+enum E1 { FOO, BAR };   // expected-note {{previous definition is 
here}}
+
+auto normal_struct = (struct S1){ 1, 2 };
+auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 };   // 
expected-error {{'struct S2' is defined as an underspecified object 
initializer}}
+auto underspecified_struct_redef = (

[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-03-18 Thread Guillot Tony via cfe-commits

to268 wrote:

I have rebased my PR to include N3018 constexpr feature and reverted a 
formatted snippet of code that is not part of the PR.
I will add constexpr tests but I need to investigate why the constexpr keyword 
does not trigger the diagnostic (not sure if it's a constexpr implementation 
bug or something I need to handle in my PR (it does not really matter TBO)).

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-02-05 Thread Guillot Tony via cfe-commits

to268 wrote:

Ping: @AaronBallman 

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-01-29 Thread Guillot Tony via cfe-commits

https://github.com/to268 created https://github.com/llvm/llvm-project/pull/79845

The N3006 Underspecified object declarations paper describes that 
underspecified declarations should be diagnosed as an error.
Example snippet:
```c
struct S1 { int x, y; };
union U1 { int a; double b; };
enum E1 { FOO, BAR };

auto valid_struct = (struct S1){ 1, 2 };
auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 }; // Error

auto valid_union = (union U1){ .a = 12 };
auto underspecified_union = (union U2 { int a; double b; }){ .a = 34 }; // Error

auto valid_enum = (enum E1){ FOO };
auto underspecified_enum = (enum E2 { BAZ, QUX }){ BAZ }; // Error
```

>From fe082a252d7290730f39228736d93eeea992e041 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Mon, 29 Jan 2024 15:14:32 +0100
Subject: [PATCH] Implementation base of N3006 Underspecified object
 declarations

---
 clang/docs/ReleaseNotes.rst   |  3 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/Sema/SemaExpr.cpp   | 27 +++
 clang/test/C/C2x/n3006.c  | 27 +++
 clang/test/Parser/c2x-underspecified-decls.c  | 12 +
 clang/www/c_status.html   |  2 +-
 6 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/C/C2x/n3006.c
 create mode 100644 clang/test/Parser/c2x-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 254e0a9cb72979d..65885968204a64d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -83,6 +83,9 @@ C Language Changes
 C23 Feature Support
 ^^^
 
+- Clang now diagnoses `N3006 Underspecified object declarations
+  `_.
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 24d32cb87c89e24..8508208a3acedd9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7639,6 +7639,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2f1ddfb215116d0..8166748c38e6e98 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7805,6 +7805,33 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
diag::err_variable_object_no_init))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(),
+   diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind()
+  << Tag->getDecl()->getName() << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
  RequireCompleteType(LParenLoc, literalType,
diag::err_typecheck_decl_incomplete_type,
diff --git a/clang/test/C/C2x/n3006.c b/clang/test/C/C2x/n3006.c
new file mode 100644
index 000..15efc0ccd6d323c
--- /dev/null
+++ b/clang/test/C/C2x/n3006.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x

[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-01-29 Thread Guillot Tony via cfe-commits


@@ -7639,6 +7639,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;

to268 wrote:

I think that the diagnostic message need to be corrected.

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-01-29 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From fe082a252d7290730f39228736d93eeea992e041 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Mon, 29 Jan 2024 15:14:32 +0100
Subject: [PATCH 1/2] Implementation base of N3006 Underspecified object
 declarations

---
 clang/docs/ReleaseNotes.rst   |  3 +++
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/Sema/SemaExpr.cpp   | 27 +++
 clang/test/C/C2x/n3006.c  | 27 +++
 clang/test/Parser/c2x-underspecified-decls.c  | 12 +
 clang/www/c_status.html   |  2 +-
 6 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/C/C2x/n3006.c
 create mode 100644 clang/test/Parser/c2x-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 254e0a9cb72979..65885968204a64 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -83,6 +83,9 @@ C Language Changes
 C23 Feature Support
 ^^^
 
+- Clang now diagnoses `N3006 Underspecified object declarations
+  `_.
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 24d32cb87c89e2..8508208a3acedd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7639,6 +7639,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2f1ddfb215116d..8166748c38e6e9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7805,6 +7805,33 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
diag::err_variable_object_no_init))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(),
+   diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind()
+  << Tag->getDecl()->getName() << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
  RequireCompleteType(LParenLoc, literalType,
diag::err_typecheck_decl_incomplete_type,
diff --git a/clang/test/C/C2x/n3006.c b/clang/test/C/C2x/n3006.c
new file mode 100644
index 00..15efc0ccd6d323
--- /dev/null
+++ b/clang/test/C/C2x/n3006.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous definition is 
here}}
+union U1 { int a; double b; };  // expected-note {{previous definition is 
here}}
+enum E1 { FOO, BAR };   // expected-note {{previous definition is 
here}}
+
+auto normal_struct = (struct S1){ 1, 2 };
+auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 };   // 
expected-error {{'struct S2' is defined as an underspecified object 
initializer}}
+auto underspecified_struct_redef = (struct S1 { char x, y; }){ 'A', 'B'}; // 
expected-error {{redefinition of 'S1'}}
+auto underspecified_em

[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-01-29 Thread Guillot Tony via cfe-commits

to268 wrote:

CC: @AaronBallman

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-01-29 Thread Guillot Tony via cfe-commits


@@ -7805,10 +7805,38 @@ Sema::BuildCompoundLiteralExpr(SourceLocation 
LParenLoc, TypeSourceInfo *TInfo,
diag::err_variable_object_no_init))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(), 
diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind() << 
Tag->getDecl()->getName()
+  << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
- RequireCompleteType(LParenLoc, literalType,
-   diag::err_typecheck_decl_incomplete_type,
-   SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd(
+ RequireCompleteType(
+ LParenLoc, literalType,
+ diag::err_typecheck_decl_incomplete_type,
+ SourceRange(LParenLoc,
+ LiteralExpr->getSourceRange().getEnd(

to268 wrote:

Yeah, the formatting CI was yelling at me for this.
I'll probably revert this since it's not part of the feature.

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-01-29 Thread Guillot Tony via cfe-commits


@@ -7639,6 +7639,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;

to268 wrote:

I also didn't wanted to just use the same wording as GCC.

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C2x] Remove confusing diagnostic auto storage class specifier in C23 (PR #68710)

2023-10-10 Thread Guillot Tony via cfe-commits

https://github.com/to268 created https://github.com/llvm/llvm-project/pull/68710

When declaring `auto int` at local or file scope, we emit a warning intended 
for C++11 and later, which is incorrect and confusing in C23.
See [Godbolt example](https://godbolt.org/z/j1acGhecd).
Now this diagnostic does not show up in C23.

>From 89dd9eaa7c7d6f3a2a91ccc4f96656f8e0266a07 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Tue, 10 Oct 2023 15:34:55 +0200
Subject: [PATCH] Removed diagnostic auto storage class specifier in C23

---
 clang/lib/Parse/ParseDecl.cpp | 2 +-
 clang/test/C/C2x/n3007.c  | 4 
 clang/test/Sema/c2x-auto.c| 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index bcc70c04dec91ba..14a28e5a31c57db 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -4042,7 +4042,7 @@ void Parser::ParseDeclarationSpecifiers(
 if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
   isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
  PrevSpec, DiagID, Policy);
-  if (!isInvalid)
+  if (!isInvalid && !getLangOpts().C23)
 Diag(Tok, diag::ext_auto_storage_class)
   << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
 } else
diff --git a/clang/test/C/C2x/n3007.c b/clang/test/C/C2x/n3007.c
index 1fd20332ceb4715..34ec419b71b271d 100644
--- a/clang/test/C/C2x/n3007.c
+++ b/clang/test/C/C2x/n3007.c
@@ -3,6 +3,10 @@
 /* WG14 N3007: Yes
  * Type Inference for object definitions
  */
+void test_auto_int(void) {
+  auto int auto_int = 12;
+}
+
 void test_qualifiers(int x, const int y, int * restrict z) {
   const auto a = x;
   auto b = y;
diff --git a/clang/test/Sema/c2x-auto.c b/clang/test/Sema/c2x-auto.c
index 916c179adcf3182..7cbd1db31315aef 100644
--- a/clang/test/Sema/c2x-auto.c
+++ b/clang/test/Sema/c2x-auto.c
@@ -4,6 +4,7 @@ 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;
+  auto int auto_int_ts = 12;
   signed auto a = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
 
   _Static_assert(_Generic(auto_int, int : 1));

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


[clang] [clang][C2x] Remove confusing diagnostic auto storage class specifier (PR #68710)

2023-10-10 Thread Guillot Tony via cfe-commits

https://github.com/to268 edited https://github.com/llvm/llvm-project/pull/68710
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C2x] Remove confusing diagnostic auto storage class specifier (PR #68710)

2023-10-10 Thread Guillot Tony via cfe-commits

to268 wrote:

Can you land this patch on my behalf?
"Guillot Tony "

https://github.com/llvm/llvm-project/pull/68710
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C2x] Remove confusing diagnostic auto storage class specifier (PR #68710)

2023-10-11 Thread Guillot Tony via cfe-commits

to268 wrote:

Nope, I can't
> This branch has no conflicts with the base branch
Only those with [write 
access](https://docs.github.com/articles/what-are-the-different-access-permissions)
 to this repository can merge pull requests.

https://github.com/llvm/llvm-project/pull/68710
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][NFC] Regroup declarations in `Sema` (PR #82217)

2024-02-21 Thread Guillot Tony via cfe-commits

to268 wrote:

FYI: There is currently 26 PRs that impacts `Sema.h`, bellow is the bash one 
liner with GitHub CLI to count the numbers of impacted PRs and another one to 
list links to impacted PRs.

- Count all impacted PRs:
```bash
gh pr list --json files --jq '.[] | {paths: [.files[].path | select(. == 
"clang/include/clang/Sema/Sema.h")]} | select(.paths | length > 0)' -L 3 | 
wc -l
```
- List the link to all impacted PRs:
```bash
gh pr list --json number,files --jq '.[] | select(.files[].path == 
"clang/include/clang/Sema/Sema.h") | {number}' -L 3 | cut -d ':' -f2 | tr 
-d '}' | sed 's|^|https://github.com/llvm/llvm-project/pull/|'
```

https://github.com/llvm/llvm-project/pull/82217
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][NFC] Regroup declarations in `Sema` (PR #82217)

2024-02-21 Thread Guillot Tony via cfe-commits

to268 wrote:

That's because you are filtering only opened PRs, not including drafts PRs.

https://github.com/llvm/llvm-project/pull/82217
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-06-29 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From 44d103f75aef4227262b823fd5168c081307ce23 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Mon, 29 Jan 2024 15:14:32 +0100
Subject: [PATCH 1/4] Implementation base of N3006 Underspecified object
 declarations

---
 clang/docs/ReleaseNotes.rst   |  5 +++-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/Sema/SemaExpr.cpp   | 27 +++
 clang/test/C/C2x/n3006.c  | 27 +++
 clang/test/Parser/c2x-underspecified-decls.c  | 12 +
 clang/www/c_status.html   |  2 +-
 6 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/C/C2x/n3006.c
 create mode 100644 clang/test/Parser/c2x-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index feba3c7ba8d77..70f00844caa2f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -104,7 +104,7 @@ ABI Changes in This Version
   ifuncs. Its purpose was to preserve backwards compatibility when the ".ifunc"
   suffix got removed from the name mangling. The alias interacts badly with
   GlobalOpt (see the issue #96197).
-  
+
 - Fixed Microsoft name mangling for auto non-type template arguments of pointer
   type for MSVC 1920+. This change resolves incompatibilities with code 
compiled
   by MSVC 1920+ but will introduce incompatibilities with code compiled by
@@ -337,6 +337,9 @@ C23 Feature Support
 - Properly promote bit-fields of bit-precise integer types to the field's type
   rather than to ``int``. #GH87641
 
+- Clang now diagnoses `N3006 Underspecified object declarations
+  `_.
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 5dc36c594bcb7..ba19fbe542176 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7781,6 +7781,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index db44cfe1288b6..89af7641e8e6e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7117,6 +7117,33 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
diagID))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(),
+   diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind()
+  << Tag->getDecl()->getName() << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
  RequireCompleteType(LParenLoc, literalType,
diag::err_typecheck_decl_incomplete_type,
diff --git a/clang/test/C/C2x/n3006.c b/clang/test/C/C2x/n3006.c
new file mode 100644
index 0..15efc0ccd6d32
--- /dev/null
+++ b/clang/test/C/C2x/n3006.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous defi

[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-06-29 Thread Guillot Tony via cfe-commits

to268 wrote:

I've rebased the branch from main

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-07-07 Thread Guillot Tony via cfe-commits


@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous definition is 
here}}
+union U1 { int a; double b; };  // expected-note {{previous definition is 
here}}
+enum E1 { FOO, BAR };   // expected-note {{previous definition is 
here}}
+
+auto normal_struct = (struct S1){ 1, 2 };
+auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 };   // 
expected-error {{'struct S2' is defined as an underspecified object 
initializer}}
+auto underspecified_struct_redef = (struct S1 { char x, y; }){ 'A', 'B'}; // 
expected-error {{redefinition of 'S1'}}
+auto underspecified_empty_struct = (struct S3 { }){ };// 
expected-error {{'struct S3' is defined as an underspecified object 
initializer}}
+
+auto normal_union_int = (union U1){ .a = 12 };
+auto normal_union_double = (union U1){ .b = 2.4 };
+auto underspecified_union = (union U2 { int a; double b; }){ .a = 34 };
 // expected-error {{'union U2' is defined as an underspecified object 
initializer}}
+auto underspecified_union_redef = (union U1 { char a; double b; }){ .a = 'A' 
}; // expected-error {{redefinition of 'U1'}}
+auto underspecified_empty_union = (union U3 {  }){  }; 
 // expected-error {{'union U3' is defined as an underspecified object 
initializer}}
+
+auto normal_enum_foo = (enum E1){ FOO };
+auto normal_enum_bar = (enum E1){ BAR };
+auto underspecified_enum = (enum E2 { BAZ, QUX }){ BAZ };   // 
expected-error {{'enum E2' is defined as an underspecified object initializer}}
+auto underspecified_enum_redef = (enum E1 { ONE, TWO }){ ONE }; // 
expected-error {{redefinition of 'E1'}}
+auto underspecified_empty_enum = (enum E3 {  }){ }; // 
expected-error {{'enum E3' is defined as an underspecified object initializer}} 
\
+   
expected-error {{use of empty enum}}

to268 wrote:

I'm not sure if declaring a non ordinary identifier `t` of type `struct T` 
should be diagnosed as an invalid declaration, since the definition of the 
`struct T` type is actually a underspecified declaration.
Interestingly, if you remove the `constexpr` keyword, there is currently no 
change in behavior in this case.

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-07-07 Thread Guillot Tony via cfe-commits


@@ -7813,6 +7813,32 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
diag::err_variable_object_no_init))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&

to268 wrote:

3 out of these 5 cases are not conforming curently:
```cpp
constexpr typeof(struct s *) x = 0;   // Wrong, no underspecifed 
diagnostics
constexpr struct S { int a, b; } y = { 0 };   // Wrong, no underspecifed 
diagnostics
constexpr int a = 0, b = 0;   // Ok, no underspecifed 
diagnostics
auto c = (struct T { int x, y; }){0, 0};  // Ok, `struct T` diagnosed 
as underspecifed
constexpr int (*fp)(struct X { int x; } val) = 0; // Wrong, no underspecifed 
diagnostics but dignoses warning: `declaration of 'struct X' will not be 
visible outside of this function`
```
I need to do more work outside of compound literals.

https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-07-07 Thread Guillot Tony via cfe-commits

https://github.com/to268 edited https://github.com/llvm/llvm-project/pull/79845
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-07-07 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From 5cd7ca393c35ea31f76ceae522d9cd480f9381f1 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Mon, 29 Jan 2024 15:14:32 +0100
Subject: [PATCH 1/5] Implementation base of N3006 Underspecified object
 declarations

---
 clang/docs/ReleaseNotes.rst   |  5 +++-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 ++
 clang/lib/Sema/SemaExpr.cpp   | 27 +++
 clang/test/C/C23/n3006.c  | 27 +++
 clang/test/Parser/c2x-underspecified-decls.c  | 12 +
 clang/www/c_status.html   |  2 +-
 6 files changed, 73 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/C/C23/n3006.c
 create mode 100644 clang/test/Parser/c2x-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 838cb69f647ee..56dcf5baf6b52 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -99,7 +99,7 @@ ABI Changes in This Version
   ifuncs. Its purpose was to preserve backwards compatibility when the ".ifunc"
   suffix got removed from the name mangling. The alias interacts badly with
   GlobalOpt (see the issue #96197).
-  
+
 - Fixed Microsoft name mangling for auto non-type template arguments of pointer
   type for MSVC 1920+. This change resolves incompatibilities with code 
compiled
   by MSVC 1920+ but will introduce incompatibilities with code compiled by
@@ -348,6 +348,9 @@ C23 Feature Support
   but C23 added them to  in
   `WG14 N2848 `_.
 
+- Clang now diagnoses `N3006 Underspecified object declarations
+  `_.
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 44fd51ec9abc9..618605a5b0f2e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7779,6 +7779,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 852344d895ffd..c0616c3047015 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6978,6 +6978,33 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
diagID))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(),
+   diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind()
+  << Tag->getDecl()->getName() << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
  RequireCompleteType(LParenLoc, literalType,
diag::err_typecheck_decl_incomplete_type,
diff --git a/clang/test/C/C23/n3006.c b/clang/test/C/C23/n3006.c
new file mode 100644
index 0..15efc0ccd6d32
--- /dev/null
+++ b/clang/test/C/C23/n3006.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous definition

[clang] Match against all plugins when parsing microsoft attributes (PR #86426)

2024-04-05 Thread Guillot Tony via cfe-commits

to268 wrote:

CC: @erichkeane, since it's a PR about attributes.
I can't add the `extension::microsoft`label to the PR myself.

https://github.com/llvm/llvm-project/pull/86426
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2024-07-24 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From 5eca1b0b822e839b5834ea87f329819368caf563 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Wed, 24 Jul 2024 13:11:48 +0200
Subject: [PATCH] Rebased N3006 feature after LLVM 19 release branch creation

---
 clang/docs/ReleaseNotes.rst   |  5 +-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/Sema/SemaExpr.cpp   | 26 
 clang/test/C/C23/n3006.c  | 66 +++
 clang/test/Parser/c2x-underspecified-decls.c  | 12 
 clang/www/c_status.html   |  2 +-
 6 files changed, 111 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/C/C23/n3006.c
 create mode 100644 clang/test/Parser/c2x-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 88f4d09308e8e..e17713c8343db 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -93,6 +93,9 @@ C2y Feature Support
 C23 Feature Support
 ^^^
 
+- Clang now diagnoses `N3006 Underspecified object declarations`
+  `_.
+
 New Compiler Flags
 --
 
@@ -117,7 +120,7 @@ Improvements to Clang's diagnostics
 - Some template related diagnostics have been improved.
 
   .. code-block:: c++
-
+
  void foo() { template  int i; } // error: templates can only be 
declared in namespace or class scope
 
  struct S {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 810abe4f23e31..597de7606cebf 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7793,6 +7793,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 9207bf7a41349..1d83e0fe43994 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7002,6 +7002,32 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, 
TypeSourceInfo *TInfo,
diagID))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(), 
diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind() << 
Tag->getDecl()->getName()
+  << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
  RequireCompleteType(LParenLoc, literalType,
diag::err_typecheck_decl_incomplete_type,
diff --git a/clang/test/C/C23/n3006.c b/clang/test/C/C23/n3006.c
new file mode 100644
index 0..85b36f45289a9
--- /dev/null
+++ b/clang/test/C/C23/n3006.c
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous definition is 
here}}
+union U1 { int a; double b; };  // expected-note {{previous definition is 
here}}
+enum E1 { FOO, BAR };   // expected-note {{previous definition is 
here}}
+
+auto normal_struct = (struct S1){ 1, 2 };
+auto normal_struct2 = (struct S1) { .x = 1, .y = 2 };
+auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 };   // 
expected-error {{'struct S2

[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2025-02-07 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From 7132c5d853fafb3e956c89b190313bf25ef1c773 Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Thu, 30 Jan 2025 01:12:13 +0100
Subject: [PATCH] N3006 base

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/Sema/SemaExpr.cpp   | 34 +-
 clang/test/C/C23/n3006.c  | 66 +++
 clang/test/Parser/c23-underspecified-decls.c  | 12 
 clang/www/c_status.html   |  2 +-
 6 files changed, 114 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/C/C23/n3006.c
 create mode 100644 clang/test/Parser/c23-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 92f63c15030898f..7046e13c3ec22ae 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -98,6 +98,8 @@ C2y Feature Support
 C23 Feature Support
 ^^^
 
+- Clang now supports `N3006 
`_ Underspecified 
object declarations.
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bcae9e9f3009387..6d0e12eac3d4d5a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7937,6 +7937,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3cd4010740d1944..f015fb9b3f2463a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7101,10 +7101,38 @@ Sema::BuildCompoundLiteralExpr(SourceLocation 
LParenLoc, TypeSourceInfo *TInfo,
diagID))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(), 
diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind() << 
Tag->getDecl()->getName()
+  << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
- RequireCompleteType(LParenLoc, literalType,
-   diag::err_typecheck_decl_incomplete_type,
-   SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd(
+ RequireCompleteType(
+ LParenLoc, literalType,
+ diag::err_typecheck_decl_incomplete_type,
+ SourceRange(LParenLoc,
+ LiteralExpr->getSourceRange().getEnd(
 return ExprError();
 
   InitializedEntity Entity
diff --git a/clang/test/C/C23/n3006.c b/clang/test/C/C23/n3006.c
new file mode 100644
index 000..882b910e96214a7
--- /dev/null
+++ b/clang/test/C/C23/n3006.c
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous definition is 
here}}
+union U1 { int a; double b; };  // expected-note {{previous definition is 
here}}
+enum E1 { FOO, BAR };   // expected-note {{previous definition is 
here}}
+
+auto normal_struct = (struct S1){ 1, 2 };
+auto normal_struct2

[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2025-01-17 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From 16328b43eac2ddd6fe999eac68e8ae07d040f54a Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Mon, 9 Dec 2024 01:46:40 +0100
Subject: [PATCH] N3006 base

---
 clang/docs/ReleaseNotes.rst   |  3 +-
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/Sema/SemaExpr.cpp   | 34 +-
 clang/test/C/C23/n3006.c  | 66 +++
 clang/test/Parser/c23-underspecified-decls.c  | 12 
 clang/www/c_status.html   |  2 +-
 6 files changed, 114 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/C/C23/n3006.c
 create mode 100644 clang/test/Parser/c23-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index aa1c02d04f7caa..ba727240998aec 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -423,6 +423,7 @@ C23 Feature Support
 - Clang now officially supports `N3030 
`_ Enhancements to 
Enumerations. Clang already supported it as an extension, so there were no 
changes to compiler behavior.
 - Fixed the value of ``BOOL_WIDTH`` in  to return ``1``
   explicitly, as mandated by the standard. Fixes #GH117348
+- Clang now supports `N3006 
`_ Underspecified 
object declarations.
 
 Non-comprehensive list of changes in this release
 -
@@ -717,7 +718,7 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses dangling references for C++20's parenthesized aggregate 
initialization (#101957).
 
-- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings 
when an unrelated class 
+- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings 
when an unrelated class
   defined a defaulted comparison operator (#GH116270).
 
   .. code-block:: c++
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index db54312ad965e8..1fea7c1814a881 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7901,6 +7901,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ae40895980d90a..c70603ce9ff246 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7087,10 +7087,38 @@ Sema::BuildCompoundLiteralExpr(SourceLocation 
LParenLoc, TypeSourceInfo *TInfo,
diagID))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(), 
diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind() << 
Tag->getDecl()->getName()
+  << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
- RequireCompleteType(LParenLoc, literalType,
-   diag::err_typecheck_decl_incomplete_type,
-   SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd(
+ RequireCompleteType(
+ LParenLoc, literalType,
+ diag::err_typecheck_decl_incomplete_type,
+ SourceRa

[clang] [clang][C23] N3006 Underspecified object declarations (PR #79845)

2025-01-29 Thread Guillot Tony via cfe-commits

https://github.com/to268 updated https://github.com/llvm/llvm-project/pull/79845

>From 6b4ac6b0dc8bafa19521d47856d7dee341439fbc Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Thu, 30 Jan 2025 01:12:13 +0100
Subject: [PATCH] N3006 base

---
 clang/docs/ReleaseNotes.rst   |  2 +
 .../clang/Basic/DiagnosticSemaKinds.td|  2 +
 clang/lib/Sema/SemaExpr.cpp   | 34 +-
 clang/test/C/C23/n3006.c  | 66 +++
 clang/test/Parser/c23-underspecified-decls.c  | 12 
 clang/www/c_status.html   |  2 +-
 6 files changed, 114 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/C/C23/n3006.c
 create mode 100644 clang/test/Parser/c23-underspecified-decls.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2b56ce974289d5e..4deeb53276ca526 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -87,6 +87,8 @@ C2y Feature Support
 C23 Feature Support
 ^^^
 
+- Clang now supports `N3006 
`_ Underspecified 
object declarations.
+
 Non-comprehensive list of changes in this release
 -
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 2ac3879a4caabca..b8ed7f6f946f8c8 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7924,6 +7924,8 @@ def err_attribute_arm_mve_polymorphism : Error<
   "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an 
MVE/NEON vector type">;
 def err_attribute_webassembly_funcref : Error<
   "'__funcref' attribute can only be applied to a function pointer type">;
+def err_c23_underspecified_object_declaration: Error<
+  "'%select{struct||union||enum}0 %1' is defined as an 
underspecified object initializer">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ba4aaa94b90ffd5..98924971b44f84a 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -7101,10 +7101,38 @@ Sema::BuildCompoundLiteralExpr(SourceLocation 
LParenLoc, TypeSourceInfo *TInfo,
diagID))
 return ExprError();
 }
+  } else if (LangOpts.C23 &&
+ (literalType->isRecordType() || literalType->isEnumeralType())) {
+// C23 6.2.1p7: Structure, union, and enumeration tags have scope that
+// begins just after the appearance of the tag in a type specifier that
+// declares the tag.
+// [...]
+// An ordinary identifier that has an underspecified definition has scope
+// that starts when the definition is completed; if the same ordinary
+// identifier declares another entity with a scope that encloses the 
current
+// block, that declaration is hidden as soon as the inner declarator is
+// completed*.)
+// [...]
+// *) That means, that the outer declaration is not visible for the
+// initializer.
+auto Range = SourceRange(LParenLoc, RParenLoc);
+const auto *Tag = literalType->castAs();
+const auto &TagRange = Tag->getDecl()->getSourceRange();
+
+// We should diagnose underspecified declaration, unless the identifier has
+// been diagnosed as being a redefinition, since the tag is made anonymous.
+if (Range.fullyContains(TagRange) && Tag->getDecl()->getIdentifier()) {
+  Diag(TagRange.getBegin(), 
diag::err_c23_underspecified_object_declaration)
+  << (unsigned)Tag->getDecl()->getTagKind() << 
Tag->getDecl()->getName()
+  << TagRange;
+  return ExprError();
+}
   } else if (!literalType->isDependentType() &&
- RequireCompleteType(LParenLoc, literalType,
-   diag::err_typecheck_decl_incomplete_type,
-   SourceRange(LParenLoc, LiteralExpr->getSourceRange().getEnd(
+ RequireCompleteType(
+ LParenLoc, literalType,
+ diag::err_typecheck_decl_incomplete_type,
+ SourceRange(LParenLoc,
+ LiteralExpr->getSourceRange().getEnd(
 return ExprError();
 
   InitializedEntity Entity
diff --git a/clang/test/C/C23/n3006.c b/clang/test/C/C23/n3006.c
new file mode 100644
index 000..882b910e96214a7
--- /dev/null
+++ b/clang/test/C/C23/n3006.c
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -std=c2x -verify %s
+
+/* WG14 N3006: Full
+ * Underspecified object declarations
+ */
+
+struct S1 { int x, y; };// expected-note {{previous definition is 
here}}
+union U1 { int a; double b; };  // expected-note {{previous definition is 
here}}
+enum E1 { FOO, BAR };   // expected-note {{previous definition is 
here}}
+
+auto normal_struct = (struct S1){ 1, 2 };
+auto normal_struct2

[clang] [C23][N3006] Documented behavior of underspecified object declarations (PR #140911)

2025-05-21 Thread Guillot Tony via cfe-commits

https://github.com/to268 created 
https://github.com/llvm/llvm-project/pull/140911

This PR is documenting the behavior of Clang towards underspecified object 
declarations in C23 as advised by @AaronBallman.

>From c9250050ce3b1f83d0a59bce16b22039db34133b Mon Sep 17 00:00:00 2001
From: Guillot Tony 
Date: Wed, 21 May 2025 16:58:31 +0200
Subject: [PATCH] Documented N3006 feature

---
 clang/docs/LanguageExtensions.rst |  48 +
 clang/docs/ReleaseNotes.rst   |   2 +
 clang/test/C/C23/n3006.c  | 113 ++
 clang/www/c_status.html   |   2 +-
 4 files changed, 164 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/C/C23/n3006.c

diff --git a/clang/docs/LanguageExtensions.rst 
b/clang/docs/LanguageExtensions.rst
index a40dd4d1a1673..aa76daf0ea459 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -6454,3 +6454,51 @@ qualifications.
 Note, Clang does not allow an ``_Atomic`` function type because
 of explicit constraints against atomically qualified (arrays and) function
 types.
+
+
+Underspecified object declarations in C
+===
+
+In C23 (N3006), when an object is declared inside of another object and that
+only exists in the scope of the declaration of the outer object. Clang allows
+underspecified object declarations for structs, unions and enums when valid.
+
+.. code-block:: c
+
+  auto s1 = (struct S1 { int x, y; }){ 1, 2 };
+  auto u1 = (union U1 { int a; double b; }){ .a = 34 };
+  auto e1 = (enum E1 { FOO, BAR }){ BAR };
+
+Note, The ``constexpr`` keyword and getting a struct member that is
+underspecified is also allowed.
+
+.. code-block:: c
+
+  constexpr auto cs1 = (struct S1 { int x, y; }){ 1, 2 };
+  constexpr auto cu1 = (union U1 { int a; double b; }){ .a = 34 };
+  constexpr auto ce1 = (enum E1 { FOO, BAR }){ BAR };
+  int i1 = (struct T { int a, b; }){0, 1}.a;
+  constexpr int ci2 = (struct T2 { int a, b; }){0, 1}.a;
+
+Moreover, some unusual cases are also allowed as described bellow.
+
+.. code-block:: c
+
+  constexpr struct S { int a, b; } y = { 0 };
+  constexpr typeof(struct s *) x = 0;
+  auto so = sizeof(struct S {});
+  auto s = ({struct T { int x; } s = {}; s.x; });
+  constexpr int (*fp)(struct X { int x; } val) = 0;
+  auto v = (void (*)(int y))0;
+
+  constexpr struct {
+  int a;
+  } si = {};
+
+  auto z = ({
+  int a = 12;
+  struct {} s;
+  a;
+  });
+
+All other cases are prohibited by Clang.
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 537f29521fb7f..c8de10f951933 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -273,6 +273,8 @@ C23 Feature Support
   be completed).
 - Fixed a failed assertion with an invalid parameter to the ``#embed``
   directive. Fixes #GH126940.
+- Documented `WG14 N3006 
`_
+  which clarified how Clang is handling underspecified object declarations.
 
 C11 Feature Support
 ^^^
diff --git a/clang/test/C/C23/n3006.c b/clang/test/C/C23/n3006.c
new file mode 100644
index 0..033e0b407e7f5
--- /dev/null
+++ b/clang/test/C/C23/n3006.c
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -std=c23 -verify %s
+
+/* WG14 N3006: Yes
+ * Underspecified object declarations
+ */
+
+void struct_test(void) {
+  struct S1 { int x, y; };  // 
expected-note {{field 'x' has type 'int' here}}
+
+  auto normal_struct = (struct S1){ 1, 2 };
+  auto normal_struct2 = (struct S1) { .x = 1, .y = 2 };
+  auto underspecified_struct = (struct S2 { int x, y; }){ 1, 2 };
+  auto underspecified_struct_redef = (struct S1 { char x, y; }){ 'A', 'B'}; // 
expected-error {{type 'struct S1' has incompatible definitions}} \
+   
expected-error {{cannot use 'auto' with array in C}} \
+   
expected-note {{field 'x' has type 'char' here}}
+  auto underspecified_empty_struct = (struct S3 { }){ };
+  auto zero_init_struct = (struct S4 { int x; }){ 0 };
+  int field_struct = (struct S5 { int y; }){ 0 }.y;
+}
+
+void union_test(void) {
+  union U1 { int a; double b; };   
   // expected-note {{field 'a' has type 'int' here}}
+
+  auto normal_union_int = (union U1){ .a = 12 };
+  auto normal_union_double = (union U1){ .b = 2.4 };
+  auto underspecified_union = (union U2 { int a; double b; }){ .a = 34 };
+  auto underspecified_union_redef = (union U1 { char a; double b; }){ .a = 'A' 
}; // expected-error {{type 'union U1' has incompatible definitions}} \
+   
  expected-error {{cannot use 'auto' with array in C}} \
+