Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -7072,6 +7072,23 @@ DAR_FailedAlreadyDiagnosed }; + /// RAII class that is used to determine whether we are deducing the type of + /// an auto variable. + class DeduceAutoTypeRAII { + Sema &SemaRef; + public: + DeduceAutoTypeRAII(Sema &SemaRef) : SemaRef(SemaRef) { + SemaRef.DeduceAutoTypeRAIIs.push_back(this); + } + ~DeduceAutoTypeRAII() { SemaRef.DeduceAutoTypeRAIIs.pop_back(); } + }; + + friend DeduceAutoTypeRAII; + + SmallVector DeduceAutoTypeRAIIs; + + bool deducingAutoType() const { return !DeduceAutoTypeRAIIs.empty(); } + DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result, Optional DependentDeductionDepth = None); 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/SemaExprMember.cpp =================================================================== --- lib/Sema/SemaExprMember.cpp +++ lib/Sema/SemaExprMember.cpp @@ -1712,6 +1712,8 @@ Base, Base->getType(), OpLoc, IsArrow, SS, TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs, S, &ExtraArgs); + Res = CheckPlaceholderExpr(Res.get()); + if (!Res.isInvalid() && isa(Res.get())) CheckMemberAccessOfNoDeref(cast(Res.get())); 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/SemaPseudoObject.cpp =================================================================== --- lib/Sema/SemaPseudoObject.cpp +++ lib/Sema/SemaPseudoObject.cpp @@ -975,7 +975,7 @@ } ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) { - if (isWeakProperty() && !S.isUnevaluatedContext() && + if (isWeakProperty() && !S.isUnevaluatedContext() && !S.deducingAutoType() && !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, SyntacticForm->getBeginLoc())) S.getCurFunction()->recordUseOfWeak(SyntacticRefExpr, Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -4402,6 +4402,8 @@ Sema::DeduceAutoResult Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, Optional DependentDeductionDepth) { + DeduceAutoTypeRAII RAII(*this); + if (Init->getType()->isNonOverloadPlaceholderType()) { ExprResult NonPlaceholder = CheckPlaceholderExpr(Init); if (NonPlaceholder.isInvalid()) @@ -4429,6 +4431,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 @@ -462,6 +462,13 @@ 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; } // This used to crash in the constructor of WeakObjectProfileTy when a