serge-sans-paille updated this revision to Diff 439435.
serge-sans-paille added a comment.
Activate `-Warray-parameter` on `-Wmost` but disable it by default
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D128449/new/
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/Misc/warning-wall.c
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 -Warray-parameter -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/test/Misc/warning-wall.c
===================================================================
--- clang/test/Misc/warning-wall.c
+++ clang/test/Misc/warning-wall.c
@@ -1,103 +1,9 @@
-RUN: diagtool tree -Wall > %t 2>&1
-RUN: FileCheck --input-file=%t %s
+RUN : diagtool tree - Wall > % t 2 > & 1 RUN : FileCheck-- input - file = % t % s
- CHECK:-Wall
-CHECK-NEXT: -Wmost
-CHECK-NEXT: -Wbool-operation
-CHECK-NEXT: -Wbitwise-instead-of-logical
-CHECK-NEXT: -Wchar-subscripts
-CHECK-NEXT: -Wcomment
-CHECK-NEXT: -Wdelete-non-virtual-dtor
-CHECK-NEXT: -Wdelete-non-abstract-non-virtual-dtor
-CHECK-NEXT: -Wdelete-abstract-non-virtual-dtor
-CHECK-NEXT: -Wformat
-CHECK-NEXT: -Wformat-extra-args
-CHECK-NEXT: -Wformat-zero-length
-CHECK-NEXT: -Wnonnull
-CHECK-NEXT: -Wformat-security
-CHECK-NEXT: -Wformat-y2k
-CHECK-NEXT: -Wformat-invalid-specifier
-CHECK-NEXT: -Wformat-insufficient-args
-CHECK-NEXT: -Wfor-loop-analysis
-CHECK-NEXT: -Wframe-address
-CHECK-NEXT: -Wimplicit
-CHECK-NEXT: -Wimplicit-function-declaration
-CHECK-NEXT: -Wimplicit-int
-CHECK-NEXT: -Winfinite-recursion
-CHECK-NEXT: -Wint-in-bool-context
-CHECK-NEXT: -Wmismatched-tags
-CHECK-NEXT: -Wmissing-braces
-CHECK-NEXT: -Wmove
-CHECK-NEXT: -Wpessimizing-move
-CHECK-NEXT: -Wredundant-move
-CHECK-NEXT: -Wreturn-std-move
-CHECK-NEXT: -Wself-move
-CHECK-NEXT: -Wmultichar
-CHECK-NEXT: -Wrange-loop-construct
-CHECK-NEXT: -Wreorder
-CHECK-NEXT: -Wreorder-ctor
-CHECK-NEXT: -Wreorder-init-list
-CHECK-NEXT: -Wreturn-type
-CHECK-NEXT: -Wreturn-type-c-linkage
-CHECK-NEXT: -Wself-assign
-CHECK-NEXT: -Wself-assign-overloaded
-CHECK-NEXT: -Wself-assign-field
-CHECK-NEXT: -Wself-move
-CHECK-NEXT: -Wsizeof-array-argument
-CHECK-NEXT: -Wsizeof-array-decay
-CHECK-NEXT: -Wstring-plus-int
-CHECK-NEXT: -Wtautological-compare
-CHECK-NEXT: -Wtautological-constant-compare
-CHECK-NEXT: -Wtautological-constant-out-of-range-compare
-CHECK-NEXT: -Wtautological-pointer-compare
-CHECK-NEXT: -Wtautological-overlap-compare
-CHECK-NEXT: -Wtautological-bitwise-compare
-CHECK-NEXT: -Wtautological-undefined-compare
-CHECK-NEXT: -Wtautological-objc-bool-compare
-CHECK-NEXT: -Wtrigraphs
-CHECK-NEXT: -Wuninitialized
-CHECK-NEXT: -Wsometimes-uninitialized
-CHECK-NEXT: -Wstatic-self-init
-CHECK-NEXT: -Wuninitialized-const-reference
-CHECK-NEXT: -Wunknown-pragmas
-CHECK-NEXT: -Wunused
-CHECK-NEXT: -Wunused-argument
-CHECK-NEXT: -Wunused-function
-CHECK-NEXT: -Wunneeded-internal-declaration
-CHECK-NEXT: -Wunused-label
-CHECK-NEXT: -Wunused-private-field
-CHECK-NEXT: -Wunused-lambda-capture
-CHECK-NEXT: -Wunused-local-typedef
-CHECK-NEXT: -Wunused-value
-CHECK-NEXT: -Wunused-comparison
-CHECK-NEXT: -Wunused-result
-CHECK-NEXT: -Wunevaluated-expression
-CHECK-NEXT: -Wpotentially-evaluated-expression
-CHECK-NEXT: -Wunused-variable
-CHECK-NEXT: -Wunused-const-variable
-CHECK-NEXT: -Wunused-but-set-variable
-CHECK-NEXT: -Wunused-property-ivar
-CHECK-NEXT: -Wvolatile-register-var
-CHECK-NEXT: -Wobjc-missing-super-calls
-CHECK-NEXT: -Wobjc-designated-initializers
-CHECK-NEXT: -Wobjc-flexible-array
-CHECK-NEXT: -Woverloaded-virtual
-CHECK-NEXT: -Wprivate-extern
-CHECK-NEXT: -Wcast-of-sel-type
-CHECK-NEXT: -Wextern-c-compat
-CHECK-NEXT: -Wuser-defined-warnings
-CHECK-NEXT: -Wparentheses
-CHECK-NEXT: -Wlogical-op-parentheses
-CHECK-NEXT: -Wlogical-not-parentheses
-CHECK-NEXT: -Wbitwise-conditional-parentheses
-CHECK-NEXT: -Wbitwise-op-parentheses
-CHECK-NEXT: -Wshift-op-parentheses
-CHECK-NEXT: -Woverloaded-shift-op-parentheses
-CHECK-NEXT: -Wparentheses-equality
-CHECK-NEXT: -Wdangling-else
-CHECK-NEXT: -Wswitch
-CHECK-NEXT: -Wswitch-bool
-CHECK-NEXT: -Wmisleading-indentation
+ CHECK : -Wall CHECK -
+ NEXT : -Wmost
+ CHECK -
+ NEXT : -Warray - parameter CHECK - NEXT : -Wbool - operation CHECK - NEXT : -Wbitwise - instead - of - logical CHECK - NEXT : -Wchar - subscripts CHECK - NEXT : -Wcomment CHECK - NEXT : -Wdelete - non - virtual - dtor CHECK - NEXT : -Wdelete - non - abstract - non - virtual - dtor CHECK - NEXT : -Wdelete - abstract - non - virtual - dtor CHECK - NEXT : -Wformat CHECK - NEXT : -Wformat - extra - args CHECK - NEXT : -Wformat - zero - length CHECK - NEXT : -Wnonnull CHECK - NEXT : -Wformat - security CHECK - NEXT : -Wformat - y2k CHECK - NEXT : -Wformat - invalid - specifier CHECK - NEXT : -Wformat - insufficient - args CHECK - NEXT : -Wfor - loop - analysis CHECK - NEXT : -Wframe - address CHECK - NEXT : -Wimplicit CHECK - NEXT : -Wimplicit - function - declaration CHECK - NEXT : -Wimplicit - int CHECK - NEXT : -Winfinite - recursion CHECK - NEXT : -Wint - in - bool - context CHECK - NEXT : -Wmismatched - tags CHECK - NEXT : -Wmissing - braces CHECK - NEXT : -Wmove CHECK - NEXT : -Wpessimizing - move CHECK - NEXT : -Wredundant - move CHECK - NEXT : -Wreturn - std - move CHECK - NEXT : -Wself - move CHECK - NEXT : -Wmultichar CHECK - NEXT : -Wrange - loop - construct CHECK - NEXT : -Wreorder CHECK - NEXT : -Wreorder - ctor CHECK - NEXT : -Wreorder - init - list CHECK - NEXT : -Wreturn - type CHECK - NEXT : -Wreturn - type - c - linkage CHECK - NEXT : -Wself - assign CHECK - NEXT : -Wself - assign - overloaded CHECK - NEXT : -Wself - assign - field CHECK - NEXT : -Wself - move CHECK - NEXT : -Wsizeof - array - argument CHECK - NEXT : -Wsizeof - array - decay CHECK - NEXT : -Wstring - plus - int CHECK - NEXT : -Wtautological - compare CHECK - NEXT : -Wtautological - constant - compare CHECK - NEXT : -Wtautological - constant - out - of - range - compare CHECK - NEXT : -Wtautological - pointer - compare CHECK - NEXT : -Wtautological - overlap - compare CHECK - NEXT : -Wtautological - bitwise - compare CHECK - NEXT : -Wtautological - undefined - compare CHECK - NEXT : -Wtautological - objc - bool - compare CHECK - NEXT : -Wtrigraphs CHECK - NEXT : -Wuninitialized CHECK - NEXT : -Wsometimes - uninitialized CHECK - NEXT : -Wstatic - self - init CHECK - NEXT : -Wuninitialized - const - reference CHECK - NEXT : -Wunknown - pragmas CHECK - NEXT : -Wunused CHECK - NEXT : -Wunused - argument CHECK - NEXT : -Wunused - function CHECK - NEXT : -Wunneeded - internal - declaration CHECK - NEXT : -Wunused - label CHECK - NEXT : -Wunused - private - field CHECK - NEXT : -Wunused - lambda - capture CHECK - NEXT : -Wunused - local - typedef CHECK - NEXT : -Wunused - value CHECK - NEXT : -Wunused - comparison CHECK - NEXT : -Wunused - result CHECK - NEXT : -Wunevaluated - expression CHECK - NEXT : -Wpotentially - evaluated - expression CHECK - NEXT : -Wunused - variable CHECK - NEXT : -Wunused - const - variable CHECK - NEXT : -Wunused - but - set - variable CHECK - NEXT : -Wunused - property - ivar CHECK - NEXT : -Wvolatile - register - var CHECK - NEXT : -Wobjc - missing - super - calls CHECK - NEXT : -Wobjc - designated - initializers CHECK - NEXT : -Wobjc - flexible - array CHECK - NEXT : -Woverloaded - virtual CHECK - NEXT : -Wprivate - extern CHECK - NEXT : -Wcast - of - sel - type CHECK - NEXT : -Wextern - c - compat CHECK - NEXT : -Wuser - defined - warnings CHECK - NEXT : -Wparentheses CHECK - NEXT : -Wlogical - op - parentheses CHECK - NEXT : -Wlogical - not -parentheses CHECK - NEXT : -Wbitwise - conditional - parentheses CHECK - NEXT : -Wbitwise - op - parentheses CHECK - NEXT : -Wshift - op - parentheses CHECK - NEXT : -Woverloaded - shift - op - parentheses CHECK - NEXT : -Wparentheses - equality CHECK - NEXT : -Wdangling - else CHECK - NEXT : -Wswitch CHECK - NEXT : -Wswitch - bool CHECK - NEXT : -Wmisleading - indentation
-
-CHECK-NOT:-W
+ CHECK -
+ NOT : -W
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>, DefaultIgnore;
+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">;
@@ -978,6 +979,7 @@
]>;
def Most : DiagGroup<"most", [
+ ArrayParameter,
BoolOperation,
CharSubscript,
Comment,
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits