Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -2054,7 +2054,7 @@ bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); void CheckVariableDeclarationType(VarDecl *NewVD); bool DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, - Expr *Init); + Expr *Init, bool DefaultedAnyToId); void CheckCompleteVariableDeclaration(VarDecl *VD); void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); @@ -7318,7 +7318,7 @@ QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, - Expr *Init); + Expr *Init, bool DefaultedAnyToId); TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -10895,7 +10895,7 @@ DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, - Expr *Init) { + Expr *Init, bool DefaultedAnyToId) { bool IsInitCapture = !VDecl; assert((!VDecl || !VDecl->isInitCapture()) && "init captures are expected to be deduced prior to initialization"); @@ -10973,18 +10973,6 @@ return QualType(); } - // Expressions default to 'id' when we're in a debugger. - bool DefaultedAnyToId = false; - if (getLangOpts().DebuggerCastResultToId && - Init->getType() == Context.UnknownAnyTy && !IsInitCapture) { - ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); - if (Result.isInvalid()) { - return QualType(); - } - Init = Result.get(); - DefaultedAnyToId = true; - } - // C++ [dcl.decomp]p1: // If the assignment-expression [...] has array type A and no ref-qualifier // is present, e has type cv A @@ -11028,10 +11016,10 @@ } bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, - Expr *Init) { + Expr *Init, bool DefaultedAnyToId) { QualType DeducedType = deduceVarTypeFromInitializer( VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(), - VDecl->getSourceRange(), DirectInit, Init); + VDecl->getSourceRange(), DirectInit, Init, DefaultedAnyToId); if (DeducedType.isNull()) { VDecl->setInvalidDecl(); return true; @@ -11095,8 +11083,33 @@ return; } Init = Res.get(); + bool DefaultedAnyToId = false; + + // Expressions default to 'id' when we're in a debugger + // and we are assigning it to a variable of Objective-C pointer type. + if (getLangOpts().DebuggerCastResultToId && + Init->getType() == Context.UnknownAnyTy) { + ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); + return; + } + Init = Result.get(); + DefaultedAnyToId = true; + } else if (!Init->getType().isNull()) { + if (auto *placeholderType = Init->getType()->getAsPlaceholderType()) + if (placeholderType->isNonOverloadPlaceholderType()) { + Res = CheckPlaceholderExpr(Init).get(); + if (!Res.isUsable()) { + VDecl->setInvalidDecl(); + return; + } + Init = Res.get(); + } + } - if (DeduceVariableDeclarationType(VDecl, DirectInit, Init)) + if (DeduceVariableDeclarationType(VDecl, DirectInit, Init, + DefaultedAnyToId)) return; } @@ -11548,7 +11561,7 @@ } if (Type->isUndeducedType() && - DeduceVariableDeclarationType(Var, false, nullptr)) + DeduceVariableDeclarationType(Var, false, nullptr, false)) return; // C++11 [class.static.data]p3: A static data member can be declared with Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -6621,6 +6621,15 @@ ExprResult Sema::ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val) { + for (size_t I = 0, E = Val.size(); I != E; ++I) + if (auto *PlaceholderType = Val[I]->getType()->getAsPlaceholderType()) + if (PlaceholderType->isNonOverloadPlaceholderType()) { + ExprResult Result = CheckPlaceholderExpr(Val[I]); + if (!Result.isUsable()) + return ExprError(); + Val[I] = Result.get(); + } + return ParenListExpr::Create(Context, L, Val, R); } Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -1793,6 +1793,15 @@ NumInits = List->getNumExprs(); } + for (unsigned I = 0, E = NumInits; I != E; ++I) + if (auto *PlaceholderType = Inits[I]->getType()->getAsPlaceholderType()) + if (PlaceholderType->isNonOverloadPlaceholderType()) { + ExprResult Result = CheckPlaceholderExpr(Inits[I]); + if (!Result.isUsable()) + return ExprError(); + Inits[I] = Result.get(); + } + // C++11 [expr.new]p15: // A new-expression that creates an object of type T initializes that // object as follows: Index: lib/Sema/SemaLambda.cpp =================================================================== --- lib/Sema/SemaLambda.cpp +++ lib/Sema/SemaLambda.cpp @@ -787,7 +787,7 @@ // Deduce the type of the init capture. QualType DeducedType = deduceVarTypeFromInitializer( /*VarDecl*/nullptr, DeclarationName(Id), DeductType, TSI, - SourceRange(Loc, Loc), IsDirectInit, Init); + SourceRange(Loc, Loc), IsDirectInit, Init, false); if (DeducedType.isNull()) return QualType(); 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++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 @@ __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.