Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------------------------------

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
51 changes: 50 additions & 1 deletion clang/test/Parser/brackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,53 @@ struct A {
const char[] A::f = "f";
// expected-error@-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@-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@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
// expected-error@-2{{function cannot return array type}}

int[1] operator ""_x(unsigned long long);
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
// expected-error@-2{{function cannot return array type}}

struct A {
int[1] operator int();
// expected-error@-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@-3{{conversion function cannot have a return type}}
// expected-error@-4{{cannot specify any part of a return type in the declaration of a conversion function}}
// expected-error@-5{{conversion function cannot convert to an array type}}

int[1] A();
// expected-error@-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@-3{{function cannot return array type}}
// expected-error@-4{{constructor cannot have a return type}}

int[1] ~A();
// expected-error@-1{{brackets are not allowed here; to declare an array, place the brackets after the name}}
// TODO: This isn't helpful.
// expected-error@-3{{array has incomplete element type 'void'}}
};

template<typename T>
struct B {
int[1] B<T>();
// expected-error@-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@-3{{function cannot return array type}}
// expected-error@-4{{constructor cannot have a return type}}
};
#endif
}

// CHECK: 32 errors generated.