diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-09-20 00:27:40 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-09-20 00:27:40 +0000 |
commit | f7ec86a55bbabd42780d94e9e9a80ce45491e19b (patch) | |
tree | 5b4e421de7775d0d5e4f4238ab8e867259ac04e2 | |
parent | b523b9c8d4629267fbcde3781f33f133153f7da3 (diff) | |
download | bcm5719-llvm-f7ec86a55bbabd42780d94e9e9a80ce45491e19b.tar.gz bcm5719-llvm-f7ec86a55bbabd42780d94e9e9a80ce45491e19b.zip |
PR17290: Use 'false' macro in fix-it hint for initializing a variable of type
_Bool in C, if the macro is defined. Also teach FixItUtils to look at whether
the macro was defined at the source location for which it is creating a fixit,
rather than looking at whether it's defined *now*. This is especially relevant
for analysis-based warnings which are delayed until end of TU.
llvm-svn: 191057
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 5 | ||||
-rw-r--r-- | clang/lib/Sema/AnalysisBasedWarnings.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaFixItUtils.cpp | 28 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 3 |
5 files changed, 32 insertions, 21 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b914cb2b209..d39d8d5d559 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -949,8 +949,9 @@ public: bool findMacroSpelling(SourceLocation &loc, StringRef name); /// \brief Get a string to suggest for zero-initialization of a type. - std::string getFixItZeroInitializerForType(QualType T) const; - std::string getFixItZeroLiteralForType(QualType T) const; + std::string + getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const; + std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const; ExprResult Owned(Expr* E) { return E; } ExprResult Owned(ExprResult R) { return R; } diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 7893a459c19..cc1cb0b342f 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -439,22 +439,22 @@ static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) { << FixItHint::CreateInsertion(VD->getLocation(), "__block "); return true; } - + // Don't issue a fixit if there is already an initializer. if (VD->getInit()) return false; - - // Suggest possible initialization (if any). - std::string Init = S.getFixItZeroInitializerForType(VariableTy); - if (Init.empty()) - return false; // Don't suggest a fixit inside macros. if (VD->getLocEnd().isMacroID()) return false; SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd()); - + + // Suggest possible initialization (if any). + std::string Init = S.getFixItZeroInitializerForType(VariableTy, Loc); + if (Init.empty()) + return false; + S.Diag(Loc, diag::note_var_fixit_add_initialization) << VD->getDeclName() << FixItHint::CreateInsertion(Loc, Init); return true; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a4fb3cfa45c..426bf68e1d6 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5328,7 +5328,8 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T, if (!Loc.isMacroID() || CC.isMacroID()) S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer) << T << clang::SourceRange(CC) - << FixItHint::CreateReplacement(Loc, S.getFixItZeroLiteralForType(T)); + << FixItHint::CreateReplacement(Loc, + S.getFixItZeroLiteralForType(T, Loc)); } if (!Source->isIntegerType() || !Target->isIntegerType()) diff --git a/clang/lib/Sema/SemaFixItUtils.cpp b/clang/lib/Sema/SemaFixItUtils.cpp index 2a845ba9898..32b56bcddc6 100644 --- a/clang/lib/Sema/SemaFixItUtils.cpp +++ b/clang/lib/Sema/SemaFixItUtils.cpp @@ -160,27 +160,33 @@ bool ConversionFixItGenerator::tryToFixConversion(const Expr *FullExpr, return false; } -static bool isMacroDefined(const Sema &S, StringRef Name) { - return S.PP.getMacroInfo(&S.getASTContext().Idents.get(Name)); +static bool isMacroDefined(const Sema &S, SourceLocation Loc, StringRef Name) { + const IdentifierInfo *II = &S.getASTContext().Idents.get(Name); + if (!II->hadMacroDefinition()) return false; + + MacroDirective *Macro = S.PP.getMacroDirectiveHistory(II); + return Macro && Macro->findDirectiveAtLoc(Loc, S.getSourceManager()); } -static std::string getScalarZeroExpressionForType(const Type& T, const Sema& S) { +static std::string getScalarZeroExpressionForType( + const Type &T, SourceLocation Loc, const Sema &S) { assert(T.isScalarType() && "use scalar types only"); // Suggest "0" for non-enumeration scalar types, unless we can find a // better initializer. if (T.isEnumeralType()) return std::string(); if ((T.isObjCObjectPointerType() || T.isBlockPointerType()) && - isMacroDefined(S, "nil")) + isMacroDefined(S, Loc, "nil")) return "nil"; if (T.isRealFloatingType()) return "0.0"; - if (T.isBooleanType() && S.LangOpts.CPlusPlus) + if (T.isBooleanType() && + (S.LangOpts.CPlusPlus || isMacroDefined(S, Loc, "false"))) return "false"; if (T.isPointerType() || T.isMemberPointerType()) { if (S.LangOpts.CPlusPlus11) return "nullptr"; - if (isMacroDefined(S, "NULL")) + if (isMacroDefined(S, Loc, "NULL")) return "NULL"; } if (T.isCharType()) @@ -194,9 +200,10 @@ static std::string getScalarZeroExpressionForType(const Type& T, const Sema& S) return "0"; } -std::string Sema::getFixItZeroInitializerForType(QualType T) const { +std::string +Sema::getFixItZeroInitializerForType(QualType T, SourceLocation Loc) const { if (T->isScalarType()) { - std::string s = getScalarZeroExpressionForType(*T, *this); + std::string s = getScalarZeroExpressionForType(*T, Loc, *this); if (!s.empty()) s = " = " + s; return s; @@ -212,6 +219,7 @@ std::string Sema::getFixItZeroInitializerForType(QualType T) const { return std::string(); } -std::string Sema::getFixItZeroLiteralForType(QualType T) const { - return getScalarZeroExpressionForType(*T, *this); +std::string +Sema::getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const { + return getScalarZeroExpressionForType(*T, Loc, *this); } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 4cb4f5651f0..753ce876d60 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2395,7 +2395,8 @@ static void warnAboutAmbiguousFunction(Sema &S, Declarator &D, S.Diag(DeclType.Loc, diag::note_empty_parens_default_ctor) << FixItHint::CreateRemoval(ParenRange); else { - std::string Init = S.getFixItZeroInitializerForType(RT); + std::string Init = + S.getFixItZeroInitializerForType(RT, ParenRange.getBegin()); if (Init.empty() && S.LangOpts.CPlusPlus11) Init = "{}"; if (!Init.empty()) |