oontvoo created this revision.
oontvoo added a reviewer: gribozavr2.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Consider: `const int* get_foo() {return nullptr;}`
The suggested fix should be `static const int* get_foo(){}`
and not `const static int* get_foo(){}`


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D81444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/warn-missing-prototypes.c


Index: clang/test/Sema/warn-missing-prototypes.c
===================================================================
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -49,3 +49,19 @@
 void not_a_prototype_test(); // expected-note{{this declaration is not a 
prototype; add 'void' to make it a prototype for a zero-parameter function}}
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:"void"
 void not_a_prototype_test() { } // expected-warning{{no previous prototype for 
function 'not_a_prototype_test'}}
+
+const int *get_const() { // expected-warning{{no previous prototype for 
function 'get_const'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be 
used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  int *ret;
+  return ret;
+}
+
+struct MyStruct {};
+
+const struct MyStruct get_struct() { // expected-warning{{no previous 
prototype for function 'get_struct'}}
+                                     // expected-note@-1{{declare 'static' if 
the function is not intended to be used outside of this translation unit}}
+                                     // CHECK: 
fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14243,11 +14243,22 @@
                         : FixItHint{});
         }
       } else {
+        auto find_begin = [FD]() {
+          // If the return type has `const` qualifier, we want to insert
+          // `static` before `const` (and not before the typename).
+          if ((FD->getReturnType()->isAnyPointerType() &&
+               FD->getReturnType()->getPointeeType().isConstQualified()) ||
+              FD->getReturnType().isConstQualified())
+            return FD->getReturnTypeSourceRange().getBegin().getLocWithOffset(
+                /*strlen("const ")=*/-6);
+          else
+            return FD->getTypeSpecStartLoc();
+        };
+
         Diag(FD->getTypeSpecStartLoc(), diag::note_static_for_internal_linkage)
             << /* function */ 1
             << (FD->getStorageClass() == SC_None
-                    ? FixItHint::CreateInsertion(FD->getTypeSpecStartLoc(),
-                                                 "static ")
+                    ? FixItHint::CreateInsertion(find_begin(), "static ")
                     : FixItHint{});
       }
 


Index: clang/test/Sema/warn-missing-prototypes.c
===================================================================
--- clang/test/Sema/warn-missing-prototypes.c
+++ clang/test/Sema/warn-missing-prototypes.c
@@ -49,3 +49,19 @@
 void not_a_prototype_test(); // expected-note{{this declaration is not a prototype; add 'void' to make it a prototype for a zero-parameter function}}
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:27-[[@LINE-1]]:27}:"void"
 void not_a_prototype_test() { } // expected-warning{{no previous prototype for function 'not_a_prototype_test'}}
+
+const int *get_const() { // expected-warning{{no previous prototype for function 'get_const'}}
+  // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  int *ret;
+  return ret;
+}
+
+struct MyStruct {};
+
+const struct MyStruct get_struct() { // expected-warning{{no previous prototype for function 'get_struct'}}
+                                     // expected-note@-1{{declare 'static' if the function is not intended to be used outside of this translation unit}}
+                                     // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:1-[[@LINE-2]]:1}:"static "
+  struct MyStruct ret;
+  return ret;
+}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -14243,11 +14243,22 @@
                         : FixItHint{});
         }
       } else {
+        auto find_begin = [FD]() {
+          // If the return type has `const` qualifier, we want to insert
+          // `static` before `const` (and not before the typename).
+          if ((FD->getReturnType()->isAnyPointerType() &&
+               FD->getReturnType()->getPointeeType().isConstQualified()) ||
+              FD->getReturnType().isConstQualified())
+            return FD->getReturnTypeSourceRange().getBegin().getLocWithOffset(
+                /*strlen("const ")=*/-6);
+          else
+            return FD->getTypeSpecStartLoc();
+        };
+
         Diag(FD->getTypeSpecStartLoc(), diag::note_static_for_internal_linkage)
             << /* function */ 1
             << (FD->getStorageClass() == SC_None
-                    ? FixItHint::CreateInsertion(FD->getTypeSpecStartLoc(),
-                                                 "static ")
+                    ? FixItHint::CreateInsertion(find_begin(), "static ")
                     : FixItHint{});
       }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to