diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/AnalysisBasedWarnings.cpp | 39 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 35 | ||||
-rw-r--r-- | lib/Sema/SemaFixItUtils.cpp | 28 |
3 files changed, 67 insertions, 35 deletions
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 3567b6bbe0..9b3191b027 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -415,42 +415,15 @@ static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) { return false; // Suggest possible initialization (if any). - const char *initialization = 0; QualType VariableTy = VD->getType().getCanonicalType(); - - if (VariableTy->isObjCObjectPointerType() || - VariableTy->isBlockPointerType()) { - // Check if 'nil' is defined. - if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("nil"))) - initialization = " = nil"; - else - initialization = " = 0"; - } - else if (VariableTy->isRealFloatingType()) - initialization = " = 0.0"; - else if (VariableTy->isBooleanType() && S.Context.getLangOptions().CPlusPlus) - initialization = " = false"; - else if (VariableTy->isEnumeralType()) + const char *Init = S.getFixItZeroInitializerForType(VariableTy); + if (!Init) return false; - else if (VariableTy->isPointerType() || VariableTy->isMemberPointerType()) { - if (S.Context.getLangOptions().CPlusPlus0x) - initialization = " = nullptr"; - // Check if 'NULL' is defined. - else if (S.PP.getMacroInfo(&S.getASTContext().Idents.get("NULL"))) - initialization = " = NULL"; - else - initialization = " = 0"; - } - else if (VariableTy->isScalarType()) - initialization = " = 0"; - if (initialization) { - SourceLocation loc = S.PP.getLocForEndOfToken(VD->getLocEnd()); - S.Diag(loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() - << FixItHint::CreateInsertion(loc, initialization); - return true; - } - return false; + SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd()); + S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() + << FixItHint::CreateInsertion(Loc, Init); + return true; } /// DiagnoseUninitializedUse -- Helper function for diagnosing uses of an diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index dc8d6ec8cf..4dcf1db2cf 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4921,8 +4921,39 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!T->isVoidType() && C.Fun.NumArgs == 0 && !C.Fun.isVariadic && !C.Fun.TrailingReturnType && C.Fun.getExceptionSpecType() == EST_None) { - Diag(C.Loc, diag::warn_empty_parens_are_function_decl) - << SourceRange(C.Loc, C.EndLoc); + 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->isEmpty() || RD->hasUserProvidedDefaultConstructor())) + Diag(C.Loc, diag::note_empty_parens_default_ctor) + << FixItHint::CreateRemoval(ParenRange); + else if (const char *Init = getFixItZeroInitializerForType(T)) + Diag(C.Loc, diag::note_empty_parens_zero_initialize) + << FixItHint::CreateReplacement(ParenRange, Init); + else if (LangOpts.CPlusPlus0x) + Diag(C.Loc, diag::note_empty_parens_zero_initialize) + << FixItHint::CreateReplacement(ParenRange, "{}"); } } diff --git a/lib/Sema/SemaFixItUtils.cpp b/lib/Sema/SemaFixItUtils.cpp index 8e8a46da73..1f17a9e83e 100644 --- a/lib/Sema/SemaFixItUtils.cpp +++ b/lib/Sema/SemaFixItUtils.cpp @@ -158,3 +158,31 @@ bool ConversionFixItGenerator::tryToFixConversion(const Expr *FullExpr, return false; } + +const char *Sema::getFixItZeroInitializerForType(QualType T) const { + // Suggest 'nil' if it's defined and appropriate. + if ((T->isObjCObjectPointerType() || T->isBlockPointerType()) && + PP.getMacroInfo(&getASTContext().Idents.get("nil"))) + return " = nil"; + if (T->isRealFloatingType()) + return " = 0.0"; + if (T->isBooleanType() && LangOpts.CPlusPlus) + return " = false"; + if (T->isPointerType() || T->isMemberPointerType()) { + if (LangOpts.CPlusPlus0x) + return " = nullptr"; + // Check if 'NULL' is defined. + else if (PP.getMacroInfo(&getASTContext().Idents.get("NULL"))) + return " = NULL"; + } + if (T->isEnumeralType()) + return 0; + if (T->isScalarType()) + return " = 0"; + const CXXRecordDecl *RD = T->getAsCXXRecordDecl(); + if (LangOpts.CPlusPlus0x && RD && !RD->hasUserProvidedDefaultConstructor()) + return "{}"; + if (T->isAggregateType()) + return " = {}"; + return 0; +} |