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

Rajveer Singh Bharadwaj via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 2 06:09:58 PDT 2024


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

>From e637dc83ec205f7e4dde356b8f5d06ce3abc899e 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                      | 16 ++++++++++++++--
 clang/test/Sema/debug-93066.cpp                  | 14 ++++++++++++++
 debug-84072.cpp                                  | 16 ++++++++++++++++
 4 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/Sema/debug-93066.cpp
 create mode 100644 debug-84072.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..62cbc8a3a6a45 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13587,10 +13587,22 @@ 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}}
+  }
+};
diff --git a/debug-84072.cpp b/debug-84072.cpp
new file mode 100644
index 0000000000000..c024f50019f8c
--- /dev/null
+++ b/debug-84072.cpp
@@ -0,0 +1,16 @@
+void Func(int x) {
+    switch (x) {
+        [[likely]] case 0:
+        case 1:
+            int i = 3;
+        case 2:
+            break;
+    }
+    switch (x) {
+        case 0:
+        case 1:
+            int i = 3;
+        case 2:
+            break;
+    }
+}



More information about the llvm-commits mailing list