diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 3464 |
1 files changed, 2353 insertions, 1111 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 170097c..0d0f2f5 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -12,10 +12,13 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/DelayedDiagnostic.h" #include "clang/Sema/Initialization.h" #include "clang/Sema/Lookup.h" +#include "clang/Sema/ScopeInfo.h" #include "clang/Sema/AnalysisBasedWarnings.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" @@ -38,6 +41,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/SemaFixItUtils.h" #include "clang/Sema/Template.h" +#include "TreeTransform.h" using namespace clang; using namespace sema; @@ -53,6 +57,12 @@ bool Sema::CanUseDecl(NamedDecl *D) { if (FD->isDeleted()) return false; } + + // See if this function is unavailable. + if (D->getAvailability() == AR_Unavailable && + cast<Decl>(CurContext)->getAvailability() != AR_Unavailable) + return false; + return true; } @@ -62,6 +72,13 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S, // See if this declaration is unavailable or deprecated. std::string Message; AvailabilityResult Result = D->getAvailability(&Message); + if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) + if (Result == AR_Available) { + const DeclContext *DC = ECD->getDeclContext(); + if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC)) + Result = TheEnumDecl->getAvailability(&Message); + } + switch (Result) { case AR_Available: case AR_NotYetIntroduced: @@ -91,6 +108,28 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S, return Result; } +/// \brief Emit a note explaining that this function is deleted or unavailable. +void Sema::NoteDeletedFunction(FunctionDecl *Decl) { + CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Decl); + + if (Method && Method->isDeleted() && !Method->isDeletedAsWritten()) { + // If the method was explicitly defaulted, point at that declaration. + if (!Method->isImplicit()) + Diag(Decl->getLocation(), diag::note_implicitly_deleted); + + // Try to diagnose why this special member function was implicitly + // deleted. This might fail, if that reason no longer applies. + CXXSpecialMember CSM = getSpecialMember(Method); + if (CSM != CXXInvalid) + ShouldDeleteSpecialMember(Method, CSM, /*Diagnose=*/true); + + return; + } + + Diag(Decl->getLocation(), diag::note_unavailable_here) + << 1 << Decl->isDeleted(); +} + /// \brief Determine whether the use of this declaration is valid, and /// emit any corresponding diagnostics. /// @@ -105,7 +144,7 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S, /// bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass) { - if (getLangOptions().CPlusPlus && isa<FunctionDecl>(D)) { + if (getLangOpts().CPlusPlus && isa<FunctionDecl>(D)) { // If there were any diagnostics suppressed by template argument deduction, // emit them now. llvm::DenseMap<Decl *, SmallVector<PartialDiagnosticAt, 1> >::iterator @@ -134,26 +173,15 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { if (FD->isDeleted()) { Diag(Loc, diag::err_deleted_function_use); - Diag(D->getLocation(), diag::note_unavailable_here) << 1 << true; + NoteDeletedFunction(FD); return true; } } - AvailabilityResult Result = - DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass); + DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass); // Warn if this is used but marked unused. if (D->hasAttr<UnusedAttr>()) Diag(Loc, diag::warn_used_but_marked_unused) << D->getDeclName(); - // For available enumerator, it will become unavailable/deprecated - // if its enum declaration is as such. - if (Result == AR_Available) - if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) { - const DeclContext *DC = ECD->getDeclContext(); - if (const EnumDecl *TheEnumDecl = dyn_cast<EnumDecl>(DC)) - DiagnoseAvailabilityOfDecl(*this, - const_cast< EnumDecl *>(TheEnumDecl), - Loc, UnknownObjCClass); - } return false; } @@ -243,17 +271,7 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, Expr *sentinelExpr = args[numArgs - numArgsAfterSentinel - 1]; if (!sentinelExpr) return; if (sentinelExpr->isValueDependent()) return; - - // nullptr_t is always treated as null. - if (sentinelExpr->getType()->isNullPtrType()) return; - - if (sentinelExpr->getType()->isAnyPointerType() && - sentinelExpr->IgnoreParenCasts()->isNullPointerConstant(Context, - Expr::NPC_ValueDependentIsNull)) - return; - - // Unfortunately, __null has type 'int'. - if (isa<GNUNullExpr>(sentinelExpr)) return; + if (Context.isSentinelNullExpr(sentinelExpr)) return; // Pick a reasonable string to insert. Optimistically use 'nil' or // 'NULL' if those are actually defined in the context. Only use @@ -314,7 +332,7 @@ ExprResult Sema::DefaultFunctionArrayConversion(Expr *E) { // An lvalue or rvalue of type "array of N T" or "array of unknown bound of // T" can be converted to an rvalue of type "pointer to T". // - if (getLangOptions().C99 || getLangOptions().CPlusPlus || E->isLValue()) + if (getLangOpts().C99 || getLangOpts().CPlusPlus || E->isLValue()) E = ImpCastExprToType(E, Context.getArrayDecayedType(Ty), CK_ArrayToPointerDecay).take(); } @@ -356,23 +374,9 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { QualType T = E->getType(); assert(!T.isNull() && "r-value conversion on typeless expression?"); - // We can't do lvalue-to-rvalue on atomics yet. - if (T->getAs<AtomicType>()) - return Owned(E); - - // Create a load out of an ObjCProperty l-value, if necessary. - if (E->getObjectKind() == OK_ObjCProperty) { - ExprResult Res = ConvertPropertyForRValue(E); - if (Res.isInvalid()) - return Owned(E); - E = Res.take(); - if (!E->isGLValue()) - return Owned(E); - } - // We don't want to throw lvalue-to-rvalue casts on top of // expressions of certain types in C++. - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && (E->getType() == Context.OverloadTy || T->isDependentType() || T->isRecordType())) @@ -400,9 +404,20 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) { if (T.hasQualifiers()) T = T.getUnqualifiedType(); + UpdateMarkingForLValueToRValue(E); + ExprResult Res = Owned(ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E, 0, VK_RValue)); + // C11 6.3.2.1p2: + // ... if the lvalue has atomic type, the value has the non-atomic version + // of the type of the lvalue ... + if (const AtomicType *Atomic = T->getAs<AtomicType>()) { + T = Atomic->getValueType().getUnqualifiedType(); + Res = Owned(ImplicitCastExpr::Create(Context, T, CK_AtomicToNonAtomic, + Res.get(), 0, VK_RValue)); + } + return Res; } @@ -495,7 +510,7 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { // is a prvalue for the temporary. // FIXME: add some way to gate this entire thing for correctness in // potentially potentially evaluated contexts. - if (getLangOptions().CPlusPlus && E->isGLValue() && + if (getLangOpts().CPlusPlus && E->isGLValue() && ExprEvalContexts.back().Context != Unevaluated) { ExprResult Temp = PerformCopyInitialization( InitializedEntity::InitializeTemporary(E->getType()), @@ -514,11 +529,23 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { /// interfaces passed by value. ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl) { - ExprResult ExprRes = CheckPlaceholderExpr(E); - if (ExprRes.isInvalid()) - return ExprError(); + if (const BuiltinType *PlaceholderTy = E->getType()->getAsPlaceholderType()) { + // Strip the unbridged-cast placeholder expression off, if applicable. + if (PlaceholderTy->getKind() == BuiltinType::ARCUnbridgedCast && + (CT == VariadicMethod || + (FDecl && FDecl->hasAttr<CFAuditedTransferAttr>()))) { + E = stripARCUnbridgedCast(E); + + // Otherwise, do normal placeholder checking. + } else { + ExprResult ExprRes = CheckPlaceholderExpr(E); + if (ExprRes.isInvalid()) + return ExprError(); + E = ExprRes.take(); + } + } - ExprRes = DefaultArgumentPromotion(E); + ExprResult ExprRes = DefaultArgumentPromotion(E); if (ExprRes.isInvalid()) return ExprError(); E = ExprRes.take(); @@ -540,17 +567,21 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, // or a non-trivial destructor, with no corresponding parameter, // is conditionally-supported with implementation-defined semantics. bool TrivialEnough = false; - if (getLangOptions().CPlusPlus0x && !E->getType()->isDependentType()) { + if (getLangOpts().CPlusPlus0x && !E->getType()->isDependentType()) { if (CXXRecordDecl *Record = E->getType()->getAsCXXRecordDecl()) { if (Record->hasTrivialCopyConstructor() && Record->hasTrivialMoveConstructor() && - Record->hasTrivialDestructor()) + Record->hasTrivialDestructor()) { + DiagRuntimeBehavior(E->getLocStart(), 0, + PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) + << E->getType() << CT); TrivialEnough = true; + } } } if (!TrivialEnough && - getLangOptions().ObjCAutoRefCount && + getLangOpts().ObjCAutoRefCount && E->getType()->isObjCLifetimeType()) TrivialEnough = true; @@ -558,14 +589,16 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, // Nothing to diagnose. This is okay. } else if (DiagRuntimeBehavior(E->getLocStart(), 0, PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) - << getLangOptions().CPlusPlus0x << E->getType() + << getLangOpts().CPlusPlus0x << E->getType() << CT)) { // Turn this into a trap. CXXScopeSpec SS; + SourceLocation TemplateKWLoc; UnqualifiedId Name; Name.setIdentifier(PP.getIdentifierInfo("__builtin_trap"), E->getLocStart()); - ExprResult TrapFn = ActOnIdExpression(TUScope, SS, Name, true, false); + ExprResult TrapFn = ActOnIdExpression(TUScope, SS, TemplateKWLoc, Name, + true, false); if (TrapFn.isInvalid()) return ExprError(); @@ -581,6 +614,11 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, E = Comma.get(); } } + // c++ rules are enforced elsewhere. + if (!getLangOpts().CPlusPlus && + RequireCompleteType(E->getExprLoc(), E->getType(), + diag::err_call_incomplete_argument)) + return ExprError(); return Owned(E); } @@ -811,14 +849,21 @@ static QualType handleComplexIntConversion(Sema &S, ExprResult &LHS, if (LHSComplexInt) { // int -> _Complex int + // FIXME: This needs to take integer ranks into account + RHS = S.ImpCastExprToType(RHS.take(), LHSComplexInt->getElementType(), + CK_IntegralCast); RHS = S.ImpCastExprToType(RHS.take(), LHSType, CK_IntegralRealToComplex); return LHSType; } assert(RHSComplexInt); // int -> _Complex int - if (!IsCompAssign) + // FIXME: This needs to take integer ranks into account + if (!IsCompAssign) { + LHS = S.ImpCastExprToType(LHS.take(), RHSComplexInt->getElementType(), + CK_IntegralCast); LHS = S.ImpCastExprToType(LHS.take(), RHSType, CK_IntegralRealToComplex); + } return RHSType; } @@ -999,7 +1044,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, if (Types[i]->getType()->isDependentType()) { IsResultDependent = true; } else { - // C1X 6.5.1.1p2 "The type name in a generic association shall specify a + // C11 6.5.1.1p2 "The type name in a generic association shall specify a // complete object type other than a variably modified type." unsigned D = 0; if (Types[i]->getType()->isIncompleteType()) @@ -1016,7 +1061,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, TypeErrorFound = true; } - // C1X 6.5.1.1p2 "No two generic associations in the same generic + // C11 6.5.1.1p2 "No two generic associations in the same generic // selection shall specify compatible types." for (unsigned j = i+1; j < NumAssocs; ++j) if (Types[j] && !Types[j]->getType()->isDependentType() && @@ -1057,7 +1102,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, CompatIndices.push_back(i); } - // C1X 6.5.1.1p2 "The controlling expression of a generic selection shall have + // C11 6.5.1.1p2 "The controlling expression of a generic selection shall have // type compatible with at most one of the types named in its generic // association list." if (CompatIndices.size() > 1) { @@ -1077,7 +1122,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, return ExprError(); } - // C1X 6.5.1.1p2 "If a generic selection has no default generic association, + // C11 6.5.1.1p2 "If a generic selection has no default generic association, // its controlling expression shall have type compatible with exactly one of // the types named in its generic association list." if (DefaultIndex == -1U && CompatIndices.size() == 0) { @@ -1089,7 +1134,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, return ExprError(); } - // C1X 6.5.1.1p3 "If a generic selection has a generic association with a + // C11 6.5.1.1p3 "If a generic selection has a generic association with a // type name that is compatible with the type of the controlling expression, // then the result expression of the generic selection is the expression // in that generic association. Otherwise, the result expression of the @@ -1104,6 +1149,43 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, ResultIndex)); } +/// getUDSuffixLoc - Create a SourceLocation for a ud-suffix, given the +/// location of the token and the offset of the ud-suffix within it. +static SourceLocation getUDSuffixLoc(Sema &S, SourceLocation TokLoc, + unsigned Offset) { + return Lexer::AdvanceToTokenCharacter(TokLoc, Offset, S.getSourceManager(), + S.getLangOpts()); +} + +/// BuildCookedLiteralOperatorCall - A user-defined literal was found. Look up +/// the corresponding cooked (non-raw) literal operator, and build a call to it. +static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope, + IdentifierInfo *UDSuffix, + SourceLocation UDSuffixLoc, + ArrayRef<Expr*> Args, + SourceLocation LitEndLoc) { + assert(Args.size() <= 2 && "too many arguments for literal operator"); + + QualType ArgTy[2]; + for (unsigned ArgIdx = 0; ArgIdx != Args.size(); ++ArgIdx) { + ArgTy[ArgIdx] = Args[ArgIdx]->getType(); + if (ArgTy[ArgIdx]->isArrayType()) + ArgTy[ArgIdx] = S.Context.getArrayDecayedType(ArgTy[ArgIdx]); + } + + DeclarationName OpName = + S.Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix); + DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc); + OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc); + + LookupResult R(S, OpName, UDSuffixLoc, Sema::LookupOrdinaryName); + if (S.LookupLiteralOperator(Scope, R, llvm::makeArrayRef(ArgTy, Args.size()), + /*AllowRawAndTemplate*/false) == Sema::LOLR_Error) + return ExprError(); + + return S.BuildLiteralOperatorCall(R, OpNameInfo, Args, LitEndLoc); +} + /// ActOnStringLiteral - The specified tokens were lexed as pasted string /// fragments (e.g. "foo" "bar" L"baz"). The result string has to handle string /// concatenation ([C99 5.1.1.2, translation phase #6]), so it may come from @@ -1111,7 +1193,8 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, /// string. /// ExprResult -Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { +Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks, + Scope *UDLScope) { assert(NumStringToks && "Must have at least one string!"); StringLiteralParser Literal(StringToks, NumStringToks, PP); @@ -1129,7 +1212,7 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { StrTy = Context.Char16Ty; else if (Literal.isUTF32()) StrTy = Context.Char32Ty; - else if (Literal.Pascal) + else if (Literal.isPascal()) StrTy = Context.UnsignedCharTy; StringLiteral::StringKind Kind = StringLiteral::Ascii; @@ -1143,7 +1226,7 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { Kind = StringLiteral::UTF32; // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). - if (getLangOptions().CPlusPlus || getLangOptions().ConstStrings) + if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) StrTy.addConst(); // Get an array type for the string, according to C99 6.4.5. This includes @@ -1154,243 +1237,32 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) { ArrayType::Normal, 0); // Pass &StringTokLocs[0], StringTokLocs.size() to factory! - return Owned(StringLiteral::Create(Context, Literal.GetString(), - Kind, Literal.Pascal, StrTy, - &StringTokLocs[0], - StringTokLocs.size())); -} - -enum CaptureResult { - /// No capture is required. - CR_NoCapture, - - /// A capture is required. - CR_Capture, - - /// A by-ref capture is required. - CR_CaptureByRef, - - /// An error occurred when trying to capture the given variable. - CR_Error -}; - -/// Diagnose an uncapturable value reference. -/// -/// \param var - the variable referenced -/// \param DC - the context which we couldn't capture through -static CaptureResult -diagnoseUncapturableValueReference(Sema &S, SourceLocation loc, - VarDecl *var, DeclContext *DC) { - switch (S.ExprEvalContexts.back().Context) { - case Sema::Unevaluated: - // The argument will never be evaluated, so don't complain. - return CR_NoCapture; - - case Sema::PotentiallyEvaluated: - case Sema::PotentiallyEvaluatedIfUsed: - break; - - case Sema::PotentiallyPotentiallyEvaluated: - // FIXME: delay these! - break; - } - - // Don't diagnose about capture if we're not actually in code right - // now; in general, there are more appropriate places that will - // diagnose this. - if (!S.CurContext->isFunctionOrMethod()) return CR_NoCapture; - - // Certain madnesses can happen with parameter declarations, which - // we want to ignore. - if (isa<ParmVarDecl>(var)) { - // - If the parameter still belongs to the translation unit, then - // we're actually just using one parameter in the declaration of - // the next. This is useful in e.g. VLAs. - if (isa<TranslationUnitDecl>(var->getDeclContext())) - return CR_NoCapture; - - // - This particular madness can happen in ill-formed default - // arguments; claim it's okay and let downstream code handle it. - if (S.CurContext == var->getDeclContext()->getParent()) - return CR_NoCapture; - } - - DeclarationName functionName; - if (FunctionDecl *fn = dyn_cast<FunctionDecl>(var->getDeclContext())) - functionName = fn->getDeclName(); - // FIXME: variable from enclosing block that we couldn't capture from! - - S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_function) - << var->getIdentifier() << functionName; - S.Diag(var->getLocation(), diag::note_local_variable_declared_here) - << var->getIdentifier(); - - return CR_Error; -} - -/// There is a well-formed capture at a particular scope level; -/// propagate it through all the nested blocks. -static CaptureResult propagateCapture(Sema &S, unsigned ValidScopeIndex, - const BlockDecl::Capture &Capture) { - VarDecl *var = Capture.getVariable(); - - // Update all the inner blocks with the capture information. - for (unsigned i = ValidScopeIndex + 1, e = S.FunctionScopes.size(); - i != e; ++i) { - BlockScopeInfo *innerBlock = cast<BlockScopeInfo>(S.FunctionScopes[i]); - innerBlock->Captures.push_back( - BlockDecl::Capture(Capture.getVariable(), Capture.isByRef(), - /*nested*/ true, Capture.getCopyExpr())); - innerBlock->CaptureMap[var] = innerBlock->Captures.size(); // +1 - } - - return Capture.isByRef() ? CR_CaptureByRef : CR_Capture; -} - -/// shouldCaptureValueReference - Determine if a reference to the -/// given value in the current context requires a variable capture. -/// -/// This also keeps the captures set in the BlockScopeInfo records -/// up-to-date. -static CaptureResult shouldCaptureValueReference(Sema &S, SourceLocation loc, - ValueDecl *Value) { - // Only variables ever require capture. - VarDecl *var = dyn_cast<VarDecl>(Value); - if (!var) return CR_NoCapture; - - // Fast path: variables from the current context never require capture. - DeclContext *DC = S.CurContext; - if (var->getDeclContext() == DC) return CR_NoCapture; - - // Only variables with local storage require capture. - // FIXME: What about 'const' variables in C++? - if (!var->hasLocalStorage()) return CR_NoCapture; - - // Otherwise, we need to capture. - - unsigned functionScopesIndex = S.FunctionScopes.size() - 1; - do { - // Only blocks (and eventually C++0x closures) can capture; other - // scopes don't work. - if (!isa<BlockDecl>(DC)) - return diagnoseUncapturableValueReference(S, loc, var, DC); - - BlockScopeInfo *blockScope = - cast<BlockScopeInfo>(S.FunctionScopes[functionScopesIndex]); - assert(blockScope->TheDecl == static_cast<BlockDecl*>(DC)); - - // Check whether we've already captured it in this block. If so, - // we're done. - if (unsigned indexPlus1 = blockScope->CaptureMap[var]) - return propagateCapture(S, functionScopesIndex, - blockScope->Captures[indexPlus1 - 1]); - - functionScopesIndex--; - DC = cast<BlockDecl>(DC)->getDeclContext(); - } while (var->getDeclContext() != DC); - - // Okay, we descended all the way to the block that defines the variable. - // Actually try to capture it. - QualType type = var->getType(); - - // Prohibit variably-modified types. - if (type->isVariablyModifiedType()) { - S.Diag(loc, diag::err_ref_vm_type); - S.Diag(var->getLocation(), diag::note_declared_at); - return CR_Error; - } - - // Prohibit arrays, even in __block variables, but not references to - // them. - if (type->isArrayType()) { - S.Diag(loc, diag::err_ref_array_type); - S.Diag(var->getLocation(), diag::note_declared_at); - return CR_Error; - } - - S.MarkDeclarationReferenced(loc, var); - - // The BlocksAttr indicates the variable is bound by-reference. - bool byRef = var->hasAttr<BlocksAttr>(); - - // Build a copy expression. - Expr *copyExpr = 0; - const RecordType *rtype; - if (!byRef && S.getLangOptions().CPlusPlus && !type->isDependentType() && - (rtype = type->getAs<RecordType>())) { - - // The capture logic needs the destructor, so make sure we mark it. - // Usually this is unnecessary because most local variables have - // their destructors marked at declaration time, but parameters are - // an exception because it's technically only the call site that - // actually requires the destructor. - if (isa<ParmVarDecl>(var)) - S.FinalizeVarWithDestructor(var, rtype); - - // According to the blocks spec, the capture of a variable from - // the stack requires a const copy constructor. This is not true - // of the copy/move done to move a __block variable to the heap. - type.addConst(); - - Expr *declRef = new (S.Context) DeclRefExpr(var, type, VK_LValue, loc); - ExprResult result = - S.PerformCopyInitialization( - InitializedEntity::InitializeBlock(var->getLocation(), - type, false), - loc, S.Owned(declRef)); - - // Build a full-expression copy expression if initialization - // succeeded and used a non-trivial constructor. Recover from - // errors by pretending that the copy isn't necessary. - if (!result.isInvalid() && - !cast<CXXConstructExpr>(result.get())->getConstructor()->isTrivial()) { - result = S.MaybeCreateExprWithCleanups(result); - copyExpr = result.take(); - } - } - - // We're currently at the declarer; go back to the closure. - functionScopesIndex++; - BlockScopeInfo *blockScope = - cast<BlockScopeInfo>(S.FunctionScopes[functionScopesIndex]); - - // Build a valid capture in this scope. - blockScope->Captures.push_back( - BlockDecl::Capture(var, byRef, /*nested*/ false, copyExpr)); - blockScope->CaptureMap[var] = blockScope->Captures.size(); // +1 - - // Propagate that to inner captures if necessary. - return propagateCapture(S, functionScopesIndex, - blockScope->Captures.back()); -} - -static ExprResult BuildBlockDeclRefExpr(Sema &S, ValueDecl *VD, - const DeclarationNameInfo &NameInfo, - bool ByRef) { - assert(isa<VarDecl>(VD) && "capturing non-variable"); - - VarDecl *var = cast<VarDecl>(VD); - assert(var->hasLocalStorage() && "capturing non-local"); - assert(ByRef == var->hasAttr<BlocksAttr>() && "byref set wrong"); - - QualType exprType = var->getType().getNonReferenceType(); - - BlockDeclRefExpr *BDRE; - if (!ByRef) { - // The variable will be bound by copy; make it const within the - // closure, but record that this was done in the expression. - bool constAdded = !exprType.isConstQualified(); - exprType.addConst(); - - BDRE = new (S.Context) BlockDeclRefExpr(var, exprType, VK_LValue, - NameInfo.getLoc(), false, - constAdded); - } else { - BDRE = new (S.Context) BlockDeclRefExpr(var, exprType, VK_LValue, - NameInfo.getLoc(), true); - } - - return S.Owned(BDRE); + StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), + Kind, Literal.Pascal, StrTy, + &StringTokLocs[0], + StringTokLocs.size()); + if (Literal.getUDSuffix().empty()) + return Owned(Lit); + + // We're building a user-defined literal. + IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix()); + SourceLocation UDSuffixLoc = + getUDSuffixLoc(*this, StringTokLocs[Literal.getUDSuffixToken()], + Literal.getUDSuffixOffset()); + + // Make sure we're allowed user-defined literals here. + if (!UDLScope) + return ExprError(Diag(UDSuffixLoc, diag::err_invalid_string_udl)); + + // C++11 [lex.ext]p5: The literal L is treated as a call of the form + // operator "" X (str, len) + QualType SizeType = Context.getSizeType(); + llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars()); + IntegerLiteral *LenArg = IntegerLiteral::Create(Context, Len, SizeType, + StringTokLocs[0]); + Expr *Args[] = { Lit, LenArg }; + return BuildCookedLiteralOperatorCall(*this, UDLScope, UDSuffix, UDSuffixLoc, + Args, StringTokLocs.back()); } ExprResult @@ -1407,7 +1279,7 @@ ExprResult Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS) { - if (getLangOptions().CUDA) + if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) if (const FunctionDecl *Callee = dyn_cast<FunctionDecl>(D)) { CUDAFunctionTarget CallerTarget = IdentifyCUDATarget(Caller), @@ -1421,12 +1293,18 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, } } - MarkDeclarationReferenced(NameInfo.getLoc(), D); + bool refersToEnclosingScope = + (CurContext != D->getDeclContext() && + D->getDeclContext()->isFunctionOrMethod()); + + DeclRefExpr *E = DeclRefExpr::Create(Context, + SS ? SS->getWithLocInContext(Context) + : NestedNameSpecifierLoc(), + SourceLocation(), + D, refersToEnclosingScope, + NameInfo, Ty, VK); - Expr *E = DeclRefExpr::Create(Context, - SS? SS->getWithLocInContext(Context) - : NestedNameSpecifierLoc(), - D, NameInfo, Ty, VK); + MarkDeclRefReferenced(E); // Just in case we're building an illegal pointer-to-member. FieldDecl *FD = dyn_cast<FieldDecl>(D); @@ -1474,9 +1352,9 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id, /// /// \return false if new lookup candidates were found bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, - CorrectTypoContext CTC, + CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs, - Expr **Args, unsigned NumArgs) { + llvm::ArrayRef<Expr *> Args) { DeclarationName Name = R.getLookupName(); unsigned diagnostic = diag::err_undeclared_var_use; @@ -1492,8 +1370,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // unqualified lookup. This is useful when (for example) the // original lookup would not have found something because it was a // dependent name. - for (DeclContext *DC = SS.isEmpty() ? CurContext : 0; - DC; DC = DC->getParent()) { + DeclContext *DC = SS.isEmpty() ? CurContext : 0; + while (DC) { if (isa<CXXRecordDecl>(DC)) { LookupQualifiedName(R, DC); @@ -1501,10 +1379,17 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // Don't give errors about ambiguities in this lookup. R.suppressDiagnostics(); + // During a default argument instantiation the CurContext points + // to a CXXMethodDecl; but we can't apply a this-> fixit inside a + // function parameter list, hence add an explicit check. + bool isDefaultArgument = !ActiveTemplateInstantiations.empty() && + ActiveTemplateInstantiations.back().Kind == + ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation; CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext); bool isInstance = CurMethod && CurMethod->isInstance() && - DC == CurMethod->getParent(); + DC == CurMethod->getParent() && !isDefaultArgument; + // Give a code modification hint to insert 'this->'. // TODO: fixit for inserting 'Base<T>::' in the other cases. @@ -1515,11 +1400,12 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>( CurMethod->getInstantiatedFromMemberFunction()); if (DepMethod) { - if (getLangOptions().MicrosoftExt) + if (getLangOpts().MicrosoftMode) diagnostic = diag::warn_found_via_dependent_bases_lookup; Diag(R.getNameLoc(), diagnostic) << Name << FixItHint::CreateInsertion(R.getNameLoc(), "this->"); QualType DepThisType = DepMethod->getThisType(Context); + CheckCXXThisCapture(R.getNameLoc()); CXXThisExpr *DepThis = new (Context) CXXThisExpr( R.getNameLoc(), DepThisType, false); TemplateArgumentListInfo TList; @@ -1531,7 +1417,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CXXDependentScopeMemberExpr *DepExpr = CXXDependentScopeMemberExpr::Create( Context, DepThis, DepThisType, true, SourceLocation(), - SS.getWithLocInContext(Context), NULL, + SS.getWithLocInContext(Context), + ULE->getTemplateKeywordLoc(), 0, R.getLookupNameInfo(), ULE->hasExplicitTemplateArgs() ? &TList : 0); CallsUndergoingInstantiation.back()->setCallee(DepExpr); @@ -1541,6 +1428,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, Diag(R.getNameLoc(), diagnostic) << Name; } } else { + if (getLangOpts().MicrosoftMode) + diagnostic = diag::warn_found_via_dependent_bases_lookup; Diag(R.getNameLoc(), diagnostic) << Name; } @@ -1548,20 +1437,40 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) Diag((*I)->getLocation(), diag::note_dependent_var_use); + // Return true if we are inside a default argument instantiation + // and the found name refers to an instance member function, otherwise + // the function calling DiagnoseEmptyLookup will try to create an + // implicit member call and this is wrong for default argument. + if (isDefaultArgument && ((*R.begin())->isCXXInstanceMember())) { + Diag(R.getNameLoc(), diag::err_member_call_without_object); + return true; + } + // Tell the callee to try to recover. return false; } R.clear(); } + + // In Microsoft mode, if we are performing lookup from within a friend + // function definition declared at class scope then we must set + // DC to the lexical parent to be able to search into the parent + // class. + if (getLangOpts().MicrosoftMode && isa<FunctionDecl>(DC) && + cast<FunctionDecl>(DC)->getFriendObjectKind() && + DC->getLexicalParent()->isRecord()) + DC = DC->getLexicalParent(); + else + DC = DC->getParent(); } // We didn't find anything, so try to correct for a typo. TypoCorrection Corrected; if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), - S, &SS, NULL, false, CTC))) { - std::string CorrectedStr(Corrected.getAsString(getLangOptions())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions())); + S, &SS, CCC))) { + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); R.setLookupName(Corrected.getCorrection()); if (NamedDecl *ND = Corrected.getCorrectionDecl()) { @@ -1575,11 +1484,11 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, dyn_cast<FunctionTemplateDecl>(*CD)) AddTemplateOverloadCandidate( FTD, DeclAccessPair::make(FTD, AS_none), ExplicitTemplateArgs, - Args, NumArgs, OCS); + Args, OCS); else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*CD)) if (!ExplicitTemplateArgs || ExplicitTemplateArgs->size() == 0) AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), - Args, NumArgs, OCS); + Args, OCS); } switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) { case OR_Success: @@ -1654,9 +1563,11 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, ExprResult Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, - bool IsAddressOfOperand) { + bool IsAddressOfOperand, + CorrectionCandidateCallback *CCC) { assert(!(IsAddressOfOperand && HasTrailingLParen) && "cannot be direct & operand and have a trailing lparen"); @@ -1699,10 +1610,9 @@ ExprResult Sema::ActOnIdExpression(Scope *S, } if (DependentID) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); - bool IvarLookupFollowUp = false; // Perform the required lookup. LookupResult R(*this, NameInfo, (Id.getKind() == UnqualifiedId::IK_ImplicitSelfParam) @@ -1719,18 +1629,18 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (MemberOfUnknownSpecialization || (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation)) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); } else { - IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl()); + bool IvarLookupFollowUp = II && !SS.isSet() && getCurMethodDecl(); LookupParsedName(R, S, &SS, !IvarLookupFollowUp); // If the result might be in a dependent base class, this is a dependent // id-expression. if (R.getResultKind() == LookupResult::NotFoundInCurrentInstantiation) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); - + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); + // If this reference is in an Objective-C method, then we need to do // some special Objective-C lookup, too. if (IvarLookupFollowUp) { @@ -1740,9 +1650,6 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (Expr *Ex = E.takeAs<Expr>()) return Owned(Ex); - - // for further use, this must be set to false if in class method. - IvarLookupFollowUp = getCurMethodDecl()->isInstanceMethod(); } } @@ -1756,7 +1663,7 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (R.empty() && !ADL) { // Otherwise, this could be an implicitly declared function reference (legal // in C90, extension in C99, forbidden in C++). - if (HasTrailingLParen && II && !getLangOptions().CPlusPlus) { + if (HasTrailingLParen && II && !getLangOpts().CPlusPlus) { NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *II, S); if (D) R.addDecl(D); } @@ -1769,12 +1676,13 @@ ExprResult Sema::ActOnIdExpression(Scope *S, // and we can't resolve an identifier then assume the identifier is type // dependent. The goal is to postpone name lookup to instantiation time // to be able to search into type dependent base classes. - if (getLangOptions().MicrosoftMode && CurContext->isDependentContext() && + if (getLangOpts().MicrosoftMode && CurContext->isDependentContext() && isa<CXXMethodDecl>(CurContext)) - return ActOnDependentIdExpression(SS, NameInfo, IsAddressOfOperand, - TemplateArgs); + return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, + IsAddressOfOperand, TemplateArgs); - if (DiagnoseEmptyLookup(S, SS, R, CTC_Unknown)) + CorrectionCandidateCallback DefaultValidator; + if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator)) return ExprError(); assert(!R.empty() && @@ -1837,11 +1745,12 @@ ExprResult Sema::ActOnIdExpression(Scope *S, isa<IndirectFieldDecl>(R.getFoundDecl()); if (MightBeImplicitMember) - return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs); + return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, + R, TemplateArgs); } - if (TemplateArgs) - return BuildTemplateIdExpr(SS, R, ADL, *TemplateArgs); + if (TemplateArgs || TemplateKWLoc.isValid()) + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, TemplateArgs); return BuildDeclarationNameExpr(SS, R, ADL); } @@ -1855,7 +1764,8 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo) { DeclContext *DC; if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext()) - return BuildDependentDeclRefExpr(SS, NameInfo, 0); + return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(), + NameInfo, /*TemplateArgs=*/0); if (RequireCompleteDeclContext(SS, DC)) return ExprError(); @@ -1912,7 +1822,8 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, if (LookForIvars) { IFace = CurMethod->getClassInterface(); ObjCInterfaceDecl *ClassDeclared; - if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) { + ObjCIvarDecl *IV = 0; + if (IFace && (IV = IFace->lookupInstanceVariable(II, ClassDeclared))) { // Diagnose using an ivar in a class method. if (IsClassMethod) return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method) @@ -1929,7 +1840,8 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, // Diagnose the use of an ivar outside of the declaring class. if (IV->getAccessControl() == ObjCIvarDecl::Private && - ClassDeclared != IFace) + !declaresSameEntity(ClassDeclared, IFace) && + !getLangOpts().DebuggerSupport) Diag(Loc, diag::error_private_ivar_access) << IV->getDeclName(); // FIXME: This should use a new expr for a direct reference, don't @@ -1939,7 +1851,8 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, SelfName.setIdentifier(&II, SourceLocation()); SelfName.setKind(UnqualifiedId::IK_ImplicitSelfParam); CXXScopeSpec SelfScopeSpec; - ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, + SourceLocation TemplateKWLoc; + ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec, TemplateKWLoc, SelfName, false, false); if (SelfExpr.isInvalid()) return ExprError(); @@ -1948,26 +1861,33 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, if (SelfExpr.isInvalid()) return ExprError(); - MarkDeclarationReferenced(Loc, IV); + MarkAnyDeclReferenced(Loc, IV); return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(), Loc, SelfExpr.take(), true, true)); } } else if (CurMethod->isInstanceMethod()) { // We should warn if a local variable hides an ivar. - ObjCInterfaceDecl *IFace = CurMethod->getClassInterface(); - ObjCInterfaceDecl *ClassDeclared; - if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) { - if (IV->getAccessControl() != ObjCIvarDecl::Private || - IFace == ClassDeclared) - Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName(); + if (ObjCInterfaceDecl *IFace = CurMethod->getClassInterface()) { + ObjCInterfaceDecl *ClassDeclared; + if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) { + if (IV->getAccessControl() != ObjCIvarDecl::Private || + declaresSameEntity(IFace, ClassDeclared)) + Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName(); + } } + } else if (Lookup.isSingleResult() && + Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod()) { + // If accessing a stand-alone ivar in a class method, this is an error. + if (const ObjCIvarDecl *IV = dyn_cast<ObjCIvarDecl>(Lookup.getFoundDecl())) + return ExprError(Diag(Loc, diag::error_ivar_use_in_class_method) + << IV->getDeclName()); } if (Lookup.empty() && II && AllowBuiltinCreation) { // FIXME. Consolidate this with similar code in LookupName. if (unsigned BuiltinID = II->getBuiltinID()) { - if (!(getLangOptions().CPlusPlus && + if (!(getLangOpts().CPlusPlus && Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))) { NamedDecl *D = LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID, S, Lookup.isForRedeclaration(), @@ -2159,7 +2079,7 @@ bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, return false; // Only in C++ or ObjC++. - if (!getLangOptions().CPlusPlus) + if (!getLangOpts().CPlusPlus) return false; // Turn off ADL when we find certain kinds of declarations during @@ -2308,30 +2228,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, return BuildAnonymousStructUnionMemberReference(SS, NameInfo.getLoc(), indirectField); - // If the identifier reference is inside a block, and it refers to a value - // that is outside the block, create a BlockDeclRefExpr instead of a - // DeclRefExpr. This ensures the value is treated as a copy-in snapshot when - // the block is formed. - // - // We do not do this for things like enum constants, global variables, etc, - // as they do not get snapshotted. - // - switch (shouldCaptureValueReference(*this, NameInfo.getLoc(), VD)) { - case CR_Error: - return ExprError(); - - case CR_Capture: - assert(!SS.isSet() && "referenced local variable with scope specifier?"); - return BuildBlockDeclRefExpr(*this, VD, NameInfo, /*byref*/ false); - - case CR_CaptureByRef: - assert(!SS.isSet() && "referenced local variable with scope specifier?"); - return BuildBlockDeclRefExpr(*this, VD, NameInfo, /*byref*/ true); - - case CR_NoCapture: { - // If this reference is not in a block or if the referenced - // variable is within the block, create a normal DeclRefExpr. - + { QualType type = VD->getType(); ExprValueKind valueKind = VK_RValue; @@ -2343,13 +2240,11 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, case Decl::type: #include "clang/AST/DeclNodes.inc" llvm_unreachable("invalid value decl kind"); - return ExprError(); // These shouldn't make it here. case Decl::ObjCAtDefsField: case Decl::ObjCIvar: llvm_unreachable("forming non-member reference to ivar?"); - return ExprError(); // Enum constants are always r-values and never references. // Unresolved using declarations are dependent. @@ -2364,7 +2259,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // exist in the high-level semantics. case Decl::Field: case Decl::IndirectField: - assert(getLangOptions().CPlusPlus && + assert(getLangOpts().CPlusPlus && "building reference to field in C?"); // These can't have reference type in well-formed programs, but @@ -2391,7 +2286,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, case Decl::Var: // In C, "extern void blah;" is valid and is an r-value. - if (!getLangOptions().CPlusPlus && + if (!getLangOpts().CPlusPlus && !type.hasQualifiers() && type->isVoidType()) { valueKind = VK_RValue; @@ -2400,12 +2295,23 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // fallthrough case Decl::ImplicitParam: - case Decl::ParmVar: + case Decl::ParmVar: { // These are always l-values. valueKind = VK_LValue; type = type.getNonReferenceType(); - break; + // FIXME: Does the addition of const really only apply in + // potentially-evaluated contexts? Since the variable isn't actually + // captured in an unevaluated context, it seems that the answer is no. + if (ExprEvalContexts.back().Context != Sema::Unevaluated) { + QualType CapturedType = getCapturedDeclRefType(cast<VarDecl>(VD), Loc); + if (!CapturedType.isNull()) + type = CapturedType; + } + + break; + } + case Decl::Function: { const FunctionType *fty = type->castAs<FunctionType>(); @@ -2418,7 +2324,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, } // Functions are l-values in C++. - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { valueKind = VK_LValue; break; } @@ -2466,11 +2372,6 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS); } - - } - - llvm_unreachable("unknown capture result"); - return ExprError(); } ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { @@ -2507,8 +2408,8 @@ ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT)); } -ExprResult Sema::ActOnCharacterConstant(const Token &Tok) { - llvm::SmallString<16> CharBuffer; +ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) { + SmallString<16> CharBuffer; bool Invalid = false; StringRef ThisTok = PP.getSpelling(Tok, CharBuffer, &Invalid); if (Invalid) @@ -2520,16 +2421,14 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok) { return ExprError(); QualType Ty; - if (!getLangOptions().CPlusPlus) - Ty = Context.IntTy; // 'x' and L'x' -> int in C. - else if (Literal.isWide()) - Ty = Context.WCharTy; // L'x' -> wchar_t in C++. + if (Literal.isWide()) + Ty = Context.WCharTy; // L'x' -> wchar_t in C and C++. else if (Literal.isUTF16()) - Ty = Context.Char16Ty; // u'x' -> char16_t in C++0x. + Ty = Context.Char16Ty; // u'x' -> char16_t in C11 and C++11. else if (Literal.isUTF32()) - Ty = Context.Char32Ty; // U'x' -> char32_t in C++0x. - else if (Literal.isMultiChar()) - Ty = Context.IntTy; // 'wxyz' -> int in C++. + Ty = Context.Char32Ty; // U'x' -> char32_t in C11 and C++11. + else if (!getLangOpts().CPlusPlus || Literal.isMultiChar()) + Ty = Context.IntTy; // 'x' -> int in C, 'wxyz' -> int in C++. else Ty = Context.CharTy; // 'x' -> char in C++ @@ -2541,21 +2440,75 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok) { else if (Literal.isUTF32()) Kind = CharacterLiteral::UTF32; - return Owned(new (Context) CharacterLiteral(Literal.getValue(), Kind, Ty, - Tok.getLocation())); + Expr *Lit = new (Context) CharacterLiteral(Literal.getValue(), Kind, Ty, + Tok.getLocation()); + + if (Literal.getUDSuffix().empty()) + return Owned(Lit); + + // We're building a user-defined literal. + IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix()); + SourceLocation UDSuffixLoc = + getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset()); + + // Make sure we're allowed user-defined literals here. + if (!UDLScope) + return ExprError(Diag(UDSuffixLoc, diag::err_invalid_character_udl)); + + // C++11 [lex.ext]p6: The literal L is treated as a call of the form + // operator "" X (ch) + return BuildCookedLiteralOperatorCall(*this, UDLScope, UDSuffix, UDSuffixLoc, + llvm::makeArrayRef(&Lit, 1), + Tok.getLocation()); } -ExprResult Sema::ActOnNumericConstant(const Token &Tok) { +ExprResult Sema::ActOnIntegerConstant(SourceLocation Loc, uint64_t Val) { + unsigned IntSize = Context.getTargetInfo().getIntWidth(); + return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val), + Context.IntTy, Loc)); +} + +static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal, + QualType Ty, SourceLocation Loc) { + const llvm::fltSemantics &Format = S.Context.getFloatTypeSemantics(Ty); + + using llvm::APFloat; + APFloat Val(Format); + + APFloat::opStatus result = Literal.GetFloatValue(Val); + + // Overflow is always an error, but underflow is only an error if + // we underflowed to zero (APFloat reports denormals as underflow). + if ((result & APFloat::opOverflow) || + ((result & APFloat::opUnderflow) && Val.isZero())) { + unsigned diagnostic; + SmallString<20> buffer; + if (result & APFloat::opOverflow) { + diagnostic = diag::warn_float_overflow; + APFloat::getLargest(Format).toString(buffer); + } else { + diagnostic = diag::warn_float_underflow; + APFloat::getSmallest(Format).toString(buffer); + } + + S.Diag(Loc, diagnostic) + << Ty + << StringRef(buffer.data(), buffer.size()); + } + + bool isExact = (result == APFloat::opOK); + return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc); +} + +ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // Fast path for a single digit (which is quite common). A single digit - // cannot have a trigraph, escaped newline, radix prefix, or type suffix. + // cannot have a trigraph, escaped newline, radix prefix, or suffix. if (Tok.getLength() == 1) { const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok); - unsigned IntSize = Context.getTargetInfo().getIntWidth(); - return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'), - Context.IntTy, Tok.getLocation())); + return ActOnIntegerConstant(Tok.getLocation(), Val-'0'); } - llvm::SmallString<512> IntegerBuffer; + SmallString<512> IntegerBuffer; // Add padding so that NumericLiteralParser can overread by one character. IntegerBuffer.resize(Tok.getLength()+1); const char *ThisTokBegin = &IntegerBuffer[0]; @@ -2571,6 +2524,96 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) { if (Literal.hadError) return ExprError(); + if (Literal.hasUDSuffix()) { + // We're building a user-defined literal. + IdentifierInfo *UDSuffix = &Context.Idents.get(Literal.getUDSuffix()); + SourceLocation UDSuffixLoc = + getUDSuffixLoc(*this, Tok.getLocation(), Literal.getUDSuffixOffset()); + + // Make sure we're allowed user-defined literals here. + if (!UDLScope) + return ExprError(Diag(UDSuffixLoc, diag::err_invalid_numeric_udl)); + + QualType CookedTy; + if (Literal.isFloatingLiteral()) { + // C++11 [lex.ext]p4: If S contains a literal operator with parameter type + // long double, the literal is treated as a call of the form + // operator "" X (f L) + CookedTy = Context.LongDoubleTy; + } else { + // C++11 [lex.ext]p3: If S contains a literal operator with parameter type + // unsigned long long, the literal is treated as a call of the form + // operator "" X (n ULL) + CookedTy = Context.UnsignedLongLongTy; + } + + DeclarationName OpName = + Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix); + DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc); + OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc); + + // Perform literal operator lookup to determine if we're building a raw + // literal or a cooked one. + LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName); + switch (LookupLiteralOperator(UDLScope, R, llvm::makeArrayRef(&CookedTy, 1), + /*AllowRawAndTemplate*/true)) { + case LOLR_Error: + return ExprError(); + + case LOLR_Cooked: { + Expr *Lit; + if (Literal.isFloatingLiteral()) { + Lit = BuildFloatingLiteral(*this, Literal, CookedTy, Tok.getLocation()); + } else { + llvm::APInt ResultVal(Context.getTargetInfo().getLongLongWidth(), 0); + if (Literal.GetIntegerValue(ResultVal)) + Diag(Tok.getLocation(), diag::warn_integer_too_large); + Lit = IntegerLiteral::Create(Context, ResultVal, CookedTy, + Tok.getLocation()); + } + return BuildLiteralOperatorCall(R, OpNameInfo, + llvm::makeArrayRef(&Lit, 1), + Tok.getLocation()); + } + + case LOLR_Raw: { + // C++11 [lit.ext]p3, p4: If S contains a raw literal operator, the + // literal is treated as a call of the form + // operator "" X ("n") + SourceLocation TokLoc = Tok.getLocation(); + unsigned Length = Literal.getUDSuffixOffset(); + QualType StrTy = Context.getConstantArrayType( + Context.CharTy, llvm::APInt(32, Length + 1), + ArrayType::Normal, 0); + Expr *Lit = StringLiteral::Create( + Context, StringRef(ThisTokBegin, Length), StringLiteral::Ascii, + /*Pascal*/false, StrTy, &TokLoc, 1); + return BuildLiteralOperatorCall(R, OpNameInfo, + llvm::makeArrayRef(&Lit, 1), TokLoc); + } + + case LOLR_Template: + // C++11 [lit.ext]p3, p4: Otherwise (S contains a literal operator + // template), L is treated as a call fo the form + // operator "" X <'c1', 'c2', ... 'ck'>() + // where n is the source character sequence c1 c2 ... ck. + TemplateArgumentListInfo ExplicitArgs; + unsigned CharBits = Context.getIntWidth(Context.CharTy); + bool CharIsUnsigned = Context.CharTy->isUnsignedIntegerType(); + llvm::APSInt Value(CharBits, CharIsUnsigned); + for (unsigned I = 0, N = Literal.getUDSuffixOffset(); I != N; ++I) { + Value = ThisTokBegin[I]; + TemplateArgument Arg(Value, Context.CharTy); + TemplateArgumentLocInfo ArgInfo; + ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo)); + } + return BuildLiteralOperatorCall(R, OpNameInfo, ArrayRef<Expr*>(), + Tok.getLocation(), &ExplicitArgs); + } + + llvm_unreachable("unexpected literal operator lookup result"); + } + Expr *Res; if (Literal.isFloatingLiteral()) { @@ -2582,39 +2625,12 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) { else Ty = Context.LongDoubleTy; - const llvm::fltSemantics &Format = Context.getFloatTypeSemantics(Ty); - - using llvm::APFloat; - APFloat Val(Format); - - APFloat::opStatus result = Literal.GetFloatValue(Val); - - // Overflow is always an error, but underflow is only an error if - // we underflowed to zero (APFloat reports denormals as underflow). - if ((result & APFloat::opOverflow) || - ((result & APFloat::opUnderflow) && Val.isZero())) { - unsigned diagnostic; - llvm::SmallString<20> buffer; - if (result & APFloat::opOverflow) { - diagnostic = diag::warn_float_overflow; - APFloat::getLargest(Format).toString(buffer); - } else { - diagnostic = diag::warn_float_underflow; - APFloat::getSmallest(Format).toString(buffer); - } - - Diag(Tok.getLocation(), diagnostic) - << Ty - << StringRef(buffer.data(), buffer.size()); - } - - bool isExact = (result == APFloat::opOK); - Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation()); + Res = BuildFloatingLiteral(*this, Literal, Ty, Tok.getLocation()); if (Ty == Context.DoubleTy) { - if (getLangOptions().SinglePrecisionConstants) { + if (getLangOpts().SinglePrecisionConstants) { Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take(); - } else if (getLangOptions().OpenCL && !getOpenCLOptions().cl_khr_fp64) { + } else if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp64) { Diag(Tok.getLocation(), diag::warn_double_const_requires_fp64); Res = ImpCastExprToType(Res, Context.FloatTy, CK_FloatingCast).take(); } @@ -2625,9 +2641,10 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) { QualType Ty; // long long is a C99 feature. - if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x && - Literal.isLongLong) - Diag(Tok.getLocation(), diag::ext_longlong); + if (!getLangOpts().C99 && Literal.isLongLong) + Diag(Tok.getLocation(), + getLangOpts().CPlusPlus0x ? + diag::warn_cxx98_compat_longlong : diag::ext_longlong); // Get the value in the widest-possible width. llvm::APInt ResultVal(Context.getTargetInfo().getIntMaxTWidth(), 0); @@ -2688,7 +2705,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok) { // To be compatible with MSVC, hex integer literals ending with the // LL or i64 suffix are always signed in Microsoft mode. if (!Literal.isUnsigned && (ResultVal[LongLongSize-1] == 0 || - (getLangOptions().MicrosoftExt && Literal.isLongLong))) + (getLangOpts().MicrosoftExt && Literal.isLongLong))) Ty = Context.LongLongTy; else if (AllowUnsigned) Ty = Context.UnsignedLongLongTy; @@ -2971,6 +2988,12 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, if (isInvalid) return ExprError(); + if (ExprKind == UETT_SizeOf && E->getType()->isVariableArrayType()) { + PE = TranformToPotentiallyEvaluated(E); + if (PE.isInvalid()) return ExprError(); + E = PE.take(); + } + // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. return Owned(new (Context) UnaryExprOrTypeTraitExpr( ExprKind, E, Context.getSizeType(), OpLoc, @@ -3044,6 +3067,11 @@ Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc, case tok::minusminus: Opc = UO_PostDec; break; } + // Since this might is a postfix expression, get rid of ParenListExprs. + ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Input); + if (Result.isInvalid()) return ExprError(); + Input = Result.take(); + return BuildUnaryOp(S, OpLoc, Opc, Input); } @@ -3057,7 +3085,7 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, Expr *LHSExp = Base, *RHSExp = Idx; - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) { return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, Context.DependentTy, @@ -3065,11 +3093,12 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, RLoc)); } - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && (LHSExp->getType()->isRecordType() || LHSExp->getType()->isEnumeralType() || RHSExp->getType()->isRecordType() || - RHSExp->getType()->isEnumeralType())) { + RHSExp->getType()->isEnumeralType()) && + !LHSExp->getType()->isObjCObjectPointerType()) { return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx); } @@ -3113,17 +3142,20 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, BaseExpr = LHSExp; IndexExpr = RHSExp; ResultType = PTy->getPointeeType(); + } else if (const ObjCObjectPointerType *PTy = + LHSTy->getAs<ObjCObjectPointerType>()) { + BaseExpr = LHSExp; + IndexExpr = RHSExp; + Result = BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, 0, 0); + if (!Result.isInvalid()) + return Owned(Result.take()); + ResultType = PTy->getPointeeType(); } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) { // Handle the uncommon case of "123[Ptr]". BaseExpr = RHSExp; IndexExpr = LHSExp; ResultType = PTy->getPointeeType(); } else if (const ObjCObjectPointerType *PTy = - LHSTy->getAs<ObjCObjectPointerType>()) { - BaseExpr = LHSExp; - IndexExpr = RHSExp; - ResultType = PTy->getPointeeType(); - } else if (const ObjCObjectPointerType *PTy = RHSTy->getAs<ObjCObjectPointerType>()) { // Handle the uncommon case of "123[Ptr]". BaseExpr = RHSExp; @@ -3188,7 +3220,7 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, return ExprError(); } - if (ResultType->isVoidType() && !getLangOptions().CPlusPlus) { + if (ResultType->isVoidType() && !getLangOpts().CPlusPlus) { // GNU extension: subscripting on pointer to void Diag(LLoc, diag::ext_gnu_subscript_void_type) << BaseExpr->getSourceRange(); @@ -3247,6 +3279,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, // the semantic constraints are checked, at the point where the // default argument expression appears. ContextRAII SavedContext(*this, FD); + LocalInstantiationScope Local(*this); Result = SubstExpr(UninstExpr, ArgList); } if (Result.isInvalid()) @@ -3257,7 +3290,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, = InitializedEntity::InitializeParameter(Context, Param); InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(), - /*FIXME:EqualLoc*/UninstExpr->getSourceRange().getBegin()); + /*FIXME:EqualLoc*/UninstExpr->getLocStart()); Expr *ResultE = Result.takeAs<Expr>(); InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1); @@ -3276,18 +3309,25 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, // be properly destroyed. // FIXME: We should really be rebuilding the default argument with new // bound temporaries; see the comment in PR5810. - for (unsigned i = 0, e = Param->getNumDefaultArgTemporaries(); i != e; ++i) { - CXXTemporary *Temporary = Param->getDefaultArgTemporary(i); - MarkDeclarationReferenced(Param->getDefaultArg()->getLocStart(), - const_cast<CXXDestructorDecl*>(Temporary->getDestructor())); - ExprTemporaries.push_back(Temporary); + // We don't need to do that with block decls, though, because + // blocks in default argument expression can never capture anything. + if (isa<ExprWithCleanups>(Param->getInit())) { + // Set the "needs cleanups" bit regardless of whether there are + // any explicit objects. ExprNeedsCleanups = true; + + // Append all the objects to the cleanup list. Right now, this + // should always be a no-op, because blocks in default argument + // expressions should never be able to capture anything. + assert(!cast<ExprWithCleanups>(Param->getInit())->getNumObjects() && + "default argument expression has capturing blocks?"); } // We already type-checked the argument, so we know it works. // Just mark all of the declarations in this potentially-evaluated expression // as being "referenced". - MarkDeclarationsReferencedInExpr(Param->getDefaultArg()); + MarkDeclarationsReferencedInExpr(Param->getDefaultArg(), + /*SkipLocalVariables=*/true); return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param)); } @@ -3371,7 +3411,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, CallType = VariadicBlock; // Block else if (isa<MemberExpr>(Fn)) CallType = VariadicMethod; - Invalid = GatherArgumentsForCall(Call->getSourceRange().getBegin(), FDecl, + Invalid = GatherArgumentsForCall(Call->getLocStart(), FDecl, Proto, 0, Args, NumArgs, AllArgs, CallType); if (Invalid) return true; @@ -3388,7 +3428,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, unsigned FirstProtoArg, Expr **Args, unsigned NumArgs, SmallVector<Expr *, 8> &AllArgs, - VariadicCallType CallType) { + VariadicCallType CallType, + bool AllowExplicit) { unsigned NumArgsInProto = Proto->getNumArgs(); unsigned NumArgsToCheck = NumArgs; bool Invalid = false; @@ -3401,33 +3442,42 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, QualType ProtoArgType = Proto->getArgType(i); Expr *Arg; + ParmVarDecl *Param; if (ArgIx < NumArgs) { Arg = Args[ArgIx++]; - if (RequireCompleteType(Arg->getSourceRange().getBegin(), + if (RequireCompleteType(Arg->getLocStart(), ProtoArgType, PDiag(diag::err_call_incomplete_argument) << Arg->getSourceRange())) return true; // Pass the argument - ParmVarDecl *Param = 0; + Param = 0; if (FDecl && i < FDecl->getNumParams()) Param = FDecl->getParamDecl(i); + // Strip the unbridged-cast placeholder expression off, if applicable. + if (Arg->getType() == Context.ARCUnbridgedCastTy && + FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() && + (!Param || !Param->hasAttr<CFConsumedAttr>())) + Arg = stripARCUnbridgedCast(Arg); + InitializedEntity Entity = Param? InitializedEntity::InitializeParameter(Context, Param) : InitializedEntity::InitializeParameter(Context, ProtoArgType, Proto->isArgConsumed(i)); ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), - Owned(Arg)); + Owned(Arg), + /*TopLevelOfInitList=*/false, + AllowExplicit); if (ArgE.isInvalid()) return true; Arg = ArgE.takeAs<Expr>(); } else { - ParmVarDecl *Param = FDecl->getParamDecl(i); + Param = FDecl->getParamDecl(i); ExprResult ArgExpr = BuildCXXDefaultArgExpr(CallLoc, FDecl, Param); @@ -3442,6 +3492,9 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, // with its own checking, such as a BinaryOperator. CheckArrayAccess(Arg); + // Check for violations of C99 static array rules (C99 6.7.5.3p7). + CheckStaticArrayArgument(CallLoc, Param, Arg); + AllArgs.push_back(Arg); } @@ -3479,6 +3532,60 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, return Invalid; } +static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) { + TypeLoc TL = PVD->getTypeSourceInfo()->getTypeLoc(); + if (ArrayTypeLoc *ATL = dyn_cast<ArrayTypeLoc>(&TL)) + S.Diag(PVD->getLocation(), diag::note_callee_static_array) + << ATL->getLocalSourceRange(); +} + +/// CheckStaticArrayArgument - If the given argument corresponds to a static +/// array parameter, check that it is non-null, and that if it is formed by +/// array-to-pointer decay, the underlying array is sufficiently large. +/// +/// C99 6.7.5.3p7: If the keyword static also appears within the [ and ] of the +/// array type derivation, then for each call to the function, the value of the +/// corresponding actual argument shall provide access to the first element of +/// an array with at least as many elements as specified by the size expression. +void +Sema::CheckStaticArrayArgument(SourceLocation CallLoc, + ParmVarDecl *Param, + const Expr *ArgExpr) { + // Static array parameters are not supported in C++. + if (!Param || getLangOpts().CPlusPlus) + return; + + QualType OrigTy = Param->getOriginalType(); + + const ArrayType *AT = Context.getAsArrayType(OrigTy); + if (!AT || AT->getSizeModifier() != ArrayType::Static) + return; + + if (ArgExpr->isNullPointerConstant(Context, + Expr::NPC_NeverValueDependent)) { + Diag(CallLoc, diag::warn_null_arg) << ArgExpr->getSourceRange(); + DiagnoseCalleeStaticArrayParam(*this, Param); + return; + } + + const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT); + if (!CAT) + return; + + const ConstantArrayType *ArgCAT = + Context.getAsConstantArrayType(ArgExpr->IgnoreParenImpCasts()->getType()); + if (!ArgCAT) + return; + + if (ArgCAT->getSize().ult(CAT->getSize())) { + Diag(CallLoc, diag::warn_static_array_too_small) + << ArgExpr->getSourceRange() + << (unsigned) ArgCAT->getSize().getZExtValue() + << (unsigned) CAT->getSize().getZExtValue(); + DiagnoseCalleeStaticArrayParam(*this, Param); + } +} + /// Given a function expression of unknown-any type, try to rebuild it /// to have a function type. static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn); @@ -3499,7 +3606,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, Expr **Args = ArgExprs.release(); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // If this is a pseudo-destructor expression, build the call immediately. if (isa<CXXPseudoDestructorExpr>(Fn)) { if (NumArgs > 0) { @@ -3508,8 +3615,6 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, << FixItHint::CreateRemoval( SourceRange(Args[0]->getLocStart(), Args[NumArgs-1]->getLocEnd())); - - NumArgs = 0; } return Owned(new (Context) CallExpr(Context, Fn, 0, 0, Context.VoidTy, @@ -3523,7 +3628,8 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, bool Dependent = false; if (Fn->isTypeDependent()) Dependent = true; - else if (Expr::hasAnyTypeDependentArguments(Args, NumArgs)) + else if (Expr::hasAnyTypeDependentArguments( + llvm::makeArrayRef(Args, NumArgs))) Dependent = true; if (Dependent) { @@ -3574,6 +3680,11 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, } // If we're directly calling a function, get the appropriate declaration. + if (Fn->getType() == Context.UnknownAnyTy) { + ExprResult result = rebuildUnknownAnyFunction(*this, Fn); + if (result.isInvalid()) return ExprError(); + Fn = result.take(); + } Expr *NakedFn = Fn->IgnoreParens(); @@ -3601,7 +3712,8 @@ Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc, QualType ConfigQTy = ConfigDecl->getType(); DeclRefExpr *ConfigDR = new (Context) DeclRefExpr( - ConfigDecl, ConfigQTy, VK_LValue, LLLLoc); + ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc); + MarkFunctionReferenced(LLLLoc, ConfigDecl); return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, 0, /*IsExecConfig=*/true); @@ -3698,7 +3810,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, << Fn->getType() << Fn->getSourceRange()); } - if (getLangOptions().CUDA) { + if (getLangOpts().CUDA) { if (Config) { // CUDA: Kernel calls must be to global functions if (FDecl && !FDecl->hasAttr<CUDAGlobalAttr>()) @@ -3719,7 +3831,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // Check for a valid return type if (CheckCallReturnType(FuncT->getResultType(), - Fn->getSourceRange().getBegin(), TheCall, + Fn->getLocStart(), TheCall, FDecl)) return ExprError(); @@ -3778,7 +3890,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, Arg = ArgE.takeAs<Expr>(); } - if (RequireCompleteType(Arg->getSourceRange().getBegin(), + if (RequireCompleteType(Arg->getLocStart(), Arg->getType(), PDiag(diag::err_call_incomplete_argument) << Arg->getSourceRange())) @@ -3852,7 +3964,8 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, = InitializedEntity::InitializeTemporary(literalType); InitializationKind Kind = InitializationKind::CreateCStyleCast(LParenLoc, - SourceRange(LParenLoc, RParenLoc)); + SourceRange(LParenLoc, RParenLoc), + /*InitList=*/true); InitializationSequence InitSeq(*this, Entity, Kind, &LiteralExpr, 1); ExprResult Result = InitSeq.Perform(*this, Entity, Kind, MultiExprArg(*this, &LiteralExpr, 1), @@ -3868,7 +3981,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, } // In C, compound literals are l-values for some reason. - ExprValueKind VK = getLangOptions().CPlusPlus ? VK_RValue : VK_LValue; + ExprValueKind VK = getLangOpts().CPlusPlus ? VK_RValue : VK_LValue; return MaybeBindToTemporary( new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, @@ -3881,6 +3994,20 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, unsigned NumInit = InitArgList.size(); Expr **InitList = InitArgList.release(); + // Immediately handle non-overload placeholders. Overloads can be + // resolved contextually, but everything else here can't. + for (unsigned I = 0; I != NumInit; ++I) { + if (InitList[I]->getType()->isNonOverloadPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(InitList[I]); + + // Ignore failures; dropping the entire initializer list because + // of one failure would be terrible for indexing/etc. + if (result.isInvalid()) continue; + + InitList[I] = result.take(); + } + } + // Semantic analysis for initializers is done by ActOnDeclarator() and // CheckInitializer() - it requires knowledge of the object being intialized. @@ -3896,7 +4023,7 @@ static void maybeExtendBlockObject(Sema &S, ExprResult &E) { assert(E.get()->isRValue()); // Only do this in an r-value context. - if (!S.getLangOptions().ObjCAutoRefCount) return; + if (!S.getLangOpts().ObjCAutoRefCount) return; E = ImplicitCastExpr::Create(S.Context, E.get()->getType(), CK_ARCExtendBlockObject, E.get(), @@ -3927,6 +4054,11 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { // pointers. Everything else should be possible. QualType SrcTy = Src.get()->getType(); + if (const AtomicType *SrcAtomicTy = SrcTy->getAs<AtomicType>()) + SrcTy = SrcAtomicTy->getValueType(); + if (const AtomicType *DestAtomicTy = DestTy->getAs<AtomicType>()) + DestTy = DestAtomicTy->getValueType(); + if (Context.hasSameUnqualifiedType(SrcTy, DestTy)) return CK_NoOp; @@ -3946,12 +4078,10 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_ObjCObjectPointer: if (SrcKind == Type::STK_ObjCObjectPointer) return CK_BitCast; - else if (SrcKind == Type::STK_CPointer) + if (SrcKind == Type::STK_CPointer) return CK_CPointerToObjCPointerCast; - else { - maybeExtendBlockObject(*this, Src); - return CK_BlockPointerToObjCPointerCast; - } + maybeExtendBlockObject(*this, Src); + return CK_BlockPointerToObjCPointerCast; case Type::STK_Bool: return CK_PointerToBoolean; case Type::STK_Integral: @@ -3962,7 +4092,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_MemberPointer: llvm_unreachable("illegal cast from pointer"); } - break; + llvm_unreachable("Should have returned before this"); case Type::STK_Bool: // casting from bool is like casting from an integer case Type::STK_Integral: @@ -3993,7 +4123,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); } - break; + llvm_unreachable("Should have returned before this"); case Type::STK_Floating: switch (DestTy->getScalarTypeKind()) { @@ -4020,7 +4150,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); } - break; + llvm_unreachable("Should have returned before this"); case Type::STK_FloatingComplex: switch (DestTy->getScalarTypeKind()) { @@ -4049,7 +4179,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); } - break; + llvm_unreachable("Should have returned before this"); case Type::STK_IntegralComplex: switch (DestTy->getScalarTypeKind()) { @@ -4078,7 +4208,7 @@ CastKind Sema::PrepareScalarCast(ExprResult &Src, QualType DestTy) { case Type::STK_MemberPointer: llvm_unreachable("member pointer type in C"); } - break; + llvm_unreachable("Should have returned before this"); } llvm_unreachable("Unhandled scalar cast"); @@ -4116,7 +4246,7 @@ ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, // (See OpenCL 6.2). if (SrcTy->isVectorType()) { if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy) - || (getLangOptions().OpenCL && + || (getLangOpts().OpenCL && (DestTy.getCanonicalType() != SrcTy.getCanonicalType()))) { Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) << DestTy << SrcTy << R; @@ -4156,7 +4286,7 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, if (D.isInvalidType()) return ExprError(); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // Check that there are no default arguments (C++ only). CheckExtraCXXDefaultArguments(D); } @@ -4172,7 +4302,7 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, // i.e. all the elements are integer constants. ParenExpr *PE = dyn_cast<ParenExpr>(CastExpr); ParenListExpr *PLE = dyn_cast<ParenListExpr>(CastExpr); - if ((getLangOptions().AltiVec || getLangOptions().OpenCL) + if ((getLangOpts().AltiVec || getLangOpts().OpenCL) && castType->isVectorType() && (PE || PLE)) { if (PLE && PLE->getNumExprs() == 0) { Diag(PLE->getExprLoc(), diag::err_altivec_empty_initializer); @@ -4239,7 +4369,9 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, // be replicated to all the components of the vector if (numExprs == 1) { QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); - ExprResult Literal = Owned(exprs[0]); + ExprResult Literal = DefaultLvalueConversion(exprs[0]); + if (Literal.isInvalid()) + return ExprError(); Literal = ImpCastExprToType(Literal.take(), ElemTy, PrepareScalarCast(Literal, ElemTy)); return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take()); @@ -4250,24 +4382,24 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, return ExprError(); } else - for (unsigned i = 0, e = numExprs; i != e; ++i) - initExprs.push_back(exprs[i]); + initExprs.append(exprs, exprs + numExprs); } else { // For OpenCL, when the number of initializers is a single value, // it will be replicated to all components of the vector. - if (getLangOptions().OpenCL && + if (getLangOpts().OpenCL && VTy->getVectorKind() == VectorType::GenericVector && numExprs == 1) { QualType ElemTy = Ty->getAs<VectorType>()->getElementType(); - ExprResult Literal = Owned(exprs[0]); + ExprResult Literal = DefaultLvalueConversion(exprs[0]); + if (Literal.isInvalid()) + return ExprError(); Literal = ImpCastExprToType(Literal.take(), ElemTy, PrepareScalarCast(Literal, ElemTy)); return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Literal.take()); } - for (unsigned i = 0, e = numExprs; i != e; ++i) - initExprs.push_back(exprs[i]); + initExprs.append(exprs, exprs + numExprs); } // FIXME: This means that pretty-printing the final AST will produce curly // braces instead of the original commas. @@ -4278,8 +4410,8 @@ ExprResult Sema::BuildVectorLiteral(SourceLocation LParenLoc, return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, initE); } -/// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence -/// of comma binary operators. +/// This is not an AltiVec-style cast or or C++ direct-initialization, so turn +/// the ParenListExpr into a sequence of comma binary operators. ExprResult Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) { ParenListExpr *E = dyn_cast<ParenListExpr>(OrigExpr); @@ -4297,18 +4429,13 @@ Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *OrigExpr) { return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get()); } -ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L, - SourceLocation R, - MultiExprArg Val) { +ExprResult Sema::ActOnParenListExpr(SourceLocation L, + SourceLocation R, + MultiExprArg Val) { unsigned nexprs = Val.size(); Expr **exprs = reinterpret_cast<Expr**>(Val.release()); assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list"); - Expr *expr; - if (nexprs == 1) - expr = new (Context) ParenExpr(L, R, exprs[0]); - else - expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R, - exprs[nexprs-1]->getType()); + Expr *expr = new (Context) ParenListExpr(Context, L, exprs, nexprs, R); return Owned(expr); } @@ -4358,11 +4485,11 @@ static bool checkCondition(Sema &S, Expr *Cond) { if (CondTy->isScalarType()) return false; // OpenCL: Sec 6.3.i says the condition is allowed to be a vector or scalar. - if (S.getLangOptions().OpenCL && CondTy->isVectorType()) + if (S.getLangOpts().OpenCL && CondTy->isVectorType()) return false; // Emit the proper error message. - S.Diag(Cond->getLocStart(), S.getLangOptions().OpenCL ? + S.Diag(Cond->getLocStart(), S.getLangOpts().OpenCL ? diag::err_typecheck_cond_expect_scalar : diag::err_typecheck_cond_expect_scalar_or_vector) << CondTy; @@ -4446,8 +4573,28 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, rhptee = RHSTy->castAs<PointerType>()->getPointeeType(); } - if (!S.Context.typesAreCompatible(lhptee.getUnqualifiedType(), - rhptee.getUnqualifiedType())) { + // C99 6.5.15p6: If both operands are pointers to compatible types or to + // differently qualified versions of compatible types, the result type is + // a pointer to an appropriately qualified version of the composite + // type. + + // Only CVR-qualifiers exist in the standard, and the differently-qualified + // clause doesn't make sense for our extensions. E.g. address space 2 should + // be incompatible with address space 3: they may live on different devices or + // anything. + Qualifiers lhQual = lhptee.getQualifiers(); + Qualifiers rhQual = rhptee.getQualifiers(); + + unsigned MergedCVRQual = lhQual.getCVRQualifiers() | rhQual.getCVRQualifiers(); + lhQual.removeCVRQualifiers(); + rhQual.removeCVRQualifiers(); + + lhptee = S.Context.getQualifiedType(lhptee.getUnqualifiedType(), lhQual); + rhptee = S.Context.getQualifiedType(rhptee.getUnqualifiedType(), rhQual); + + QualType CompositeTy = S.Context.mergeTypes(lhptee, rhptee); + + if (CompositeTy.isNull()) { S.Diag(Loc, diag::warn_typecheck_cond_incompatible_pointers) << LHSTy << RHSTy << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); @@ -4461,16 +4608,12 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, } // The pointer types are compatible. - // C99 6.5.15p6: If both operands are pointers to compatible types *or* to - // differently qualified versions of compatible types, the result type is - // a pointer to an appropriately qualified version of the *composite* - // type. - // FIXME: Need to calculate the composite type. - // FIXME: Need to add qualifiers + QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual); + ResultTy = S.Context.getPointerType(ResultTy); - LHS = S.ImpCastExprToType(LHS.take(), LHSTy, CK_BitCast); - RHS = S.ImpCastExprToType(RHS.take(), LHSTy, CK_BitCast); - return LHSTy; + LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast); + RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast); + return ResultTy; } /// \brief Return the resulting type when the operands are both block pointers. @@ -4574,7 +4717,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, RHS = move(RHSResult); // C++ is sufficiently different to merit its own checker. - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) return CXXCheckConditionalOperands(Cond, LHS, RHS, VK, OK, QuestionLoc); VK = VK_RValue; @@ -4605,7 +4748,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // OpenCL: If the condition is a vector, and both operands are scalar, // attempt to implicity convert them to the vector type to act like the // built in select. - if (getLangOptions().OpenCL && CondTy->isVectorType()) + if (getLangOpts().OpenCL && CondTy->isVectorType()) if (checkConditionalConvertScalarsToVectors(*this, LHS, RHS, CondTy)) return QualType(); @@ -4780,6 +4923,14 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, } // Check Objective-C object pointer types and 'void *' if (LHSTy->isVoidPointerType() && RHSTy->isObjCObjectPointerType()) { + if (getLangOpts().ObjCAutoRefCount) { + // ARC forbids the implicit conversion of object pointers to 'void *', + // so these types are not compatible. + Diag(QuestionLoc, diag::err_cond_voidptr_arc) << LHSTy << RHSTy + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + LHS = RHS = true; + return QualType(); + } QualType lhptee = LHSTy->getAs<PointerType>()->getPointeeType(); QualType rhptee = RHSTy->getAs<ObjCObjectPointerType>()->getPointeeType(); QualType destPointee @@ -4792,6 +4943,14 @@ QualType Sema::FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, return destType; } if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) { + if (getLangOpts().ObjCAutoRefCount) { + // ARC forbids the implicit conversion of object pointers to 'void *', + // so these types are not compatible. + Diag(QuestionLoc, diag::err_cond_voidptr_arc) << LHSTy << RHSTy + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + LHS = RHS = true; + return QualType(); + } QualType lhptee = LHSTy->getAs<ObjCObjectPointerType>()->getPointeeType(); QualType rhptee = RHSTy->getAs<PointerType>()->getPointeeType(); QualType destPointee @@ -4938,7 +5097,7 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, // We usually want to apply unary conversions *before* saving, except // in the special case of a C++ l-value conditional. - if (!(getLangOptions().CPlusPlus + if (!(getLangOpts().CPlusPlus && !commonExpr->isTypeDependent() && commonExpr->getValueKind() == RHSExpr->getValueKind() && commonExpr->isGLValue() @@ -4954,7 +5113,8 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, opaqueValue = new (Context) OpaqueValueExpr(commonExpr->getExprLoc(), commonExpr->getType(), commonExpr->getValueKind(), - commonExpr->getObjectKind()); + commonExpr->getObjectKind(), + commonExpr); LHSExpr = CondExpr = opaqueValue; } @@ -5019,9 +5179,9 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { // It's okay to add or remove GC or lifetime qualifiers when converting to // and from void*. - else if (lhq.withoutObjCGCAttr().withoutObjCGLifetime() + else if (lhq.withoutObjCGCAttr().withoutObjCLifetime() .compatiblyIncludes( - rhq.withoutObjCGCAttr().withoutObjCGLifetime()) + rhq.withoutObjCGCAttr().withoutObjCLifetime()) && (lhptee->isVoidType() || rhptee->isVoidType())) ; // keep old @@ -5099,7 +5259,7 @@ checkPointerTypesForAssignment(Sema &S, QualType LHSType, QualType RHSType) { // General pointer incompatibility takes priority over qualifiers. return Sema::IncompatiblePointer; } - if (!S.getLangOptions().CPlusPlus && + if (!S.getLangOpts().CPlusPlus && S.IsNoReturnConversion(ltrans, rtrans, ltrans)) return Sema::IncompatiblePointer; return ConvTy; @@ -5122,7 +5282,7 @@ checkBlockPointerTypesForAssignment(Sema &S, QualType LHSType, rhptee = cast<BlockPointerType>(RHSType)->getPointeeType(); // In C++, the types have to match exactly. - if (S.getLangOptions().CPlusPlus) + if (S.getLangOpts().CPlusPlus) return Sema::IncompatibleBlockPointer; Sema::AssignConvertType ConvTy = Sema::Compatible; @@ -5161,7 +5321,9 @@ checkObjCPointerTypesForAssignment(Sema &S, QualType LHSType, QualType lhptee = LHSType->getAs<ObjCObjectPointerType>()->getPointeeType(); QualType rhptee = RHSType->getAs<ObjCObjectPointerType>()->getPointeeType(); - if (!lhptee.isAtLeastAsQualifiedAs(rhptee)) + if (!lhptee.isAtLeastAsQualifiedAs(rhptee) && + // make an exception for id<P> + !LHSType->isObjCQualifiedIdType()) return Sema::CompatiblePointerDiscardsQualifiers; if (S.Context.typesAreCompatible(LHSType, RHSType)) @@ -5213,9 +5375,6 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, LHSType = Context.getCanonicalType(LHSType).getUnqualifiedType(); RHSType = Context.getCanonicalType(RHSType).getUnqualifiedType(); - // We can't do assignment from/to atomics yet. - if (LHSType->isAtomicType()) - return Incompatible; // Common case: no conversion required. if (LHSType == RHSType) { @@ -5223,6 +5382,21 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, return Compatible; } + if (const AtomicType *AtomicTy = dyn_cast<AtomicType>(LHSType)) { + if (AtomicTy->getValueType() == RHSType) { + Kind = CK_NonAtomicToAtomic; + return Compatible; + } + } + + if (const AtomicType *AtomicTy = dyn_cast<AtomicType>(RHSType)) { + if (AtomicTy->getValueType() == LHSType) { + Kind = CK_AtomicToNonAtomic; + return Compatible; + } + } + + // If the left-hand side is a reference type, then we are in a // (rare!) case where we've allowed the use of references in C, // e.g., as a parameter type in a built-in function. In this case, @@ -5269,7 +5443,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // If we are allowing lax vector conversions, and LHS and RHS are both // vectors, the total size only needs to be the same. This is a bitcast; // no bits are changed but the result type is different. - if (getLangOptions().LaxVectorConversions && + if (getLangOpts().LaxVectorConversions && (Context.getTypeSize(LHSType) == Context.getTypeSize(RHSType))) { Kind = CK_BitCast; return IncompatibleVectors; @@ -5280,7 +5454,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, // Arithmetic conversions. if (LHSType->isArithmeticType() && RHSType->isArithmeticType() && - !(getLangOptions().CPlusPlus && LHSType->isEnumeralType())) { + !(getLangOpts().CPlusPlus && LHSType->isEnumeralType())) { Kind = PrepareScalarCast(RHS, LHSType); return Compatible; } @@ -5346,7 +5520,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, } // id -> T^ - if (getLangOptions().ObjC1 && RHSType->isObjCIdType()) { + if (getLangOpts().ObjC1 && RHSType->isObjCIdType()) { Kind = CK_AnyPointerToBlockPointerCast; return Compatible; } @@ -5368,7 +5542,7 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, Kind = CK_BitCast; Sema::AssignConvertType result = checkObjCPointerTypesForAssignment(*this, LHSType, RHSType); - if (getLangOptions().ObjCAutoRefCount && + if (getLangOpts().ObjCAutoRefCount && result == Compatible && !CheckObjCARCUnavailableWeakConversion(OrigLHSType, RHSType)) result = IncompatibleObjCWeakRef; @@ -5535,18 +5709,32 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Sema::AssignConvertType Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose) { - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { if (!LHSType->isRecordType() && !LHSType->isAtomicType()) { // C++ 5.17p3: If the left operand is not of class type, the // expression is implicitly converted (C++ 4) to the // cv-unqualified type of the left operand. - ExprResult Res = PerformImplicitConversion(RHS.get(), - LHSType.getUnqualifiedType(), - AA_Assigning, Diagnose); + ExprResult Res; + if (Diagnose) { + Res = PerformImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(), + AA_Assigning); + } else { + ImplicitConversionSequence ICS = + TryImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(), + /*SuppressUserConversions=*/false, + /*AllowExplicit=*/false, + /*InOverloadResolution=*/false, + /*CStyle=*/false, + /*AllowObjCWritebackConversion=*/false); + if (ICS.isFailure()) + return Incompatible; + Res = PerformImplicitConversion(RHS.get(), LHSType.getUnqualifiedType(), + ICS, AA_Assigning); + } if (Res.isInvalid()) return Incompatible; Sema::AssignConvertType result = Compatible; - if (getLangOptions().ObjCAutoRefCount && + if (getLangOpts().ObjCAutoRefCount && !CheckObjCARCUnavailableWeakConversion(LHSType, RHS.get()->getType())) result = IncompatibleObjCWeakRef; @@ -5609,6 +5797,15 @@ QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &LHS, QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign) { + if (!IsCompAssign) { + LHS = DefaultFunctionArrayLvalueConversion(LHS.take()); + if (LHS.isInvalid()) + return QualType(); + } + RHS = DefaultFunctionArrayLvalueConversion(RHS.take()); + if (RHS.isInvalid()) + return QualType(); + // For conversion purposes, we ignore any qualifiers. // For example, "const float" and "float" are equivalent. QualType LHSType = @@ -5633,7 +5830,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, return RHSType; } - if (getLangOptions().LaxVectorConversions && + if (getLangOpts().LaxVectorConversions && Context.getTypeSize(LHSType) == Context.getTypeSize(RHSType)) { // If we are allowing lax vector conversions, and LHS and RHS are both // vectors, the total size only needs to be the same. This is a @@ -5738,9 +5935,15 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); + if (!LHS.get()->getType()->isArithmeticType() || - !RHS.get()->getType()->isArithmeticType()) + !RHS.get()->getType()->isArithmeticType()) { + if (IsCompAssign && + LHS.get()->getType()->isAtomicType() && + RHS.get()->getType()->isArithmeticType()) + return compType; return InvalidOperands(Loc, LHS, RHS); + } // Check for division by zero. if (IsDiv && @@ -5784,7 +5987,7 @@ QualType Sema::CheckRemainderOperands( /// \brief Diagnose invalid arithmetic on two void pointers. static void diagnoseArithmeticOnTwoVoidPointers(Sema &S, SourceLocation Loc, Expr *LHSExpr, Expr *RHSExpr) { - S.Diag(Loc, S.getLangOptions().CPlusPlus + S.Diag(Loc, S.getLangOpts().CPlusPlus ? diag::err_typecheck_pointer_arith_void_type : diag::ext_gnu_void_ptr) << 1 /* two pointers */ << LHSExpr->getSourceRange() @@ -5794,7 +5997,7 @@ static void diagnoseArithmeticOnTwoVoidPointers(Sema &S, SourceLocation Loc, /// \brief Diagnose invalid arithmetic on a void pointer. static void diagnoseArithmeticOnVoidPointer(Sema &S, SourceLocation Loc, Expr *Pointer) { - S.Diag(Loc, S.getLangOptions().CPlusPlus + S.Diag(Loc, S.getLangOpts().CPlusPlus ? diag::err_typecheck_pointer_arith_void_type : diag::ext_gnu_void_ptr) << 0 /* one pointer */ << Pointer->getSourceRange(); @@ -5805,7 +6008,7 @@ static void diagnoseArithmeticOnTwoFunctionPointers(Sema &S, SourceLocation Loc, Expr *LHS, Expr *RHS) { assert(LHS->getType()->isAnyPointerType()); assert(RHS->getType()->isAnyPointerType()); - S.Diag(Loc, S.getLangOptions().CPlusPlus + S.Diag(Loc, S.getLangOpts().CPlusPlus ? diag::err_typecheck_pointer_arith_function_type : diag::ext_gnu_ptr_func_arith) << 1 /* two pointers */ << LHS->getType()->getPointeeType() @@ -5820,7 +6023,7 @@ static void diagnoseArithmeticOnTwoFunctionPointers(Sema &S, SourceLocation Loc, static void diagnoseArithmeticOnFunctionPointer(Sema &S, SourceLocation Loc, Expr *Pointer) { assert(Pointer->getType()->isAnyPointerType()); - S.Diag(Loc, S.getLangOptions().CPlusPlus + S.Diag(Loc, S.getLangOpts().CPlusPlus ? diag::err_typecheck_pointer_arith_function_type : diag::ext_gnu_ptr_func_arith) << 0 /* one pointer */ << Pointer->getType()->getPointeeType() @@ -5861,11 +6064,11 @@ static bool checkArithmeticOpPointerOperand(Sema &S, SourceLocation Loc, QualType PointeeTy = Operand->getType()->getPointeeType(); if (PointeeTy->isVoidType()) { diagnoseArithmeticOnVoidPointer(S, Loc, Operand); - return !S.getLangOptions().CPlusPlus; + return !S.getLangOpts().CPlusPlus; } if (PointeeTy->isFunctionType()) { diagnoseArithmeticOnFunctionPointer(S, Loc, Operand); - return !S.getLangOptions().CPlusPlus; + return !S.getLangOpts().CPlusPlus; } if (checkArithmeticIncompletePointerType(S, Loc, Operand)) return false; @@ -5900,7 +6103,7 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc, else if (!isLHSVoidPtr) diagnoseArithmeticOnVoidPointer(S, Loc, RHSExpr); else diagnoseArithmeticOnTwoVoidPointers(S, Loc, LHSExpr, RHSExpr); - return !S.getLangOptions().CPlusPlus; + return !S.getLangOpts().CPlusPlus; } bool isLHSFuncPtr = isLHSPointer && LHSPointeeTy->isFunctionType(); @@ -5911,7 +6114,7 @@ static bool checkArithmeticBinOpPointerOperands(Sema &S, SourceLocation Loc, RHSExpr); else diagnoseArithmeticOnTwoFunctionPointers(S, Loc, LHSExpr, RHSExpr); - return !S.getLangOptions().CPlusPlus; + return !S.getLangOpts().CPlusPlus; } if (checkArithmeticIncompletePointerType(S, Loc, LHSExpr)) return false; @@ -5934,6 +6137,46 @@ static bool checkArithmethicPointerOnNonFragileABI(Sema &S, return false; } +/// diagnoseStringPlusInt - Emit a warning when adding an integer to a string +/// literal. +static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, + Expr *LHSExpr, Expr *RHSExpr) { + StringLiteral* StrExpr = dyn_cast<StringLiteral>(LHSExpr->IgnoreImpCasts()); + Expr* IndexExpr = RHSExpr; + if (!StrExpr) { + StrExpr = dyn_cast<StringLiteral>(RHSExpr->IgnoreImpCasts()); + IndexExpr = LHSExpr; + } + + bool IsStringPlusInt = StrExpr && + IndexExpr->getType()->isIntegralOrUnscopedEnumerationType(); + if (!IsStringPlusInt) + return; + + llvm::APSInt index; + if (IndexExpr->EvaluateAsInt(index, Self.getASTContext())) { + unsigned StrLenWithNull = StrExpr->getLength() + 1; + if (index.isNonNegative() && + index <= llvm::APSInt(llvm::APInt(index.getBitWidth(), StrLenWithNull), + index.isUnsigned())) + return; + } + + SourceRange DiagRange(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); + Self.Diag(OpLoc, diag::warn_string_plus_int) + << DiagRange << IndexExpr->IgnoreImpCasts()->getType(); + + // Only print a fixit for "str" + int, not for int + "str". + if (IndexExpr == RHSExpr) { + SourceLocation EndLoc = Self.PP.getLocForEndOfToken(RHSExpr->getLocEnd()); + Self.Diag(OpLoc, diag::note_string_plus_int_silence) + << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&") + << FixItHint::CreateReplacement(SourceRange(OpLoc), "[") + << FixItHint::CreateInsertion(EndLoc, "]"); + } else + Self.Diag(OpLoc, diag::note_string_plus_int_silence); +} + /// \brief Emit error when two pointers are incompatible. static void diagnosePointerIncompatibility(Sema &S, SourceLocation Loc, Expr *LHSExpr, Expr *RHSExpr) { @@ -5945,7 +6188,8 @@ static void diagnosePointerIncompatibility(Sema &S, SourceLocation Loc, } QualType Sema::CheckAdditionOperands( // C99 6.5.6 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, QualType* CompLHSTy) { + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, + QualType* CompLHSTy) { checkArithmeticNull(*this, LHS, RHS, Loc, /*isCompare=*/false); if (LHS.get()->getType()->isVectorType() || @@ -5959,6 +6203,10 @@ QualType Sema::CheckAdditionOperands( // C99 6.5.6 if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); + // Diagnose "string literal" '+' int. + if (Opc == BO_Add) + diagnoseStringPlusInt(*this, Loc, LHS.get(), RHS.get()); + // handle the common case first (both operands are arithmetic). if (LHS.get()->getType()->isArithmeticType() && RHS.get()->getType()->isArithmeticType()) { @@ -5966,6 +6214,12 @@ QualType Sema::CheckAdditionOperands( // C99 6.5.6 return compType; } + if (LHS.get()->getType()->isAtomicType() && + RHS.get()->getType()->isArithmeticType()) { + *CompLHSTy = LHS.get()->getType(); + return compType; + } + // Put any potential pointer into PExp Expr* PExp = LHS.get(), *IExp = RHS.get(); if (IExp->getType()->isAnyPointerType()) @@ -6026,6 +6280,12 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, return compType; } + if (LHS.get()->getType()->isAtomicType() && + RHS.get()->getType()->isArithmeticType()) { + *CompLHSTy = LHS.get()->getType(); + return compType; + } + // Either ptr - int or ptr - ptr. if (LHS.get()->getType()->isAnyPointerType()) { QualType lpointee = LHS.get()->getType()->getPointeeType(); @@ -6039,11 +6299,9 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, if (!checkArithmeticOpPointerOperand(*this, Loc, LHS.get())) return QualType(); - Expr *IExpr = RHS.get()->IgnoreParenCasts(); - UnaryOperator negRex(IExpr, UO_Minus, IExpr->getType(), VK_RValue, - OK_Ordinary, IExpr->getExprLoc()); // Check array bounds for pointer arithemtic - CheckArrayAccess(LHS.get()->IgnoreParenCasts(), &negRex); + CheckArrayAccess(LHS.get(), RHS.get(), /*ArraySubscriptExpr*/0, + /*AllowOnePastEnd*/true, /*IndexNegated*/true); if (CompLHSTy) *CompLHSTy = LHS.get()->getType(); return LHS.get()->getType(); @@ -6054,7 +6312,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, = RHS.get()->getType()->getAs<PointerType>()) { QualType rpointee = RHSPTy->getPointeeType(); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // Pointee types must be the same: C++ [expr.add] if (!Context.hasSameUnqualifiedType(lpointee, rpointee)) { diagnosePointerIncompatibility(*this, Loc, LHS.get(), RHS.get()); @@ -6131,7 +6389,7 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &LHS, ExprResult &RHS, // Print the bit representation of the signed integer as an unsigned // hexadecimal number. - llvm::SmallString<40> HexResult; + SmallString<40> HexResult; Result.toString(HexResult, 16, /*Signed =*/false, /*Literal =*/true); // If we are only missing a sign bit, this is less likely to result in actual @@ -6459,7 +6717,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, QualType RCanPointeeTy = RHSType->castAs<PointerType>()->getPointeeType().getCanonicalType(); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { if (LCanPointeeTy == RCanPointeeTy) return ResultTy; if (!IsRelational && @@ -6515,7 +6773,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, return ResultTy; } - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // Comparison of nullptr_t with itself. if (LHSType->isNullPtrType() && RHSType->isNullPtrType()) return ResultTy; @@ -6639,11 +6897,11 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, bool isError = false; if ((LHSIsNull && LHSType->isIntegerType()) || (RHSIsNull && RHSType->isIntegerType())) { - if (IsRelational && !getLangOptions().CPlusPlus) + if (IsRelational && !getLangOpts().CPlusPlus) DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_and_zero; - } else if (IsRelational && !getLangOptions().CPlusPlus) + } else if (IsRelational && !getLangOpts().CPlusPlus) DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer; - else if (getLangOptions().CPlusPlus) { + else if (getLangOpts().CPlusPlus) { DiagID = diag::err_typecheck_comparison_of_pointer_integer; isError = true; } else @@ -6681,6 +6939,26 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, return InvalidOperands(Loc, LHS, RHS); } + +// Return a signed type that is of identical size and number of elements. +// For floating point vectors, return an integer type of identical size +// and number of elements. +QualType Sema::GetSignedVectorType(QualType V) { + const VectorType *VTy = V->getAs<VectorType>(); + unsigned TypeSize = Context.getTypeSize(VTy->getElementType()); + if (TypeSize == Context.getTypeSize(Context.CharTy)) + return Context.getExtVectorType(Context.CharTy, VTy->getNumElements()); + else if (TypeSize == Context.getTypeSize(Context.ShortTy)) + return Context.getExtVectorType(Context.ShortTy, VTy->getNumElements()); + else if (TypeSize == Context.getTypeSize(Context.IntTy)) + return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); + else if (TypeSize == Context.getTypeSize(Context.LongTy)) + return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); + assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && + "Unhandled vector element size in vector compare"); + return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); +} + /// CheckVectorCompareOperands - vector comparisons are a clang extension that /// operates on extended vector types. Instead of producing an IntTy result, /// like a scalar comparison, a vector comparison produces a vector of integer @@ -6695,7 +6973,6 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, return vType; QualType LHSType = LHS.get()->getType(); - QualType RHSType = RHS.get()->getType(); // If AltiVec, the comparison results in a numeric type, i.e. // bool for C++, int for C @@ -6706,8 +6983,10 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, // x == x, x != x, x < x, etc. These always evaluate to a constant, and // often indicate logic errors in the program. if (!LHSType->hasFloatingRepresentation()) { - if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LHS.get()->IgnoreParens())) - if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHS.get()->IgnoreParens())) + if (DeclRefExpr* DRL + = dyn_cast<DeclRefExpr>(LHS.get()->IgnoreParenImpCasts())) + if (DeclRefExpr* DRR + = dyn_cast<DeclRefExpr>(RHS.get()->IgnoreParenImpCasts())) if (DRL->getDecl() == DRR->getDecl()) DiagRuntimeBehavior(Loc, 0, PDiag(diag::warn_comparison_always) @@ -6718,26 +6997,23 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, // Check for comparisons of floating point operands using != and ==. if (!IsRelational && LHSType->hasFloatingRepresentation()) { - assert (RHSType->hasFloatingRepresentation()); + assert (RHS.get()->getType()->hasFloatingRepresentation()); CheckFloatComparison(Loc, LHS.get(), RHS.get()); } + + // Return a signed type for the vector. + return GetSignedVectorType(LHSType); +} - // Return the type for the comparison, which is the same as vector type for - // integer vectors, or an integer type of identical size and number of - // elements for floating point vectors. - if (LHSType->hasIntegerRepresentation()) - return LHSType; - - const VectorType *VTy = LHSType->getAs<VectorType>(); - unsigned TypeSize = Context.getTypeSize(VTy->getElementType()); - if (TypeSize == Context.getTypeSize(Context.IntTy)) - return Context.getExtVectorType(Context.IntTy, VTy->getNumElements()); - if (TypeSize == Context.getTypeSize(Context.LongTy)) - return Context.getExtVectorType(Context.LongTy, VTy->getNumElements()); - - assert(TypeSize == Context.getTypeSize(Context.LongLongTy) && - "Unhandled vector element size in vector compare"); - return Context.getExtVectorType(Context.LongLongTy, VTy->getNumElements()); +QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc) { + // Ensure that either both operands are of the same vector type, or + // one operand is of a vector type and the other is of its element type. + QualType vType = CheckVectorOperands(LHS, RHS, Loc, false); + if (vType.isNull() || vType->isFloatingType()) + return InvalidOperands(Loc, LHS, RHS); + + return GetSignedVectorType(LHS.get()->getType()); } inline QualType Sema::CheckBitwiseOperands( @@ -6770,6 +7046,10 @@ inline QualType Sema::CheckBitwiseOperands( inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc) { + // Check vector operands differently. + if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) + return CheckVectorLogicalOperands(LHS, RHS, Loc); + // Diagnose cases where the user write a logical and/or but probably meant a // bitwise one. We do this when the LHS is a non-bool integer and the RHS // is a constant. @@ -6782,10 +7062,10 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] // that isn't 0 or 1 (which indicate a potential logical operation that // happened to fold to true/false) then warn. // Parens on the RHS are ignored. - Expr::EvalResult Result; - if (RHS.get()->Evaluate(Result, Context) && !Result.HasSideEffects) - if ((getLangOptions().Bool && !RHS.get()->getType()->isBooleanType()) || - (Result.Val.getInt() != 0 && Result.Val.getInt() != 1)) { + llvm::APSInt Result; + if (RHS.get()->EvaluateAsInt(Result, Context)) + if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType()) || + (Result != 0 && Result != 1)) { Diag(Loc, diag::warn_logical_instead_of_bitwise) << RHS.get()->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||"); @@ -6794,7 +7074,7 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] << (Opc == BO_LAnd ? "&" : "|") << FixItHint::CreateReplacement(SourceRange( Loc, Lexer::getLocForEndOfToken(Loc, 0, getSourceManager(), - getLangOptions())), + getLangOpts())), Opc == BO_LAnd ? "&" : "|"); if (Opc == BO_LAnd) // Suggest replacing "Foo() && kNonZero" with "Foo()" @@ -6803,12 +7083,12 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] SourceRange( Lexer::getLocForEndOfToken(LHS.get()->getLocEnd(), 0, getSourceManager(), - getLangOptions()), + getLangOpts()), RHS.get()->getLocEnd())); } } - if (!Context.getLangOptions().CPlusPlus) { + if (!Context.getLangOpts().CPlusPlus) { LHS = UsualUnaryConversions(LHS.take()); if (LHS.isInvalid()) return QualType(); @@ -6851,63 +7131,68 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] /// depends on various declarations and thus must be treated specially. /// static bool IsReadonlyProperty(Expr *E, Sema &S) { - if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) { - const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(E); - if (PropExpr->isImplicitProperty()) return false; + const ObjCPropertyRefExpr *PropExpr = dyn_cast<ObjCPropertyRefExpr>(E); + if (!PropExpr) return false; + if (PropExpr->isImplicitProperty()) return false; - ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty(); - QualType BaseType = PropExpr->isSuperReceiver() ? + ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty(); + QualType BaseType = PropExpr->isSuperReceiver() ? PropExpr->getSuperReceiverType() : PropExpr->getBase()->getType(); - if (const ObjCObjectPointerType *OPT = - BaseType->getAsObjCInterfacePointerType()) - if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl()) - if (S.isPropertyReadonly(PDecl, IFace)) - return true; - } - return false; -} - -static bool IsConstProperty(Expr *E, Sema &S) { - if (E->getStmtClass() == Expr::ObjCPropertyRefExprClass) { - const ObjCPropertyRefExpr* PropExpr = cast<ObjCPropertyRefExpr>(E); - if (PropExpr->isImplicitProperty()) return false; - - ObjCPropertyDecl *PDecl = PropExpr->getExplicitProperty(); - QualType T = PDecl->getType(); - if (T->isReferenceType()) - T = T->getAs<ReferenceType>()->getPointeeType(); - CanQualType CT = S.Context.getCanonicalType(T); - return CT.isConstQualified(); - } + if (const ObjCObjectPointerType *OPT = + BaseType->getAsObjCInterfacePointerType()) + if (ObjCInterfaceDecl *IFace = OPT->getInterfaceDecl()) + if (S.isPropertyReadonly(PDecl, IFace)) + return true; return false; } static bool IsReadonlyMessage(Expr *E, Sema &S) { - if (E->getStmtClass() != Expr::MemberExprClass) - return false; - const MemberExpr *ME = cast<MemberExpr>(E); - NamedDecl *Member = ME->getMemberDecl(); - if (isa<FieldDecl>(Member)) { - Expr *Base = ME->getBase()->IgnoreParenImpCasts(); - if (Base->getStmtClass() != Expr::ObjCMessageExprClass) - return false; - return cast<ObjCMessageExpr>(Base)->getMethodDecl() != 0; - } - return false; + const MemberExpr *ME = dyn_cast<MemberExpr>(E); + if (!ME) return false; + if (!isa<FieldDecl>(ME->getMemberDecl())) return false; + ObjCMessageExpr *Base = + dyn_cast<ObjCMessageExpr>(ME->getBase()->IgnoreParenImpCasts()); + if (!Base) return false; + return Base->getMethodDecl() != 0; +} + +/// Is the given expression (which must be 'const') a reference to a +/// variable which was originally non-const, but which has become +/// 'const' due to being captured within a block? +enum NonConstCaptureKind { NCCK_None, NCCK_Block, NCCK_Lambda }; +static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) { + assert(E->isLValue() && E->getType().isConstQualified()); + E = E->IgnoreParens(); + + // Must be a reference to a declaration from an enclosing scope. + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E); + if (!DRE) return NCCK_None; + if (!DRE->refersToEnclosingLocal()) return NCCK_None; + + // The declaration must be a variable which is not declared 'const'. + VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl()); + if (!var) return NCCK_None; + if (var->getType().isConstQualified()) return NCCK_None; + assert(var->hasLocalStorage() && "capture added 'const' to non-local?"); + + // Decide whether the first capture was for a block or a lambda. + DeclContext *DC = S.CurContext; + while (DC->getParent() != var->getDeclContext()) + DC = DC->getParent(); + return (isa<BlockDecl>(DC) ? NCCK_Block : NCCK_Lambda); } /// CheckForModifiableLvalue - Verify that E is a modifiable lvalue. If not, /// emit an error and return true. If so, return false. static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { + assert(!E->hasPlaceholderType(BuiltinType::PseudoObject)); SourceLocation OrigLoc = Loc; Expr::isModifiableLvalueResult IsLV = E->isModifiableLvalue(S.Context, &Loc); if (IsLV == Expr::MLV_Valid && IsReadonlyProperty(E, S)) IsLV = Expr::MLV_ReadonlyProperty; - else if (Expr::MLV_ConstQualified && IsConstProperty(E, S)) - IsLV = Expr::MLV_Valid; else if (IsLV == Expr::MLV_ClassTemporary && IsReadonlyMessage(E, S)) IsLV = Expr::MLV_InvalidMessageExpression; if (IsLV == Expr::MLV_Valid) @@ -6919,9 +7204,19 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { case Expr::MLV_ConstQualified: Diag = diag::err_typecheck_assign_const; + // Use a specialized diagnostic when we're assigning to an object + // from an enclosing function or block. + if (NonConstCaptureKind NCCK = isReferenceToNonConstCapture(S, E)) { + if (NCCK == NCCK_Block) + Diag = diag::err_block_decl_ref_not_modifiable_lvalue; + else + Diag = diag::err_lambda_decl_ref_not_modifiable_lvalue; + break; + } + // In ARC, use some specialized diagnostics for occasions where we // infer 'const'. These are always pseudo-strong variables. - if (S.getLangOptions().ObjCAutoRefCount) { + if (S.getLangOpts().ObjCAutoRefCount) { DeclRefExpr *declRef = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()); if (declRef && isa<VarDecl>(declRef->getDecl())) { VarDecl *var = cast<VarDecl>(declRef->getDecl()); @@ -6935,7 +7230,9 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { // - self ObjCMethodDecl *method = S.getCurMethodDecl(); if (method && var == method->getSelfDecl()) - Diag = diag::err_typecheck_arr_assign_self; + Diag = method->isClassMethod() + ? diag::err_typecheck_arc_assign_self_class_method + : diag::err_typecheck_arc_assign_self; // - fast enumeration variables else @@ -6979,15 +7276,9 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { case Expr::MLV_DuplicateVectorComponents: Diag = diag::err_typecheck_duplicate_vector_components_not_mlvalue; break; - case Expr::MLV_NotBlockQualified: - Diag = diag::err_block_decl_ref_not_modifiable_lvalue; - break; case Expr::MLV_ReadonlyProperty: - Diag = diag::error_readonly_property_assignment; - break; case Expr::MLV_NoSetterProperty: - Diag = diag::error_nosetter_property_assignment; - break; + llvm_unreachable("readonly properties should be processed differently"); case Expr::MLV_InvalidMessageExpression: Diag = diag::error_readonly_message_assignment; break; @@ -7012,6 +7303,8 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, SourceLocation Loc, QualType CompoundType) { + assert(!LHSExpr->hasPlaceholderType(BuiltinType::PseudoObject)); + // Verify that LHS is a modifiable lvalue, and emit error if not. if (CheckForModifiableLvalue(LHSExpr, Loc, *this)) return QualType(); @@ -7022,14 +7315,6 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, AssignConvertType ConvTy; if (CompoundType.isNull()) { QualType LHSTy(LHSType); - // Simple assignment "x = y". - if (LHSExpr->getObjectKind() == OK_ObjCProperty) { - ExprResult LHSResult = Owned(LHSExpr); - ConvertPropertyForLValue(LHSResult, RHS, LHSTy); - if (LHSResult.isInvalid()) - return QualType(); - LHSExpr = LHSResult.take(); - } ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS); if (RHS.isInvalid()) return QualType(); @@ -7042,10 +7327,9 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, ConvTy = Compatible; if (ConvTy == Compatible && - getLangOptions().ObjCNonFragileABI && LHSType->isObjCObjectType()) - Diag(Loc, diag::err_assignment_requires_nonfragile_object) - << LHSType; + Diag(Loc, diag::err_objc_object_assignment) + << LHSType; // If the RHS is a unary plus or minus, check to see if they = and + are // right next to each other. If so, the user may have typo'd "x =+ 4" @@ -7072,7 +7356,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, if (ConvTy == Compatible) { if (LHSType.getObjCLifetime() == Qualifiers::OCL_Strong) checkRetainCycles(LHSExpr, RHS.get()); - else if (getLangOptions().ObjCAutoRefCount) + else if (getLangOpts().ObjCAutoRefCount) checkUnsafeExprAssigns(Loc, LHSExpr, RHS.get()); } } else { @@ -7093,7 +7377,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, // is converted to the type of the assignment expression (above). // C++ 5.17p1: the type of the assignment expression is that of its left // operand. - return (getLangOptions().CPlusPlus + return (getLangOpts().CPlusPlus ? LHSType : LHSType.getUnqualifiedType()); } @@ -7117,7 +7401,7 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS, if (LHS.isInvalid()) return QualType(); - if (!S.getLangOptions().CPlusPlus) { + if (!S.getLangOpts().CPlusPlus) { RHS = S.DefaultFunctionArrayLvalueConversion(RHS.take()); if (RHS.isInvalid()) return QualType(); @@ -7139,9 +7423,15 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, return S.Context.DependentTy; QualType ResType = Op->getType(); + // Atomic types can be used for increment / decrement where the non-atomic + // versions can, so ignore the _Atomic() specifier for the purpose of + // checking. + if (const AtomicType *ResAtomicType = ResType->getAs<AtomicType>()) + ResType = ResAtomicType->getValueType(); + assert(!ResType.isNull() && "no type for increment/decrement expression"); - if (S.getLangOptions().CPlusPlus && ResType->isBooleanType()) { + if (S.getLangOpts().CPlusPlus && ResType->isBooleanType()) { // Decrement of bool is not allowed. if (!IsInc) { S.Diag(OpLoc, diag::err_decrement_bool) << Op->getSourceRange(); @@ -7168,7 +7458,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, if (PR.isInvalid()) return QualType(); return CheckIncrementDecrementOperand(S, PR.take(), VK, OpLoc, IsInc, IsPrefix); - } else if (S.getLangOptions().AltiVec && ResType->isVectorType()) { + } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) { // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 ) } else { S.Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement) @@ -7182,7 +7472,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, // In C++, a prefix increment is the same type as the operand. Otherwise // (in C or with postfix), the increment is the unqualified type of the // operand. - if (IsPrefix && S.getLangOptions().CPlusPlus) { + if (IsPrefix && S.getLangOpts().CPlusPlus) { VK = VK_LValue; return ResType; } else { @@ -7190,102 +7480,6 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, return ResType.getUnqualifiedType(); } } - -ExprResult Sema::ConvertPropertyForRValue(Expr *E) { - assert(E->getValueKind() == VK_LValue && - E->getObjectKind() == OK_ObjCProperty); - const ObjCPropertyRefExpr *PRE = E->getObjCProperty(); - - QualType T = E->getType(); - QualType ReceiverType; - if (PRE->isObjectReceiver()) - ReceiverType = PRE->getBase()->getType(); - else if (PRE->isSuperReceiver()) - ReceiverType = PRE->getSuperReceiverType(); - else - ReceiverType = Context.getObjCInterfaceType(PRE->getClassReceiver()); - - ExprValueKind VK = VK_RValue; - if (PRE->isImplicitProperty()) { - if (ObjCMethodDecl *GetterMethod = - PRE->getImplicitPropertyGetter()) { - T = getMessageSendResultType(ReceiverType, GetterMethod, - PRE->isClassReceiver(), - PRE->isSuperReceiver()); - VK = Expr::getValueKindForType(GetterMethod->getResultType()); - } - else { - Diag(PRE->getLocation(), diag::err_getter_not_found) - << PRE->getBase()->getType(); - } - } - else { - // lvalue-ness of an explicit property is determined by - // getter type. - QualType ResT = PRE->getGetterResultType(); - VK = Expr::getValueKindForType(ResT); - } - - E = ImplicitCastExpr::Create(Context, T, CK_GetObjCProperty, - E, 0, VK); - - ExprResult Result = MaybeBindToTemporary(E); - if (!Result.isInvalid()) - E = Result.take(); - - return Owned(E); -} - -void Sema::ConvertPropertyForLValue(ExprResult &LHS, ExprResult &RHS, - QualType &LHSTy) { - assert(LHS.get()->getValueKind() == VK_LValue && - LHS.get()->getObjectKind() == OK_ObjCProperty); - const ObjCPropertyRefExpr *PropRef = LHS.get()->getObjCProperty(); - - bool Consumed = false; - - if (PropRef->isImplicitProperty()) { - // If using property-dot syntax notation for assignment, and there is a - // setter, RHS expression is being passed to the setter argument. So, - // type conversion (and comparison) is RHS to setter's argument type. - if (const ObjCMethodDecl *SetterMD = PropRef->getImplicitPropertySetter()) { - ObjCMethodDecl::param_const_iterator P = SetterMD->param_begin(); - LHSTy = (*P)->getType(); - Consumed = (getLangOptions().ObjCAutoRefCount && - (*P)->hasAttr<NSConsumedAttr>()); - - // Otherwise, if the getter returns an l-value, just call that. - } else { - QualType Result = PropRef->getImplicitPropertyGetter()->getResultType(); - ExprValueKind VK = Expr::getValueKindForType(Result); - if (VK == VK_LValue) { - LHS = ImplicitCastExpr::Create(Context, LHS.get()->getType(), - CK_GetObjCProperty, LHS.take(), 0, VK); - return; - } - } - } else if (getLangOptions().ObjCAutoRefCount) { - const ObjCMethodDecl *setter - = PropRef->getExplicitProperty()->getSetterMethodDecl(); - if (setter) { - ObjCMethodDecl::param_const_iterator P = setter->param_begin(); - LHSTy = (*P)->getType(); - Consumed = (*P)->hasAttr<NSConsumedAttr>(); - } - } - - if ((getLangOptions().CPlusPlus && LHSTy->isRecordType()) || - getLangOptions().ObjCAutoRefCount) { - InitializedEntity Entity = - InitializedEntity::InitializeParameter(Context, LHSTy, Consumed); - ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), RHS); - if (!ArgE.isInvalid()) { - RHS = ArgE; - if (getLangOptions().ObjCAutoRefCount && !PropRef->isSuperReceiver()) - checkRetainCycles(const_cast<Expr*>(PropRef->getBase()), RHS.get()); - } - } -} /// getPrimaryDecl - Helper function for CheckAddressOfOperand(). @@ -7369,33 +7563,41 @@ static void diagnoseAddressOfInvalidType(Sema &S, SourceLocation Loc, /// operator (C99 6.3.2.1p[2-4]), and its result is never an lvalue. /// In C++, the operand might be an overloaded function name, in which case /// we allow the '&' but retain the overloaded-function type. -static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp, +static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, SourceLocation OpLoc) { - if (OrigOp->isTypeDependent()) - return S.Context.DependentTy; - if (OrigOp->getType() == S.Context.OverloadTy) { - if (!isa<OverloadExpr>(OrigOp->IgnoreParens())) { - S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) - << OrigOp->getSourceRange(); + if (const BuiltinType *PTy = OrigOp.get()->getType()->getAsPlaceholderType()){ + if (PTy->getKind() == BuiltinType::Overload) { + if (!isa<OverloadExpr>(OrigOp.get()->IgnoreParens())) { + S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) + << OrigOp.get()->getSourceRange(); + return QualType(); + } + + return S.Context.OverloadTy; + } + + if (PTy->getKind() == BuiltinType::UnknownAny) + return S.Context.UnknownAnyTy; + + if (PTy->getKind() == BuiltinType::BoundMember) { + S.Diag(OpLoc, diag::err_invalid_form_pointer_member_function) + << OrigOp.get()->getSourceRange(); return QualType(); } - - return S.Context.OverloadTy; - } - if (OrigOp->getType() == S.Context.UnknownAnyTy) - return S.Context.UnknownAnyTy; - if (OrigOp->getType() == S.Context.BoundMemberTy) { - S.Diag(OpLoc, diag::err_invalid_form_pointer_member_function) - << OrigOp->getSourceRange(); - return QualType(); + + OrigOp = S.CheckPlaceholderExpr(OrigOp.take()); + if (OrigOp.isInvalid()) return QualType(); } - assert(!OrigOp->getType()->isPlaceholderType()); + if (OrigOp.get()->isTypeDependent()) + return S.Context.DependentTy; + + assert(!OrigOp.get()->getType()->isPlaceholderType()); // Make sure to ignore parentheses in subsequent checks - Expr *op = OrigOp->IgnoreParens(); + Expr *op = OrigOp.get()->IgnoreParens(); - if (S.getLangOptions().C99) { + if (S.getLangOpts().C99) { // Implement C99-only parts of addressof rules. if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) { if (uOp->getOpcode() == UO_Deref) @@ -7426,16 +7628,16 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp, // If the underlying expression isn't a decl ref, give up. if (!isa<DeclRefExpr>(op)) { S.Diag(OpLoc, diag::err_invalid_form_pointer_member_function) - << OrigOp->getSourceRange(); + << OrigOp.get()->getSourceRange(); return QualType(); } DeclRefExpr *DRE = cast<DeclRefExpr>(op); CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl()); // The id-expression was parenthesized. - if (OrigOp != DRE) { + if (OrigOp.get() != DRE) { S.Diag(OpLoc, diag::err_parens_pointer_member_function) - << OrigOp->getSourceRange(); + << OrigOp.get()->getSourceRange(); // The method was named without a qualifier. } else if (!DRE->getQualifier()) { @@ -7449,10 +7651,15 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp, // C99 6.5.3.2p1 // The operand must be either an l-value or a function designator if (!op->getType()->isFunctionType()) { - // FIXME: emit more specific diag... - S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) - << op->getSourceRange(); - return QualType(); + // Use a special diagnostic for loads from property references. + if (isa<PseudoObjectExpr>(op)) { + AddressOfError = AO_Property_Expansion; + } else { + // FIXME: emit more specific diag... + S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) + << op->getSourceRange(); + return QualType(); + } } } else if (op->getObjectKind() == OK_BitField) { // C99 6.5.3.2p1 // The operand cannot be a bit-field @@ -7460,9 +7667,6 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp, } else if (op->getObjectKind() == OK_VectorComponent) { // The operand cannot be an element of a vector AddressOfError = AO_Vector_Element; - } else if (op->getObjectKind() == OK_ObjCProperty) { - // cannot take address of a property expression. - AddressOfError = AO_Property_Expansion; } else if (dcl) { // C99 6.5.3.2p1 // We have an lvalue with a decl. Make sure the decl is not declared // with the register storage-class specifier. @@ -7470,7 +7674,7 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp, // in C++ it is not error to take address of a register // variable (c++03 7.1.1P3) if (vd->getStorageClass() == SC_Register && - !S.getLangOptions().CPlusPlus) { + !S.getLangOpts().CPlusPlus) { AddressOfError = AO_Register_Variable; } } else if (isa<FunctionTemplateDecl>(dcl)) { @@ -7562,7 +7766,7 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK, VK = VK_LValue; // ...except that certain expressions are never l-values in C. - if (!S.getLangOptions().CPlusPlus && Result.isCForbiddenLValueType()) + if (!S.getLangOpts().CPlusPlus && Result.isCForbiddenLValueType()) VK = VK_RValue; return Result; @@ -7669,6 +7873,25 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr, ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr) { + if (getLangOpts().CPlusPlus0x && isa<InitListExpr>(RHSExpr)) { + // The syntax only allows initializer lists on the RHS of assignment, + // so we don't need to worry about accepting invalid code for + // non-assignment operators. + // C++11 5.17p9: + // The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning + // of x = {} is x = T(). + InitializationKind Kind = + InitializationKind::CreateDirectList(RHSExpr->getLocStart()); + InitializedEntity Entity = + InitializedEntity::InitializeTemporary(LHSExpr->getType()); + InitializationSequence InitSeq(*this, Entity, Kind, &RHSExpr, 1); + ExprResult Init = InitSeq.Perform(*this, Entity, Kind, + MultiExprArg(&RHSExpr, 1)); + if (Init.isInvalid()) + return Init; + RHSExpr = Init.take(); + } + ExprResult LHS = Owned(LHSExpr), RHS = Owned(RHSExpr); QualType ResultTy; // Result type of the binary operator. // The following two variables are used for compound assignment operators @@ -7677,27 +7900,10 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, ExprValueKind VK = VK_RValue; ExprObjectKind OK = OK_Ordinary; - // Check if a 'foo<int>' involved in a binary op, identifies a single - // function unambiguously (i.e. an lvalue ala 13.4) - // But since an assignment can trigger target based overload, exclude it in - // our blind search. i.e: - // template<class T> void f(); template<class T, class U> void f(U); - // f<int> == 0; // resolve f<int> blindly - // void (*p)(int); p = f<int>; // resolve f<int> using target - if (Opc != BO_Assign) { - ExprResult resolvedLHS = CheckPlaceholderExpr(LHS.get()); - if (!resolvedLHS.isUsable()) return ExprError(); - LHS = move(resolvedLHS); - - ExprResult resolvedRHS = CheckPlaceholderExpr(RHS.get()); - if (!resolvedRHS.isUsable()) return ExprError(); - RHS = move(resolvedRHS); - } - switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType()); - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() != OK_ObjCProperty) { VK = LHS.get()->getValueKind(); OK = LHS.get()->getObjectKind(); @@ -7719,7 +7925,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, ResultTy = CheckRemainderOperands(LHS, RHS, OpLoc); break; case BO_Add: - ResultTy = CheckAdditionOperands(LHS, RHS, OpLoc); + ResultTy = CheckAdditionOperands(LHS, RHS, OpLoc, Opc); break; case BO_Sub: ResultTy = CheckSubtractionOperands(LHS, RHS, OpLoc); @@ -7762,7 +7968,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy); break; case BO_AddAssign: - CompResultTy = CheckAdditionOperands(LHS, RHS, OpLoc, &CompLHSTy); + CompResultTy = CheckAdditionOperands(LHS, RHS, OpLoc, Opc, &CompLHSTy); if (!CompResultTy.isNull() && !LHS.isInvalid() && !RHS.isInvalid()) ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy); break; @@ -7788,7 +7994,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, break; case BO_Comma: ResultTy = CheckCommaOperands(*this, LHS, RHS, OpLoc); - if (getLangOptions().CPlusPlus && !RHS.isInvalid()) { + if (getLangOpts().CPlusPlus && !RHS.isInvalid()) { VK = RHS.get()->getValueKind(); OK = RHS.get()->getObjectKind(); } @@ -7804,7 +8010,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, if (CompResultTy.isNull()) return Owned(new (Context) BinaryOperator(LHS.take(), RHS.take(), Opc, ResultTy, VK, OK, OpLoc)); - if (getLangOptions().CPlusPlus && LHS.get()->getObjectKind() != + if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() != OK_ObjCProperty) { VK = VK_LValue; OK = LHS.get()->getObjectKind(); @@ -7989,38 +8195,98 @@ ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc, return BuildBinOp(S, TokLoc, Opc, LHSExpr, RHSExpr); } +/// Build an overloaded binary operator expression in the given scope. +static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc, + BinaryOperatorKind Opc, + Expr *LHS, Expr *RHS) { + // Find all of the overloaded operators visible from this + // point. We perform both an operator-name lookup from the local + // scope and an argument-dependent lookup based on the types of + // the arguments. + UnresolvedSet<16> Functions; + OverloadedOperatorKind OverOp + = BinaryOperator::getOverloadedOperator(Opc); + if (Sc && OverOp != OO_None) + S.LookupOverloadedOperatorName(OverOp, Sc, LHS->getType(), + RHS->getType(), Functions); + + // Build the (potentially-overloaded, potentially-dependent) + // binary operation. + return S.CreateOverloadedBinOp(OpLoc, Opc, Functions, LHS, RHS); +} + ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr) { - if (getLangOptions().CPlusPlus) { - bool UseBuiltinOperator; - - if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) { - UseBuiltinOperator = false; - } else if (Opc == BO_Assign && - LHSExpr->getObjectKind() == OK_ObjCProperty) { - UseBuiltinOperator = true; - } else { - UseBuiltinOperator = !LHSExpr->getType()->isOverloadableType() && - !RHSExpr->getType()->isOverloadableType(); + // We want to end up calling one of checkPseudoObjectAssignment + // (if the LHS is a pseudo-object), BuildOverloadedBinOp (if + // both expressions are overloadable or either is type-dependent), + // or CreateBuiltinBinOp (in any other case). We also want to get + // any placeholder types out of the way. + + // Handle pseudo-objects in the LHS. + if (const BuiltinType *pty = LHSExpr->getType()->getAsPlaceholderType()) { + // Assignments with a pseudo-object l-value need special analysis. + if (pty->getKind() == BuiltinType::PseudoObject && + BinaryOperator::isAssignmentOp(Opc)) + return checkPseudoObjectAssignment(S, OpLoc, Opc, LHSExpr, RHSExpr); + + // Don't resolve overloads if the other type is overloadable. + if (pty->getKind() == BuiltinType::Overload) { + // We can't actually test that if we still have a placeholder, + // though. Fortunately, none of the exceptions we see in that + // code below are valid when the LHS is an overload set. Note + // that an overload set can be dependently-typed, but it never + // instantiates to having an overloadable type. + ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr); + if (resolvedRHS.isInvalid()) return ExprError(); + RHSExpr = resolvedRHS.take(); + + if (RHSExpr->isTypeDependent() || + RHSExpr->getType()->isOverloadableType()) + return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); } + + ExprResult LHS = CheckPlaceholderExpr(LHSExpr); + if (LHS.isInvalid()) return ExprError(); + LHSExpr = LHS.take(); + } + + // Handle pseudo-objects in the RHS. + if (const BuiltinType *pty = RHSExpr->getType()->getAsPlaceholderType()) { + // An overload in the RHS can potentially be resolved by the type + // being assigned to. + if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) { + if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) + return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); - if (!UseBuiltinOperator) { - // Find all of the overloaded operators visible from this - // point. We perform both an operator-name lookup from the local - // scope and an argument-dependent lookup based on the types of - // the arguments. - UnresolvedSet<16> Functions; - OverloadedOperatorKind OverOp - = BinaryOperator::getOverloadedOperator(Opc); - if (S && OverOp != OO_None) - LookupOverloadedOperatorName(OverOp, S, LHSExpr->getType(), - RHSExpr->getType(), Functions); + if (LHSExpr->getType()->isOverloadableType()) + return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); - // Build the (potentially-overloaded, potentially-dependent) - // binary operation. - return CreateOverloadedBinOp(OpLoc, Opc, Functions, LHSExpr, RHSExpr); + return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr); } + + // Don't resolve overloads if the other type is overloadable. + if (pty->getKind() == BuiltinType::Overload && + LHSExpr->getType()->isOverloadableType()) + return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); + + ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr); + if (!resolvedRHS.isUsable()) return ExprError(); + RHSExpr = resolvedRHS.take(); + } + + if (getLangOpts().CPlusPlus) { + // If either expression is type-dependent, always build an + // overloaded op. + if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) + return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); + + // Otherwise, build an overloaded op if either expression has an + // overloadable type. + if (LHSExpr->getType()->isOverloadableType() || + RHSExpr->getType()->isOverloadableType()) + return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr); } // Build a built-in binary operation. @@ -8046,12 +8312,9 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, Opc == UO_PreDec); break; case UO_AddrOf: - resultType = CheckAddressOfOperand(*this, Input.get(), OpLoc); + resultType = CheckAddressOfOperand(*this, Input, OpLoc); break; case UO_Deref: { - ExprResult resolved = CheckPlaceholderExpr(Input.get()); - if (!resolved.isUsable()) return ExprError(); - Input = move(resolved); Input = DefaultFunctionArrayLvalueConversion(Input.take()); resultType = CheckIndirectionOperand(*this, Input.get(), VK, OpLoc); break; @@ -8066,18 +8329,13 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, if (resultType->isArithmeticType() || // C99 6.5.3.3p1 resultType->isVectorType()) break; - else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6-7 + else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6-7 resultType->isEnumeralType()) break; - else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6 + else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6 Opc == UO_Plus && resultType->isPointerType()) break; - else if (resultType->isPlaceholderType()) { - Input = CheckPlaceholderExpr(Input.take()); - if (Input.isInvalid()) return ExprError(); - return CreateBuiltinUnaryOp(OpLoc, Opc, Input.take()); - } return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) << resultType << Input.get()->getSourceRange()); @@ -8095,11 +8353,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, << resultType << Input.get()->getSourceRange(); else if (resultType->hasIntegerRepresentation()) break; - else if (resultType->isPlaceholderType()) { - Input = CheckPlaceholderExpr(Input.take()); - if (Input.isInvalid()) return ExprError(); - return CreateBuiltinUnaryOp(OpLoc, Opc, Input.take()); - } else { + else { return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) << resultType << Input.get()->getSourceRange()); } @@ -8121,16 +8375,16 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, break; if (resultType->isScalarType()) { // C99 6.5.3.3p1: ok, fallthrough; - if (Context.getLangOptions().CPlusPlus) { + if (Context.getLangOpts().CPlusPlus) { // C++03 [expr.unary.op]p8, C++0x [expr.unary.op]p9: // operand contextually converted to bool. Input = ImpCastExprToType(Input.take(), Context.BoolTy, ScalarTypeToBooleanCastKind(resultType)); } - } else if (resultType->isPlaceholderType()) { - Input = CheckPlaceholderExpr(Input.take()); - if (Input.isInvalid()) return ExprError(); - return CreateBuiltinUnaryOp(OpLoc, Opc, Input.take()); + } else if (resultType->isExtVectorType()) { + // Vector logical not returns the signed variant of the operand type. + resultType = GetSignedVectorType(resultType); + break; } else { return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr) << resultType << Input.get()->getSourceRange()); @@ -8143,11 +8397,17 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_Real: case UO_Imag: resultType = CheckRealImagOperand(*this, Input, OpLoc, Opc == UO_Real); - // _Real and _Imag map ordinary l-values into ordinary l-values. + // _Real maps ordinary l-values into ordinary l-values. _Imag maps ordinary + // complex l-values to ordinary l-values and all other values to r-values. if (Input.isInvalid()) return ExprError(); - if (Input.get()->getValueKind() != VK_RValue && - Input.get()->getObjectKind() == OK_Ordinary) - VK = Input.get()->getValueKind(); + if (Opc == UO_Real || Input.get()->getType()->isAnyComplexType()) { + if (Input.get()->getValueKind() != VK_RValue && + Input.get()->getObjectKind() == OK_Ordinary) + VK = Input.get()->getValueKind(); + } else if (!getLangOpts().CPlusPlus) { + // In C, a volatile scalar is read by __imag. In C++, it is not. + Input = DefaultLvalueConversion(Input.take()); + } break; case UO_Extension: resultType = Input.get()->getType(); @@ -8169,10 +8429,79 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, VK, OK, OpLoc)); } +/// \brief Determine whether the given expression is a qualified member +/// access expression, of a form that could be turned into a pointer to member +/// with the address-of operator. +static bool isQualifiedMemberAccess(Expr *E) { + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { + if (!DRE->getQualifier()) + return false; + + ValueDecl *VD = DRE->getDecl(); + if (!VD->isCXXClassMember()) + return false; + + if (isa<FieldDecl>(VD) || isa<IndirectFieldDecl>(VD)) + return true; + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(VD)) + return Method->isInstance(); + + return false; + } + + if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { + if (!ULE->getQualifier()) + return false; + + for (UnresolvedLookupExpr::decls_iterator D = ULE->decls_begin(), + DEnd = ULE->decls_end(); + D != DEnd; ++D) { + if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*D)) { + if (Method->isInstance()) + return true; + } else { + // Overload set does not contain methods. + break; + } + } + + return false; + } + + return false; +} + ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input) { - if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType() && - UnaryOperator::getOverloadedOperator(Opc) != OO_None) { + // First things first: handle placeholders so that the + // overloaded-operator check considers the right type. + if (const BuiltinType *pty = Input->getType()->getAsPlaceholderType()) { + // Increment and decrement of pseudo-object references. + if (pty->getKind() == BuiltinType::PseudoObject && + UnaryOperator::isIncrementDecrementOp(Opc)) + return checkPseudoObjectIncDec(S, OpLoc, Opc, Input); + + // extension is always a builtin operator. + if (Opc == UO_Extension) + return CreateBuiltinUnaryOp(OpLoc, Opc, Input); + + // & gets special logic for several kinds of placeholder. + // The builtin code knows what to do. + if (Opc == UO_AddrOf && + (pty->getKind() == BuiltinType::Overload || + pty->getKind() == BuiltinType::UnknownAny || + pty->getKind() == BuiltinType::BoundMember)) + return CreateBuiltinUnaryOp(OpLoc, Opc, Input); + + // Anything else needs to be handled now. + ExprResult Result = CheckPlaceholderExpr(Input); + if (Result.isInvalid()) return ExprError(); + Input = Result.take(); + } + + if (getLangOpts().CPlusPlus && Input->getType()->isOverloadableType() && + UnaryOperator::getOverloadedOperator(Opc) != OO_None && + !(Opc == UO_AddrOf && isQualifiedMemberAccess(Input))) { // Find all of the overloaded operators visible from this // point. We perform both an operator-name lookup from the local // scope and an argument-dependent lookup based on the types of @@ -8227,12 +8556,29 @@ static Expr *maybeRebuildARCConsumingStmt(Stmt *Statement) { return cleanups; } +void Sema::ActOnStartStmtExpr() { + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); +} + +void Sema::ActOnStmtExprError() { + // Note that function is also called by TreeTransform when leaving a + // StmtExpr scope without rebuilding anything. + + DiscardCleanupsInEvaluationContext(); + PopExpressionEvaluationContext(); +} + ExprResult Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc) { // "({..})" assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!"); CompoundStmt *Compound = cast<CompoundStmt>(SubStmt); + if (hasAnyUnrecoverableErrorsInThisFunction()) + DiscardCleanupsInEvaluationContext(); + assert(!ExprNeedsCleanups && "cleanups within StmtExpr not correctly bound!"); + PopExpressionEvaluationContext(); + bool isFileScope = (getCurFunctionOrMethodDecl() == 0) && (getCurBlock() == 0); if (isFileScope) @@ -8353,15 +8699,19 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, } else CurrentType = Context.DependentTy; + ExprResult IdxRval = DefaultLvalueConversion(static_cast<Expr*>(OC.U.E)); + if (IdxRval.isInvalid()) + return ExprError(); + Expr *Idx = IdxRval.take(); + // The expression must be an integral expression. // FIXME: An integral constant expression? - Expr *Idx = static_cast<Expr*>(OC.U.E); if (!Idx->isTypeDependent() && !Idx->isValueDependent() && !Idx->getType()->isIntegerType()) return ExprError(Diag(Idx->getLocStart(), diag::err_typecheck_subscript_not_integer) << Idx->getSourceRange()); - + // Record this array index. Comps.push_back(OffsetOfNode(OC.LocStart, Exprs.size(), OC.LocEnd)); Exprs.push_back(Idx); @@ -8500,11 +8850,11 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, } else { // The conditional expression is required to be a constant expression. llvm::APSInt condEval(32); - SourceLocation ExpLoc; - if (!CondExpr->isIntegerConstantExpr(condEval, Context, &ExpLoc)) - return ExprError(Diag(ExpLoc, - diag::err_typecheck_choose_expr_requires_constant) - << CondExpr->getSourceRange()); + ExprResult CondICE = VerifyIntegerConstantExpression(CondExpr, &condEval, + PDiag(diag::err_typecheck_choose_expr_requires_constant), false); + if (CondICE.isInvalid()) + return ExprError(); + CondExpr = CondICE.take(); // If the condition is > zero, then the AST type is the same as the LSHExpr. Expr *ActiveExpr = condEval.getZExtValue() ? LHSExpr : RHSExpr; @@ -8534,6 +8884,12 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) { PushDeclContext(CurScope, Block); else CurContext = Block; + + getCurBlock()->HasImplicitReturnType = true; + + // Enter a new evaluation context to insulate the block from any + // cleanups from the enclosing full-expression. + PushExpressionEvaluationContext(PotentiallyEvaluated); } void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { @@ -8585,7 +8941,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { // Don't allow returning a objc interface by value. if (RetTy->isObjCObjectType()) { - Diag(ParamInfo.getSourceRange().getBegin(), + Diag(ParamInfo.getLocStart(), diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy; return; } @@ -8594,8 +8950,11 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { // return type. TODO: what should we do with declarators like: // ^ * { ... } // If the answer is "apply template argument deduction".... - if (RetTy != Context.DependentTy) + if (RetTy != Context.DependentTy) { CurBlock->ReturnType = RetTy; + CurBlock->TheDecl->setBlockMissingReturnType(false); + CurBlock->HasImplicitReturnType = false; + } // Push block parameters from the declarator if we had them. SmallVector<ParmVarDecl*, 8> Params; @@ -8605,7 +8964,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { if (Param->getIdentifier() == 0 && !Param->isImplicit() && !Param->isInvalidDecl() && - !getLangOptions().CPlusPlus) + !getLangOpts().CPlusPlus) Diag(Param->getLocation(), diag::err_parameter_name_omitted); Params.push_back(Param); } @@ -8617,7 +8976,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { I = Fn->arg_type_begin(), E = Fn->arg_type_end(); I != E; ++I) { ParmVarDecl *Param = BuildParmVarDeclForTypedef(CurBlock->TheDecl, - ParamInfo.getSourceRange().getBegin(), + ParamInfo.getLocStart(), *I); Params.push_back(Param); } @@ -8634,12 +8993,6 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { // Finally we can process decl attributes. ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo); - if (!isVariadic && CurBlock->TheDecl->getAttr<SentinelAttr>()) { - Diag(ParamInfo.getAttributes()->getLoc(), - diag::warn_attribute_sentinel_not_variadic) << 1; - // FIXME: remove the attribute. - } - // Put the parameter variables in scope. We can bail out immediately // if we don't have any. if (Params.empty()) @@ -8661,9 +9014,13 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { /// ActOnBlockError - If there is an error parsing a block, this callback /// is invoked to pop the information about the block from the action impl. void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) { + // Leave the expression-evaluation context. + DiscardCleanupsInEvaluationContext(); + PopExpressionEvaluationContext(); + // Pop off CurBlock, handle nested blocks. PopDeclContext(); - PopFunctionOrBlockScope(); + PopFunctionScopeInfo(); } /// ActOnBlockStmtExpr - This is called when the body of a block statement @@ -8674,6 +9031,12 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (!LangOpts.Blocks) Diag(CaretLoc, diag::err_blocks_disable); + // Leave the expression-evaluation context. + if (hasAnyUnrecoverableErrorsInThisFunction()) + DiscardCleanupsInEvaluationContext(); + assert(!ExprNeedsCleanups && "cleanups within block not correctly bound!"); + PopExpressionEvaluationContext(); + BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back()); PopDeclContext(); @@ -8686,8 +9049,18 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, QualType BlockTy; // Set the captured variables on the block. - BSI->TheDecl->setCaptures(Context, BSI->Captures.begin(), BSI->Captures.end(), - BSI->CapturesCXXThis); + // FIXME: Share capture structure between BlockDecl and CapturingScopeInfo! + SmallVector<BlockDecl::Capture, 4> Captures; + for (unsigned i = 0, e = BSI->Captures.size(); i != e; i++) { + CapturingScopeInfo::Capture &Cap = BSI->Captures[i]; + if (Cap.isThisCapture()) + continue; + BlockDecl::Capture NewCap(Cap.getVariable(), Cap.isBlockCapture(), + Cap.isNested(), Cap.getCopyExpr()); + Captures.push_back(NewCap); + } + BSI->TheDecl->setCaptures(Context, Captures.begin(), Captures.end(), + BSI->CXXThisCaptureIndex != 0); // If the user wrote a function type in some form, try to use that. if (!BSI->FunctionType.isNull()) { @@ -8738,20 +9111,31 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, BSI->TheDecl->setBody(cast<CompoundStmt>(Body)); - for (BlockDecl::capture_const_iterator ci = BSI->TheDecl->capture_begin(), - ce = BSI->TheDecl->capture_end(); ci != ce; ++ci) { - const VarDecl *variable = ci->getVariable(); - QualType T = variable->getType(); - QualType::DestructionKind destructKind = T.isDestructedType(); - if (destructKind != QualType::DK_none) - getCurFunction()->setHasBranchProtectedScope(); - } - computeNRVO(Body, getCurBlock()); BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); const AnalysisBasedWarnings::Policy &WP = AnalysisWarnings.getDefaultPolicy(); - PopFunctionOrBlockScope(&WP, Result->getBlockDecl(), Result); + PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result); + + // If the block isn't obviously global, i.e. it captures anything at + // all, then we need to do a few things in the surrounding context: + if (Result->getBlockDecl()->hasCaptures()) { + // First, this expression has a new cleanup object. + ExprCleanupObjects.push_back(Result->getBlockDecl()); + ExprNeedsCleanups = true; + + // It also gets a branch-protected scope if any of the captured + // variables needs destruction. + for (BlockDecl::capture_const_iterator + ci = Result->getBlockDecl()->capture_begin(), + ce = Result->getBlockDecl()->capture_end(); ci != ce; ++ci) { + const VarDecl *var = ci->getVariable(); + if (var->getType().isDestructedType() != QualType::DK_none) { + getCurFunction()->setHasBranchProtectedScope(); + break; + } + } + } return Owned(Result); } @@ -8859,7 +9243,7 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, Expr *SrcExpr, FixItHint &Hint) { - if (!SemaRef.getLangOptions().ObjC1) + if (!SemaRef.getLangOpts().ObjC1) return; const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>(); @@ -8874,8 +9258,15 @@ static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, return; } - // Strip off any parens and casts. - StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr->IgnoreParenCasts()); + // Ignore any parens, implicit casts (should only be + // array-to-pointer decays), and not-so-opaque values. The last is + // important for making this trigger for property assignments. + SrcExpr = SrcExpr->IgnoreParenImpCasts(); + if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr)) + if (OV->getSourceExpr()) + SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts(); + + StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr); if (!SL || !SL->isAscii()) return; @@ -8893,13 +9284,13 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, // Decode the result (notice that AST's are still created for extensions). bool CheckInferredResultType = false; bool isInvalid = false; - unsigned DiagKind; + unsigned DiagKind = 0; FixItHint Hint; ConversionFixItGenerator ConvHints; bool MayHaveConvFixit = false; + bool MayHaveFunctionDiff = false; switch (ConvTy) { - default: llvm_unreachable("Unknown conversion type"); case Compatible: return false; case PointerToInt: DiagKind = diag::ext_typecheck_convert_pointer_int; @@ -8956,7 +9347,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, // expression, rather than a type), which should be done as part // of a larger effort to fix checkPointerTypesForAssignment for // C++ semantics. - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && IsStringLiteralToNonConstPointerConversion(SrcExpr, DstType)) return false; DiagKind = diag::ext_typecheck_convert_discards_qualifiers; @@ -8986,6 +9377,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this); MayHaveConvFixit = true; isInvalid = true; + MayHaveFunctionDiff = true; break; } @@ -9015,17 +9407,23 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, // If we can fix the conversion, suggest the FixIts. assert(ConvHints.isNull() || Hint.isNull()); if (!ConvHints.isNull()) { - for (llvm::SmallVector<FixItHint, 1>::iterator - HI = ConvHints.Hints.begin(), HE = ConvHints.Hints.end(); - HI != HE; ++HI) + for (std::vector<FixItHint>::iterator HI = ConvHints.Hints.begin(), + HE = ConvHints.Hints.end(); HI != HE; ++HI) FDiag << *HI; } else { FDiag << Hint; } if (MayHaveConvFixit) { FDiag << (unsigned) (ConvHints.Kind); } + if (MayHaveFunctionDiff) + HandleFunctionTypeMismatch(FDiag, SecondType, FirstType); + Diag(Loc, FDiag); + if (SecondType == Context.OverloadTy) + NoteAllOverloadCandidates(OverloadExpr::find(SrcExpr).Expression, + FirstType); + if (CheckInferredResultType) EmitRelatedResultTypeNote(SrcExpr); @@ -9034,77 +9432,213 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, return isInvalid; } -bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){ - llvm::APSInt ICEResult; - if (E->isIntegerConstantExpr(ICEResult, Context)) { +ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, + llvm::APSInt *Result) { + return VerifyIntegerConstantExpression(E, Result, + PDiag(diag::err_expr_not_ice) << LangOpts.CPlusPlus); +} + +ExprResult Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, + PartialDiagnostic NotIceDiag, + bool AllowFold, + PartialDiagnostic FoldDiag) { + SourceLocation DiagLoc = E->getLocStart(); + + if (getLangOpts().CPlusPlus0x) { + // C++11 [expr.const]p5: + // If an expression of literal class type is used in a context where an + // integral constant expression is required, then that class type shall + // have a single non-explicit conversion function to an integral or + // unscoped enumeration type + ExprResult Converted; + if (NotIceDiag.getDiagID()) { + Converted = ConvertToIntegralOrEnumerationType( + DiagLoc, E, + PDiag(diag::err_ice_not_integral), + PDiag(diag::err_ice_incomplete_type), + PDiag(diag::err_ice_explicit_conversion), + PDiag(diag::note_ice_conversion_here), + PDiag(diag::err_ice_ambiguous_conversion), + PDiag(diag::note_ice_conversion_here), + PDiag(0), + /*AllowScopedEnumerations*/ false); + } else { + // The caller wants to silently enquire whether this is an ICE. Don't + // produce any diagnostics if it isn't. + Converted = ConvertToIntegralOrEnumerationType( + DiagLoc, E, PDiag(), PDiag(), PDiag(), PDiag(), + PDiag(), PDiag(), PDiag(), false); + } + if (Converted.isInvalid()) + return Converted; + E = Converted.take(); + if (!E->getType()->isIntegralOrUnscopedEnumerationType()) + return ExprError(); + } else if (!E->getType()->isIntegralOrUnscopedEnumerationType()) { + // An ICE must be of integral or unscoped enumeration type. + if (NotIceDiag.getDiagID()) + Diag(DiagLoc, NotIceDiag) << E->getSourceRange(); + return ExprError(); + } + + // Circumvent ICE checking in C++11 to avoid evaluating the expression twice + // in the non-ICE case. + if (!getLangOpts().CPlusPlus0x && E->isIntegerConstantExpr(Context)) { if (Result) - *Result = ICEResult; - return false; + *Result = E->EvaluateKnownConstInt(Context); + return Owned(E); } Expr::EvalResult EvalResult; + llvm::SmallVector<PartialDiagnosticAt, 8> Notes; + EvalResult.Diag = &Notes; + + // Try to evaluate the expression, and produce diagnostics explaining why it's + // not a constant expression as a side-effect. + bool Folded = E->EvaluateAsRValue(EvalResult, Context) && + EvalResult.Val.isInt() && !EvalResult.HasSideEffects; + + // In C++11, we can rely on diagnostics being produced for any expression + // which is not a constant expression. If no diagnostics were produced, then + // this is a constant expression. + if (Folded && getLangOpts().CPlusPlus0x && Notes.empty()) { + if (Result) + *Result = EvalResult.Val.getInt(); + return Owned(E); + } - if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() || - EvalResult.HasSideEffects) { - Diag(E->getExprLoc(), diag::err_expr_not_ice) << E->getSourceRange(); + // If our only note is the usual "invalid subexpression" note, just point + // the caret at its location rather than producing an essentially + // redundant note. + if (Notes.size() == 1 && Notes[0].second.getDiagID() == + diag::note_invalid_subexpr_in_const_expr) { + DiagLoc = Notes[0].first; + Notes.clear(); + } - if (EvalResult.Diag) { - // We only show the note if it's not the usual "invalid subexpression" - // or if it's actually in a subexpression. - if (EvalResult.Diag != diag::note_invalid_subexpr_in_ice || - E->IgnoreParens() != EvalResult.DiagExpr->IgnoreParens()) - Diag(EvalResult.DiagLoc, EvalResult.Diag); + if (!Folded || !AllowFold) { + if (NotIceDiag.getDiagID()) { + Diag(DiagLoc, NotIceDiag) << E->getSourceRange(); + for (unsigned I = 0, N = Notes.size(); I != N; ++I) + Diag(Notes[I].first, Notes[I].second); } - return true; + return ExprError(); } - Diag(E->getExprLoc(), diag::ext_expr_not_ice) << - E->getSourceRange(); - - if (EvalResult.Diag && - Diags.getDiagnosticLevel(diag::ext_expr_not_ice, EvalResult.DiagLoc) - != DiagnosticsEngine::Ignored) - Diag(EvalResult.DiagLoc, EvalResult.Diag); + if (FoldDiag.getDiagID()) + Diag(DiagLoc, FoldDiag) << E->getSourceRange(); + else + Diag(DiagLoc, diag::ext_expr_not_ice) + << E->getSourceRange() << LangOpts.CPlusPlus; + for (unsigned I = 0, N = Notes.size(); I != N; ++I) + Diag(Notes[I].first, Notes[I].second); if (Result) *Result = EvalResult.Val.getInt(); - return false; + return Owned(E); +} + +namespace { + // Handle the case where we conclude a expression which we speculatively + // considered to be unevaluated is actually evaluated. + class TransformToPE : public TreeTransform<TransformToPE> { + typedef TreeTransform<TransformToPE> BaseTransform; + + public: + TransformToPE(Sema &SemaRef) : BaseTransform(SemaRef) { } + + // Make sure we redo semantic analysis + bool AlwaysRebuild() { return true; } + + // Make sure we handle LabelStmts correctly. + // FIXME: This does the right thing, but maybe we need a more general + // fix to TreeTransform? + StmtResult TransformLabelStmt(LabelStmt *S) { + S->getDecl()->setStmt(0); + return BaseTransform::TransformLabelStmt(S); + } + + // We need to special-case DeclRefExprs referring to FieldDecls which + // are not part of a member pointer formation; normal TreeTransforming + // doesn't catch this case because of the way we represent them in the AST. + // FIXME: This is a bit ugly; is it really the best way to handle this + // case? + // + // Error on DeclRefExprs referring to FieldDecls. + ExprResult TransformDeclRefExpr(DeclRefExpr *E) { + if (isa<FieldDecl>(E->getDecl()) && + SemaRef.ExprEvalContexts.back().Context != Sema::Unevaluated) + return SemaRef.Diag(E->getLocation(), + diag::err_invalid_non_static_member_use) + << E->getDecl() << E->getSourceRange(); + + return BaseTransform::TransformDeclRefExpr(E); + } + + // Exception: filter out member pointer formation + ExprResult TransformUnaryOperator(UnaryOperator *E) { + if (E->getOpcode() == UO_AddrOf && E->getType()->isMemberPointerType()) + return E; + + return BaseTransform::TransformUnaryOperator(E); + } + + ExprResult TransformLambdaExpr(LambdaExpr *E) { + // Lambdas never need to be transformed. + return E; + } + }; +} + +ExprResult Sema::TranformToPotentiallyEvaluated(Expr *E) { + assert(ExprEvalContexts.back().Context == Unevaluated && + "Should only transform unevaluated expressions"); + ExprEvalContexts.back().Context = + ExprEvalContexts[ExprEvalContexts.size()-2].Context; + if (ExprEvalContexts.back().Context == Unevaluated) + return E; + return TransformToPE(*this).TransformExpr(E); } void -Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) { +Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, + Decl *LambdaContextDecl, + bool IsDecltype) { ExprEvalContexts.push_back( ExpressionEvaluationContextRecord(NewContext, - ExprTemporaries.size(), - ExprNeedsCleanups)); + ExprCleanupObjects.size(), + ExprNeedsCleanups, + LambdaContextDecl, + IsDecltype)); ExprNeedsCleanups = false; + if (!MaybeODRUseExprs.empty()) + std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs); } void Sema::PopExpressionEvaluationContext() { - // Pop the current expression evaluation context off the stack. - ExpressionEvaluationContextRecord Rec = ExprEvalContexts.back(); - ExprEvalContexts.pop_back(); - - if (Rec.Context == PotentiallyPotentiallyEvaluated) { - if (Rec.PotentiallyReferenced) { - // Mark any remaining declarations in the current position of the stack - // as "referenced". If they were not meant to be referenced, semantic - // analysis would have eliminated them (e.g., in ActOnCXXTypeId). - for (PotentiallyReferencedDecls::iterator - I = Rec.PotentiallyReferenced->begin(), - IEnd = Rec.PotentiallyReferenced->end(); - I != IEnd; ++I) - MarkDeclarationReferenced(I->first, I->second); - } - - if (Rec.PotentiallyDiagnosed) { - // Emit any pending diagnostics. - for (PotentiallyEmittedDiagnostics::iterator - I = Rec.PotentiallyDiagnosed->begin(), - IEnd = Rec.PotentiallyDiagnosed->end(); - I != IEnd; ++I) - Diag(I->first, I->second); + ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); + + if (!Rec.Lambdas.empty()) { + if (Rec.Context == Unevaluated) { + // C++11 [expr.prim.lambda]p2: + // A lambda-expression shall not appear in an unevaluated operand + // (Clause 5). + for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) + Diag(Rec.Lambdas[I]->getLocStart(), + diag::err_lambda_unevaluated_operand); + } else { + // Mark the capture expressions odr-used. This was deferred + // during lambda expression creation. + for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) { + LambdaExpr *Lambda = Rec.Lambdas[I]; + for (LambdaExpr::capture_init_iterator + C = Lambda->capture_init_begin(), + CEnd = Lambda->capture_init_end(); + C != CEnd; ++C) { + MarkDeclarationsReferencedInExpr(*C); + } + } } } @@ -9112,89 +9646,86 @@ void Sema::PopExpressionEvaluationContext() { // temporaries that we may have created as part of the evaluation of // the expression in that context: they aren't relevant because they // will never be constructed. - if (Rec.Context == Unevaluated) { - ExprTemporaries.erase(ExprTemporaries.begin() + Rec.NumTemporaries, - ExprTemporaries.end()); + if (Rec.Context == Unevaluated || Rec.Context == ConstantEvaluated) { + ExprCleanupObjects.erase(ExprCleanupObjects.begin() + Rec.NumCleanupObjects, + ExprCleanupObjects.end()); ExprNeedsCleanups = Rec.ParentNeedsCleanups; - + CleanupVarDeclMarking(); + std::swap(MaybeODRUseExprs, Rec.SavedMaybeODRUseExprs); // Otherwise, merge the contexts together. } else { ExprNeedsCleanups |= Rec.ParentNeedsCleanups; + MaybeODRUseExprs.insert(Rec.SavedMaybeODRUseExprs.begin(), + Rec.SavedMaybeODRUseExprs.end()); } - // Destroy the popped expression evaluation record. - Rec.Destroy(); + // Pop the current expression evaluation context off the stack. + ExprEvalContexts.pop_back(); } void Sema::DiscardCleanupsInEvaluationContext() { - ExprTemporaries.erase( - ExprTemporaries.begin() + ExprEvalContexts.back().NumTemporaries, - ExprTemporaries.end()); + ExprCleanupObjects.erase( + ExprCleanupObjects.begin() + ExprEvalContexts.back().NumCleanupObjects, + ExprCleanupObjects.end()); ExprNeedsCleanups = false; + MaybeODRUseExprs.clear(); } -/// \brief Note that the given declaration was referenced in the source code. -/// -/// This routine should be invoke whenever a given declaration is referenced -/// in the source code, and where that reference occurred. If this declaration -/// reference means that the the declaration is used (C++ [basic.def.odr]p2, -/// C99 6.9p3), then the declaration will be marked as used. -/// -/// \param Loc the location where the declaration was referenced. -/// -/// \param D the declaration that has been referenced by the source code. -void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { - assert(D && "No declaration?"); - - D->setReferenced(); - - if (D->isUsed(false)) - return; - - // Mark a parameter or variable declaration "used", regardless of whether - // we're in a template or not. The reason for this is that unevaluated - // expressions (e.g. (void)sizeof()) constitute a use for warning purposes - // (-Wunused-variables and -Wunused-parameters) - if (isa<ParmVarDecl>(D) || - (isa<VarDecl>(D) && D->getDeclContext()->isFunctionOrMethod())) { - D->setUsed(); - return; - } - - if (!isa<VarDecl>(D) && !isa<FunctionDecl>(D)) - return; +ExprResult Sema::HandleExprEvaluationContextForTypeof(Expr *E) { + if (!E->getType()->isVariablyModifiedType()) + return E; + return TranformToPotentiallyEvaluated(E); +} +static bool IsPotentiallyEvaluatedContext(Sema &SemaRef) { // Do not mark anything as "used" within a dependent context; wait for // an instantiation. - if (CurContext->isDependentContext()) - return; + if (SemaRef.CurContext->isDependentContext()) + return false; - switch (ExprEvalContexts.back().Context) { - case Unevaluated: + switch (SemaRef.ExprEvalContexts.back().Context) { + case Sema::Unevaluated: // We are in an expression that is not potentially evaluated; do nothing. - return; + // (Depending on how you read the standard, we actually do need to do + // something here for null pointer constants, but the standard's + // definition of a null pointer constant is completely crazy.) + return false; - case PotentiallyEvaluated: - // We are in a potentially-evaluated expression, so this declaration is - // "used"; handle this below. - break; + case Sema::ConstantEvaluated: + case Sema::PotentiallyEvaluated: + // We are in a potentially evaluated expression (or a constant-expression + // in C++03); we need to do implicit template instantiation, implicitly + // define class members, and mark most declarations as used. + return true; - case PotentiallyPotentiallyEvaluated: - // We are in an expression that may be potentially evaluated; queue this - // declaration reference until we know whether the expression is - // potentially evaluated. - ExprEvalContexts.back().addReferencedDecl(Loc, D); - return; - - case PotentiallyEvaluatedIfUsed: + case Sema::PotentiallyEvaluatedIfUsed: // Referenced declarations will only be used if the construct in the // containing expression is used. - return; + return false; } + llvm_unreachable("Invalid context"); +} + +/// \brief Mark a function referenced, and check whether it is odr-used +/// (C++ [basic.def.odr]p2, C99 6.9p3) +void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { + assert(Func && "No function?"); + + Func->setReferenced(); + + // Don't mark this function as used multiple times, unless it's a constexpr + // function which we need to instantiate. + if (Func->isUsed(false) && + !(Func->isConstexpr() && !Func->getBody() && + Func->isImplicitlyInstantiable())) + return; + + if (!IsPotentiallyEvaluatedContext(*this)) + return; // Note that this declaration has been used. - if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { - if (Constructor->isDefaulted()) { + if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Func)) { + if (Constructor->isDefaulted() && !Constructor->isDeleted()) { if (Constructor->isDefaultConstructor()) { if (Constructor->isTrivial()) return; @@ -9210,13 +9741,16 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { } MarkVTableUsed(Loc, Constructor->getParent()); - } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { - if (Destructor->isDefaulted() && !Destructor->isUsed(false)) + } else if (CXXDestructorDecl *Destructor = + dyn_cast<CXXDestructorDecl>(Func)) { + if (Destructor->isDefaulted() && !Destructor->isDeleted() && + !Destructor->isUsed(false)) DefineImplicitDestructor(Loc, Destructor); if (Destructor->isVirtual()) MarkVTableUsed(Loc, Destructor->getParent()); - } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(D)) { - if (MethodDecl->isDefaulted() && MethodDecl->isOverloadedOperator() && + } else if (CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(Func)) { + if (MethodDecl->isDefaulted() && !MethodDecl->isDeleted() && + MethodDecl->isOverloadedOperator() && MethodDecl->getOverloadedOperator() == OO_Equal) { if (!MethodDecl->isUsed(false)) { if (MethodDecl->isCopyAssignmentOperator()) @@ -9224,90 +9758,703 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { else DefineImplicitMoveAssignment(Loc, MethodDecl); } + } else if (isa<CXXConversionDecl>(MethodDecl) && + MethodDecl->getParent()->isLambda()) { + CXXConversionDecl *Conversion = cast<CXXConversionDecl>(MethodDecl); + if (Conversion->isLambdaToBlockPointerConversion()) + DefineImplicitLambdaToBlockPointerConversion(Loc, Conversion); + else + DefineImplicitLambdaToFunctionPointerConversion(Loc, Conversion); } else if (MethodDecl->isVirtual()) MarkVTableUsed(Loc, MethodDecl->getParent()); } - if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) { - // Recursive functions should be marked when used from another function. - if (CurContext == Function) return; - - // Implicit instantiation of function templates and member functions of - // class templates. - if (Function->isImplicitlyInstantiable()) { - bool AlreadyInstantiated = false; - if (FunctionTemplateSpecializationInfo *SpecInfo - = Function->getTemplateSpecializationInfo()) { - if (SpecInfo->getPointOfInstantiation().isInvalid()) - SpecInfo->setPointOfInstantiation(Loc); - else if (SpecInfo->getTemplateSpecializationKind() - == TSK_ImplicitInstantiation) - AlreadyInstantiated = true; - } else if (MemberSpecializationInfo *MSInfo - = Function->getMemberSpecializationInfo()) { - if (MSInfo->getPointOfInstantiation().isInvalid()) - MSInfo->setPointOfInstantiation(Loc); - else if (MSInfo->getTemplateSpecializationKind() - == TSK_ImplicitInstantiation) - AlreadyInstantiated = true; + + // Recursive functions should be marked when used from another function. + // FIXME: Is this really right? + if (CurContext == Func) return; + + // Implicit instantiation of function templates and member functions of + // class templates. + if (Func->isImplicitlyInstantiable()) { + bool AlreadyInstantiated = false; + SourceLocation PointOfInstantiation = Loc; + if (FunctionTemplateSpecializationInfo *SpecInfo + = Func->getTemplateSpecializationInfo()) { + if (SpecInfo->getPointOfInstantiation().isInvalid()) + SpecInfo->setPointOfInstantiation(Loc); + else if (SpecInfo->getTemplateSpecializationKind() + == TSK_ImplicitInstantiation) { + AlreadyInstantiated = true; + PointOfInstantiation = SpecInfo->getPointOfInstantiation(); + } + } else if (MemberSpecializationInfo *MSInfo + = Func->getMemberSpecializationInfo()) { + if (MSInfo->getPointOfInstantiation().isInvalid()) + MSInfo->setPointOfInstantiation(Loc); + else if (MSInfo->getTemplateSpecializationKind() + == TSK_ImplicitInstantiation) { + AlreadyInstantiated = true; + PointOfInstantiation = MSInfo->getPointOfInstantiation(); } + } - if (!AlreadyInstantiated) { - if (isa<CXXRecordDecl>(Function->getDeclContext()) && - cast<CXXRecordDecl>(Function->getDeclContext())->isLocalClass()) - PendingLocalImplicitInstantiations.push_back(std::make_pair(Function, - Loc)); + if (!AlreadyInstantiated || Func->isConstexpr()) { + if (isa<CXXRecordDecl>(Func->getDeclContext()) && + cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass()) + PendingLocalImplicitInstantiations.push_back( + std::make_pair(Func, PointOfInstantiation)); + else if (Func->isConstexpr()) + // Do not defer instantiations of constexpr functions, to avoid the + // expression evaluator needing to call back into Sema if it sees a + // call to such a function. + InstantiateFunctionDefinition(PointOfInstantiation, Func); + else { + PendingInstantiations.push_back(std::make_pair(Func, + PointOfInstantiation)); + // Notify the consumer that a function was implicitly instantiated. + Consumer.HandleCXXImplicitFunctionInstantiation(Func); + } + } + } else { + // Walk redefinitions, as some of them may be instantiable. + for (FunctionDecl::redecl_iterator i(Func->redecls_begin()), + e(Func->redecls_end()); i != e; ++i) { + if (!i->isUsed(false) && i->isImplicitlyInstantiable()) + MarkFunctionReferenced(Loc, *i); + } + } + + // Keep track of used but undefined functions. + if (!Func->isPure() && !Func->hasBody() && + Func->getLinkage() != ExternalLinkage) { + SourceLocation &old = UndefinedInternals[Func->getCanonicalDecl()]; + if (old.isInvalid()) old = Loc; + } + + Func->setUsed(true); +} + +static void +diagnoseUncapturableValueReference(Sema &S, SourceLocation loc, + VarDecl *var, DeclContext *DC) { + DeclContext *VarDC = var->getDeclContext(); + + // If the parameter still belongs to the translation unit, then + // we're actually just using one parameter in the declaration of + // the next. + if (isa<ParmVarDecl>(var) && + isa<TranslationUnitDecl>(VarDC)) + return; + + // For C code, don't diagnose about capture if we're not actually in code + // right now; it's impossible to write a non-constant expression outside of + // function context, so we'll get other (more useful) diagnostics later. + // + // For C++, things get a bit more nasty... it would be nice to suppress this + // diagnostic for certain cases like using a local variable in an array bound + // for a member of a local class, but the correct predicate is not obvious. + if (!S.getLangOpts().CPlusPlus && !S.CurContext->isFunctionOrMethod()) + return; + + if (isa<CXXMethodDecl>(VarDC) && + cast<CXXRecordDecl>(VarDC->getParent())->isLambda()) { + S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_lambda) + << var->getIdentifier(); + } else if (FunctionDecl *fn = dyn_cast<FunctionDecl>(VarDC)) { + S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_function) + << var->getIdentifier() << fn->getDeclName(); + } else if (isa<BlockDecl>(VarDC)) { + S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_block) + << var->getIdentifier(); + } else { + // FIXME: Is there any other context where a local variable can be + // declared? + S.Diag(loc, diag::err_reference_to_local_var_in_enclosing_context) + << var->getIdentifier(); + } + + S.Diag(var->getLocation(), diag::note_local_variable_declared_here) + << var->getIdentifier(); + + // FIXME: Add additional diagnostic info about class etc. which prevents + // capture. +} + +/// \brief Capture the given variable in the given lambda expression. +static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, + VarDecl *Var, QualType FieldType, + QualType DeclRefType, + SourceLocation Loc) { + CXXRecordDecl *Lambda = LSI->Lambda; + + // Build the non-static data member. + FieldDecl *Field + = FieldDecl::Create(S.Context, Lambda, Loc, Loc, 0, FieldType, + S.Context.getTrivialTypeSourceInfo(FieldType, Loc), + 0, false, false); + Field->setImplicit(true); + Field->setAccess(AS_private); + Lambda->addDecl(Field); + + // C++11 [expr.prim.lambda]p21: + // When the lambda-expression is evaluated, the entities that + // are captured by copy are used to direct-initialize each + // corresponding non-static data member of the resulting closure + // object. (For array members, the array elements are + // direct-initialized in increasing subscript order.) These + // initializations are performed in the (unspecified) order in + // which the non-static data members are declared. + + // Introduce a new evaluation context for the initialization, so + // that temporaries introduced as part of the capture are retained + // to be re-"exported" from the lambda expression itself. + S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); + + // C++ [expr.prim.labda]p12: + // An entity captured by a lambda-expression is odr-used (3.2) in + // the scope containing the lambda-expression. + Expr *Ref = new (S.Context) DeclRefExpr(Var, false, DeclRefType, + VK_LValue, Loc); + Var->setReferenced(true); + Var->setUsed(true); + + // When the field has array type, create index variables for each + // dimension of the array. We use these index variables to subscript + // the source array, and other clients (e.g., CodeGen) will perform + // the necessary iteration with these index variables. + SmallVector<VarDecl *, 4> IndexVariables; + QualType BaseType = FieldType; + QualType SizeType = S.Context.getSizeType(); + LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size()); + while (const ConstantArrayType *Array + = S.Context.getAsConstantArrayType(BaseType)) { + // Create the iteration variable for this array index. + IdentifierInfo *IterationVarName = 0; + { + SmallString<8> Str; + llvm::raw_svector_ostream OS(Str); + OS << "__i" << IndexVariables.size(); + IterationVarName = &S.Context.Idents.get(OS.str()); + } + VarDecl *IterationVar + = VarDecl::Create(S.Context, S.CurContext, Loc, Loc, + IterationVarName, SizeType, + S.Context.getTrivialTypeSourceInfo(SizeType, Loc), + SC_None, SC_None); + IndexVariables.push_back(IterationVar); + LSI->ArrayIndexVars.push_back(IterationVar); + + // Create a reference to the iteration variable. + ExprResult IterationVarRef + = S.BuildDeclRefExpr(IterationVar, SizeType, VK_LValue, Loc); + assert(!IterationVarRef.isInvalid() && + "Reference to invented variable cannot fail!"); + IterationVarRef = S.DefaultLvalueConversion(IterationVarRef.take()); + assert(!IterationVarRef.isInvalid() && + "Conversion of invented variable cannot fail!"); + + // Subscript the array with this iteration variable. + ExprResult Subscript = S.CreateBuiltinArraySubscriptExpr( + Ref, Loc, IterationVarRef.take(), Loc); + if (Subscript.isInvalid()) { + S.CleanupVarDeclMarking(); + S.DiscardCleanupsInEvaluationContext(); + S.PopExpressionEvaluationContext(); + return ExprError(); + } + + Ref = Subscript.take(); + BaseType = Array->getElementType(); + } + + // Construct the entity that we will be initializing. For an array, this + // will be first element in the array, which may require several levels + // of array-subscript entities. + SmallVector<InitializedEntity, 4> Entities; + Entities.reserve(1 + IndexVariables.size()); + Entities.push_back( + InitializedEntity::InitializeLambdaCapture(Var, Field, Loc)); + for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I) + Entities.push_back(InitializedEntity::InitializeElement(S.Context, + 0, + Entities.back())); + + InitializationKind InitKind + = InitializationKind::CreateDirect(Loc, Loc, Loc); + InitializationSequence Init(S, Entities.back(), InitKind, &Ref, 1); + ExprResult Result(true); + if (!Init.Diagnose(S, Entities.back(), InitKind, &Ref, 1)) + Result = Init.Perform(S, Entities.back(), InitKind, + MultiExprArg(S, &Ref, 1)); + + // If this initialization requires any cleanups (e.g., due to a + // default argument to a copy constructor), note that for the + // lambda. + if (S.ExprNeedsCleanups) + LSI->ExprNeedsCleanups = true; + + // Exit the expression evaluation context used for the capture. + S.CleanupVarDeclMarking(); + S.DiscardCleanupsInEvaluationContext(); + S.PopExpressionEvaluationContext(); + return Result; +} + +bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, + TryCaptureKind Kind, SourceLocation EllipsisLoc, + bool BuildAndDiagnose, + QualType &CaptureType, + QualType &DeclRefType) { + bool Nested = false; + + DeclContext *DC = CurContext; + if (Var->getDeclContext() == DC) return true; + if (!Var->hasLocalStorage()) return true; + + bool HasBlocksAttr = Var->hasAttr<BlocksAttr>(); + + // Walk up the stack to determine whether we can capture the variable, + // performing the "simple" checks that don't depend on type. We stop when + // we've either hit the declared scope of the variable or find an existing + // capture of that variable. + CaptureType = Var->getType(); + DeclRefType = CaptureType.getNonReferenceType(); + bool Explicit = (Kind != TryCapture_Implicit); + unsigned FunctionScopesIndex = FunctionScopes.size() - 1; + do { + // Only block literals and lambda expressions can capture; other + // scopes don't work. + DeclContext *ParentDC; + if (isa<BlockDecl>(DC)) + ParentDC = DC->getParent(); + else if (isa<CXXMethodDecl>(DC) && + cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call && + cast<CXXRecordDecl>(DC->getParent())->isLambda()) + ParentDC = DC->getParent()->getParent(); + else { + if (BuildAndDiagnose) + diagnoseUncapturableValueReference(*this, Loc, Var, DC); + return true; + } + + CapturingScopeInfo *CSI = + cast<CapturingScopeInfo>(FunctionScopes[FunctionScopesIndex]); + + // Check whether we've already captured it. + if (CSI->CaptureMap.count(Var)) { + // If we found a capture, any subcaptures are nested. + Nested = true; + + // Retrieve the capture type for this variable. + CaptureType = CSI->getCapture(Var).getCaptureType(); + + // Compute the type of an expression that refers to this variable. + DeclRefType = CaptureType.getNonReferenceType(); + + const CapturingScopeInfo::Capture &Cap = CSI->getCapture(Var); + if (Cap.isCopyCapture() && + !(isa<LambdaScopeInfo>(CSI) && cast<LambdaScopeInfo>(CSI)->Mutable)) + DeclRefType.addConst(); + break; + } + + bool IsBlock = isa<BlockScopeInfo>(CSI); + bool IsLambda = !IsBlock; + + // Lambdas are not allowed to capture unnamed variables + // (e.g. anonymous unions). + // FIXME: The C++11 rule don't actually state this explicitly, but I'm + // assuming that's the intent. + if (IsLambda && !Var->getDeclName()) { + if (BuildAndDiagnose) { + Diag(Loc, diag::err_lambda_capture_anonymous_var); + Diag(Var->getLocation(), diag::note_declared_at); + } + return true; + } + + // Prohibit variably-modified types; they're difficult to deal with. + if (Var->getType()->isVariablyModifiedType()) { + if (BuildAndDiagnose) { + if (IsBlock) + Diag(Loc, diag::err_ref_vm_type); else - PendingInstantiations.push_back(std::make_pair(Function, Loc)); + Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName(); + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); } + return true; + } + + // Lambdas are not allowed to capture __block variables; they don't + // support the expected semantics. + if (IsLambda && HasBlocksAttr) { + if (BuildAndDiagnose) { + Diag(Loc, diag::err_lambda_capture_block) + << Var->getDeclName(); + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return true; + } + + if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) { + // No capture-default + if (BuildAndDiagnose) { + Diag(Loc, diag::err_lambda_impcap) << Var->getDeclName(); + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + Diag(cast<LambdaScopeInfo>(CSI)->Lambda->getLocStart(), + diag::note_lambda_decl); + } + return true; + } + + FunctionScopesIndex--; + DC = ParentDC; + Explicit = false; + } while (!Var->getDeclContext()->Equals(DC)); + + // Walk back down the scope stack, computing the type of the capture at + // each step, checking type-specific requirements, and adding captures if + // requested. + for (unsigned I = ++FunctionScopesIndex, N = FunctionScopes.size(); I != N; + ++I) { + CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[I]); + + // Compute the type of the capture and of a reference to the capture within + // this scope. + if (isa<BlockScopeInfo>(CSI)) { + Expr *CopyExpr = 0; + bool ByRef = false; + + // Blocks are not allowed to capture arrays. + if (CaptureType->isArrayType()) { + if (BuildAndDiagnose) { + Diag(Loc, diag::err_ref_array_type); + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return true; + } + + // Forbid the block-capture of autoreleasing variables. + if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) { + if (BuildAndDiagnose) { + Diag(Loc, diag::err_arc_autoreleasing_capture) + << /*block*/ 0; + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return true; + } + + if (HasBlocksAttr || CaptureType->isReferenceType()) { + // Block capture by reference does not change the capture or + // declaration reference types. + ByRef = true; + } else { + // Block capture by copy introduces 'const'. + CaptureType = CaptureType.getNonReferenceType().withConst(); + DeclRefType = CaptureType; + + if (getLangOpts().CPlusPlus && BuildAndDiagnose) { + if (const RecordType *Record = DeclRefType->getAs<RecordType>()) { + // The capture logic needs the destructor, so make sure we mark it. + // Usually this is unnecessary because most local variables have + // their destructors marked at declaration time, but parameters are + // an exception because it's technically only the call site that + // actually requires the destructor. + if (isa<ParmVarDecl>(Var)) + FinalizeVarWithDestructor(Var, Record); + + // According to the blocks spec, the capture of a variable from + // the stack requires a const copy constructor. This is not true + // of the copy/move done to move a __block variable to the heap. + Expr *DeclRef = new (Context) DeclRefExpr(Var, false, + DeclRefType.withConst(), + VK_LValue, Loc); + ExprResult Result + = PerformCopyInitialization( + InitializedEntity::InitializeBlock(Var->getLocation(), + CaptureType, false), + Loc, Owned(DeclRef)); + + // Build a full-expression copy expression if initialization + // succeeded and used a non-trivial constructor. Recover from + // errors by pretending that the copy isn't necessary. + if (!Result.isInvalid() && + !cast<CXXConstructExpr>(Result.get())->getConstructor() + ->isTrivial()) { + Result = MaybeCreateExprWithCleanups(Result); + CopyExpr = Result.take(); + } + } + } + } + + // Actually capture the variable. + if (BuildAndDiagnose) + CSI->addCapture(Var, HasBlocksAttr, ByRef, Nested, Loc, + SourceLocation(), CaptureType, CopyExpr); + Nested = true; + continue; + } + + LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI); + + // Determine whether we are capturing by reference or by value. + bool ByRef = false; + if (I == N - 1 && Kind != TryCapture_Implicit) { + ByRef = (Kind == TryCapture_ExplicitByRef); + } else { + ByRef = (LSI->ImpCaptureStyle == LambdaScopeInfo::ImpCap_LambdaByref); + } + + // Compute the type of the field that will capture this variable. + if (ByRef) { + // C++11 [expr.prim.lambda]p15: + // An entity is captured by reference if it is implicitly or + // explicitly captured but not captured by copy. It is + // unspecified whether additional unnamed non-static data + // members are declared in the closure type for entities + // captured by reference. + // + // FIXME: It is not clear whether we want to build an lvalue reference + // to the DeclRefType or to CaptureType.getNonReferenceType(). GCC appears + // to do the former, while EDG does the latter. Core issue 1249 will + // clarify, but for now we follow GCC because it's a more permissive and + // easily defensible position. + CaptureType = Context.getLValueReferenceType(DeclRefType); } else { - // Walk redefinitions, as some of them may be instantiable. - for (FunctionDecl::redecl_iterator i(Function->redecls_begin()), - e(Function->redecls_end()); i != e; ++i) { - if (!i->isUsed(false) && i->isImplicitlyInstantiable()) - MarkDeclarationReferenced(Loc, *i); + // C++11 [expr.prim.lambda]p14: + // For each entity captured by copy, an unnamed non-static + // data member is declared in the closure type. The + // declaration order of these members is unspecified. The type + // of such a data member is the type of the corresponding + // captured entity if the entity is not a reference to an + // object, or the referenced type otherwise. [Note: If the + // captured entity is a reference to a function, the + // corresponding data member is also a reference to a + // function. - end note ] + if (const ReferenceType *RefType = CaptureType->getAs<ReferenceType>()){ + if (!RefType->getPointeeType()->isFunctionType()) + CaptureType = RefType->getPointeeType(); + } + + // Forbid the lambda copy-capture of autoreleasing variables. + if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) { + if (BuildAndDiagnose) { + Diag(Loc, diag::err_arc_autoreleasing_capture) << /*lambda*/ 1; + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return true; } } - // Keep track of used but undefined functions. - if (!Function->isPure() && !Function->hasBody() && - Function->getLinkage() != ExternalLinkage) { - SourceLocation &old = UndefinedInternals[Function->getCanonicalDecl()]; - if (old.isInvalid()) old = Loc; + // Capture this variable in the lambda. + Expr *CopyExpr = 0; + if (BuildAndDiagnose) { + ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType, + DeclRefType, Loc); + if (!Result.isInvalid()) + CopyExpr = Result.take(); + } + + // Compute the type of a reference to this captured variable. + if (ByRef) + DeclRefType = CaptureType.getNonReferenceType(); + else { + // C++ [expr.prim.lambda]p5: + // The closure type for a lambda-expression has a public inline + // function call operator [...]. This function call operator is + // declared const (9.3.1) if and only if the lambda-expression’s + // parameter-declaration-clause is not followed by mutable. + DeclRefType = CaptureType.getNonReferenceType(); + if (!LSI->Mutable && !CaptureType->isReferenceType()) + DeclRefType.addConst(); } + + // Add the capture. + if (BuildAndDiagnose) + CSI->addCapture(Var, /*IsBlock=*/false, ByRef, Nested, Loc, + EllipsisLoc, CaptureType, CopyExpr); + Nested = true; + } - Function->setUsed(true); - return; + return false; +} + +bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, + TryCaptureKind Kind, SourceLocation EllipsisLoc) { + QualType CaptureType; + QualType DeclRefType; + return tryCaptureVariable(Var, Loc, Kind, EllipsisLoc, + /*BuildAndDiagnose=*/true, CaptureType, + DeclRefType); +} + +QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) { + QualType CaptureType; + QualType DeclRefType; + + // Determine whether we can capture this variable. + if (tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(), + /*BuildAndDiagnose=*/false, CaptureType, DeclRefType)) + return QualType(); + + return DeclRefType; +} + +static void MarkVarDeclODRUsed(Sema &SemaRef, VarDecl *Var, + SourceLocation Loc) { + // Keep track of used but undefined variables. + // FIXME: We shouldn't suppress this warning for static data members. + if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly && + Var->getLinkage() != ExternalLinkage && + !(Var->isStaticDataMember() && Var->hasInit())) { + SourceLocation &old = SemaRef.UndefinedInternals[Var->getCanonicalDecl()]; + if (old.isInvalid()) old = Loc; } - if (VarDecl *Var = dyn_cast<VarDecl>(D)) { - // Implicit instantiation of static data members of class templates. - if (Var->isStaticDataMember() && - Var->getInstantiatedFromStaticDataMember()) { - MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); - assert(MSInfo && "Missing member specialization information?"); - if (MSInfo->getPointOfInstantiation().isInvalid() && - MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) { - MSInfo->setPointOfInstantiation(Loc); + SemaRef.tryCaptureVariable(Var, Loc); + + Var->setUsed(true); +} + +void Sema::UpdateMarkingForLValueToRValue(Expr *E) { + // Per C++11 [basic.def.odr], a variable is odr-used "unless it is + // an object that satisfies the requirements for appearing in a + // constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) + // is immediately applied." This function handles the lvalue-to-rvalue + // conversion part. + MaybeODRUseExprs.erase(E->IgnoreParens()); +} + +ExprResult Sema::ActOnConstantExpression(ExprResult Res) { + if (!Res.isUsable()) + return Res; + + // If a constant-expression is a reference to a variable where we delay + // deciding whether it is an odr-use, just assume we will apply the + // lvalue-to-rvalue conversion. In the one case where this doesn't happen + // (a non-type template argument), we have special handling anyway. + UpdateMarkingForLValueToRValue(Res.get()); + return Res; +} + +void Sema::CleanupVarDeclMarking() { + for (llvm::SmallPtrSetIterator<Expr*> i = MaybeODRUseExprs.begin(), + e = MaybeODRUseExprs.end(); + i != e; ++i) { + VarDecl *Var; + SourceLocation Loc; + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*i)) { + Var = cast<VarDecl>(DRE->getDecl()); + Loc = DRE->getLocation(); + } else if (MemberExpr *ME = dyn_cast<MemberExpr>(*i)) { + Var = cast<VarDecl>(ME->getMemberDecl()); + Loc = ME->getMemberLoc(); + } else { + llvm_unreachable("Unexpcted expression"); + } + + MarkVarDeclODRUsed(*this, Var, Loc); + } + + MaybeODRUseExprs.clear(); +} + +// Mark a VarDecl referenced, and perform the necessary handling to compute +// odr-uses. +static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, + VarDecl *Var, Expr *E) { + Var->setReferenced(); + + if (!IsPotentiallyEvaluatedContext(SemaRef)) + return; + + // Implicit instantiation of static data members of class templates. + if (Var->isStaticDataMember() && Var->getInstantiatedFromStaticDataMember()) { + MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo(); + assert(MSInfo && "Missing member specialization information?"); + bool AlreadyInstantiated = !MSInfo->getPointOfInstantiation().isInvalid(); + if (MSInfo->getTemplateSpecializationKind() == TSK_ImplicitInstantiation && + (!AlreadyInstantiated || + Var->isUsableInConstantExpressions(SemaRef.Context))) { + if (!AlreadyInstantiated) { // This is a modification of an existing AST node. Notify listeners. - if (ASTMutationListener *L = getASTMutationListener()) + if (ASTMutationListener *L = SemaRef.getASTMutationListener()) L->StaticDataMemberInstantiated(Var); - PendingInstantiations.push_back(std::make_pair(Var, Loc)); + MSInfo->setPointOfInstantiation(Loc); } - } + SourceLocation PointOfInstantiation = MSInfo->getPointOfInstantiation(); + if (Var->isUsableInConstantExpressions(SemaRef.Context)) + // Do not defer instantiations of variables which could be used in a + // constant expression. + SemaRef.InstantiateStaticDataMemberDefinition(PointOfInstantiation,Var); + else + SemaRef.PendingInstantiations.push_back( + std::make_pair(Var, PointOfInstantiation)); + } + } + + // Per C++11 [basic.def.odr], a variable is odr-used "unless it is + // an object that satisfies the requirements for appearing in a + // constant expression (5.19) and the lvalue-to-rvalue conversion (4.1) + // is immediately applied." We check the first part here, and + // Sema::UpdateMarkingForLValueToRValue deals with the second part. + // Note that we use the C++11 definition everywhere because nothing in + // C++03 depends on whether we get the C++03 version correct. This does not + // apply to references, since they are not objects. + const VarDecl *DefVD; + if (E && !isa<ParmVarDecl>(Var) && !Var->getType()->isReferenceType() && + Var->isUsableInConstantExpressions(SemaRef.Context) && + Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE()) + SemaRef.MaybeODRUseExprs.insert(E); + else + MarkVarDeclODRUsed(SemaRef, Var, Loc); +} - // Keep track of used but undefined variables. We make a hole in - // the warning for static const data members with in-line - // initializers. - if (Var->hasDefinition() == VarDecl::DeclarationOnly - && Var->getLinkage() != ExternalLinkage - && !(Var->isStaticDataMember() && Var->hasInit())) { - SourceLocation &old = UndefinedInternals[Var->getCanonicalDecl()]; - if (old.isInvalid()) old = Loc; - } +/// \brief Mark a variable referenced, and check whether it is odr-used +/// (C++ [basic.def.odr]p2, C99 6.9p3). Note that this should not be +/// used directly for normal expressions referring to VarDecl. +void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) { + DoMarkVarDeclReferenced(*this, Loc, Var, 0); +} - D->setUsed(true); +static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, + Decl *D, Expr *E) { + if (VarDecl *Var = dyn_cast<VarDecl>(D)) { + DoMarkVarDeclReferenced(SemaRef, Loc, Var, E); return; } + + SemaRef.MarkAnyDeclReferenced(Loc, D); +} + +/// \brief Perform reference-marking and odr-use handling for a DeclRefExpr. +void Sema::MarkDeclRefReferenced(DeclRefExpr *E) { + MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E); +} + +/// \brief Perform reference-marking and odr-use handling for a MemberExpr. +void Sema::MarkMemberReferenced(MemberExpr *E) { + MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E); +} + +/// \brief Perform marking for a reference to an arbitrary declaration. It +/// marks the declaration referenced, and performs odr-use checking for functions +/// and variables. This method should not be used when building an normal +/// expression which refers to a variable. +void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D) { + if (VarDecl *VD = dyn_cast<VarDecl>(D)) + MarkVariableReferenced(Loc, VD); + else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + MarkFunctionReferenced(Loc, FD); + else + D->setReferenced(); } namespace { @@ -9331,7 +10478,8 @@ namespace { bool MarkReferencedDecls::TraverseTemplateArgument( const TemplateArgument &Arg) { if (Arg.getKind() == TemplateArgument::Declaration) { - S.MarkDeclarationReferenced(Loc, Arg.getAsDecl()); + if (Decl *D = Arg.getAsDecl()) + S.MarkAnyDeclReferenced(Loc, D); } return Inherited::TraverseTemplateArgument(Arg); @@ -9357,38 +10505,51 @@ namespace { /// potentially-evaluated subexpressions as "referenced". class EvaluatedExprMarker : public EvaluatedExprVisitor<EvaluatedExprMarker> { Sema &S; + bool SkipLocalVariables; public: typedef EvaluatedExprVisitor<EvaluatedExprMarker> Inherited; - explicit EvaluatedExprMarker(Sema &S) : Inherited(S.Context), S(S) { } + EvaluatedExprMarker(Sema &S, bool SkipLocalVariables) + : Inherited(S.Context), S(S), SkipLocalVariables(SkipLocalVariables) { } void VisitDeclRefExpr(DeclRefExpr *E) { - S.MarkDeclarationReferenced(E->getLocation(), E->getDecl()); + // If we were asked not to visit local variables, don't. + if (SkipLocalVariables) { + if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) + if (VD->hasLocalStorage()) + return; + } + + S.MarkDeclRefReferenced(E); } void VisitMemberExpr(MemberExpr *E) { - S.MarkDeclarationReferenced(E->getMemberLoc(), E->getMemberDecl()); + S.MarkMemberReferenced(E); Inherited::VisitMemberExpr(E); } + void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { + S.MarkFunctionReferenced(E->getLocStart(), + const_cast<CXXDestructorDecl*>(E->getTemporary()->getDestructor())); + Visit(E->getSubExpr()); + } + void VisitCXXNewExpr(CXXNewExpr *E) { - if (E->getConstructor()) - S.MarkDeclarationReferenced(E->getLocStart(), E->getConstructor()); if (E->getOperatorNew()) - S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorNew()); + S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorNew()); if (E->getOperatorDelete()) - S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete()); + S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete()); Inherited::VisitCXXNewExpr(E); } - + void VisitCXXDeleteExpr(CXXDeleteExpr *E) { if (E->getOperatorDelete()) - S.MarkDeclarationReferenced(E->getLocStart(), E->getOperatorDelete()); + S.MarkFunctionReferenced(E->getLocStart(), E->getOperatorDelete()); QualType Destroyed = S.Context.getBaseElementType(E->getDestroyedType()); if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); - S.MarkDeclarationReferenced(E->getLocStart(), + S.MarkFunctionReferenced(E->getLocStart(), S.LookupDestructor(Record)); } @@ -9396,24 +10557,31 @@ namespace { } void VisitCXXConstructExpr(CXXConstructExpr *E) { - S.MarkDeclarationReferenced(E->getLocStart(), E->getConstructor()); + S.MarkFunctionReferenced(E->getLocStart(), E->getConstructor()); Inherited::VisitCXXConstructExpr(E); } - void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { - S.MarkDeclarationReferenced(E->getLocation(), E->getDecl()); - } - void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) { Visit(E->getExpr()); } + + void VisitImplicitCastExpr(ImplicitCastExpr *E) { + Inherited::VisitImplicitCastExpr(E); + + if (E->getCastKind() == CK_LValueToRValue) + S.UpdateMarkingForLValueToRValue(E->getSubExpr()); + } }; } /// \brief Mark any declarations that appear within this expression or any /// potentially-evaluated subexpressions as "referenced". -void Sema::MarkDeclarationsReferencedInExpr(Expr *E) { - EvaluatedExprMarker(*this).Visit(E); +/// +/// \param SkipLocalVariables If true, don't mark local variables as +/// 'referenced'. +void Sema::MarkDeclarationsReferencedInExpr(Expr *E, + bool SkipLocalVariables) { + EvaluatedExprMarker(*this, SkipLocalVariables).Visit(E); } /// \brief Emit a diagnostic that describes an effect on the run-time behavior @@ -9439,6 +10607,10 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, // The argument will never be evaluated, so don't complain. break; + case ConstantEvaluated: + // Relevant diagnostics should be produced by constant evaluation. + break; + case PotentiallyEvaluated: case PotentiallyEvaluatedIfUsed: if (Statement && getCurFunctionOrMethodDecl()) { @@ -9449,10 +10621,6 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, Diag(Loc, PD); return true; - - case PotentiallyPotentiallyEvaluated: - ExprEvalContexts.back().addDiagnostic(Loc, PD); - break; } return false; @@ -9463,6 +10631,13 @@ bool Sema::CheckCallReturnType(QualType ReturnType, SourceLocation Loc, if (ReturnType->isVoidType() || !ReturnType->isIncompleteType()) return false; + // If we're inside a decltype's expression, don't check for a valid return + // type or construct temporaries until we know whether this is the last call. + if (ExprEvalContexts.back().IsDecltype) { + ExprEvalContexts.back().DelayedDecltypeCalls.push_back(CE); + return false; + } + PartialDiagnostic Note = FD ? PDiag(diag::note_function_with_incomplete_return_type_declared_here) << FD->getDeclName() : PDiag(); @@ -9522,7 +10697,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) { Diag(Loc, diagnostic) << E->getSourceRange(); - SourceLocation Open = E->getSourceRange().getBegin(); + SourceLocation Open = E->getLocStart(); SourceLocation Close = PP.getLocForEndOfToken(E->getSourceRange().getEnd()); Diag(Loc, diag::note_condition_assign_silence) << FixItHint::CreateInsertion(Open, "(") @@ -9556,9 +10731,10 @@ void Sema::DiagnoseEqualityWithExtraParens(ParenExpr *ParenE) { SourceLocation Loc = opE->getOperatorLoc(); Diag(Loc, diag::warn_equality_with_extra_parens) << E->getSourceRange(); + SourceRange ParenERange = ParenE->getSourceRange(); Diag(Loc, diag::note_equality_comparison_silence) - << FixItHint::CreateRemoval(ParenE->getSourceRange().getBegin()) - << FixItHint::CreateRemoval(ParenE->getSourceRange().getEnd()); + << FixItHint::CreateRemoval(ParenERange.getBegin()) + << FixItHint::CreateRemoval(ParenERange.getEnd()); Diag(Loc, diag::note_equality_comparison_to_assign) << FixItHint::CreateReplacement(Loc, "="); } @@ -9574,7 +10750,7 @@ ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) { E = result.take(); if (!E->isTypeDependent()) { - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) return CheckCXXBooleanCondition(E); // C++ 6.4p4 ExprResult ERes = DefaultFunctionArrayLvalueConversion(E); @@ -9613,7 +10789,6 @@ namespace { ExprResult VisitStmt(Stmt *S) { llvm_unreachable("unexpected statement!"); - return ExprError(); } ExprResult VisitExpr(Expr *E) { @@ -9662,7 +10837,7 @@ namespace { E->setType(VD->getType()); assert(E->getValueKind() == VK_RValue); - if (S.getLangOptions().CPlusPlus && + if (S.getLangOpts().CPlusPlus && !(isa<CXXMethodDecl>(VD) && cast<CXXMethodDecl>(VD)->isInstance())) E->setValueKind(VK_LValue); @@ -9706,7 +10881,6 @@ namespace { ExprResult VisitStmt(Stmt *S) { llvm_unreachable("unexpected statement!"); - return ExprError(); } ExprResult VisitExpr(Expr *E) { @@ -9870,20 +11044,39 @@ ExprResult RebuildUnknownAnyExpr::VisitObjCMessageExpr(ObjCMessageExpr *E) { ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) { // The only case we should ever see here is a function-to-pointer decay. - assert(E->getCastKind() == CK_FunctionToPointerDecay); - assert(E->getValueKind() == VK_RValue); - assert(E->getObjectKind() == OK_Ordinary); + if (E->getCastKind() == CK_FunctionToPointerDecay) { + assert(E->getValueKind() == VK_RValue); + assert(E->getObjectKind() == OK_Ordinary); + + E->setType(DestType); + + // Rebuild the sub-expression as the pointee (function) type. + DestType = DestType->castAs<PointerType>()->getPointeeType(); + + ExprResult Result = Visit(E->getSubExpr()); + if (!Result.isUsable()) return ExprError(); + + E->setSubExpr(Result.take()); + return S.Owned(E); + } else if (E->getCastKind() == CK_LValueToRValue) { + assert(E->getValueKind() == VK_RValue); + assert(E->getObjectKind() == OK_Ordinary); - E->setType(DestType); + assert(isa<BlockPointerType>(E->getType())); - // Rebuild the sub-expression as the pointee (function) type. - DestType = DestType->castAs<PointerType>()->getPointeeType(); + E->setType(DestType); - ExprResult Result = Visit(E->getSubExpr()); - if (!Result.isUsable()) return ExprError(); + // The sub-expression has to be a lvalue reference, so rebuild it as such. + DestType = S.Context.getLValueReferenceType(DestType); - E->setSubExpr(Result.take()); - return S.Owned(E); + ExprResult Result = Visit(E->getSubExpr()); + if (!Result.isUsable()) return ExprError(); + + E->setSubExpr(Result.take()); + return S.Owned(E); + } else { + llvm_unreachable("Unhandled cast type!"); + } } ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { @@ -9915,7 +11108,7 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { } // Function references aren't l-values in C. - if (!S.getLangOptions().CPlusPlus) + if (!S.getLangOpts().CPlusPlus) ValueKind = VK_RValue; // - variables @@ -9957,6 +11150,10 @@ ExprResult Sema::checkUnknownAnyCast(SourceRange TypeRange, QualType CastType, return CastExpr; } +ExprResult Sema::forceUnknownAnyToType(Expr *E, QualType ToType) { + return RebuildUnknownAnyExpr(*this, ToType).Visit(E); +} + static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { Expr *orig = E; unsigned diagID = diag::err_uncasted_use_of_unknown_any; @@ -10003,11 +11200,13 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { /// Check for operands with placeholder types and complain if found. /// Returns true if there was an error and no recovery was possible. ExprResult Sema::CheckPlaceholderExpr(Expr *E) { - // Placeholder types are always *exactly* the appropriate builtin type. - QualType type = E->getType(); + const BuiltinType *placeholderType = E->getType()->getAsPlaceholderType(); + if (!placeholderType) return Owned(E); + + switch (placeholderType->getKind()) { // Overloaded expressions. - if (type == Context.OverloadTy) { + case BuiltinType::Overload: { // Try to resolve a single function template specialization. // This is obligatory. ExprResult result = Owned(E); @@ -10023,19 +11222,37 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { } // Bound member functions. - if (type == Context.BoundMemberTy) { + case BuiltinType::BoundMember: { ExprResult result = Owned(E); tryToRecoverWithCall(result, PDiag(diag::err_bound_member_function), /*complain*/ true); return result; - } + } + + // ARC unbridged casts. + case BuiltinType::ARCUnbridgedCast: { + Expr *realCast = stripARCUnbridgedCast(E); + diagnoseARCUnbridgedCast(realCast); + return Owned(realCast); + } // Expressions of unknown type. - if (type == Context.UnknownAnyTy) + case BuiltinType::UnknownAny: return diagnoseUnknownAnyExpr(*this, E); - assert(!type->isPlaceholderType()); - return Owned(E); + // Pseudo-objects. + case BuiltinType::PseudoObject: + return checkPseudoObjectRValue(E); + + // Everything else should be impossible. +#define BUILTIN_TYPE(Id, SingletonId) \ + case BuiltinType::Id: +#define PLACEHOLDER_TYPE(Id, SingletonId) +#include "clang/AST/BuiltinTypes.def" + break; + } + + llvm_unreachable("invalid placeholder type!"); } bool Sema::CheckCaseExpression(Expr *E) { @@ -10045,3 +11262,28 @@ bool Sema::CheckCaseExpression(Expr *E) { return E->getType()->isIntegralOrEnumerationType(); return false; } + +/// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. +ExprResult +Sema::ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) { + assert((Kind == tok::kw___objc_yes || Kind == tok::kw___objc_no) && + "Unknown Objective-C Boolean value!"); + QualType ObjCBoolLiteralQT = Context.ObjCBuiltinBoolTy; + // signed char is the default type for boolean literals. Use 'BOOL' + // instead, if BOOL typedef is visible in its scope instead. + Decl *TD = + LookupSingleName(TUScope, &Context.Idents.get("BOOL"), + SourceLocation(), LookupOrdinaryName); + if (TypedefDecl *BoolTD = dyn_cast_or_null<TypedefDecl>(TD)) { + QualType QT = BoolTD->getUnderlyingType(); + if (!QT->isIntegralOrUnscopedEnumerationType()) { + Diag(OpLoc, diag::warn_bool_for_boolean_literal) << QT; + Diag(BoolTD->getLocation(), diag::note_previous_declaration); + } + else + ObjCBoolLiteralQT = QT; + } + + return Owned(new (Context) ObjCBoolLiteralExpr(Kind == tok::kw___objc_yes, + ObjCBoolLiteralQT, OpLoc)); +} |