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 <andrewsuk...@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}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits