Richard,
here's the reference-cast case of the unrelated hierarchy patch I recently
created for ptr-to-class (http://llvm.org/bugs/show_bug.cgi?id=17456). I had a
bit of a struggle coming up with a nicely worded diagnostic. This now produces:
17456-2.cc:6:10: error: non-const lvalue reference to class 'B' cannot bind to a
value of class 'A', which is not related by inheritance
return static_cast<B&>(arg);
^ ~~~
when the src and target reference types are classes. It also notes if either is
incomplete.
ok?
nathan
Index: src/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- src/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td (revision 228403)
+++ src/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td (working copy)
@@ -1470,6 +1470,10 @@ def err_lvalue_reference_bind_to_unrelat
"%select{non-const|volatile}0 lvalue reference "
"%diff{to type $ cannot bind to a value of unrelated type $|"
"cannot bind to a value of unrelated type}1,2">;
+def err_lvalue_reference_bind_to_unrelated_class : Error<
+ "%select{non-const|volatile}0 lvalue reference "
+ "%diff{to class $ cannot bind to a value of class $, which is not related by inheritance|"
+ "cannot bind to a value of class type that is not related by inheritance}1,2">;
def err_reference_bind_drops_quals : Error<
"binding of reference %diff{to type $ to a value of type $ drops qualifiers|"
"drops qualifiers}0,1">;
Index: src/tools/clang/lib/Sema/SemaInit.cpp
===================================================================
--- src/tools/clang/lib/Sema/SemaInit.cpp (revision 228403)
+++ src/tools/clang/lib/Sema/SemaInit.cpp (working copy)
@@ -6646,14 +6646,32 @@ bool InitializationSequence::Diagnose(Se
// Intentional fallthrough
case FK_NonConstLValueReferenceBindingToUnrelated:
- S.Diag(Kind.getLocation(),
- Failure == FK_NonConstLValueReferenceBindingToTemporary
+ {
+ auto DestNonRef = DestType.getNonReferenceType();
+ auto SrcType = Args[0]->getType();
+ auto DestRec = DestNonRef->getAs<RecordType>();
+ auto SrcRec = SrcType->getAs<RecordType>();
+ S.Diag(Kind.getLocation(),
+ Failure == FK_NonConstLValueReferenceBindingToTemporary
? diag::err_lvalue_reference_bind_to_temporary
+ : DestRec && SrcRec
+ ? diag::err_lvalue_reference_bind_to_unrelated_class
: diag::err_lvalue_reference_bind_to_unrelated)
- << DestType.getNonReferenceType().isVolatileQualified()
- << DestType.getNonReferenceType()
- << Args[0]->getType()
- << Args[0]->getSourceRange();
+ << DestNonRef.isVolatileQualified() << DestNonRef
+ << SrcType << Args[0]->getSourceRange();
+ if (SrcRec) {
+ auto SrcDecl = SrcRec->getAsCXXRecordDecl();
+ if (!SrcDecl->isCompleteDefinition())
+ S.Diag(SrcDecl->getLocation(), diag::note_type_incomplete)
+ << SrcDecl->getDeclName();
+ }
+ if (DestRec) {
+ auto DestDecl = DestRec->getAsCXXRecordDecl();
+ if (!DestDecl->isCompleteDefinition())
+ S.Diag(DestDecl->getLocation(), diag::note_type_incomplete)
+ << DestDecl->getDeclName();
+ }
+ }
break;
case FK_RValueReferenceBindingToLValue:
Index: src/tools/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
===================================================================
--- src/tools/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp (revision 228403)
+++ src/tools/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp (working copy)
@@ -51,7 +51,7 @@ void bind_lvalue_to_lvalue(Base b, Deriv
Base &br1 = b;
Base &br2 = d;
Derived &dr1 = d;
- Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'Derived' cannot bind to a value of unrelated type 'Base'}}
+ Derived &dr2 = b; // expected-error{{non-const lvalue reference to class 'Derived' cannot bind to a value of class 'Base', which is not related by inheritance}}
Base &br3 = bc; // expected-error{{drops qualifiers}}
Base &br4 = dc; // expected-error{{drops qualifiers}}
Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'Diamond' to base class 'Base':}}
@@ -83,8 +83,8 @@ void bind_lvalue_to_rvalue() {
}
void bind_lvalue_to_unrelated(Unrelated ur) {
- Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a value of unrelated type 'Unrelated'}}
- const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a value of unrelated type 'Unrelated'}}
+ Base &br1 = ur; // expected-error{{non-const lvalue reference to class 'Base' cannot bind to a value of class 'Unrelated', which is not related by inheritance}}
+ const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to class 'const volatile Base' cannot bind to a value of class 'Unrelated', which is not related by inheritance}}
}
void bind_lvalue_to_conv_lvalue() {
Index: src/tools/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p9.cpp
===================================================================
Index: src/tools/clang/test/Misc/diag-template-diffing-color.cpp
===================================================================
--- src/tools/clang/test/Misc/diag-template-diffing-color.cpp (revision 228403)
+++ src/tools/clang/test/Misc/diag-template-diffing-color.cpp (working copy)
@@ -13,8 +13,8 @@ int main() {
foo<int> A;
foo<double> &B = A;
-// CHECK: {{.*}}non-const lvalue reference to type 'foo<[[CYAN]]double[[RESET]][[BOLD:.\[1m]]>' cannot bind to a value of unrelated type 'foo<[[CYAN]]int[[RESET]][[BOLD]]>'[[RESET]]
-// TREE: non-const lvalue reference cannot bind to a value of unrelated type
+// CHECK: {{.*}}non-const lvalue reference to class 'foo<[[CYAN]]double[[RESET]][[BOLD:.\[1m]]>' cannot bind to a value of class 'foo<[[CYAN]]int[[RESET]][[BOLD]]>', which is not related by inheritance[[RESET]]
+// TREE: non-const lvalue reference cannot bind to a value of class type that is not related by inheritance
// TREE: foo<
// TREE: {{\[}}[[CYAN]]double[[RESET]][[BOLD:.\[1m]] != [[CYAN]]int[[RESET]][[BOLD]]]>[[RESET]]
Index: src/tools/clang/test/SemaCXX/rval-references.cpp
===================================================================
--- src/tools/clang/test/SemaCXX/rval-references.cpp (revision 228403)
+++ src/tools/clang/test/SemaCXX/rval-references.cpp (working copy)
@@ -48,7 +48,7 @@ void f() {
conv_to_not_int_rvalue cnir;
not_int &&ni4 = cnir;
- not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'not_int' cannot bind to a value of unrelated type 'conv_to_not_int_rvalue'}}
+ not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to class 'not_int' cannot bind to a value of class 'conv_to_not_int_rvalue', which is not related by inheritance}}
not_int &&ni6 = conv_to_not_int_rvalue();
fun_type &&fun_ref = fun; // works because functions are special
Index: src/tools/clang/test/SemaCXX/static-cast.cpp
===================================================================
--- src/tools/clang/test/SemaCXX/static-cast.cpp (revision 228403)
+++ src/tools/clang/test/SemaCXX/static-cast.cpp (working copy)
@@ -93,7 +93,7 @@ void t_529_5_8()
(void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
(void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
(void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'B *' to 'E *', which are not related by inheritance, is not allowed}}
- (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot bind to a value of unrelated type 'B'}}
+ (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to class 'E' cannot bind to a value of class 'B', which is not related by inheritance}}
(void)static_cast<E*>((J*)0); // expected-error {{static_cast from 'J *' to 'E *', which are not related by inheritance, is not allowed}}
Index: src/tools/clang/test/SemaTemplate/derived.cpp
===================================================================
--- src/tools/clang/test/SemaTemplate/derived.cpp (revision 228403)
+++ src/tools/clang/test/SemaTemplate/derived.cpp (working copy)
@@ -25,7 +25,7 @@ namespace rdar13267210 {
void AddSourceLocation(A<long> &R); // expected-note{{passing argument to parameter 'R' here}}
void AddTemplateKWAndArgsInfo() {
- AddSourceLocation(Record); // expected-error{{non-const lvalue reference to type}}
+ AddSourceLocation(Record); // expected-error{{non-const lvalue reference to class 'A<long>' cannot bind to a value of class 'C<long, 64>', which is not related by inheritance}}
}
};
}
# svn diff src/tools/clang/tools/extra
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits