From 03544fccd1782418c1bf2528111683e18f43b913 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 19 Apr 2012 06:58:00 +0000 Subject: [PATCH] Add missing -Wc++98-compat warnings for initializer list initializations which initialize references, create std::initializer_list objects, or call constructors. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155105 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 9 ++++++++ lib/Sema/SemaInit.cpp | 15 +++++++++++++ test/SemaCXX/cxx98-compat.cpp | 26 +++++++++++++++++++++- 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 86d42bb72c..d972774628 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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, DefaultIgnore; +def warn_cxx98_compat_reference_list_init : Warning< + "reference initialized from initializer list is incompatible with C++98">, + InGroup, DefaultIgnore; +def warn_cxx98_compat_initializer_list_init : Warning< + "initialization of initializer_list object is incompatible with C++98">, + InGroup, DefaultIgnore; +def warn_cxx98_compat_ctor_list_init : Warning< + "constructor call from initializer list is incompatible with C++98">, + InGroup, DefaultIgnore; def err_illegal_initializer : Error< "illegal initializer (only variables can be initialized)">; def err_illegal_initializer_type : Error<"illegal initializer type %0">; diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a65b41fd1c..4b80b77ecc 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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(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(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(CurInit.take()); + S.Diag(ILE->getExprLoc(), diag::warn_cxx98_compat_initializer_list_init) + << ILE->getSourceRange(); unsigned NumInits = ILE->getNumInits(); SmallVector Converted(NumInits); InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary( diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp index 47589135c9..2688232122 100644 --- a/test/SemaCXX/cxx98-compat.cpp +++ b/test/SemaCXX/cxx98-compat.cpp @@ -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 struct initializer_list { + initializer_list(T*, size_t); + T *p; + size_t n; + }; +} template // 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); +}; + 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 s = {}; // ok, aggregate s = {}; // expected-warning {{generalized initializer lists are incompatible with C++98}} + std::initializer_list 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 { -- 2.40.0