serge-sans-paille updated this revision to Diff 439718.
serge-sans-paille added a comment.
Take review into account : rework indentation, style cleaning and be more
accurate about bounds reporting
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,32 @@
+// 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]);
+void f3(int a[2]); // no warning
+
+void f4(int a[static 2]);
+void f4(int a[2]); // no warning
+
+void f5(int a[restrict 2]);
+void f5(int a[2]); // no warning
+
+void f6(int a[*]);
+void f6(int a[]); // no warning
+
+void f7(int n, int a[*]); // expected-note {{previously declared as int[*] here}}
+void f7(int n, int a[n]); // expected-warning {{argument 'a' of type 'int[n]' with mismatched bound}}
+
+void f8(int *a);
+void f8(int a[2]);
+void f8(int a[]); // expected-warning {{argument 'a' of type 'int[]' with mismatched bound}}
+ // expected-note@-2 {{previously declared as int[2] here}}
+void f8(int a[2]) // expected-warning {{argument 'a' of type 'int[2]' with mismatched bound}}
+ // expected-note@-3 {{previously declared as int[] here}}
+{}
Index: clang/test/Misc/warning-wall.c
===================================================================
--- clang/test/Misc/warning-wall.c
+++ clang/test/Misc/warning-wall.c
@@ -3,6 +3,7 @@
CHECK:-Wall
CHECK-NEXT: -Wmost
+CHECK-NEXT: -Warray-parameter
CHECK-NEXT: -Wbool-operation
CHECK-NEXT: -Wbitwise-instead-of-logical
CHECK-NEXT: -Wchar-subscripts
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -3209,6 +3209,36 @@
if (!foundAny) newDecl->dropAttrs();
}
+static bool EquivalentArrayTypes(QualType Old, QualType New) {
+ auto NoSizeInfo = [](QualType Ty) {
+ return Ty->isIncompleteArrayType() || Ty->isPointerType() ||
+ (Ty->isVariableArrayType() &&
+ cast<VariableArrayType>(Ty)->getSizeModifier() ==
+ ArrayType::ArraySizeModifier::Star);
+ };
+
+ // `type[]` is equivalent to `type *` and `type[*]`
+ if (NoSizeInfo(Old) && NoSizeInfo(New))
+ return true;
+
+ // Don't try to compare VLA sizes, unless one of them has the star modifier
+ if (Old->isVariableArrayType() && New->isVariableArrayType()) {
+ const auto *OldVAT = cast<VariableArrayType>(Old);
+ const auto *NewVAT = cast<VariableArrayType>(New);
+ if ((OldVAT->getSizeModifier() == ArrayType::ArraySizeModifier::Star) ^
+ (NewVAT->getSizeModifier() == ArrayType::ArraySizeModifier::Star))
+ return false;
+ return true;
+ }
+
+ // Only compare size, ignore Size modifiers and CVR
+ if (Old->isConstantArrayType() && New->isConstantArrayType())
+ return cast<ConstantArrayType>(Old)->getSize() ==
+ cast<ConstantArrayType>(New)->getSize();
+
+ return Old == New;
+}
+
static void mergeParamDeclTypes(ParmVarDecl *NewParam,
const ParmVarDecl *OldParam,
Sema &S) {
@@ -3234,6 +3264,20 @@
NewParam->setType(NewT);
}
}
+ const auto *OldParamDT = dyn_cast<DecayedType>(OldParam->getType());
+ const auto *NewParamDT = dyn_cast<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