From: Richard Smith Date: Tue, 5 Feb 2013 05:52:24 +0000 (+0000) Subject: Add some missing diagnostics for C++11 narrowing conversions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a4dc51b46861eb52626f89183da7610437baba93;p=clang Add some missing diagnostics for C++11 narrowing conversions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174337 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index c8888a3275..dbdfb1ebef 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -3697,7 +3697,8 @@ public: MultiExprArg ArgsPtr, SourceLocation Loc, SmallVectorImpl &ConvertedArgs, - bool AllowExplicit = false); + bool AllowExplicit = false, + bool IsListInitialization = false); ParsedType getDestructorName(SourceLocation TildeLoc, IdentifierInfo &II, SourceLocation NameLoc, @@ -6623,7 +6624,8 @@ public: Expr **Args, unsigned NumArgs, SmallVector &AllArgs, VariadicCallType CallType = VariadicDoesNotApply, - bool AllowExplicit = false); + bool AllowExplicit = false, + bool IsListInitialization = false); // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but // will create a runtime trap if the resulting type is not a POD type. diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index ead7b6548b..b5df54765d 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -9594,7 +9594,8 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, MultiExprArg ArgsPtr, SourceLocation Loc, SmallVectorImpl &ConvertedArgs, - bool AllowExplicit) { + bool AllowExplicit, + bool IsListInitialization) { // FIXME: This duplicates a lot of code from Sema::ConvertArgumentsForCall. unsigned NumArgs = ArgsPtr.size(); Expr **Args = ArgsPtr.data(); @@ -9615,7 +9616,8 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor, SmallVector AllArgs; bool Invalid = GatherArgumentsForCall(Loc, Constructor, Proto, 0, Args, NumArgs, AllArgs, - CallType, AllowExplicit); + CallType, AllowExplicit, + IsListInitialization); ConvertedArgs.append(AllArgs.begin(), AllArgs.end()); DiagnoseSentinelCalls(Constructor, Loc, AllArgs.data(), AllArgs.size()); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ef852d354f..5b8b8fdcbf 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3720,7 +3720,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, Expr **Args, unsigned NumArgs, SmallVector &AllArgs, VariadicCallType CallType, - bool AllowExplicit) { + bool AllowExplicit, + bool IsListInitialization) { unsigned NumArgsInProto = Proto->getNumArgs(); unsigned NumArgsToCheck = NumArgs; bool Invalid = false; @@ -3760,7 +3761,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), Owned(Arg), - /*TopLevelOfInitList=*/false, + IsListInitialization, AllowExplicit); if (ArgE.isInvalid()) return true; diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 95f6c76be7..87e6648d92 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -4729,7 +4729,8 @@ PerformConstructorInitialization(Sema &S, // call. if (S.CompleteConstructorCall(Constructor, Args, Loc, ConstructorArgs, - AllowExplicitConv)) + AllowExplicitConv, + IsListInitialization)) return ExprError(); @@ -5474,9 +5475,9 @@ InitializationSequence::Perform(Sema &S, for (unsigned i = 0; i < NumInits; ++i) { Element.setElementIndex(i); ExprResult Init = S.Owned(ILE->getInit(i)); - ExprResult Res = S.PerformCopyInitialization(Element, - Init.get()->getExprLoc(), - Init); + ExprResult Res = S.PerformCopyInitialization( + Element, Init.get()->getExprLoc(), Init, + /*TopLevelOfInitList=*/ true); assert(!Res.isInvalid() && "Result changed since try phase."); Converted[i] = Res.take(); } @@ -6189,7 +6190,11 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "OpenCL event_t from zero"; break; } + + OS << " [" << S->Type.getAsString() << ']'; } + + OS << '\n'; } void InitializationSequence::dump() const { diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp index 3450003a6e..c7fb24fb44 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3-0x.cpp @@ -21,7 +21,7 @@ namespace std { }; } -namespace bullet2 { +namespace bullet1 { double ad[] = { 1, 2.0 }; int ai[] = { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} @@ -62,12 +62,16 @@ namespace bullet4_example3 { }; S s1 = { 1, 2, 3.0 }; - // FIXME: This is an ill-formed narrowing initialization. - S s2 { 1.0, 2, 3 }; + S s2 { 1.0, 2, 3 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} S s3 {}; } namespace bullet5 { + int x1 {2}; + int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} +} + +namespace bullet6 { struct S { S(std::initializer_list) {} S(const std::string &) {} @@ -75,17 +79,12 @@ namespace bullet5 { const S& r1 = { 1, 2, 3.0 }; const S& r2 = { "Spinach" }; - S& r3 = { 1, 2, 3 }; // expected-error {{non-const lvalue reference to type 'bullet5::S' cannot bind to an initializer list temporary}} + S& r3 = { 1, 2, 3 }; // expected-error {{non-const lvalue reference to type 'bullet6::S' cannot bind to an initializer list temporary}} const int& i1 = { 1 }; const int& i2 = { 1.1 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}} const int (&iar)[2] = { 1, 2 }; } -namespace bullet6 { - int x1 {2}; - int x2 {2.0}; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} -} - namespace bullet7 { int** pp {}; } @@ -99,14 +98,14 @@ namespace bullet8 { B(std::initializer_list i) {} }; B b1 { 1, 2 }; - B b2 { 1, 2.0 }; + B b2 { 1, 2.0 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} struct C { C(int i, double j) {} }; C c1 = { 1, 2.2 }; - // FIXME: This is an ill-formed narrowing initialization. - C c2 = { 1.1, 2 }; // expected-warning {{implicit conversion}} + // FIXME: Suppress the narrowing warning in the cases where we issue a narrowing error. + C c2 = { 1.1, 2 }; // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} expected-warning {{implicit conversion}} int j { 1 }; int k { }; diff --git a/test/SemaCXX/cxx0x-initializer-constructor.cpp b/test/SemaCXX/cxx0x-initializer-constructor.cpp index 45ec0cbfdd..dc179f81bd 100644 --- a/test/SemaCXX/cxx0x-initializer-constructor.cpp +++ b/test/SemaCXX/cxx0x-initializer-constructor.cpp @@ -75,9 +75,8 @@ namespace objects { { F<0> f = {}; } // Narrowing conversions don't affect viability. The next two choose // the initializer_list constructor. - // FIXME: Emit narrowing conversion errors. - { F<3> f{1, 1.0}; } // xpected-error {{narrowing conversion}} - { F<3> f = {1, 1.0}; } // xpected-error {{narrowing conversion}} + { F<3> f{1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} + { F<3> f = {1, 1.0}; } // expected-error {{type 'double' cannot be narrowed to 'int' in initializer list}} expected-note {{override}} { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; } { F<3> f = {1, 2, 3, 4, 5, 6, 7, 8}; } { F<3> f{1, 2, 3, 4, 5, 6, 7, 8}; }