[clang] [clang][Sema] Simplify err_init_conversion_failed diagnostic message for const variables (PR #82109)
Artem Tyurin via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 17 06:21:52 PST 2024
https://github.com/agentcooper created https://github.com/llvm/llvm-project/pull/82109
Fixes #73399.
I initially tried to create a new `EntityKind` enum case to represent constants as it makes it easier to use `Entity.getKind()` with the diagnostic message. But in the end I've decided against it, as the new case needs to be handled in many places and feels error-prone.
>From 114a6b7a5c1b9993e06d49bfd0c377baaef2d7cb Mon Sep 17 00:00:00 2001
From: Artem Tyurin <artem.tyurin at gmail.com>
Date: Sat, 17 Feb 2024 15:16:17 +0100
Subject: [PATCH 1/2] [clang][Sema] Simplify err_init_conversion_failed
diagnostic message for const variables
---
.../clang/Basic/DiagnosticSemaKinds.td | 2 +-
clang/lib/Sema/SemaInit.cpp | 22 ++++++++++++++-----
.../SemaCXX/constant-expression-cxx11.cpp | 2 +-
.../SemaCXX/err_init_conversion_failed.cpp | 11 ++++++++++
4 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b4dc4feee8e63a..1c9a69167c28d1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2204,7 +2204,7 @@ def err_destructor_template : Error<
// C++ initialization
def err_init_conversion_failed : Error<
- "cannot initialize %select{a variable|a parameter|template parameter|"
+ "cannot initialize %select{a constant|a variable|a parameter|template parameter|"
"return object|statement expression result|an "
"exception object|a member subobject|an array element|a new value|a value|a "
"base class|a constructor delegation|a vector element|a block element|a "
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index b6de06464cd6f3..c1846d9a80c8f2 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -9804,12 +9804,22 @@ bool InitializationSequence::Diagnose(Sema &S,
case FK_ConversionFailed: {
QualType FromType = OnlyArg->getType();
- PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed)
- << (int)Entity.getKind()
- << DestType
- << OnlyArg->isLValue()
- << FromType
- << Args[0]->getSourceRange();
+
+ // NOTE: need to be in sync with err_init_conversion_failed
+ const auto TotalSpecialKinds = 1;
+
+ PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed);
+ if (Entity.getKind() == InitializedEntity::EK_Variable &&
+ DestType.isConstQualified()) {
+ QualType NonConstDestType = DestType;
+ NonConstDestType.removeLocalConst();
+ PDiag << 0 /* a constant */
+ << NonConstDestType;
+ } else {
+ PDiag << (TotalSpecialKinds + (int)Entity.getKind()) << DestType;
+ }
+ PDiag << OnlyArg->isLValue() << FromType << Args[0]->getSourceRange();
+
S.HandleFunctionTypeMismatch(PDiag, FromType, DestType);
S.Diag(Kind.getLocation(), PDiag);
emitBadConversionNotes(S, Entity, Args[0]);
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 9e2ae07cbe4c9c..19ab0cc27cc015 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -901,7 +901,7 @@ static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
// Core issue 903: we do not perform constant evaluation when checking for a
// null pointer in C++11. Just check for an integer literal with value 0.
-constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a variable of type 'Base *const' with an rvalue of type 'int'}}
+constexpr Base *nullB = 42 - 6 * 7; // expected-error {{cannot initialize a constant of type 'Base *' with an rvalue of type 'int'}}
constexpr Base *nullB1 = 0;
static_assert((Bottom*)nullB == 0, "");
static_assert((Derived*)nullB1 == 0, "");
diff --git a/clang/test/SemaCXX/err_init_conversion_failed.cpp b/clang/test/SemaCXX/err_init_conversion_failed.cpp
index e31f215b4528cb..107ba1bbf51969 100644
--- a/clang/test/SemaCXX/err_init_conversion_failed.cpp
+++ b/clang/test/SemaCXX/err_init_conversion_failed.cpp
@@ -59,3 +59,14 @@ void test_15() {
// expected-error-re at -1{{cannot initialize a member subobject of type 'void (template_test::S::*)(const int &){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (template_test::S::*)(int){{( __attribute__\(\(thiscall\)\))?}}': type mismatch at 1st parameter ('const int &' vs 'int')}}
}
}
+
+void test_16() {
+ const int a = (void)0;
+ // expected-error at -1{{cannot initialize a constant of type 'int'}}
+
+ int* const c = (void)0;
+ // expected-error at -1{{cannot initialize a constant of type 'int *'}}
+
+ const int* b = (void)0;
+ // expected-error at -1{{cannot initialize a variable of type 'const int *'}}
+}
\ No newline at end of file
>From b430a73246ef66e5a48bdb73fbd0fc8a8aba0752 Mon Sep 17 00:00:00 2001
From: Artem Tyurin <artem.tyurin at gmail.com>
Date: Sat, 17 Feb 2024 15:18:23 +0100
Subject: [PATCH 2/2] Add newline
---
clang/test/SemaCXX/err_init_conversion_failed.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/SemaCXX/err_init_conversion_failed.cpp b/clang/test/SemaCXX/err_init_conversion_failed.cpp
index 107ba1bbf51969..359d840070f2c4 100644
--- a/clang/test/SemaCXX/err_init_conversion_failed.cpp
+++ b/clang/test/SemaCXX/err_init_conversion_failed.cpp
@@ -69,4 +69,4 @@ void test_16() {
const int* b = (void)0;
// expected-error at -1{{cannot initialize a variable of type 'const int *'}}
-}
\ No newline at end of file
+}
More information about the cfe-commits
mailing list