[clang] [clang] Diagnose misplaced array bounds with non-identifier declarators. (PR #155064)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 22 19:58:42 PDT 2025
https://github.com/keinflue created https://github.com/llvm/llvm-project/pull/155064
ParseMisplacedBracketDeclarator assumed that declarators without associated identifier are ill-formed and already diagnosed previously. This didn't consider declarators using template-ids, constructors, destructors, conversion functions, etc.
Fixes #147333.
>From b8f51c5dbad044fdbaf90e3db84f3bbbfaee337a Mon Sep 17 00:00:00 2001
From: keinflue <keinflue at posteo.de>
Date: Sat, 23 Aug 2025 04:50:28 +0200
Subject: [PATCH] [clang] Diagnose misplaced array bounds with non-identifier
declarators.
ParseMisplacedBracketDeclarator assumed that declarators without associated
identifier are ill-formed and already diagnosed previously. This didn't
consider declarators using template-ids, constructors, destructors, conversion
functions, etc.
Fixes #147333.
---
clang/docs/ReleaseNotes.rst | 4 +++
clang/lib/Parse/ParseDecl.cpp | 4 +--
clang/test/Parser/brackets.cpp | 51 +++++++++++++++++++++++++++++++++-
3 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 465c50784f27f..2b91c622c2b33 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -234,6 +234,10 @@ Improvements to Clang's diagnostics
however, non-preprocessor use of tokens now triggers a pedantic warning in C++.
Compilation in C mode is unchanged, and still permits these tokens to be used. (#GH147217)
+- Clang now diagnoses misplaced array bounds on declarators for template
+ specializations in th same way as it already did for other declarators.
+ (#GH147333)
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 65504ff7f6728..10355bb874762 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -7878,9 +7878,9 @@ void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
D.AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
}
- // The missing identifier would have been diagnosed in ParseDirectDeclarator.
+ // The missing name would have been diagnosed in ParseDirectDeclarator.
// If parentheses are required, always suggest them.
- if (!D.getIdentifier() && !NeedParens)
+ if (!D.hasName() && !NeedParens)
return;
SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();
diff --git a/clang/test/Parser/brackets.cpp b/clang/test/Parser/brackets.cpp
index 927b66a7ebcb8..91d4f9b507c8f 100644
--- a/clang/test/Parser/brackets.cpp
+++ b/clang/test/Parser/brackets.cpp
@@ -158,4 +158,53 @@ struct A {
const char[] A::f = "f";
// expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
}
-// CHECK: 15 errors generated.
+
+namespace gh147333 {
+ template<class T, char fmt>
+ constexpr inline auto& to_print_fmt = "";
+ template<> constexpr inline char[] to_print_fmt<unsigned, 'x'> = "0x%x";
+ // expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
+
+#ifndef FIXIT
+ // Further related test cases.
+
+ int[1] operator+();
+ // expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
+ // expected-error at -2{{function cannot return array type}}
+
+ int[1] operator ""_x(unsigned long long);
+ // expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
+ // expected-error at -2{{function cannot return array type}}
+
+ struct A {
+ int[1] operator int();
+ // expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
+ // TODO: The following is too noisy and redundant.
+ // expected-error at -3{{conversion function cannot have a return type}}
+ // expected-error at -4{{cannot specify any part of a return type in the declaration of a conversion function}}
+ // expected-error at -5{{conversion function cannot convert to an array type}}
+
+ int[1] A();
+ // expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
+ // TODO: The following is too noisy and redundant.
+ // expected-error at -3{{function cannot return array type}}
+ // expected-error at -4{{constructor cannot have a return type}}
+
+ int[1] ~A();
+ // expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
+ // TODO: This isn't helpful.
+ // expected-error at -3{{array has incomplete element type 'void'}}
+ };
+
+ template<typename T>
+ struct B {
+ int[1] B<T>();
+ // expected-error at -1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
+ // TODO: The following is too noisy and redundant.
+ // expected-error at -3{{function cannot return array type}}
+ // expected-error at -4{{constructor cannot have a return type}}
+ };
+#endif
+}
+
+// CHECK: 32 errors generated.
More information about the cfe-commits
mailing list