aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2011-09-08 06:33:04 +0000
committerDavid Blaikie <dblaikie@gmail.com>2011-09-08 06:33:04 +0000
commit14068e83f30864ed278fa43c5954404b47e99e7d (patch)
treed29c7a12245ae481f55ddc0617444f5c03943faf /lib/Sema/SemaDecl.cpp
parente97179c675b341927807c718be215c8d1aab8acb (diff)
Adding FixIts to static/inline main declaration diagnostics.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139282 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp71
1 files changed, 36 insertions, 35 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9938954fe1..f4898a1dd8 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -4782,8 +4782,19 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!getLangOptions().CPlusPlus) {
// Perform semantic checking on the function declaration.
bool isExplicitSpecialization=false;
- CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization,
- Redeclaration);
+ if (!NewFD->isInvalidDecl()) {
+ if (NewFD->getResultType()->isVariablyModifiedType()) {
+ // Functions returning a variably modified type violate C99 6.7.5.2p2
+ // because all functions have linkage.
+ Diag(NewFD->getLocation(), diag::err_vm_func_decl);
+ NewFD->setInvalidDecl();
+ } else {
+ if (NewFD->isMain())
+ CheckMain(NewFD, D.getDeclSpec());
+ CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization,
+ Redeclaration);
+ }
+ }
assert((NewFD->isInvalidDecl() || !Redeclaration ||
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
"previous declaration set still overloaded");
@@ -4889,9 +4900,19 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
// Perform semantic checking on the function declaration.
- if (!isDependentClassScopeExplicitSpecialization)
- CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization,
- Redeclaration);
+ if (!isDependentClassScopeExplicitSpecialization) {
+ if (NewFD->isInvalidDecl()) {
+ // If this is a class member, mark the class invalid immediately.
+ // This avoids some consistency errors later.
+ if (CXXMethodDecl* methodDecl = dyn_cast<CXXMethodDecl>(NewFD))
+ methodDecl->getParent()->setInvalidDecl();
+ } else {
+ if (NewFD->isMain())
+ CheckMain(NewFD, D.getDeclSpec());
+ CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization,
+ Redeclaration);
+ }
+ }
assert((NewFD->isInvalidDecl() || !Redeclaration ||
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
@@ -5101,25 +5122,8 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
LookupResult &Previous,
bool IsExplicitSpecialization,
bool &Redeclaration) {
- // If NewFD is already known erroneous, don't do any of this checking.
- if (NewFD->isInvalidDecl()) {
- // If this is a class member, mark the class invalid immediately.
- // This avoids some consistency errors later.
- if (isa<CXXMethodDecl>(NewFD))
- cast<CXXMethodDecl>(NewFD)->getParent()->setInvalidDecl();
-
- return;
- }
-
- if (NewFD->getResultType()->isVariablyModifiedType()) {
- // Functions returning a variably modified type violate C99 6.7.5.2p2
- // because all functions have linkage.
- Diag(NewFD->getLocation(), diag::err_vm_func_decl);
- return NewFD->setInvalidDecl();
- }
-
- if (NewFD->isMain())
- CheckMain(NewFD);
+ assert(!NewFD->getResultType()->isVariablyModifiedType()
+ && "Variably modified return types are not handled here");
// Check for a previous declaration of this name.
if (Previous.empty() && NewFD->isExternC()) {
@@ -5292,22 +5296,19 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
}
-void Sema::CheckMain(FunctionDecl* FD) {
+void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) {
// C++ [basic.start.main]p3: A program that declares main to be inline
// or static is ill-formed.
// C99 6.7.4p4: In a hosted environment, the inline function specifier
// shall not appear in a declaration of main.
// static main is not an error under C99, but we should warn about it.
- bool isInline = FD->isInlineSpecified();
- bool isStatic = FD->getStorageClass() == SC_Static;
- if (isInline || isStatic) {
- unsigned diagID = diag::warn_unusual_main_decl;
- if (isInline || getLangOptions().CPlusPlus)
- diagID = diag::err_unusual_main_decl;
-
- int which = isStatic + (isInline << 1) - 1;
- Diag(FD->getLocation(), diagID) << which;
- }
+ if (FD->getStorageClass() == SC_Static)
+ Diag(DS.getStorageClassSpecLoc(), getLangOptions().CPlusPlus
+ ? diag::err_static_main : diag::warn_static_main)
+ << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
+ if (FD->isInlineSpecified())
+ Diag(DS.getInlineSpecLoc(), diag::err_inline_main)
+ << FixItHint::CreateRemoval(DS.getInlineSpecLoc());
QualType T = FD->getType();
assert(T->isFunctionType() && "function decl is not of function type");