forked from OSchip/llvm-project
Add FixItHint for -Wnull-conversion to initialize with an appropriate literal.
Reviewed by Doug Gregor. llvm-svn: 155839
This commit is contained in:
parent
f68e809c5e
commit
7665a62cf7
|
@ -833,7 +833,8 @@ public:
|
|||
bool findMacroSpelling(SourceLocation &loc, StringRef name);
|
||||
|
||||
/// \brief Get a string to suggest for zero-initialization of a type.
|
||||
const char *getFixItZeroInitializerForType(QualType T) const;
|
||||
std::string getFixItZeroInitializerForType(QualType T) const;
|
||||
std::string getFixItZeroLiteralForType(QualType T) const;
|
||||
|
||||
ExprResult Owned(Expr* E) { return E; }
|
||||
ExprResult Owned(ExprResult R) { return R; }
|
||||
|
|
|
@ -438,8 +438,8 @@ static bool SuggestInitializationFixit(Sema &S, const VarDecl *VD) {
|
|||
return false;
|
||||
|
||||
// Suggest possible initialization (if any).
|
||||
const char *Init = S.getFixItZeroInitializerForType(VariableTy);
|
||||
if (!Init)
|
||||
std::string Init = S.getFixItZeroInitializerForType(VariableTy);
|
||||
if (Init.empty())
|
||||
return false;
|
||||
SourceLocation Loc = S.PP.getLocForEndOfToken(VD->getLocEnd());
|
||||
|
||||
|
|
|
@ -4220,7 +4220,8 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
|
|||
if (Loc.isMacroID())
|
||||
Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first;
|
||||
S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
|
||||
<< T << Loc << clang::SourceRange(CC);
|
||||
<< T << clang::SourceRange(CC)
|
||||
<< FixItHint::CreateReplacement(Loc, S.getFixItZeroLiteralForType(T));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -5090,12 +5090,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
(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, "{}");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,42 +163,54 @@ static bool isMacroDefined(const Sema &S, StringRef Name) {
|
|||
return S.PP.getMacroInfo(&S.getASTContext().Idents.get(Name));
|
||||
}
|
||||
|
||||
const char *Sema::getFixItZeroInitializerForType(QualType T) const {
|
||||
static std::string getScalarZeroExpressionForType(const Type& T, 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"))
|
||||
return "nil";
|
||||
if (T.isRealFloatingType())
|
||||
return "0.0";
|
||||
if (T.isBooleanType() && S.LangOpts.CPlusPlus)
|
||||
return "false";
|
||||
if (T.isPointerType() || T.isMemberPointerType()) {
|
||||
if (S.LangOpts.CPlusPlus0x)
|
||||
return "nullptr";
|
||||
if (isMacroDefined(S, "NULL"))
|
||||
return "NULL";
|
||||
}
|
||||
if (T.isCharType())
|
||||
return "'\\0'";
|
||||
if (T.isWideCharType())
|
||||
return "L'\\0'";
|
||||
if (T.isChar16Type())
|
||||
return "u'\\0'";
|
||||
if (T.isChar32Type())
|
||||
return "U'\\0'";
|
||||
return "0";
|
||||
}
|
||||
|
||||
std::string Sema::getFixItZeroInitializerForType(QualType T) const {
|
||||
if (T->isScalarType()) {
|
||||
// Suggest " = 0" for non-enumeration scalar types, unless we can find a
|
||||
// better initializer.
|
||||
if (T->isEnumeralType())
|
||||
return 0;
|
||||
if ((T->isObjCObjectPointerType() || T->isBlockPointerType()) &&
|
||||
isMacroDefined(*this, "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";
|
||||
else if (isMacroDefined(*this, "NULL"))
|
||||
return " = NULL";
|
||||
}
|
||||
if (T->isCharType())
|
||||
return " = '\\0'";
|
||||
if (T->isWideCharType())
|
||||
return " = L'\\0'";
|
||||
if (T->isChar16Type())
|
||||
return " = u'\\0'";
|
||||
if (T->isChar32Type())
|
||||
return " = U'\\0'";
|
||||
return " = 0";
|
||||
std::string s = getScalarZeroExpressionForType(*T, *this);
|
||||
if (!s.empty())
|
||||
s = " = " + s;
|
||||
return s;
|
||||
}
|
||||
|
||||
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
|
||||
if (!RD || !RD->hasDefinition())
|
||||
return 0;
|
||||
return std::string();
|
||||
if (LangOpts.CPlusPlus0x && !RD->hasUserProvidedDefaultConstructor())
|
||||
return "{}";
|
||||
if (RD->isAggregate())
|
||||
return " = {}";
|
||||
return 0;
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string Sema::getFixItZeroLiteralForType(QualType T) const {
|
||||
return getScalarZeroExpressionForType(*T, *this);
|
||||
}
|
||||
|
|
|
@ -205,7 +205,6 @@ template<template<typename> Foo, // expected-error {{template template parameter
|
|||
template<typename> struct Baz> // expected-error {{template template parameter requires 'class' after the parameter list}}
|
||||
void func();
|
||||
|
||||
|
||||
namespace ShadowedTagType {
|
||||
class Foo {
|
||||
public:
|
||||
|
@ -218,6 +217,9 @@ class Foo {
|
|||
void Foo::SetBar(Bar bar) { bar_ = bar; } // expected-error {{must use 'enum' tag to refer to type 'Bar' in this scope}}
|
||||
}
|
||||
|
||||
#define NULL __null
|
||||
char c = NULL; // expected-warning {{implicit conversion of NULL constant to 'char'}}
|
||||
|
||||
namespace arrow_suggest {
|
||||
|
||||
template <typename T>
|
||||
|
|
Loading…
Reference in New Issue