diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-30 21:30:52 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-07-30 21:30:52 +0000 |
commit | b9c6261d02f688d0a9a36b736ad5956fbc737854 (patch) | |
tree | 7bbc4ac74593d5784db5cb5c912ecc7b3c18729d /lib/Sema/SemaDecl.cpp | |
parent | 1b0a13e91088f6818016464ffb23616ced820cbc (diff) |
Improvements to vexing-parse warnings. Make the no-parameters case more
accurate by asking the parser whether there was an ambiguity rather than trying
to reverse-engineer it from the DeclSpec. Make the with-parameters case have
better diagnostics by using semantic information to drive the warning,
improving the diagnostics and adding a fixit.
Patch by Nikola Smiljanic. Some minor changes by me to suppress diagnostics for
declarations of the form 'T (*x)(...)', which seem to have a very high false
positive rate, and to reduce indentation in 'warnAboutAmbiguousFunction'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160998 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 58 |
1 files changed, 3 insertions, 55 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6dfd796f40..e511157366 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5245,58 +5245,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, FunctionTemplate->setInvalidDecl(); } - // If we see "T var();" at block scope, where T is a class type, it is - // probably an attempt to initialize a variable, not a function declaration. - // We don't catch this case earlier, since there is no ambiguity here. - if (!FunctionTemplate && D.getFunctionDefinitionKind() == FDK_Declaration && - CurContext->isFunctionOrMethod() && - D.getNumTypeObjects() == 1 && D.isFunctionDeclarator() && - D.getDeclSpec().getStorageClassSpecAsWritten() - == DeclSpec::SCS_unspecified) { - QualType T = R->getAs<FunctionType>()->getResultType(); - DeclaratorChunk &C = D.getTypeObject(0); - if (!T->isVoidType() && C.Fun.NumArgs == 0 && !C.Fun.isVariadic && - !C.Fun.hasTrailingReturnType() && - C.Fun.getExceptionSpecType() == EST_None) { - SourceRange ParenRange(C.Loc, C.EndLoc); - Diag(C.Loc, diag::warn_empty_parens_are_function_decl) << ParenRange; - - // If the declaration looks like: - // T var1, - // f(); - // and name lookup finds a function named 'f', then the ',' was - // probably intended to be a ';'. - if (!D.isFirstDeclarator() && D.getIdentifier()) { - FullSourceLoc Comma(D.getCommaLoc(), SourceMgr); - FullSourceLoc Name(D.getIdentifierLoc(), SourceMgr); - if (Comma.getFileID() != Name.getFileID() || - Comma.getSpellingLineNumber() != Name.getSpellingLineNumber()) { - LookupResult Result(*this, D.getIdentifier(), SourceLocation(), - LookupOrdinaryName); - if (LookupName(Result, S)) - Diag(D.getCommaLoc(), diag::note_empty_parens_function_call) - << FixItHint::CreateReplacement(D.getCommaLoc(), ";") << NewFD; - } - } - const CXXRecordDecl *RD = T->getAsCXXRecordDecl(); - // Empty parens mean value-initialization, and no parens mean default - // initialization. These are equivalent if the default constructor is - // user-provided, or if zero-initialization is a no-op. - if (RD && RD->hasDefinition() && - (RD->isEmpty() || RD->hasUserProvidedDefaultConstructor())) - Diag(C.Loc, diag::note_empty_parens_default_ctor) - << FixItHint::CreateRemoval(ParenRange); - else { - std::string Init = getFixItZeroInitializerForType(T); - if (Init.empty() && LangOpts.CPlusPlus0x) - Init = "{}"; - if (!Init.empty()) - Diag(C.Loc, diag::note_empty_parens_zero_initialize) - << FixItHint::CreateReplacement(ParenRange, Init); - } - } - } - // C++ [dcl.fct.spec]p5: // The virtual specifier shall only be used in declarations of // nonstatic class member functions that appear within a @@ -7915,10 +7863,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, (void)Error; // Silence warning. assert(!Error && "Error setting up implicit decl!"); Declarator D(DS, Declarator::BlockContext); - D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0, - 0, 0, true, SourceLocation(), + D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, false, + SourceLocation(), 0, 0, 0, true, + SourceLocation(), SourceLocation(), SourceLocation(), SourceLocation(), - SourceLocation(), EST_None, SourceLocation(), 0, 0, 0, 0, Loc, Loc, D), DS.getAttributes(), |