-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[clang] Diagnose misplaced array bounds with non-identifier declarators. #155064
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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 llvm#147333.
@llvm/pr-subscribers-clang Author: None (keinflue) ChangesParseMisplacedBracketDeclarator 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. Full diff: https://github.com/llvm/llvm-project/pull/155064.diff 3 Files Affected:
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@-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.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@cor3ntin I do not have commit access. Can you land this PR for me? Thank you. |
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.