Author: Michael Buch
Date: 2026-02-12T15:53:04Z
New Revision: 9c9fff983fff3b92406065e33468234b28278b11

URL: 
https://github.com/llvm/llvm-project/commit/9c9fff983fff3b92406065e33468234b28278b11
DIFF: 
https://github.com/llvm/llvm-project/commit/9c9fff983fff3b92406065e33468234b28278b11.diff

LOG: [clang][Sema] Split a err_typecheck_assign_const diagnostic into a 
separate tablegen entry (#179895)

As of recently, in LLDB, when trying to mutate an object in a const
method, we emit a hint about why we failed to run the expression (with
an associated hint on how to fix it). This relies on the diagnostic ID
that Clang told us about. However, we only want to emit this message
when we assign to a member in a const method. But not all the other
situations that `err_typecheck_assign` gets used in. We currently work
around this by grepping the error message, but it would be nice if we
could just rely on the diagnostic ID.

This patch splits out the relevant diagnostic.

This isn't urgent and we can live with the "grep the error message"
approach. But if the Clang maintainers don't feel strongly about keeping
the tablegen as-is, it'd be nice to clean up from LLDB's perspective.

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaExpr.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 887d1b5f2bbfd..85a023435ba23 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7964,24 +7964,31 @@ def warn_arith_conv_mixed_unicode_types
               "
diff erent Unicode character types %1 and %2">,
       InGroup<CharacterConversion>;
 
-def err_typecheck_assign_const : Error<
-  "%select{"
-  "cannot assign to return value because function %1 returns a const value|"
-  "cannot assign to variable %1 with const-qualified type %2|"
-  "cannot assign to %select{non-|}1static data member %2 "
-  "with const-qualified type %3|"
-  "cannot assign to non-static data member within const member function %1|"
-  "cannot assign to %select{variable %2|non-static data member %2|lvalue}1 "
-  "with %select{|nested }3const-qualified data member %4|"
-  "read-only variable is not assignable}0">;
-
-def note_typecheck_assign_const : Note<
-  "%select{"
-  "function %1 which returns const-qualified type %2 declared here|"
-  "variable %1 declared const here|"
-  "%select{non-|}1static data member %2 declared const here|"
-  "member function %q1 is declared const here|"
-  "%select{|nested }1data member %2 declared const here}0">;
+def err_typecheck_assign_const
+    : Error<"%select{"
+            "cannot assign to return value because function %1 returns a const 
"
+            "value|"
+            "cannot assign to variable %1 with const-qualified type %2|"
+            "cannot assign to %select{non-|}1static data member %2 "
+            "with const-qualified type %3|"
+            "cannot assign to %select{variable %2|non-static data member "
+            "%2|lvalue}1 "
+            "with %select{|nested }3const-qualified data member %4|"
+            "read-only variable is not assignable}0">;
+
+def note_typecheck_assign_const
+    : Note<"%select{"
+           "function %1 which returns const-qualified type %2 declared here|"
+           "variable %1 declared const here|"
+           "%select{non-|}1static data member %2 declared const here|"
+           "%select{|nested }1data member %2 declared const here}0">;
+
+def err_typecheck_assign_const_method
+    : Error<"cannot assign to non-static data member within const member "
+            "function %0">;
+
+def note_typecheck_assign_const_method
+    : Note<"member function %q0 is declared const here">;
 
 def warn_unsigned_always_true_comparison : Warning<
   "result of comparison of %select{%3|unsigned expression}0 %2 "

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 233f9ff297608..fce803fcdd395 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13837,9 +13837,8 @@ enum {
   ConstFunction,
   ConstVariable,
   ConstMember,
-  ConstMethod,
   NestedConstMember,
-  ConstUnknown,  // Keep as last element
+  ConstUnknown, // Keep as last element
 };
 
 /// Emit the "read-only variable not assignable" error and print notes to give
@@ -13947,12 +13946,12 @@ static void DiagnoseConstAssignment(Sema &S, const 
Expr *E,
       if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC)) {
         if (MD->isConst()) {
           if (!DiagnosticEmitted) {
-            S.Diag(Loc, diag::err_typecheck_assign_const) << ExprRange
-                                                          << ConstMethod << MD;
+            S.Diag(Loc, diag::err_typecheck_assign_const_method)
+                << ExprRange << MD;
             DiagnosticEmitted = true;
           }
-          S.Diag(MD->getLocation(), diag::note_typecheck_assign_const)
-              << ConstMethod << MD << MD->getSourceRange();
+          S.Diag(MD->getLocation(), diag::note_typecheck_assign_const_method)
+              << MD << MD->getSourceRange();
         }
       }
     }

diff  --git 
a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp 
b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
index 4fcc640d90716..03ef2116bcaed 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp
@@ -956,12 +956,8 @@ void ClangUserExpression::FixupCVRParseErrorDiagnostics(
       [](std::unique_ptr<Diagnostic> const &diag) {
         switch (diag->GetCompilerID()) {
         case clang::diag::err_member_function_call_bad_cvr:
+        case clang::diag::err_typecheck_assign_const_method:
           return true;
-        case clang::diag::err_typecheck_assign_const:
-          // FIXME: can we split this particular error into a separate
-          // diagnostic ID so we don't need to scan the error message?
-          return diag->GetDetail().message.find(
-                     "within const member function") != std::string::npos;
         default:
           return false;
         }


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to