Author: keinflue
Date: 2025-08-23T11:43:58+02:00
New Revision: 16b044e9789d6b9dc9ec6ed7e5b98731e60e3fcd

URL: 
https://github.com/llvm/llvm-project/commit/16b044e9789d6b9dc9ec6ed7e5b98731e60e3fcd
DIFF: 
https://github.com/llvm/llvm-project/commit/16b044e9789d6b9dc9ec6ed7e5b98731e60e3fcd.diff

LOG: [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.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseDecl.cpp
    clang/test/Parser/brackets.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index a941c6521d90e..99d51f35a4835 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -235,6 +235,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.


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to