diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-04-07 19:37:57 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-04-07 19:37:57 +0000 |
commit | 85a5319ea4b5c916d7dd665e84af61e4a8a0b9c2 (patch) | |
tree | f8d79d5ab45d4ad1c2d465b4d35314954fb586b4 /lib/Sema/SemaDecl.cpp | |
parent | 5c1aaafbd6dd25a99ca1960e1c3c98aeefe9d728 (diff) |
Diagnose uses of function specifiers on declarations which don't declare
functions. Fixes PR3941.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68541 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 7cf44bf6ac..54be9b4c3d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1478,6 +1478,24 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl, } } +/// \brief Diagnose function specifiers on a declaration of an identifier that +/// does not identify a function. +void Sema::DiagnoseFunctionSpecifiers(Declarator& D) { + // FIXME: We should probably indicate the identifier in question to avoid + // confusion for constructs like "inline int a(), b;" + if (D.getDeclSpec().isInlineSpecified()) + Diag(D.getDeclSpec().getInlineSpecLoc(), + diag::err_inline_non_function); + + if (D.getDeclSpec().isVirtualSpecified()) + Diag(D.getDeclSpec().getVirtualSpecLoc(), + diag::err_virtual_non_function); + + if (D.getDeclSpec().isExplicitSpecified()) + Diag(D.getDeclSpec().getExplicitSpecLoc(), + diag::err_explicit_non_function); +} + NamedDecl* Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, Decl* PrevDecl, bool& InvalidDecl, @@ -1494,12 +1512,10 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (getLangOptions().CPlusPlus) { // Check that there are no default arguments (C++ only). CheckExtraCXXDefaultArguments(D); - - if (D.getDeclSpec().isVirtualSpecified()) - Diag(D.getDeclSpec().getVirtualSpecLoc(), - diag::err_virtual_non_function); } + DiagnoseFunctionSpecifiers(D); + TypedefDecl *NewTD = ParseTypedefDecl(S, D, R); if (!NewTD) return 0; @@ -1639,9 +1655,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, return 0; } - if (D.getDeclSpec().isVirtualSpecified()) - Diag(D.getDeclSpec().getVirtualSpecLoc(), - diag::err_virtual_non_function); + DiagnoseFunctionSpecifiers(D); bool ThreadSpecified = D.getDeclSpec().isThreadSpecified(); if (!DC->isRecord() && S->getFnParent() == 0) { @@ -2615,7 +2629,8 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { diag::err_invalid_storage_class_in_func_decl); D.getMutableDeclSpec().ClearStorageClassSpecs(); } - + DiagnoseFunctionSpecifiers(D); + // Check that there are no default arguments inside the type of this // parameter (C++ only). if (getLangOptions().CPlusPlus) @@ -3566,12 +3581,10 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, if (getLangOptions().CPlusPlus) { CheckExtraCXXDefaultArguments(D); - - if (D.getDeclSpec().isVirtualSpecified()) - Diag(D.getDeclSpec().getVirtualSpecLoc(), - diag::err_virtual_non_function); } + DiagnoseFunctionSpecifiers(D); + NamedDecl *PrevDecl = LookupName(S, II, LookupMemberName, true); if (PrevDecl && !isDeclInScope(PrevDecl, Record, S)) PrevDecl = 0; |