Skip to content

Commit 16b044e

Browse files
authored
[clang] Diagnose misplaced array bounds with non-identifier declarators. (#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.
1 parent 230b9b2 commit 16b044e

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ Improvements to Clang's diagnostics
235235
however, non-preprocessor use of tokens now triggers a pedantic warning in C++.
236236
Compilation in C mode is unchanged, and still permits these tokens to be used. (#GH147217)
237237

238+
- Clang now diagnoses misplaced array bounds on declarators for template
239+
specializations in th same way as it already did for other declarators.
240+
(#GH147333)
241+
238242
Improvements to Clang's time-trace
239243
----------------------------------
240244

clang/lib/Parse/ParseDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7878,9 +7878,9 @@ void Parser::ParseMisplacedBracketDeclarator(Declarator &D) {
78787878
D.AddTypeInfo(Chunk, TempDeclarator.getAttributePool(), SourceLocation());
78797879
}
78807880

7881-
// The missing identifier would have been diagnosed in ParseDirectDeclarator.
7881+
// The missing name would have been diagnosed in ParseDirectDeclarator.
78827882
// If parentheses are required, always suggest them.
7883-
if (!D.getIdentifier() && !NeedParens)
7883+
if (!D.hasName() && !NeedParens)
78847884
return;
78857885

78867886
SourceLocation EndBracketLoc = TempDeclarator.getEndLoc();

clang/test/Parser/brackets.cpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,53 @@ struct A {
158158
const char[] A::f = "f";
159159
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
160160
}
161-
// CHECK: 15 errors generated.
161+
162+
namespace gh147333 {
163+
template<class T, char fmt>
164+
constexpr inline auto& to_print_fmt = "";
165+
template<> constexpr inline char[] to_print_fmt<unsigned, 'x'> = "0x%x";
166+
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
167+
168+
#ifndef FIXIT
169+
// Further related test cases.
170+
171+
int[1] operator+();
172+
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
173+
// expected-error@-2{{function cannot return array type}}
174+
175+
int[1] operator ""_x(unsigned long long);
176+
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
177+
// expected-error@-2{{function cannot return array type}}
178+
179+
struct A {
180+
int[1] operator int();
181+
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
182+
// TODO: The following is too noisy and redundant.
183+
// expected-error@-3{{conversion function cannot have a return type}}
184+
// expected-error@-4{{cannot specify any part of a return type in the declaration of a conversion function}}
185+
// expected-error@-5{{conversion function cannot convert to an array type}}
186+
187+
int[1] A();
188+
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
189+
// TODO: The following is too noisy and redundant.
190+
// expected-error@-3{{function cannot return array type}}
191+
// expected-error@-4{{constructor cannot have a return type}}
192+
193+
int[1] ~A();
194+
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
195+
// TODO: This isn't helpful.
196+
// expected-error@-3{{array has incomplete element type 'void'}}
197+
};
198+
199+
template<typename T>
200+
struct B {
201+
int[1] B<T>();
202+
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
203+
// TODO: The following is too noisy and redundant.
204+
// expected-error@-3{{function cannot return array type}}
205+
// expected-error@-4{{constructor cannot have a return type}}
206+
};
207+
#endif
208+
}
209+
210+
// CHECK: 32 errors generated.

0 commit comments

Comments
 (0)