r350917 - [Sema] If CheckPlaceholderExpr rewrites the initializer of an auto

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 23 19:21:07 PDT 2019


Hi Akira,

I've reverted this in r359066. This subtly breaks the semantics of C++
initializers by strripping off an outer level of parentheses / braces
in some cases. Testcase:

  struct A {
    A();
    A(const A&) = delete;
  };
  auto x = [a{A()}] {};

(This should be accepted in C++17 mode onwards, but this patch rejects
it by losing the braces around the A() expression.)

Moreover, I think this is fundamentally the wrong approach:
DeduceAutoType should not ever be changing the initializer expression
(and it certainly shouldn't expect those changes to stick around).
Instead, we should check for a placeholder type before attempting
deduction, just like we correct typos in the initializer before
attempting deduction.

On Thu, 10 Jan 2019 at 21:01, Akira Hatanaka via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
>
> Author: ahatanak
> Date: Thu Jan 10 20:57:34 2019
> New Revision: 350917
>
> URL: http://llvm.org/viewvc/llvm-project?rev=350917&view=rev
> Log:
> [Sema] If CheckPlaceholderExpr rewrites the initializer of an auto
> variable during auto type deduction, use the rewritten initializer when
> performing initialization of the variable.
>
> This silences spurious -Warc-repeated-use-of-weak warnings that are
> issued when the initializer uses a weak ObjC pointer.
>
> Differential Revision: https://reviews.llvm.org/D55662
>
> Modified:
>     cfe/trunk/include/clang/Sema/Sema.h
>     cfe/trunk/lib/Sema/SemaDecl.cpp
>     cfe/trunk/lib/Sema/SemaExprCXX.cpp
>     cfe/trunk/lib/Sema/SemaLambda.cpp
>     cfe/trunk/test/SemaObjC/arc-repeated-weak.mm
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=350917&r1=350916&r2=350917&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Jan 10 20:57:34 2019
> @@ -1960,7 +1960,7 @@ public:
>    bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
>    void CheckVariableDeclarationType(VarDecl *NewVD);
>    bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
> -                                     Expr *Init);
> +                                     Expr *&Init);
>    void CheckCompleteVariableDeclaration(VarDecl *VD);
>    void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD);
>    void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
> @@ -7095,7 +7095,7 @@ public:
>    QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
>                                          QualType Type, TypeSourceInfo *TSI,
>                                          SourceRange Range, bool DirectInit,
> -                                        Expr *Init);
> +                                        Expr *&Init);
>
>    TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;
>
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=350917&r1=350916&r2=350917&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 10 20:57:34 2019
> @@ -10812,7 +10812,7 @@ QualType Sema::deduceVarTypeFromInitiali
>                                              DeclarationName Name, QualType Type,
>                                              TypeSourceInfo *TSI,
>                                              SourceRange Range, bool DirectInit,
> -                                            Expr *Init) {
> +                                            Expr *&Init) {
>    bool IsInitCapture = !VDecl;
>    assert((!VDecl || !VDecl->isInitCapture()) &&
>           "init captures are expected to be deduced prior to initialization");
> @@ -10928,7 +10928,8 @@ QualType Sema::deduceVarTypeFromInitiali
>            << (DeduceInit->getType().isNull() ? TSI->getType()
>                                               : DeduceInit->getType())
>            << DeduceInit->getSourceRange();
> -  }
> +  } else
> +    Init = DeduceInit;
>
>    // Warn if we deduced 'id'. 'auto' usually implies type-safety, but using
>    // 'id' instead of a specific object type prevents most of our usual
> @@ -10945,7 +10946,7 @@ QualType Sema::deduceVarTypeFromInitiali
>  }
>
>  bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
> -                                         Expr *Init) {
> +                                         Expr *&Init) {
>    QualType DeducedType = deduceVarTypeFromInitializer(
>        VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
>        VDecl->getSourceRange(), DirectInit, Init);
> @@ -11451,8 +11452,9 @@ void Sema::ActOnUninitializedDecl(Decl *
>        return;
>      }
>
> +    Expr *TmpInit = nullptr;
>      if (Type->isUndeducedType() &&
> -        DeduceVariableDeclarationType(Var, false, nullptr))
> +        DeduceVariableDeclarationType(Var, false, TmpInit))
>        return;
>
>      // C++11 [class.static.data]p3: A static data member can be declared with
>
> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=350917&r1=350916&r2=350917&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jan 10 20:57:34 2019
> @@ -1865,12 +1865,11 @@ Sema::BuildCXXNew(SourceRange Range, boo
>      if (Braced && !getLangOpts().CPlusPlus17)
>        Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
>            << AllocType << TypeRange;
> -    Expr *Deduce = Inits[0];
>      QualType DeducedType;
> -    if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
> +    if (DeduceAutoType(AllocTypeInfo, Inits[0], DeducedType) == DAR_Failed)
>        return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
> -                       << AllocType << Deduce->getType()
> -                       << TypeRange << Deduce->getSourceRange());
> +                       << AllocType << Inits[0]->getType()
> +                       << TypeRange << Inits[0]->getSourceRange());
>      if (DeducedType.isNull())
>        return ExprError();
>      AllocType = DeducedType;
>
> Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=350917&r1=350916&r2=350917&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLambda.cpp Thu Jan 10 20:57:34 2019
> @@ -759,14 +759,15 @@ QualType Sema::buildLambdaInitCaptureIni
>    TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType);
>
>    // Deduce the type of the init capture.
> +  Expr *DeduceInit = Init;
>    QualType DeducedType = deduceVarTypeFromInitializer(
>        /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI,
> -      SourceRange(Loc, Loc), IsDirectInit, Init);
> +      SourceRange(Loc, Loc), IsDirectInit, DeduceInit);
>    if (DeducedType.isNull())
>      return QualType();
>
>    // Are we a non-list direct initialization?
> -  ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
> +  bool CXXDirectInit = isa<ParenListExpr>(Init);
>
>    // Perform initialization analysis and ensure any implicit conversions
>    // (such as lvalue-to-rvalue) are enforced.
> @@ -779,10 +780,7 @@ QualType Sema::buildLambdaInitCaptureIni
>                             : InitializationKind::CreateDirectList(Loc))
>            : InitializationKind::CreateCopy(Loc, Init->getBeginLoc());
>
> -  MultiExprArg Args = Init;
> -  if (CXXDirectInit)
> -    Args =
> -        MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs());
> +  MultiExprArg Args = DeduceInit;
>    QualType DclT;
>    InitializationSequence InitSeq(*this, Entity, Kind, Args);
>    ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT);
>
> Modified: cfe/trunk/test/SemaObjC/arc-repeated-weak.mm
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-repeated-weak.mm?rev=350917&r1=350916&r2=350917&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/arc-repeated-weak.mm (original)
> +++ cfe/trunk/test/SemaObjC/arc-repeated-weak.mm Thu Jan 10 20:57:34 2019
> @@ -1,5 +1,5 @@
> -// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
> -// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
> +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
> +// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
>
>  @interface Test {
>  @public
> @@ -467,6 +467,18 @@ void foo() {
>    __typeof__(NSBundle2.foo2.weakProp) t5;
>  }
>
> +void testAuto() {
> +  auto __weak wp = NSBundle2.foo2.weakProp;
> +}
> +
> +void testLambdaCaptureInit() {
> +  [capture(NSBundle2.foo2.weakProp)] {} ();
> +}
> +
> +void testAutoNew() {
> +  auto p = new auto(NSBundle2.foo2.weakProp);
> +}
> +
>  // This used to crash in the constructor of WeakObjectProfileTy when a
>  // DeclRefExpr was passed that didn't reference a VarDecl.
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list