Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -1959,7 +1959,8 @@ bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, - Expr *Init); + Expr *Init, + Expr **DeducedAutoInit = nullptr); void CheckCompleteVariableDeclaration(VarDecl *VD); void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); @@ -7094,7 +7095,7 @@ QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, - Expr *Init); + Expr *Init, Expr **DeducedAutoInit); TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -10813,7 +10813,8 @@ DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, - Expr *Init) { + Expr *Init, + Expr **DeducedAutoInit) { bool IsInitCapture = !VDecl; assert((!VDecl || !VDecl->isInitCapture()) && "init captures are expected to be deduced prior to initialization"); @@ -10929,7 +10930,8 @@ << (DeduceInit->getType().isNull() ? TSI->getType() : DeduceInit->getType()) << DeduceInit->getSourceRange(); - } + } else if (DeducedAutoInit) + *DeducedAutoInit = 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 @@ -10946,10 +10948,10 @@ } bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, - Expr *Init) { + Expr *Init, Expr **DeducedAutoInit) { QualType DeducedType = deduceVarTypeFromInitializer( VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(), - VDecl->getSourceRange(), DirectInit, Init); + VDecl->getSourceRange(), DirectInit, Init, DeducedAutoInit); if (DeducedType.isNull()) { VDecl->setInvalidDecl(); return true; @@ -11014,8 +11016,12 @@ } Init = Res.get(); - if (DeduceVariableDeclarationType(VDecl, DirectInit, Init)) + Expr *DeducedAutoInit = nullptr; + if (DeduceVariableDeclarationType(VDecl, DirectInit, Init, + &DeducedAutoInit)) return; + if (DeducedAutoInit) + Init = DeducedAutoInit; } // dllimport cannot be used on variable definitions. Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -14550,6 +14550,10 @@ } ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) { + ExprResult Result = CheckPlaceholderExpr(E); + if (Result.isInvalid()) + return ExprError(); + E = Result.get(); if (!E->getType()->isVariablyModifiedType()) return E; return TransformToPotentiallyEvaluated(E); Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -6543,6 +6543,11 @@ ExpressionEvaluationContextRecord::EK_Decltype && "not in a decltype expression"); + ExprResult Result = CheckPlaceholderExpr(E); + if (Result.isInvalid()) + return ExprError(); + E = Result.get(); + // C++11 [expr.call]p11: // If a function call is a prvalue of object type, // -- if the function call is either Index: lib/Sema/SemaExprObjC.cpp =================================================================== --- lib/Sema/SemaExprObjC.cpp +++ lib/Sema/SemaExprObjC.cpp @@ -3161,7 +3161,7 @@ Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak; if (!IsWeak && Sel.isUnarySelector()) IsWeak = ReturnType.getObjCLifetime() & Qualifiers::OCL_Weak; - if (IsWeak && + if (IsWeak && !isUnevaluatedContext() && !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, LBracLoc)) getCurFunction()->recordUseOfWeak(Result, Prop); } Index: lib/Sema/SemaLambda.cpp =================================================================== --- lib/Sema/SemaLambda.cpp +++ lib/Sema/SemaLambda.cpp @@ -759,9 +759,10 @@ TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, DeductType); // Deduce the type of the init capture. + Expr *DeducedAutoInit = nullptr; QualType DeducedType = deduceVarTypeFromInitializer( /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI, - SourceRange(Loc, Loc), IsDirectInit, Init); + SourceRange(Loc, Loc), IsDirectInit, Init, &DeducedAutoInit); if (DeducedType.isNull()) return QualType(); @@ -779,10 +780,18 @@ : InitializationKind::CreateDirectList(Loc)) : InitializationKind::CreateCopy(Loc, Init->getBeginLoc()); - MultiExprArg Args = Init; - if (CXXDirectInit) + MultiExprArg Args; + + if (DeducedAutoInit) { + assert(!isa(DeducedAutoInit) && + "paren list expr not expected"); + Args = DeducedAutoInit; + } else if (CXXDirectInit) Args = MultiExprArg(CXXDirectInit->getExprs(), CXXDirectInit->getNumExprs()); + else + Args = Init; + QualType DclT; InitializationSequence InitSeq(*this, Entity, Kind, Args); ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Args, &DclT); Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -4429,6 +4429,10 @@ return DAR_FailedAlreadyDiagnosed; } + ExprResult ER = CheckPlaceholderExpr(Init); + if (ER.isInvalid()) + return DAR_FailedAlreadyDiagnosed; + Init = ER.get(); QualType Deduced = BuildDecltypeType(Init, Init->getBeginLoc(), false); if (Deduced.isNull()) return DAR_FailedAlreadyDiagnosed; Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -8056,9 +8056,7 @@ } QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) { - ExprResult ER = CheckPlaceholderExpr(E); - if (ER.isInvalid()) return QualType(); - E = ER.get(); + assert(!E->hasPlaceholderType() && "unexpected placeholder"); if (!getLangOpts().CPlusPlus && E->refersToBitField()) Diag(E->getExprLoc(), diag::err_sizeof_alignof_typeof_bitfield) << 2; @@ -8143,9 +8141,7 @@ QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc, bool AsUnevaluated) { - ExprResult ER = CheckPlaceholderExpr(E); - if (ER.isInvalid()) return QualType(); - E = ER.get(); + assert(!E->hasPlaceholderType() && "unexpected placeholder"); if (AsUnevaluated && CodeSynthesisContexts.empty() && E->HasSideEffects(Context, false)) { Index: test/SemaObjC/arc-repeated-weak.mm =================================================================== --- test/SemaObjC/arc-repeated-weak.mm +++ test/SemaObjC/arc-repeated-weak.mm @@ -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++11 -Warc-repeated-use-of-weak -std=c++14 -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 -std=c++14 -verify %s @interface Test { @public @@ -462,6 +462,17 @@ NSString * t2 = NSBundle.foo2.prop; use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}} use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}} + decltype([NSBundle2.foo2 weakProp]) t3; + decltype(NSBundle2.foo2.weakProp) t4; + __typeof__(NSBundle2.foo2.weakProp) t5; +} + +void testAuto() { + auto __weak wp = NSBundle2.foo2.weakProp; +} + +void testLambdaCaptureInit() { + [capture(NSBundle2.foo2.weakProp)] {} (); } // This used to crash in the constructor of WeakObjectProfileTy when a