[cfe-commits] r116448 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp test/SemaCXX/virtual-override.cpp
Douglas Gregor
dgregor at apple.com
Wed Oct 13 15:55:32 PDT 2010
Author: dgregor
Date: Wed Oct 13 17:55:32 2010
New Revision: 116448
URL: http://llvm.org/viewvc/llvm-project?rev=116448&view=rev
Log:
Diagnose when a 'static' member function overrides a virtual function
in a base class. Fixes PR8168.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/SemaCXX/virtual-override.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=116448&r1=116447&r2=116448&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Oct 13 17:55:32 2010
@@ -608,6 +608,8 @@
"'virtual' can only appear on non-static member functions">;
def err_virtual_out_of_class : Error<
"'virtual' can only be specified inside the class definition">;
+def err_static_overrides_virtual : Error<
+ "'static' member function %0 overrides a virtual function in a base class">;
def err_explicit_non_function : Error<
"'explicit' can only appear on non-static member functions">;
def err_explicit_out_of_class : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=116448&r1=116447&r2=116448&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Oct 13 17:55:32 2010
@@ -712,7 +712,7 @@
MultiTemplateParamsArg TemplateParamLists,
bool IsFunctionDefinition,
bool &Redeclaration);
- void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
+ bool AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
void CheckFunctionDeclaration(Scope *S,
FunctionDecl *NewFD, LookupResult &Previous,
bool IsExplicitSpecialization,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=116448&r1=116447&r2=116448&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Oct 13 17:55:32 2010
@@ -3153,23 +3153,28 @@
/// AddOverriddenMethods - See if a method overrides any in the base classes,
/// and if so, check that it's a valid override and remember it.
-void Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
+bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
// Look for virtual methods in base classes that this method might override.
CXXBasePaths Paths;
FindOverriddenMethodData Data;
Data.Method = MD;
Data.S = this;
+ bool AddedAny = false;
if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) {
for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
E = Paths.found_decls_end(); I != E; ++I) {
if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
if (!CheckOverridingFunctionReturnType(MD, OldMD) &&
!CheckOverridingFunctionExceptionSpec(MD, OldMD) &&
- !CheckOverridingFunctionAttributes(MD, OldMD))
+ !CheckOverridingFunctionAttributes(MD, OldMD)) {
MD->addOverriddenMethod(OldMD->getCanonicalDecl());
+ AddedAny = true;
+ }
}
}
}
+
+ return AddedAny;
}
static void DiagnoseInvalidRedeclaration(Sema &S, FunctionDecl *NewFD) {
@@ -3964,8 +3969,6 @@
DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(
Context.getCanonicalType(ClassType));
-// NewFD->getDeclName().dump();
-// Name.dump();
if (NewFD->getDeclName() != Name) {
Diag(NewFD->getLocation(), diag::err_destructor_name);
return NewFD->setInvalidDecl();
@@ -3979,8 +3982,23 @@
// Find any virtual functions that this function overrides.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD)) {
if (!Method->isFunctionTemplateSpecialization() &&
- !Method->getDescribedFunctionTemplate())
- AddOverriddenMethods(Method->getParent(), Method);
+ !Method->getDescribedFunctionTemplate()) {
+ if (AddOverriddenMethods(Method->getParent(), Method)) {
+ // If the function was marked as "static", we have a problem.
+ if (NewFD->getStorageClass() == SC_Static) {
+ Diag(NewFD->getLocation(), diag::err_static_overrides_virtual)
+ << NewFD->getDeclName();
+ for (CXXMethodDecl::method_iterator
+ Overridden = Method->begin_overridden_methods(),
+ OverriddenEnd = Method->end_overridden_methods();
+ Overridden != OverriddenEnd;
+ ++Overridden) {
+ Diag((*Overridden)->getLocation(),
+ diag::note_overridden_virtual_function);
+ }
+ }
+ }
+ }
}
// Extra checking for C++ overloaded operators (C++ [over.oper]).
Modified: cfe/trunk/test/SemaCXX/virtual-override.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/virtual-override.cpp?rev=116448&r1=116447&r2=116448&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/virtual-override.cpp (original)
+++ cfe/trunk/test/SemaCXX/virtual-override.cpp Wed Oct 13 17:55:32 2010
@@ -276,3 +276,15 @@
virtual B& f(); // expected-error {{virtual function 'f' has a different return type ('T12::B &') than the function it overrides (which has return type 'T12::A &&')}}
};
};
+
+namespace PR8168 {
+ class A {
+ public:
+ virtual void foo() {} // expected-note{{overridden virtual function is here}}
+ };
+
+ class B : public A {
+ public:
+ static void foo() {} // expected-error{{'static' member function 'foo' overrides a virtual function}}
+ };
+}
More information about the cfe-commits
mailing list