Skip to content

Commit

Permalink
[Sema] If CheckPlaceholderExpr rewrites the initializer of an auto
Browse files Browse the repository at this point in the history
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

llvm-svn: 350917
  • Loading branch information
ahatanaka committed Jan 11, 2019
1 parent eb139de commit d458ced
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 18 deletions.
4 changes: 2 additions & 2 deletions clang/include/clang/Sema/Sema.h
Expand Up @@ -1960,7 +1960,7 @@ class Sema {
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);
Expand Down Expand Up @@ -7095,7 +7095,7 @@ class Sema {
QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name,
QualType Type, TypeSourceInfo *TSI,
SourceRange Range, bool DirectInit,
Expr *Init);
Expr *&Init);

TypeLoc getReturnTypeLoc(FunctionDecl *FD) const;

Expand Down
10 changes: 6 additions & 4 deletions clang/lib/Sema/SemaDecl.cpp
Expand Up @@ -10812,7 +10812,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
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");
Expand Down Expand Up @@ -10928,7 +10928,8 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
<< (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
Expand All @@ -10945,7 +10946,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
}

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);
Expand Down Expand Up @@ -11451,8 +11452,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
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
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/Sema/SemaExprCXX.cpp
Expand Up @@ -1865,12 +1865,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
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;
Expand Down
10 changes: 4 additions & 6 deletions clang/lib/Sema/SemaLambda.cpp
Expand Up @@ -759,14 +759,15 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
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.
Expand All @@ -779,10 +780,7 @@ QualType Sema::buildLambdaInitCaptureInitialization(SourceLocation Loc,
: 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);
Expand Down
16 changes: 14 additions & 2 deletions clang/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
Expand Down Expand Up @@ -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.

Expand Down

0 comments on commit d458ced

Please sign in to comment.