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