[clang] [clang] Disallow VLA type compound literals (PR #91891)
@@ -7274,12 +7274,19 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, // init a VLA in C++ in all cases (such as with non-trivial constructors). // FIXME: should we allow this construct in C++ when it makes sense to do // so? - std::optional NumInits; - if (const auto *ILE = dyn_cast(LiteralExpr)) -NumInits = ILE->getNumInits(); - if ((LangOpts.CPlusPlus || NumInits.value_or(0)) && - !tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, - diag::err_variable_object_no_init)) + // + // But: C99-C23 6.5.2.5 Compound literals constraint 1: The type name + // shall specify an object type or an array of unknown size, but not a + // variable length array type. This seems odd, as it allows int a[size] = + // {}; but forbids int a[size] = (int[size]){}; As this is what the J-MR-T wrote: Sorry, I should have been more clear, I didn't mean it would be allowed in another C standard, just that it's unexpected from a language point of view. But it's not that important anyway, so I hope the new version works better :). https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
https://github.com/J-MR-T ready_for_review https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
https://github.com/J-MR-T updated https://github.com/llvm/llvm-project/pull/91891 From 9aab9284fc094d22e12a2ee1217a3bc99e5837b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20M=2E=20R=2E=20Teichgr=C3=A4ber?= Date: Sun, 12 May 2024 13:33:37 +0200 Subject: [PATCH 1/5] [clang] Disallow VLA type compound literals C99-C23 6.5.2.5 says: The type name shall specify an object type or an array of unknown size, but not a variable length array type Issue: https://github.com/llvm/llvm-project/issues/89835 --- .../clang/Basic/DiagnosticSemaKinds.td| 2 ++ clang/lib/Sema/SemaExpr.cpp | 19 +-- clang/test/C/C2x/n2900_n3011.c| 8 +++- clang/test/C/C2x/n2900_n3011_2.c | 16 clang/test/Sema/compound-literal.c| 15 +-- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d6863f90edb6e..008d7b2a29cd9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3371,6 +3371,8 @@ def err_field_with_address_space : Error< "field may not be qualified with an address space">; def err_compound_literal_with_address_space : Error< "compound literal in function scope may not be qualified with an address space">; +def err_compound_literal_with_vla_type : Error< + "compound literal has variable-length array type">; def err_address_space_mismatch_templ_inst : Error< "conflicting address space qualifiers are provided between types %0 and %1">; def err_attr_objc_ownership_redundant : Error< diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c688cb21f2364..e62e3f3285e5d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7274,12 +7274,19 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, // init a VLA in C++ in all cases (such as with non-trivial constructors). // FIXME: should we allow this construct in C++ when it makes sense to do // so? - std::optional NumInits; - if (const auto *ILE = dyn_cast(LiteralExpr)) -NumInits = ILE->getNumInits(); - if ((LangOpts.CPlusPlus || NumInits.value_or(0)) && - !tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, - diag::err_variable_object_no_init)) + // + // But: C99-C23 6.5.2.5 Compound literals constraint 1: The type name + // shall specify an object type or an array of unknown size, but not a + // variable length array type. This seems odd, as it allows int a[size] = + // {}; but forbids int a[size] = (int[size]){}; As this is what the + // standard says, this is what's implemented here for C (except for the + // extension that permits constant foldable size arrays) + + auto diagID = LangOpts.CPlusPlus +? diag::err_variable_object_no_init +: diag::err_compound_literal_with_vla_type; + if (!tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, + diagID)) return ExprError(); } } else if (!literalType->isDependentType() && diff --git a/clang/test/C/C2x/n2900_n3011.c b/clang/test/C/C2x/n2900_n3011.c index 4350aa140691b..f0be8b9e41861 100644 --- a/clang/test/C/C2x/n2900_n3011.c +++ b/clang/test/C/C2x/n2900_n3011.c @@ -27,8 +27,14 @@ void test(void) { compat-warning {{use of an empty initializer is incompatible with C standards before C23}} int vla[i] = {}; // compat-warning {{use of an empty initializer is incompatible with C standards before C23}} \ pedantic-warning {{use of an empty initializer is a C23 extension}} + // C99 6.5.2.5 Compound literals constraint 1: The type name shall specify an + // object type or an array of unknown size, but not a variable length array + // type. int *compound_literal_vla = (int[i]){}; // compat-warning {{use of an empty initializer is incompatible with C standards before C23}} \ - pedantic-warning {{use of an empty initializer is a C23 extension}} + pedantic-warning {{use of an empty initializer is a C23 extension}}\ + compat-error {{compound literal has variable-length array type}} \ + pedantic-error {{compound literal has variable-length array type}}\ + struct T { int i; diff --git a/clang/test/C/C2x/n2900_n3011_2.c b/clang/test/C/C2x/n2900_n3011_2.c index eb15fbf905c86..ab659d636d155 100644 --- a/clang/test/C/C2x/n2900_n3011_2.c +++ b/clang/test/C/C2x/n2900_n3011_2.c @@ -76,22 +76,6 @@ void test_zero_size_vla() { // CHECK-NEXT: call void @llvm
[clang] [clang] Disallow VLA type compound literals (PR #91891)
J-MR-T wrote: > Btw, you can probably move this PR out of Draft status, it seems awfully > close to finished I'll finish implementing your suggestions, run the tests again locally and then move it out of draft, if that's alright with you :). https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
@@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -pedantic %s +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -pedantic -Wno-comment %s J-MR-T wrote: Ah, that's good to know! Seeing as I had to modify the test again anyway, it seems nicer to use this syntax. https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
https://github.com/J-MR-T updated https://github.com/llvm/llvm-project/pull/91891 From 9aab9284fc094d22e12a2ee1217a3bc99e5837b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20M=2E=20R=2E=20Teichgr=C3=A4ber?= Date: Sun, 12 May 2024 13:33:37 +0200 Subject: [PATCH 1/3] [clang] Disallow VLA type compound literals C99-C23 6.5.2.5 says: The type name shall specify an object type or an array of unknown size, but not a variable length array type Issue: https://github.com/llvm/llvm-project/issues/89835 --- .../clang/Basic/DiagnosticSemaKinds.td| 2 ++ clang/lib/Sema/SemaExpr.cpp | 19 +-- clang/test/C/C2x/n2900_n3011.c| 8 +++- clang/test/C/C2x/n2900_n3011_2.c | 16 clang/test/Sema/compound-literal.c| 15 +-- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d6863f90edb6e..008d7b2a29cd9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3371,6 +3371,8 @@ def err_field_with_address_space : Error< "field may not be qualified with an address space">; def err_compound_literal_with_address_space : Error< "compound literal in function scope may not be qualified with an address space">; +def err_compound_literal_with_vla_type : Error< + "compound literal has variable-length array type">; def err_address_space_mismatch_templ_inst : Error< "conflicting address space qualifiers are provided between types %0 and %1">; def err_attr_objc_ownership_redundant : Error< diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c688cb21f2364..e62e3f3285e5d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7274,12 +7274,19 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, // init a VLA in C++ in all cases (such as with non-trivial constructors). // FIXME: should we allow this construct in C++ when it makes sense to do // so? - std::optional NumInits; - if (const auto *ILE = dyn_cast(LiteralExpr)) -NumInits = ILE->getNumInits(); - if ((LangOpts.CPlusPlus || NumInits.value_or(0)) && - !tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, - diag::err_variable_object_no_init)) + // + // But: C99-C23 6.5.2.5 Compound literals constraint 1: The type name + // shall specify an object type or an array of unknown size, but not a + // variable length array type. This seems odd, as it allows int a[size] = + // {}; but forbids int a[size] = (int[size]){}; As this is what the + // standard says, this is what's implemented here for C (except for the + // extension that permits constant foldable size arrays) + + auto diagID = LangOpts.CPlusPlus +? diag::err_variable_object_no_init +: diag::err_compound_literal_with_vla_type; + if (!tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, + diagID)) return ExprError(); } } else if (!literalType->isDependentType() && diff --git a/clang/test/C/C2x/n2900_n3011.c b/clang/test/C/C2x/n2900_n3011.c index 4350aa140691b..f0be8b9e41861 100644 --- a/clang/test/C/C2x/n2900_n3011.c +++ b/clang/test/C/C2x/n2900_n3011.c @@ -27,8 +27,14 @@ void test(void) { compat-warning {{use of an empty initializer is incompatible with C standards before C23}} int vla[i] = {}; // compat-warning {{use of an empty initializer is incompatible with C standards before C23}} \ pedantic-warning {{use of an empty initializer is a C23 extension}} + // C99 6.5.2.5 Compound literals constraint 1: The type name shall specify an + // object type or an array of unknown size, but not a variable length array + // type. int *compound_literal_vla = (int[i]){}; // compat-warning {{use of an empty initializer is incompatible with C standards before C23}} \ - pedantic-warning {{use of an empty initializer is a C23 extension}} + pedantic-warning {{use of an empty initializer is a C23 extension}}\ + compat-error {{compound literal has variable-length array type}} \ + pedantic-error {{compound literal has variable-length array type}}\ + struct T { int i; diff --git a/clang/test/C/C2x/n2900_n3011_2.c b/clang/test/C/C2x/n2900_n3011_2.c index eb15fbf905c86..ab659d636d155 100644 --- a/clang/test/C/C2x/n2900_n3011_2.c +++ b/clang/test/C/C2x/n2900_n3011_2.c @@ -76,22 +76,6 @@ void test_zero_size_vla() { // CHECK-NEXT: call void @llvm
[clang] [clang] Disallow VLA type compound literals (PR #91891)
J-MR-T wrote: > Please be sure to add a release note to clang/docs/ReleaseNotes.rst so users > know about the fix. Oh, sorry, I didn't find anything know how release notes were handled - will do! A question on that, would you classify this as a breaking change? Technically, it could break the compilation of programs previously compiled with Clang 17 that compile VLA type compound literals, but never execute the code that they're used in; is that enough for it to be listed as a breaking change? If so, would this go under the `C/C++ Language Potentially Breaking Changes` header? Or should I create a new `C Language Potentially Breaking Changes` header, as this does not affect Clang's C++ behavior itself in any way? PS: I hope multiple commits in this PR are fine, they are squashed at the end anyway, right? https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
@@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -pedantic %s +// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -pedantic -Wno-comment %s J-MR-T wrote: [This line](https://github.com/llvm/llvm-project/pull/91891/files#diff-7d0182b6392ee774cf192fde090a22efd8367b693b28bac42d2e3ae2f8c2d94bR50-R51) both warns about the empty initializer being used without `-std=c2x`, and now triggers the new diagnostic. As I understand `-verify`, this cannot be tested using `//` on subsequent lines, so I used the `\` syntax to chain these checks, as some other tests do. Without `-Wno-comment`, this would lead to an additional warning for the multiline `// ... \` comment. https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
https://github.com/J-MR-T updated https://github.com/llvm/llvm-project/pull/91891 From 9aab9284fc094d22e12a2ee1217a3bc99e5837b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20M=2E=20R=2E=20Teichgr=C3=A4ber?= Date: Sun, 12 May 2024 13:33:37 +0200 Subject: [PATCH 1/2] [clang] Disallow VLA type compound literals C99-C23 6.5.2.5 says: The type name shall specify an object type or an array of unknown size, but not a variable length array type Issue: https://github.com/llvm/llvm-project/issues/89835 --- .../clang/Basic/DiagnosticSemaKinds.td| 2 ++ clang/lib/Sema/SemaExpr.cpp | 19 +-- clang/test/C/C2x/n2900_n3011.c| 8 +++- clang/test/C/C2x/n2900_n3011_2.c | 16 clang/test/Sema/compound-literal.c| 15 +-- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d6863f90edb6e..008d7b2a29cd9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3371,6 +3371,8 @@ def err_field_with_address_space : Error< "field may not be qualified with an address space">; def err_compound_literal_with_address_space : Error< "compound literal in function scope may not be qualified with an address space">; +def err_compound_literal_with_vla_type : Error< + "compound literal has variable-length array type">; def err_address_space_mismatch_templ_inst : Error< "conflicting address space qualifiers are provided between types %0 and %1">; def err_attr_objc_ownership_redundant : Error< diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c688cb21f2364..e62e3f3285e5d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7274,12 +7274,19 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, // init a VLA in C++ in all cases (such as with non-trivial constructors). // FIXME: should we allow this construct in C++ when it makes sense to do // so? - std::optional NumInits; - if (const auto *ILE = dyn_cast(LiteralExpr)) -NumInits = ILE->getNumInits(); - if ((LangOpts.CPlusPlus || NumInits.value_or(0)) && - !tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, - diag::err_variable_object_no_init)) + // + // But: C99-C23 6.5.2.5 Compound literals constraint 1: The type name + // shall specify an object type or an array of unknown size, but not a + // variable length array type. This seems odd, as it allows int a[size] = + // {}; but forbids int a[size] = (int[size]){}; As this is what the + // standard says, this is what's implemented here for C (except for the + // extension that permits constant foldable size arrays) + + auto diagID = LangOpts.CPlusPlus +? diag::err_variable_object_no_init +: diag::err_compound_literal_with_vla_type; + if (!tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, + diagID)) return ExprError(); } } else if (!literalType->isDependentType() && diff --git a/clang/test/C/C2x/n2900_n3011.c b/clang/test/C/C2x/n2900_n3011.c index 4350aa140691b..f0be8b9e41861 100644 --- a/clang/test/C/C2x/n2900_n3011.c +++ b/clang/test/C/C2x/n2900_n3011.c @@ -27,8 +27,14 @@ void test(void) { compat-warning {{use of an empty initializer is incompatible with C standards before C23}} int vla[i] = {}; // compat-warning {{use of an empty initializer is incompatible with C standards before C23}} \ pedantic-warning {{use of an empty initializer is a C23 extension}} + // C99 6.5.2.5 Compound literals constraint 1: The type name shall specify an + // object type or an array of unknown size, but not a variable length array + // type. int *compound_literal_vla = (int[i]){}; // compat-warning {{use of an empty initializer is incompatible with C standards before C23}} \ - pedantic-warning {{use of an empty initializer is a C23 extension}} + pedantic-warning {{use of an empty initializer is a C23 extension}}\ + compat-error {{compound literal has variable-length array type}} \ + pedantic-error {{compound literal has variable-length array type}}\ + struct T { int i; diff --git a/clang/test/C/C2x/n2900_n3011_2.c b/clang/test/C/C2x/n2900_n3011_2.c index eb15fbf905c86..ab659d636d155 100644 --- a/clang/test/C/C2x/n2900_n3011_2.c +++ b/clang/test/C/C2x/n2900_n3011_2.c @@ -76,22 +76,6 @@ void test_zero_size_vla() { // CHECK-NEXT: call void @llvm
[clang] [clang] Disallow VLA type compound literals (PR #91891)
@@ -3371,6 +3371,8 @@ def err_field_with_address_space : Error< "field may not be qualified with an address space">; def err_compound_literal_with_address_space : Error< "compound literal in function scope may not be qualified with an address space">; +def err_compound_literal_with_vla_type : Error< + "compound literal has variable-length array type">; J-MR-T wrote: That's clearer, thank you! https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
https://github.com/J-MR-T edited https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
https://github.com/J-MR-T edited https://github.com/llvm/llvm-project/pull/91891 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Disallow VLA type compound literals (PR #91891)
https://github.com/J-MR-T created https://github.com/llvm/llvm-project/pull/91891 C99-C23 6.5.2.5 says: The type name shall specify an object type or an array of unknown size, but not a variable length array type. Closes issue #89835 . I ran `git clang-format`'ed my changes and ran the clang tests, which passed after minor adjustments to the new behavior. I mostly implemented everything as discussed in #89835, with the exception of [clang/test/C/C2x/n2900_n3011_2.c](https://github.com/llvm/llvm-project/compare/main...J-MR-T:llvm-project:main#diff-aa2b77ff42fcd2f2c02cc456f5023e923d44e5018dd2af7c046ebdcc8cb00a4a): in that file I deleted the part about VLA compound literals, because the file relies on LLVM-IR being emitted by clang, and that wouldn't have fit with the rest of the file. Adding another RUN line and handling this case independently in that file would be an option, but it felt out of place. Of course, I'm still open to doing it that way, or preserving the test another way, if that is preferred. As I point out [here](https://github.com/llvm/llvm-project/compare/main...J-MR-T:llvm-project:main#diff-3c28567b5e0c77d68f174541a0b77f5a85d093f58b89cd3675ee04a550a44880R7278-R7283), the new behavior leads to a confusing reality brought about by the C23 standard: ```c int a[size] = {}; ``` is valid code, while ```c int a[size] = (int[size]){}; ``` is not. As this seems to be what the standard requests, I implemented it that way for now. Tagging @Sirraide and @AaronBallman as requested :). From 9aab9284fc094d22e12a2ee1217a3bc99e5837b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jim=20M=2E=20R=2E=20Teichgr=C3=A4ber?= Date: Sun, 12 May 2024 13:33:37 +0200 Subject: [PATCH] [clang] Disallow VLA type compound literals C99-C23 6.5.2.5 says: The type name shall specify an object type or an array of unknown size, but not a variable length array type Issue: https://github.com/llvm/llvm-project/issues/89835 --- .../clang/Basic/DiagnosticSemaKinds.td| 2 ++ clang/lib/Sema/SemaExpr.cpp | 19 +-- clang/test/C/C2x/n2900_n3011.c| 8 +++- clang/test/C/C2x/n2900_n3011_2.c | 16 clang/test/Sema/compound-literal.c| 15 +-- 5 files changed, 35 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index d6863f90edb6e..008d7b2a29cd9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3371,6 +3371,8 @@ def err_field_with_address_space : Error< "field may not be qualified with an address space">; def err_compound_literal_with_address_space : Error< "compound literal in function scope may not be qualified with an address space">; +def err_compound_literal_with_vla_type : Error< + "compound literal has variable-length array type">; def err_address_space_mismatch_templ_inst : Error< "conflicting address space qualifiers are provided between types %0 and %1">; def err_attr_objc_ownership_redundant : Error< diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c688cb21f2364..e62e3f3285e5d 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7274,12 +7274,19 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, // init a VLA in C++ in all cases (such as with non-trivial constructors). // FIXME: should we allow this construct in C++ when it makes sense to do // so? - std::optional NumInits; - if (const auto *ILE = dyn_cast(LiteralExpr)) -NumInits = ILE->getNumInits(); - if ((LangOpts.CPlusPlus || NumInits.value_or(0)) && - !tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, - diag::err_variable_object_no_init)) + // + // But: C99-C23 6.5.2.5 Compound literals constraint 1: The type name + // shall specify an object type or an array of unknown size, but not a + // variable length array type. This seems odd, as it allows int a[size] = + // {}; but forbids int a[size] = (int[size]){}; As this is what the + // standard says, this is what's implemented here for C (except for the + // extension that permits constant foldable size arrays) + + auto diagID = LangOpts.CPlusPlus +? diag::err_variable_object_no_init +: diag::err_compound_literal_with_vla_type; + if (!tryToFixVariablyModifiedVarType(TInfo, literalType, LParenLoc, + diagID)) return ExprError(); } } else if (!literalType->isDependentType() && diff --git a/clang/test/C/C2x/n2900_n3011.c b/clang/test/C/C2x/n2900_n3011.c index 4350aa140691b..f0be8b9e41861 100644 --- a/clang/test/C/C2x/n2900_n3011.c +++ b/clang/test/C/C2x/n2900_n3011.c @@ -27