diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2014-08-08 00:10:39 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2014-08-08 00:10:39 +0000 |
| commit | d96b99740d1f2c47941e589d9719016388ee6453 (patch) | |
| tree | 1948bfebd62c54547ae481c4ad1b81b622126bcc /clang/lib/Sema | |
| parent | 7d498629f1e038d2642116b40a04f4acf6532a26 (diff) | |
| download | bcm5719-llvm-d96b99740d1f2c47941e589d9719016388ee6453.tar.gz bcm5719-llvm-d96b99740d1f2c47941e589d9719016388ee6453.zip | |
MS ABI: Don't force bases to have an inheritance model
Previously, assigning an inheritance model to a derived class would
trigger further assiginments to the various bases of the class. This
was done to fix a bug where we couldn't handle an implicit
base-to-derived conversion for pointers-to-members when the conversion
was ambiguous at an earlier point.
However, this is not how the MS scheme works. Instead, assign
inheritance models to *just* the class which owns to declaration we
ended up referencing.
N.B. This result is surprising in many ways. It means that it is
possible for a base to have a "larger" inheritance model than it's
derived classes. It also means that bases in the conversion path do not
get assigned a model.
struct A { void f(); void f(int); };
struct B : A {};
struct C : B {};
void f() { void (C::*x)() = &A::f; }
We can only begin to assign an inheritance model *after* we've seen the
address-of but *before* we've done the implicit conversion the more
derived pointer-to-member type. After that point, both 'A' and 'C' will
have an inheritance model but 'B' will not. Surprising, right?
llvm-svn: 215174
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 8 |
2 files changed, 8 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index eb7924f473a..49d1fdfb3f2 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2898,6 +2898,14 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, return ExprError(); if (CheckExceptionSpecCompatibility(From, ToType)) return ExprError(); + + // We may not have been able to figure out what this member pointer resolved + // to up until this exact point. Attempt to lock-in it's inheritance model. + QualType FromType = From->getType(); + if (FromType->isMemberPointerType()) + if (Context.getTargetInfo().getCXXABI().isMicrosoft()) + RequireCompleteType(From->getExprLoc(), FromType, 0); + From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK) .get(); break; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index b6b024c89ab..029d2c2806c 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -5163,14 +5163,6 @@ static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) { ? S.ImplicitMSInheritanceAttrLoc : RD->getSourceRange())); } - - if (RD->hasDefinition()) { - // Assign inheritance models to all of the base classes, because now we can - // form pointers to members of base classes without calling - // RequireCompleteType on the pointer to member of the base class type. - for (const CXXBaseSpecifier &BS : RD->bases()) - assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl()); - } } /// \brief The implementation of RequireCompleteType |

