From owner-svn-src-stable-11@freebsd.org Tue Jan 16 08:00:09 2018 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 809D2EB2CA3; Tue, 16 Jan 2018 08:00:09 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 434EA6CAB3; Tue, 16 Jan 2018 08:00:09 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 857AA1DA11; Tue, 16 Jan 2018 08:00:08 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0G808n3037633; Tue, 16 Jan 2018 08:00:08 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0G808qs037630; Tue, 16 Jan 2018 08:00:08 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201801160800.w0G808qs037630@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Tue, 16 Jan 2018 08:00:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r328043 - in stable/11/contrib/llvm/tools/clang: include/clang/AST lib/AST lib/Sema X-SVN-Group: stable-11 X-SVN-Commit-Author: dim X-SVN-Commit-Paths: in stable/11/contrib/llvm/tools/clang: include/clang/AST lib/AST lib/Sema X-SVN-Commit-Revision: 328043 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Jan 2018 08:00:09 -0000 Author: dim Date: Tue Jan 16 08:00:07 2018 New Revision: 328043 URL: https://svnweb.freebsd.org/changeset/base/328043 Log: MFC r327930: Pull in r314499 from upstream clang trunk (by Daniel Marjamäki): [Sema] Suppress warnings for C's zero initializer Patch by S. Gilles! Differential Revision: https://reviews.llvm.org/D28148 Pull in r314838 from upstream clang trunk (by Richard Smith): Suppress -Wmissing-braces warning when aggregate-initializing a struct with a single field that is itself an aggregate. In C++, such initialization of std::array types is guaranteed to work by the standard, is completely idiomatic, and the "suggested" alternative from Clang was technically invalid. Together, these suppress unneeded "suggest braces around initialization of subobject" warnings for C++11 initializer lists. Modified: stable/11/contrib/llvm/tools/clang/include/clang/AST/Expr.h stable/11/contrib/llvm/tools/clang/lib/AST/Expr.cpp stable/11/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp Directory Properties: stable/11/ (props changed) Modified: stable/11/contrib/llvm/tools/clang/include/clang/AST/Expr.h ============================================================================== --- stable/11/contrib/llvm/tools/clang/include/clang/AST/Expr.h Tue Jan 16 06:24:19 2018 (r328042) +++ stable/11/contrib/llvm/tools/clang/include/clang/AST/Expr.h Tue Jan 16 08:00:07 2018 (r328043) @@ -3986,6 +3986,10 @@ class InitListExpr : public Expr { (public) /// initializer)? bool isTransparent() const; + /// Is this the zero initializer {0} in a language which considers it + /// idiomatic? + bool isIdiomaticZeroInitializer(const LangOptions &LangOpts) const; + SourceLocation getLBraceLoc() const { return LBraceLoc; } void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -3994,6 +3998,9 @@ class InitListExpr : public Expr { (public) bool isSemanticForm() const { return AltForm.getInt(); } InitListExpr *getSemanticForm() const { return isSemanticForm() ? nullptr : AltForm.getPointer(); + } + bool isSyntacticForm() const { + return !AltForm.getInt() || !AltForm.getPointer(); } InitListExpr *getSyntacticForm() const { return isSemanticForm() ? AltForm.getPointer() : nullptr; Modified: stable/11/contrib/llvm/tools/clang/lib/AST/Expr.cpp ============================================================================== --- stable/11/contrib/llvm/tools/clang/lib/AST/Expr.cpp Tue Jan 16 06:24:19 2018 (r328042) +++ stable/11/contrib/llvm/tools/clang/lib/AST/Expr.cpp Tue Jan 16 08:00:07 2018 (r328043) @@ -1899,6 +1899,17 @@ bool InitListExpr::isTransparent() const { getInit(0)->getType().getCanonicalType(); } +bool InitListExpr::isIdiomaticZeroInitializer(const LangOptions &LangOpts) const { + assert(isSyntacticForm() && "only test syntactic form as zero initializer"); + + if (LangOpts.CPlusPlus || getNumInits() != 1) { + return false; + } + + const IntegerLiteral *Lit = dyn_cast(getInit(0)); + return Lit && Lit->getValue() == 0; +} + SourceLocation InitListExpr::getLocStart() const { if (InitListExpr *SyntacticForm = getSyntacticForm()) return SyntacticForm->getLocStart(); Modified: stable/11/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp ============================================================================== --- stable/11/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp Tue Jan 16 06:24:19 2018 (r328042) +++ stable/11/contrib/llvm/tools/clang/lib/Sema/SemaInit.cpp Tue Jan 16 08:00:07 2018 (r328043) @@ -826,6 +826,34 @@ int InitListChecker::numStructUnionElements(QualType D return InitializableMembers - structDecl->hasFlexibleArrayMember(); } +/// Determine whether Entity is an entity for which it is idiomatic to elide +/// the braces in aggregate initialization. +static bool isIdiomaticBraceElisionEntity(const InitializedEntity &Entity) { + // Recursive initialization of the one and only field within an aggregate + // class is considered idiomatic. This case arises in particular for + // initialization of std::array, where the C++ standard suggests the idiom of + // + // std::array arr = {1, 2, 3}; + // + // (where std::array is an aggregate struct containing a single array field. + + // FIXME: Should aggregate initialization of a struct with a single + // base class and no members also suppress the warning? + if (Entity.getKind() != InitializedEntity::EK_Member || !Entity.getParent()) + return false; + + auto *ParentRD = + Entity.getParent()->getType()->castAs()->getDecl(); + if (CXXRecordDecl *CXXRD = dyn_cast(ParentRD)) + if (CXXRD->getNumBases()) + return false; + + auto FieldIt = ParentRD->field_begin(); + assert(FieldIt != ParentRD->field_end() && + "no fields but have initializer for member?"); + return ++FieldIt == ParentRD->field_end(); +} + /// Check whether the range of the initializer \p ParentIList from element /// \p Index onwards can be used to initialize an object of type \p T. Update /// \p Index to indicate how many elements of the list were consumed. @@ -886,7 +914,9 @@ void InitListChecker::CheckImplicitInitList(const Init } // Complain about missing braces. - if (T->isArrayType() || T->isRecordType()) { + if ((T->isArrayType() || T->isRecordType()) && + !ParentIList->isIdiomaticZeroInitializer(SemaRef.getLangOpts()) && + !isIdiomaticBraceElisionEntity(Entity)) { SemaRef.Diag(StructuredSubobjectInitList->getLocStart(), diag::warn_missing_braces) << StructuredSubobjectInitList->getSourceRange() @@ -1833,7 +1863,9 @@ void InitListChecker::CheckStructUnionTypes( // worthwhile to skip over the rest of the initializer, though. RecordDecl *RD = DeclType->getAs()->getDecl(); RecordDecl::field_iterator FieldEnd = RD->field_end(); - bool CheckForMissingFields = true; + bool CheckForMissingFields = + !IList->isIdiomaticZeroInitializer(SemaRef.getLangOpts()); + while (Index < IList->getNumInits()) { Expr *Init = IList->getInit(Index);