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
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
-------------------------
"%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 "
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");
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);