[Sema] Call CheckPlaceholderExpr to resolve typeof or decltype

placeholder expressions while an unevaluated context is still on the
expression evaluation context stack.

This prevents recordUseOfWeek from being called when a weak variable is
used as an operand of a decltype or a typeof expression and fixes
spurious -Warc-repeated-use-of-weak warnings.

rdar://problem/45742525

Differential Revision: https://reviews.llvm.org/D55662

llvm-svn: 350887
This commit is contained in:
Akira Hatanaka 2019-01-10 20:12:16 +00:00
parent 0f36e23540
commit 0a84856431
6 changed files with 19 additions and 7 deletions

View File

@ -14557,6 +14557,10 @@ void Sema::DiscardCleanupsInEvaluationContext() {
}
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);

View File

@ -6543,6 +6543,11 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) {
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

View File

@ -3161,7 +3161,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
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);
}

View File

@ -4429,6 +4429,10 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result,
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;

View File

@ -8055,9 +8055,7 @@ QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword,
}
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;
@ -8142,9 +8140,7 @@ static QualType getDecltypeForExpr(Sema &S, Expr *E) {
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)) {

View File

@ -462,6 +462,9 @@ void foo() {
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;
}
// This used to crash in the constructor of WeakObjectProfileTy when a