[clang] [clang] Improve diagnostics with incompatible VLA types (PR #101261)
Andrew Sukach via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 20 04:57:10 PDT 2024
https://github.com/sookach updated https://github.com/llvm/llvm-project/pull/101261
>From 2666871e019dee2314933cc60bcb4ca27d7555ba Mon Sep 17 00:00:00 2001
From: Andrew Sukach <andrewsukach at gmail.com>
Date: Tue, 30 Jul 2024 19:31:41 -0400
Subject: [PATCH] [clang] Improve diagnostics with incompatible VLA types
---
.../clang/Basic/DiagnosticSemaKinds.td | 3 ++
clang/lib/Basic/Diagnostic.cpp | 35 +++++++++++++------
.../test/Sema/incompatible-vla-assignment.cpp | 9 +++++
3 files changed, 37 insertions(+), 10 deletions(-)
create mode 100644 clang/test/Sema/incompatible-vla-assignment.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9e6d85c469d641..5533ffb4b991c3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8643,6 +8643,9 @@ def err_typecheck_convert_incompatible_pointer : Error<
"; take the address with &|"
"; remove *|"
"; remove &}3">;
+def err_typecheck_convert_incompatible_vla : Error<
+ "incompatible assignment of pointers of variable-length array type %0"
+ "; consider using a typedef to use the same variable-length array type for both operands">;
def err_typecheck_convert_incompatible_function_pointer : Error<
"incompatible function pointer types "
"%select{%diff{assigning to $ from $|assigning to different types}0,1"
diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
index 66776daa5e1493..b7029dd6472e7c 100644
--- a/clang/lib/Basic/Diagnostic.cpp
+++ b/clang/lib/Basic/Diagnostic.cpp
@@ -1099,37 +1099,52 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
const char *FirstDollar = ScanFormat(Argument, ArgumentEnd, '$');
const char *SecondDollar = ScanFormat(FirstDollar + 1, ArgumentEnd, '$');
- // Append before text
- FormatDiagnostic(Argument, FirstDollar, OutStr);
-
- // Append first type
+ // Get first type text
TDT.PrintTree = false;
TDT.PrintFromType = true;
+ SmallString<64> FromTypeStr, ToTypeStr;
getDiags()->ConvertArgToString(Kind, val,
StringRef(Modifier, ModifierLen),
StringRef(Argument, ArgumentLen),
FormattedArgs,
- OutStr, QualTypeVals);
+ FromTypeStr, QualTypeVals);
if (!TDT.TemplateDiffUsed)
FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
TDT.FromType));
- // Append middle text
- FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
-
- // Append second type
+ // Get second type text
TDT.PrintFromType = false;
getDiags()->ConvertArgToString(Kind, val,
StringRef(Modifier, ModifierLen),
StringRef(Argument, ArgumentLen),
FormattedArgs,
- OutStr, QualTypeVals);
+ ToTypeStr, QualTypeVals);
if (!TDT.TemplateDiffUsed)
FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
TDT.ToType));
+ // Append before text
+ FormatDiagnostic(Argument, FirstDollar, OutStr);
+
+ // Append first type
+ OutStr.append(FromTypeStr);
+
+ // Append middle text
+ FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr);
+
+ // Append second type
+ OutStr.append(ToTypeStr);
+
// Append end text
FormatDiagnostic(SecondDollar + 1, Pipe, OutStr);
+
+ if (FromTypeStr == ToTypeStr) {
+ SmallString<86> IncompatibleVLADiag(
+ "; consider using a typedef to use the same variable-length array "
+ "type for both operands");
+ OutStr.append(IncompatibleVLADiag);
+ }
+
break;
}
}
diff --git a/clang/test/Sema/incompatible-vla-assignment.cpp b/clang/test/Sema/incompatible-vla-assignment.cpp
new file mode 100644
index 00000000000000..8be063631b7a8a
--- /dev/null
+++ b/clang/test/Sema/incompatible-vla-assignment.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void func(int n) {
+ int grp[n][n];
+ int (*ptr)[n];
+
+ for (int i = 0; i < n; i++)
+ ptr = &grp[i]; // expected-error {{incompatible pointer types assigning to 'int (*)[n]' from 'int (*)[n]'; consider using a typedef to use the same variable-length array type for both operands}}
+}
More information about the cfe-commits
mailing list