diff options
author | Anders Carlsson <andersca@mac.com> | 2009-05-14 22:15:41 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-05-14 22:15:41 +0000 |
commit | 77b7f1d4fb782c9152f91b76f9f8b1d1af21bd35 (patch) | |
tree | 7e40dbdd2b136b3e3dadad70d31c778a0b746fbb | |
parent | a75e8534f2b7c2480c48f31f301bd00b241c5499 (diff) |
Check that the function being overridden is virtual.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71802 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Decl.h | 11 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 5 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 | ||||
-rw-r--r-- | test/SemaCXX/virtual-override.cpp | 13 |
7 files changed, 31 insertions, 12 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index a0b47c9e40..0bf86876e2 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -517,7 +517,7 @@ private: unsigned SClass : 2; bool IsInline : 1; bool C99InlineDefinition : 1; - bool IsVirtual : 1; + bool IsVirtualAsWritten : 1; bool IsPure : 1; bool HasInheritedPrototype : 1; bool HasWrittenPrototype : 1; @@ -546,7 +546,7 @@ protected: DeclContext(DK), ParamInfo(0), Body(), PreviousDeclaration(0), SClass(S), IsInline(isInline), C99InlineDefinition(false), - IsVirtual(false), IsPure(false), HasInheritedPrototype(false), + IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL), TemplateOrInstantiation() {} @@ -590,10 +590,9 @@ public: void setBody(Stmt *B) { Body = B; } void setLazyBody(uint64_t Offset) { Body = Offset; } - /// Whether this function is virtual, either by explicit marking, or by - /// overriding a virtual function. Only valid on C++ member functions. - bool isVirtual() { return IsVirtual; } - void setVirtual(bool V = true) { IsVirtual = V; } + /// Whether this function is marked as virtual explicitly. + bool isVirtualAsWritten() const { return IsVirtualAsWritten; } + void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; } /// Whether this virtual function is pure, i.e. makes the containing class /// abstract. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index d7f268fc6a..88d6f9fa2b 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -476,6 +476,11 @@ public: return getLexicalDeclContext() != getDeclContext(); } + bool isVirtual() const { + // FIXME: Check if it's inherited virtual as well. + return isVirtualAsWritten(); + } + /// getParent - Returns the parent of this method declaration, which /// is the class in which this method is defined. const CXXRecordDecl *getParent() const { diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 45af36c82f..865dd97db6 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -149,7 +149,7 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) { FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]); FD->setInline(Record[Idx++]); FD->setC99InlineDefinition(Record[Idx++]); - FD->setVirtual(Record[Idx++]); + FD->setVirtualAsWritten(Record[Idx++]); FD->setPure(Record[Idx++]); FD->setHasInheritedPrototype(Record[Idx++]); FD->setHasWrittenPrototype(Record[Idx++]); diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index 48c7dc2d4a..5d08334dee 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -149,7 +149,7 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) { Record.push_back(D->getStorageClass()); // FIXME: stable encoding Record.push_back(D->isInline()); Record.push_back(D->isC99InlineDefinition()); - Record.push_back(D->isVirtual()); + Record.push_back(D->isVirtualAsWritten()); Record.push_back(D->isPure()); Record.push_back(D->hasInheritedPrototype()); Record.push_back(D->hasWrittenPrototype()); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 1c464d16b0..feb9595736 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2125,7 +2125,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, SourceRange(D.getDeclSpec().getVirtualSpecLoc())); } else { // Okay: Add virtual to the method. - cast<CXXMethodDecl>(NewFD)->setVirtual(); + cast<CXXMethodDecl>(NewFD)->setVirtualAsWritten(true); CXXRecordDecl *CurClass = cast<CXXRecordDecl>(DC); CurClass->setAggregate(false); CurClass->setPOD(false); @@ -2152,6 +2152,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, // FIXME: Is this OK? Should it be done by LookupInBases? if (IsOverload(NewMD, OldMD, MatchedDecl)) continue; + if (!OldMD->isVirtual()) + continue; if (!CheckOverridingFunctionReturnType(NewMD, OldMD)) { // FIXME: Add OldMD to the list of methods NewMD overrides. @@ -2490,7 +2492,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { Expr *Init = static_cast<Expr *>(init.get()); if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 && Context.getCanonicalType(IL->getType()) == Context.IntTy) { - if (Method->isVirtual()) { + if (Method->isVirtualAsWritten()) { Method->setPure(); // A class is abstract if at least one function is pure virtual. diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 19aaafbcc6..02df5931a5 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -546,8 +546,8 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl) { CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner); New->setAccess(Tmpl->getAccess()); - if (Tmpl->isVirtual()) { - New->setVirtual(); + if (Tmpl->isVirtualAsWritten()) { + New->setVirtualAsWritten(true); Record->setAggregate(false); Record->setPOD(false); Record->setPolymorphic(true); diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp index fc5d779495..4a3b10fa97 100644 --- a/test/SemaCXX/virtual-override.cpp +++ b/test/SemaCXX/virtual-override.cpp @@ -91,3 +91,16 @@ class B : A { }; } + +namespace T7 { + struct a { }; + struct b { }; + + class A { + a* f(); + }; + + class B : A { + virtual b* f(); + }; +} |