aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp39
-rw-r--r--lib/Sema/SemaDecl.cpp35
-rw-r--r--lib/Sema/SemaFixItUtils.cpp28
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;
+}