[clang][Sema] Remove dead diagnostic for loss of __unaligned qualifier
authorTakuya Shimizu <shimizu2486@gmail.com>
Thu, 29 Jun 2023 14:02:09 +0000 (23:02 +0900)
committerTakuya Shimizu <shimizu2486@gmail.com>
Thu, 29 Jun 2023 14:02:09 +0000 (23:02 +0900)
D120936 has made the loss of `__unaligned` qualifier NOT a bad-conversion.
Because of this, the bad-conversion note about the loss of this qualifier does not take effect.
e.g.
```
void foo(int *ptr);

void func(const __unaligned int *var) { foo(var); }
```
BEFORE this patch:
```
source.cpp:3:41: error: no matching function for call to 'foo'
    3 | void func(const __unaligned int *var) { foo(var); }
      |                                         ^~~
source.cpp:1:6: note: candidate function not viable: 1st argument ('const __unaligned int *') would lose __unaligned qualifier
    1 | void foo(int *ptr);
      |      ^
    2 |
    3 | void func(const __unaligned int *var) { foo(var); }
      |                                             ~~~
```
AFTER this patch:
```
source.cpp:3:41: error: no matching function for call to 'foo'
    3 | void func(const __unaligned int *var) { foo(var); }
      |                                         ^~~
source.cpp:1:6: note: candidate function not viable: 1st argument ('const __unaligned int *') would lose const qualifier
    1 | void foo(int *ptr);
      |      ^
    2 |
    3 | void func(const __unaligned int *var) { foo(var); }
      |                                             ~~~
```
Please note the different mentions of `__unaligned` and `const` in notes.

Reviewed By: cjdb, rnk
Differential Revision: https://reviews.llvm.org/D153690

clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaOverload.cpp
clang/test/SemaCXX/MicrosoftExtensions.cpp

index f00082f..03c27a2 100644 (file)
@@ -375,6 +375,8 @@ Improvements to Clang's diagnostics
   by making use of the syntactical structure of function calls. This avoids display
   of syntactically invalid codes in diagnostics.
   (`#57081: <https://github.com/llvm/llvm-project/issues/57081>`_)
+- Clang no longer emits inappropriate notes about the loss of ``__unaligned`` qualifier
+  on overload resolution, when the actual reason for the failure is loss of other qualifiers.
 
 Bug Fixes in This Version
 -------------------------
index 507e9f1..c2b8bd4 100644 (file)
@@ -4700,9 +4700,6 @@ def note_ovl_candidate_bad_cvr : Note<
     "%select{const|restrict|const and restrict|volatile|const and volatile|"
     "volatile and restrict|const, volatile, and restrict}4 qualifier"
     "%select{||s||s|s|s}4">;
-def note_ovl_candidate_bad_unaligned : Note<
-    "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
-    "%ordinal5 argument (%3) would lose __unaligned qualifier">;
 def note_ovl_candidate_bad_base_to_derived_conv : Note<
     "candidate %sub{select_ovl_candidate_kind}0,1,2 not viable: "
     "cannot %select{convert from|convert from|bind}3 "
index 0d2db9f..febcbad 100644 (file)
@@ -10821,15 +10821,6 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
       return;
     }
 
-    if (FromQs.hasUnaligned() != ToQs.hasUnaligned()) {
-      S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_unaligned)
-          << (unsigned)FnKindPair.first << (unsigned)FnKindPair.second << FnDesc
-          << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy
-          << FromQs.hasUnaligned() << I + 1;
-      MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl);
-      return;
-    }
-
     unsigned CVR = FromQs.getCVRQualifiers() & ~ToQs.getCVRQualifiers();
     assert(CVR && "expected qualifiers mismatch");
 
index effe2e6..960030d 100644 (file)
@@ -68,19 +68,23 @@ __unaligned int aligned_type4::* __unaligned p3_aligned_type4 = &aligned_type4::
 void (aligned_type4::*__unaligned p4_aligned_type4)();
 
 // Check that __unaligned qualifier can be used for overloading
-void foo_unaligned(int *arg) {}
-void foo_unaligned(__unaligned int *arg) {}
+void foo_unaligned(int *arg) {} // expected-note {{not viable: 1st argument ('const __unaligned int *') would lose const qualifier}}
+void foo_unaligned(__unaligned int *arg) {} // expected-note {{not viable: 1st argument ('const __unaligned int *') would lose const qualifier}}
 void foo_unaligned(int arg) {} // expected-note {{previous definition is here}}
-void foo_unaligned(__unaligned int arg) {} // expected-error {{redefinition of 'foo_unaligned'}}
+void foo_unaligned(__unaligned int arg) {} // expected-error {{redefinition of 'foo_unaligned'}} \
+                                           // expected-note {{not viable: no known conversion from 'const __unaligned int *' to '__unaligned int'}}
 class A_unaligned {};
 class B_unaligned : public A_unaligned {};
-int foo_unaligned(__unaligned A_unaligned *arg) { return 0; }
-void *foo_unaligned(B_unaligned *arg) { return 0; }
+int foo_unaligned(__unaligned A_unaligned *arg) { return 0; } // expected-note {{not viable: no known conversion from 'const __unaligned int *' to '__unaligned A_unaligned *'}}
+void *foo_unaligned(B_unaligned *arg) { return 0; } // expected-note {{not viable: no known conversion from 'const __unaligned int *' to 'B_unaligned *'}}
 
 void test_unaligned() {
   int *p1 = 0;
   foo_unaligned(p1);
 
+  const __unaligned int *const_p1 = 0;
+  foo_unaligned(const_p1); // expected-error {{no matching function for call to 'foo_unaligned'}}
+
   __unaligned int *p2 = 0;
   foo_unaligned(p2);