[clang] [clang] Fix-it hint for `++this` -> `++*this` when deref is modifiable (PR #94159)

Rajveer Singh Bharadwaj via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 2 06:08:35 PDT 2024


https://github.com/Rajveer100 created https://github.com/llvm/llvm-project/pull/94159

Resolves #93066

>From 9c90d4a83a913566d782774700a06dd640722dfd Mon Sep 17 00:00:00 2001
From: Rajveer <rajveer.developer at icloud.com>
Date: Sun, 2 Jun 2024 18:33:37 +0530
Subject: [PATCH] [clang] Fix-it hint for `++this` -> `++*this` when deref is
 modifiable

Resolves #93066
---
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  3 +++
 clang/lib/Sema/SemaExpr.cpp                      | 15 +++++++++++++--
 clang/test/Sema/debug-93066.cpp                  | 14 ++++++++++++++
 3 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/debug-93066.cpp

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 270b0a1e01307..0f5445296e45f 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8777,6 +8777,9 @@ def err_typecheck_incomplete_type_not_modifiable_lvalue : Error<
 def err_typecheck_lvalue_casts_not_supported : Error<
   "assignment to cast is illegal, lvalue casts are not supported">;
 
+def note_typecheck_expression_not_modifiable_lvalue : Note<
+  "dereference the pointer to modify">; 
+
 def err_typecheck_duplicate_vector_components_not_mlvalue : Error<
   "vector is not assignable (contains duplicate components)">;
 def err_block_decl_ref_not_modifiable_lvalue : Error<
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ff9c5ead36dcf..39e7962fcb2a6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13587,10 +13587,21 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) {
   SourceRange Assign;
   if (Loc != OrigLoc)
     Assign = SourceRange(OrigLoc, OrigLoc);
-  if (NeedType)
+  if (NeedType) {
     S.Diag(Loc, DiagID) << E->getType() << E->getSourceRange() << Assign;
-  else
+  } else {
+    ExprResult Deref;
+    unsigned FixitDiagID = 0;
+    {
+      Sema::TentativeAnalysisScope Trap(S);
+      Deref = S.ActOnUnaryOp(S.getCurScope(), Loc, tok::star, E);
+    }
     S.Diag(Loc, DiagID) << E->getSourceRange() << Assign;
+    if (Deref.isUsable() && Deref.get()->isModifiableLvalue(S.Context, &Loc) == Expr::MLV_Valid) {
+      FixitDiagID = diag::note_typecheck_expression_not_modifiable_lvalue;
+      S.Diag(Loc, FixitDiagID) << E->getSourceRange() << Assign;
+    }
+  }
   return true;
 }
 
diff --git a/clang/test/Sema/debug-93066.cpp b/clang/test/Sema/debug-93066.cpp
new file mode 100644
index 0000000000000..7abedcd0d4d80
--- /dev/null
+++ b/clang/test/Sema/debug-93066.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
+
+struct S {
+  void f() {
+    ++this;
+    // expected-error at -1 {{expression is not assignable}}
+    // expected-note at -2 {{dereference the pointer to modify}}
+  }
+
+  void g() const {
+    ++this;
+    // expected-error at -1 {{expression is not assignable}}
+  }
+};



More information about the cfe-commits mailing list