[PATCH] D85390: [Clang] Add note for bad conversion error when expression is of forward-declared type
Zequan Wu via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 7 10:50:02 PDT 2020
zequanwu updated this revision to Diff 283949.
zequanwu added a comment.
Update diag note.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D85390/new/
https://reviews.llvm.org/D85390
Files:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaInit.cpp
clang/test/Modules/namespaces.cpp
clang/test/SemaCXX/elaborated-type-specifier.cpp
clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp
Index: clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class A1 {};
+class B1; // expected-note{{'B1' is not defined, but forward declared here; conversion would be valid if it's derived from 'A1'}}
+B1 *b1;
+A1 *a1 = b1; // expected-error{{cannot initialize a variable of type 'A1 *' with an lvalue of type 'B1 *'}}
+
+template <class C> class A2 {};
+template <class C> class B2;
+B2<int> *b2;
+A2<int> *a2 = b2; // expected-error{{cannot initialize a variable of type 'A2<int> *' with an lvalue of type 'B2<int> *'}}
Index: clang/test/SemaCXX/elaborated-type-specifier.cpp
===================================================================
--- clang/test/SemaCXX/elaborated-type-specifier.cpp
+++ clang/test/SemaCXX/elaborated-type-specifier.cpp
@@ -26,7 +26,7 @@
}
void test_X_elab(NS::X x) {
- struct S4 *s4 = 0;
+ struct S4 *s4 = 0; // expected-note{{'S4' is not defined, but forward declared here; conversion would be valid if it's derived from 'NS::S4'}}
x.test_elab2(s4); // expected-error{{cannot initialize a parameter of type 'NS::S4 *' with an lvalue of type 'struct S4 *'}}
}
Index: clang/test/Modules/namespaces.cpp
===================================================================
--- clang/test/Modules/namespaces.cpp
+++ clang/test/Modules/namespaces.cpp
@@ -78,7 +78,8 @@
// expected-note at Inputs/namespaces-right.h:60 {{passing argument to parameter here}}
// expected-note at Inputs/namespaces-right.h:67 {{passing argument to parameter here}}
-
+// expected-note at Inputs/namespaces-left.h:63 {{'N11::(anonymous namespace)::Foo' is not defined, but forward declared here; conversion would be valid if it's derived from 'N11::(anonymous namespace)::Foo'}}
+// expected-note at Inputs/namespaces-left.h:63 {{'N12::(anonymous namespace)::Foo' is not defined, but forward declared here; conversion would be valid if it's derived from 'N12::(anonymous namespace)::Foo'}}
// Test that bringing in one name from an overload set does not hide the rest.
void testPartialImportOfOverloadSet() {
void (*p)() = N13::p;
Index: clang/lib/Sema/SemaInit.cpp
===================================================================
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -8707,6 +8707,16 @@
if (entity.getKind() == InitializedEntity::EK_Result)
S.EmitRelatedResultTypeNoteForReturn(destType);
}
+ QualType fromType = op->getType();
+ auto *fromDecl = fromType.getTypePtr()->getPointeeCXXRecordDecl();
+ auto *destDecl = destType.getTypePtr()->getPointeeCXXRecordDecl();
+ if (fromDecl && destDecl && fromDecl->getDeclKind() == Decl::CXXRecord &&
+ destDecl->getDeclKind() == Decl::CXXRecord &&
+ !fromDecl->isInvalidDecl() && !destDecl->isInvalidDecl() &&
+ !fromDecl->hasDefinition())
+ S.Diag(fromDecl->getLocation(), diag::note_forward_class_conversion)
+ << S.getASTContext().getTagDeclType(fromDecl)
+ << S.getASTContext().getTagDeclType(destDecl);
}
static void diagnoseListInit(Sema &S, const InitializedEntity &Entity,
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2005,6 +2005,8 @@
"|: different return type%diff{ ($ vs $)|}5,6"
"|: different qualifiers (%5 vs %6)"
"|: different exception specifications}4">;
+def note_forward_class_conversion : Note<"%0 is not defined, but forward "
+ "declared here; conversion would be valid if it's derived from %1">;
def err_lvalue_to_rvalue_ref : Error<"rvalue reference %diff{to type $ cannot "
"bind to lvalue of type $|cannot bind to incompatible lvalue}0,1">;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85390.283949.patch
Type: text/x-patch
Size: 3949 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200807/d67c3012/attachment-0001.bin>
More information about the cfe-commits
mailing list