forked from OSchip/llvm-project
Add missing -Wc++98-compat warnings for initializer list initializations which
initialize references, create std::initializer_list objects, or call constructors. llvm-svn: 155105
This commit is contained in:
parent
eb63a4df26
commit
2b349aee5b
|
@ -3070,6 +3070,15 @@ def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">;
|
|||
def warn_cxx98_compat_empty_scalar_initializer : Warning<
|
||||
"scalar initialized from empty initializer list is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def warn_cxx98_compat_reference_list_init : Warning<
|
||||
"reference initialized from initializer list is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def warn_cxx98_compat_initializer_list_init : Warning<
|
||||
"initialization of initializer_list object is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def warn_cxx98_compat_ctor_list_init : Warning<
|
||||
"constructor call from initializer list is incompatible with C++98">,
|
||||
InGroup<CXX98Compat>, DefaultIgnore;
|
||||
def err_illegal_initializer : Error<
|
||||
"illegal initializer (only variables can be initialized)">;
|
||||
def err_illegal_initializer_type : Error<"illegal initializer type %0">;
|
||||
|
|
|
@ -4816,6 +4816,17 @@ InitializationSequence::Perform(Sema &S,
|
|||
if (Steps.empty())
|
||||
return S.Owned((Expr *)0);
|
||||
|
||||
if (S.getLangOpts().CPlusPlus0x && Entity.getType()->isReferenceType() &&
|
||||
Args.size() == 1 && isa<InitListExpr>(Args.get()[0]) &&
|
||||
Entity.getKind() != InitializedEntity::EK_Parameter) {
|
||||
// Produce a C++98 compatibility warning if we are initializing a reference
|
||||
// from an initializer list. For parameters, we produce a better warning
|
||||
// elsewhere.
|
||||
Expr *Init = Args.get()[0];
|
||||
S.Diag(Init->getLocStart(), diag::warn_cxx98_compat_reference_list_init)
|
||||
<< Init->getSourceRange();
|
||||
}
|
||||
|
||||
QualType DestType = Entity.getType().getNonReferenceType();
|
||||
// FIXME: Ugly hack around the fact that Entity.getType() is not
|
||||
// the same as Entity.getDecl()->getType() in cases involving type merging,
|
||||
|
@ -5153,6 +5164,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
Entity.getType().getNonReferenceType());
|
||||
bool UseTemporary = Entity.getType()->isReferenceType();
|
||||
InitListExpr *InitList = cast<InitListExpr>(CurInit.get());
|
||||
S.Diag(InitList->getExprLoc(), diag::warn_cxx98_compat_ctor_list_init)
|
||||
<< InitList->getSourceRange();
|
||||
MultiExprArg Arg(InitList->getInits(), InitList->getNumInits());
|
||||
CurInit = PerformConstructorInitialization(S, UseTemporary ? TempEntity :
|
||||
Entity,
|
||||
|
@ -5330,6 +5343,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
}
|
||||
|
||||
InitListExpr *ILE = cast<InitListExpr>(CurInit.take());
|
||||
S.Diag(ILE->getExprLoc(), diag::warn_cxx98_compat_initializer_list_init)
|
||||
<< ILE->getSourceRange();
|
||||
unsigned NumInits = ILE->getNumInits();
|
||||
SmallVector<Expr*, 16> Converted(NumInits);
|
||||
InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary(
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -verify %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s
|
||||
|
||||
namespace std { struct type_info; }
|
||||
namespace std {
|
||||
struct type_info;
|
||||
using size_t = decltype(sizeof(0)); // expected-warning {{decltype}} expected-warning {{alias}}
|
||||
template<typename T> struct initializer_list {
|
||||
initializer_list(T*, size_t);
|
||||
T *p;
|
||||
size_t n;
|
||||
};
|
||||
}
|
||||
|
||||
template<typename ...T> // expected-warning {{variadic templates are incompatible with C++98}}
|
||||
class Variadic1 {};
|
||||
|
@ -39,6 +47,14 @@ void Lambda() {
|
|||
[]{}(); // expected-warning {{lambda expressions are incompatible with C++98}}
|
||||
}
|
||||
|
||||
struct Ctor {
|
||||
Ctor(int, char);
|
||||
Ctor(double, long);
|
||||
};
|
||||
struct InitListCtor {
|
||||
InitListCtor(std::initializer_list<bool>);
|
||||
};
|
||||
|
||||
int InitList(int i = {}) { // expected-warning {{generalized initializer lists are incompatible with C++98}} \
|
||||
// expected-warning {{scalar initialized from empty initializer list is incompatible with C++98}}
|
||||
(void)new int {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} \
|
||||
|
@ -48,6 +64,14 @@ int InitList(int i = {}) { // expected-warning {{generalized initializer lists a
|
|||
int x { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
|
||||
S<int> s = {}; // ok, aggregate
|
||||
s = {}; // expected-warning {{generalized initializer lists are incompatible with C++98}}
|
||||
std::initializer_list<int> xs = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
|
||||
auto ys = { 1, 2, 3 }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}} \
|
||||
// expected-warning {{'auto' type specifier is incompatible with C++98}}
|
||||
Ctor c1 = { 1, 2 }; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
|
||||
Ctor c2 = { 3.0, 4l }; // expected-warning {{constructor call from initializer list is incompatible with C++98}}
|
||||
InitListCtor ilc = { true, false }; // expected-warning {{initialization of initializer_list object is incompatible with C++98}}
|
||||
const int &r = { 0 }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
|
||||
struct { int a; const int &r; } rr = { 0, {{0}} }; // expected-warning {{reference initialized from initializer list is incompatible with C++98}}
|
||||
return { 0 }; // expected-warning {{generalized initializer lists are incompatible with C++98}}
|
||||
}
|
||||
struct DelayedDefaultArgumentParseInitList {
|
||||
|
|
Loading…
Reference in New Issue