[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
Thu Jun 6 07:05:23 PDT 2024


================
@@ -13367,6 +13367,21 @@ static void DiagnoseConstAssignment(Sema &S, const Expr *E,
         if (!DiagnosticEmitted) {
           S.Diag(Loc, diag::err_typecheck_assign_const)
               << ExprRange << ConstVariable << VD << VD->getType();
+          ExprResult Deref;
+          Expr *TE = const_cast<Expr *>(E);
+          {
+            Sema::TentativeAnalysisScope Trap(S);
+            Deref = S.ActOnUnaryOp(S.getCurScope(), Loc, tok::star, TE);
+          }
+          if (Deref.isUsable() &&
+              Deref.get()->isModifiableLvalue(S.Context, &Loc) ==
+                  Expr::MLV_Valid &&
+              !E->getType()->isObjCObjectPointerType()) {
+            S.Diag(Loc, diag::note_typecheck_expression_not_modifiable_lvalue)
+                << E->getSourceRange()
+                << FixItHint::CreateInsertion(E->getBeginLoc(),
+                                              "*" + VD->getNameAsString());
----------------
Rajveer100 wrote:

This is what it currently looks like:

<details><summary>Details</summary>
<p>

```C++
clang/test/Sema/debug-93066.cpp:5:5: error: expression is not assignable
    5 |     ++this; // expected-error {{expression is not assignable}}
      |     ^ ~~~~
clang/test/Sema/debug-93066.cpp:5:5: note: add '*' to dereference it
    5 |     ++this; // expected-error {{expression is not assignable}}
      |     ^ ~~~~
      |       *(this)
clang/test/Sema/debug-93066.cpp:10:5: error: expression is not assignable
   10 |     ++this; // expected-error {{expression is not assignable}}
      |     ^ ~~~~
clang/test/Sema/debug-93066.cpp:15:3: error: assignment to cast is illegal, lvalue casts are not supported
   15 |   (int*)d = 4; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
      |   ^~~~~~~ ~
clang/test/Sema/debug-93066.cpp:15:3: note: add '*' to dereference it
   15 |   (int*)d = 4; // expected-error {{assignment to cast is illegal, lvalue casts are not supported}}
      |   ^~~~~~~ ~
      |   *(int *)
clang/test/Sema/debug-93066.cpp:19:3: error: cannot assign to variable 'b' with const-qualified type 'int *const'
   19 |   ++b; // expected-error {{cannot assign to variable 'b' with const-qualified type 'int *const'}}
      |   ^ ~
clang/test/Sema/debug-93066.cpp:19:3: note: add '*' to dereference it
   19 |   ++b; // expected-error {{cannot assign to variable 'b' with const-qualified type 'int *const'}}
      |   ^ ~
      |     *b
clang/test/Sema/debug-93066.cpp:14:27: note: variable 'b' declared const here
   14 | void f(int* a, int* const b, const int* const c, __UINTPTR_TYPE__ d) {
      |                ~~~~~~~~~~~^
clang/test/Sema/debug-93066.cpp:22:3: error: cannot assign to variable 'c' with const-qualified type 'const int *const'
   22 |   ++c; // expected-error {{cannot assign to variable 'c' with const-qualified type 'const int *const'}}
      |   ^ ~
clang/test/Sema/debug-93066.cpp:14:47: note: variable 'c' declared const here
   14 | void f(int* a, int* const b, const int* const c, __UINTPTR_TYPE__ d) {
      |                              ~~~~~~~~~~~~~~~~~^
clang/test/Sema/debug-93066.cpp:25:30: error: expression is not assignable
   25 |   reinterpret_cast<int*>(42) += 3; // expected-error {{expression is not assignable}}
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
clang/test/Sema/debug-93066.cpp:25:30: note: add '*' to dereference it
   25 |   reinterpret_cast<int*>(42) += 3; // expected-error {{expression is not assignable}}
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
      |   *(int *)
clang/test/Sema/debug-93066.cpp:29:26: error: expression is not assignable
   29 |   (const_cast<int*>(&x)) += 3; // expected-error {{expression is not assignable}}
      |   ~~~~~~~~~~~~~~~~~~~~~~ ^
clang/test/Sema/debug-93066.cpp:29:26: note: add '*' to dereference it
   29 |   (const_cast<int*>(&x)) += 3; // expected-error {{expression is not assignable}}
      |   ~~~~~~~~~~~~~~~~~~~~~~ ^
      |   *()

```

</p>
</details> 

Maybe we could FixItReplace instead?

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


More information about the cfe-commits mailing list