aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-05-14 22:15:41 +0000
committerAnders Carlsson <andersca@mac.com>2009-05-14 22:15:41 +0000
commit77b7f1d4fb782c9152f91b76f9f8b1d1af21bd35 (patch)
tree7e40dbdd2b136b3e3dadad70d31c778a0b746fbb
parenta75e8534f2b7c2480c48f31f301bd00b241c5499 (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.h11
-rw-r--r--include/clang/AST/DeclCXX.h5
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp2
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp4
-rw-r--r--test/SemaCXX/virtual-override.cpp13
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();
+ };
+}