diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-10-31 14:43:28 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-10-31 14:43:28 +0000 |
commit | 0777972d38a3125efed962b045704c30ae6965cf (patch) | |
tree | f5e6da0b14f4fae70e9d16cc0af4ed62e8f3f6e3 /lib/Sema/SemaInherit.cpp | |
parent | ea8a1854137faca10ccb24acf4f1a74912fccfb2 (diff) |
Implement semantic checking of static_cast and dynamic_cast.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58509 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInherit.cpp')
-rw-r--r-- | lib/Sema/SemaInherit.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp index ce48a43111..b2d9b88fcd 100644 --- a/lib/Sema/SemaInherit.cpp +++ b/lib/Sema/SemaInherit.cpp @@ -42,6 +42,7 @@ void BasePaths::clear() { Paths.clear(); ClassSubobjects.clear(); ScratchPath.clear(); + DetectedVirtual = 0; } /// IsDerivedFrom - Determine whether the type Derived is derived from @@ -50,7 +51,8 @@ void BasePaths::clear() { /// Derived* to a Base* is legal, because it does not account for /// ambiguous conversions or conversions to private/protected bases. bool Sema::IsDerivedFrom(QualType Derived, QualType Base) { - BasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false); + BasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/false, + /*DetectVirtual=*/false); return IsDerivedFrom(Derived, Base, Paths); } @@ -64,10 +66,10 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base) { /// information about all of the paths (if @c Paths.isRecordingPaths()). bool Sema::IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths) { bool FoundPath = false; - + Derived = Context.getCanonicalType(Derived).getUnqualifiedType(); Base = Context.getCanonicalType(Base).getUnqualifiedType(); - + if (!Derived->isRecordType() || !Base->isRecordType()) return false; @@ -87,9 +89,17 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths) { // updating the count of subobjects appropriately. std::pair<bool, unsigned>& Subobjects = Paths.ClassSubobjects[BaseType]; bool VisitBase = true; + bool SetVirtual = false; if (BaseSpec->isVirtual()) { VisitBase = !Subobjects.first; Subobjects.first = true; + if (Paths.isDetectingVirtual() && Paths.DetectedVirtual == 0) { + // If this is the first virtual we find, remember it. If it turns out + // there is no base path here, we'll reset it later. + Paths.DetectedVirtual = static_cast<const CXXRecordType*>( + BaseType->getAsRecordType()); + SetVirtual = true; + } } else ++Subobjects.second; @@ -127,6 +137,10 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, BasePaths &Paths) { // collecting paths). if (Paths.isRecordingPaths()) Paths.ScratchPath.pop_back(); + // If we set a virtual earlier, and this isn't a path, forget it again. + if (SetVirtual && !FoundPath) { + Paths.DetectedVirtual = 0; + } } } @@ -148,7 +162,8 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, // ambiguous. This is slightly more expensive than checking whether // the Derived to Base conversion exists, because here we need to // explore multiple paths to determine if there is an ambiguity. - BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false); + BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, + /*DetectVirtual=*/false); bool DerivationOkay = IsDerivedFrom(Derived, Base, Paths); assert(DerivationOkay && "Can only be used with a derived-to-base conversion"); if (!DerivationOkay) |