serge-sans-paille created this revision.
serge-sans-paille added reviewers: RKSimon, aaron.ballman, tstellar.
Herald added a project: All.
serge-sans-paille requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This warning exist in GCC[0] and warns about re-declarations of functions
involving arguments of array or pointer types of inconsistent kinds or forms.

This is not the exact same implementation as GCC's : there's no warning level
and that flag has no effect on -Warray-bounds.

[0] 
https://gcc.gnu.org/onlinedocs/gcc-12.1.0/gcc/Warning-Options.html#index-Wno-array-parameter


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128449

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/array-parameter.c

Index: clang/test/Sema/array-parameter.c
===================================================================
--- /dev/null
+++ clang/test/Sema/array-parameter.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -Wno-unused -verify %s
+
+void f0(int a[]);
+void f0(int *a); // no warning
+
+void f1(int a[]);  // expected-note {{previously declared as int[] here}}
+void f1(int a[2]); // expected-warning {{argument 'a' of type 'int[2]' with mismatched bound}}
+
+void f2(int a[3]); // expected-note {{previously declared as int[3] here}}
+void f2(int a[2]); // expected-warning {{argument 'a' of type 'int[2]' with mismatched bound}}
+
+void f3(int a[const 2]); // expected-note {{previously declared as int[const 2] here}}
+void f3(int a[2]);       // expected-warning {{argument 'a' of type 'int[2]' with mismatched bound}}
+
+void f4(int a[static 2]); // expected-note {{previously declared as int[static 2] here}}
+void f4(int a[2]);        // expected-warning {{argument 'a' of type 'int[2]' with mismatched bound}}
+
+void f5(int a[restrict 2]); // expected-note {{previously declared as int[__restrict 2] here}}
+void f5(int a[2]);          // expected-warning {{argument 'a' of type 'int[2]' with mismatched bound}}
+
+void f6(int a[*]); // expected-note {{previously declared as int[*] here}}
+void f6(int a[]);  // expected-warning {{argument 'a' of type 'int[]' with mismatched bound}}
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -46,6 +46,7 @@
 #include "clang/Sema/Template.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cstring>
 #include <functional>
@@ -3209,6 +3210,19 @@
   if (!foundAny) newDecl->dropAttrs();
 }
 
+static bool EquivalentArrayTypes(QualType Old, QualType New) {
+  // type[] is equivalent to type *
+  if ((Old->isIncompleteArrayType() && New->isPointerType()) ||
+      (New->isIncompleteArrayType() && Old->isPointerType()))
+    return true;
+
+  // Don't try to compare VLA sizes
+  if (Old->isVariableArrayType() && New->isVariableArrayType())
+    return true;
+
+  return Old == New;
+}
+
 static void mergeParamDeclTypes(ParmVarDecl *NewParam,
                                 const ParmVarDecl *OldParam,
                                 Sema &S) {
@@ -3234,6 +3248,22 @@
       NewParam->setType(NewT);
     }
   }
+  const DecayedType *OldParamDT =
+      dyn_cast<const DecayedType>(OldParam->getType());
+  const DecayedType *NewParamDT =
+      dyn_cast<const DecayedType>(NewParam->getType());
+  if (OldParamDT && NewParamDT &&
+      OldParamDT->getPointeeType() == NewParamDT->getPointeeType()) {
+    QualType OldParamOT = OldParamDT->getOriginalType();
+    QualType NewParamOT = NewParamDT->getOriginalType();
+    if (!EquivalentArrayTypes(OldParamOT, NewParamOT)) {
+      S.Diag(NewParam->getLocation(), diag::warn_inconsistent_array_form)
+          << NewParam->getName()
+          << NewParamOT->getCanonicalTypeInternal().getAsString();
+      S.Diag(OldParam->getLocation(), diag::note_previous_declaration_as)
+          << OldParamOT->getCanonicalTypeInternal().getAsString();
+    }
+  }
 }
 
 namespace {
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9393,6 +9393,12 @@
 def note_array_declared_here : Note<
   "array %0 declared here">;
 
+def warn_inconsistent_array_form : Warning<
+  "argument '%0' of type '%1' with mismatched bound">,
+  InGroup<ArrayParameter>;
+def note_previous_declaration_as : Note<
+  "previously declared as %0 here">;
+
 def warn_printf_insufficient_data_args : Warning<
   "more '%%' conversions than data arguments">, InGroup<FormatInsufficientArgs>;
 def warn_printf_data_arg_not_used : Warning<
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -31,6 +31,7 @@
 def GNUAutoType : DiagGroup<"gnu-auto-type">;
 def ArrayBounds : DiagGroup<"array-bounds">;
 def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">;
+def ArrayParameter : DiagGroup<"array-parameter">;
 def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-sanitizer">;
 def Availability : DiagGroup<"availability">;
 def Section : DiagGroup<"section">;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -309,6 +309,9 @@
   removed in the future once clang supports all such operations.
 - Added the ``-print-diagnostic-options`` option, which prints a list of
   warnings the compiler supports.
+- Added the ``-Warray-parameter`` warning. It detects function redefinition,
+  where different definition involve argument type that decay to the same
+  pointer type from different array types.
 
 Deprecated Compiler Flags
 -------------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to