[clang] cc5b772 - [clang] Introduce -Warray-parameter
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 8 13:37:27 PDT 2022
Author: serge-sans-paille
Date: 2022-07-08T22:36:05+02:00
New Revision: cc5b77273af3705b6f5cf574567b49d5158bb3a9
URL: https://github.com/llvm/llvm-project/commit/cc5b77273af3705b6f5cf574567b49d5158bb3a9
DIFF: https://github.com/llvm/llvm-project/commit/cc5b77273af3705b6f5cf574567b49d5158bb3a9.diff
LOG: [clang] Introduce -Warray-parameter
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
Differential Revision: https://reviews.llvm.org/D128449
Added:
clang/test/Sema/array-parameter.c
clang/test/Sema/array-parameter.cpp
Modified:
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
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9d244ca5fbf0d..c6d36568099b4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -321,6 +321,11 @@ New Compiler Flags
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 diagnoses
diff erences between
+ array parameters between function redeclarations (arrays of
diff erent extents,
+ etc). This flag is related to the same flag in GCC, but is
diff erent in that
+ it does not accept an explicitly- specified warning level and use of this flag
+ has no effect on ``-Warray-bounds``.
Deprecated Compiler Flags
-------------------------
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 10da02ecbf7e8..0c9646e525e50 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -31,6 +31,7 @@ def GNUAnonymousStruct : DiagGroup<"gnu-anonymous-struct">;
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 Extra : DiagGroup<"extra", [
]>;
def Most : DiagGroup<"most", [
+ ArrayParameter,
BoolOperation,
CharSubscript,
Comment,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c811cd855d503..fd10bd9c70e6a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9400,6 +9400,12 @@ def warn_array_index_exceeds_max_addressable_bounds : Warning<
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<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index d6c89d525cdc2..927d81826425b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3207,6 +3207,39 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl,
if (!foundAny) newDecl->dropAttrs();
}
+static bool EquivalentArrayTypes(QualType Old, QualType New,
+ const ASTContext &Ctx) {
+
+ auto NoSizeInfo = [&Ctx](QualType Ty) {
+ if (Ty->isIncompleteArrayType() || Ty->isPointerType())
+ return true;
+ if (const auto *VAT = Ctx.getAsVariableArrayType(Ty))
+ return VAT->getSizeModifier() == ArrayType::ArraySizeModifier::Star;
+ return false;
+ };
+
+ // `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 = Ctx.getAsVariableArrayType(Old);
+ const auto *NewVAT = Ctx.getAsVariableArrayType(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 Ctx.getAsConstantArrayType(Old)->getSize() ==
+ Ctx.getAsConstantArrayType(New)->getSize();
+
+ return Old == New;
+}
+
static void mergeParamDeclTypes(ParmVarDecl *NewParam,
const ParmVarDecl *OldParam,
Sema &S) {
@@ -3232,6 +3265,19 @@ static void mergeParamDeclTypes(ParmVarDecl *NewParam,
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.getASTContext())) {
+ S.Diag(NewParam->getLocation(), diag::warn_inconsistent_array_form)
+ << NewParam << NewParamOT;
+ S.Diag(OldParam->getLocation(), diag::note_previous_declaration_as)
+ << OldParamOT;
+ }
+ }
}
namespace {
diff --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c
index a4a79bec934af..e57c5d6d501da 100644
--- a/clang/test/Misc/warning-wall.c
+++ b/clang/test/Misc/warning-wall.c
@@ -3,6 +3,7 @@ RUN: FileCheck --input-file=%t %s
CHECK:-Wall
CHECK-NEXT: -Wmost
+CHECK-NEXT: -Warray-parameter
CHECK-NEXT: -Wbool-operation
CHECK-NEXT: -Wbitwise-instead-of-logical
CHECK-NEXT: -Wchar-subscripts
diff --git a/clang/test/Sema/array-parameter.c b/clang/test/Sema/array-parameter.c
new file mode 100644
index 0000000000000..2aa9ab0cdc17c
--- /dev/null
+++ b/clang/test/Sema/array-parameter.c
@@ -0,0 +1,35 @@
+// 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[volatile 2]);
+void f6(int a[2]); // no warning
+
+void f7(int a[*]);
+void f7(int a[]); // no warning
+
+void f8(int n, int a[*]); // expected-note {{previously declared as 'int[*]' here}}
+void f8(int n, int a[n]); // expected-warning {{argument 'a' of type 'int[n]' with mismatched bound}}
+
+void f9(int *a);
+void f9(int a[2]);
+void f9(int a[]); // expected-warning {{argument 'a' of type 'int[]' with mismatched bound}}
+ // expected-note at -2 {{previously declared as 'int[2]' here}}
+void f9(int a[2]) // expected-warning {{argument 'a' of type 'int[2]' with mismatched bound}}
+ // expected-note at -3 {{previously declared as 'int[]' here}}
+{}
diff --git a/clang/test/Sema/array-parameter.cpp b/clang/test/Sema/array-parameter.cpp
new file mode 100644
index 0000000000000..6842226c71ea7
--- /dev/null
+++ b/clang/test/Sema/array-parameter.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -Warray-parameter -verify %s
+
+template <int N>
+void func(int i[10]); // expected-note {{previously declared as 'int[10]' here}}
+
+template <int N>
+void func(int i[N]); // expected-warning {{argument 'i' of type 'int[N]' with mismatched bound}}
+
+template <int N>
+void func(int (&Val)[N]);
+
+template <>
+void func<10>(int (&Val)[10]) {
+}
+
+static constexpr int Extent = 10;
+void funk(int i[10]);
+void funk(int i[Extent]); // no-warning
More information about the cfe-commits
mailing list