diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp | 2490 |
1 files changed, 1563 insertions, 927 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp index a9179fd..e1f65f4 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaExpr.cpp @@ -15,6 +15,7 @@ #include "TreeTransform.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclObjC.h" @@ -140,11 +141,13 @@ static AvailabilityResult DiagnoseAvailabilityOfDecl(Sema &S, return Result; } -/// \brief Emit a note explaining that this function is deleted or unavailable. +/// \brief Emit a note explaining that this function is deleted. void Sema::NoteDeletedFunction(FunctionDecl *Decl) { + assert(Decl->isDeleted()); + CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Decl); - if (Method && Method->isDeleted() && !Method->isDeletedAsWritten()) { + if (Method && Method->isDeleted() && Method->isDefaulted()) { // If the method was explicitly defaulted, point at that declaration. if (!Method->isImplicit()) Diag(Decl->getLocation(), diag::note_implicitly_deleted); @@ -158,8 +161,23 @@ void Sema::NoteDeletedFunction(FunctionDecl *Decl) { return; } + if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(Decl)) { + if (CXXConstructorDecl *BaseCD = + const_cast<CXXConstructorDecl*>(CD->getInheritedConstructor())) { + Diag(Decl->getLocation(), diag::note_inherited_deleted_here); + if (BaseCD->isDeleted()) { + NoteDeletedFunction(BaseCD); + } else { + // FIXME: An explanation of why exactly it can't be inherited + // would be nice. + Diag(BaseCD->getLocation(), diag::note_cannot_inherit); + } + return; + } + } + Diag(Decl->getLocation(), diag::note_unavailable_here) - << 1 << Decl->isDeleted(); + << 1 << true; } /// \brief Determine whether a FunctionDecl was ever declared with an @@ -197,11 +215,11 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S, return; if (!Current->isInlined()) return; - if (Current->getLinkage() != ExternalLinkage) + if (!Current->isExternallyVisible()) return; - + // Check if the decl has internal linkage. - if (D->getLinkage() != InternalLinkage) + if (D->getFormalLinkage() != InternalLinkage) return; // Downgrade from ExtWarn to Extension if @@ -212,7 +230,7 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S, // This last can give us false negatives, but it's better than warning on // wrappers for simple C library functions. const FunctionDecl *UsedFn = dyn_cast<FunctionDecl>(D); - bool DowngradeWarning = S.getSourceManager().isFromMainFile(Loc); + bool DowngradeWarning = S.getSourceManager().isInMainFile(Loc); if (!DowngradeWarning && UsedFn) DowngradeWarning = UsedFn->isInlined() || UsedFn->hasAttr<ConstAttr>(); @@ -228,7 +246,7 @@ static void diagnoseUseOfInternalDeclInInlineFunction(Sema &S, } void Sema::MaybeSuggestAddingStaticToDecl(const FunctionDecl *Cur) { - const FunctionDecl *First = Cur->getFirstDeclaration(); + const FunctionDecl *First = Cur->getFirstDecl(); // Suggest "static" on the function, if possible. if (!hasAnyExplicitStorageClass(First)) { @@ -255,7 +273,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, 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 + SuppressedDiagnosticsMap::iterator Pos = SuppressedDiagnostics.find(D->getCanonicalDecl()); if (Pos != SuppressedDiagnostics.end()) { SmallVectorImpl<PartialDiagnosticAt> &Suppressed = Pos->second; @@ -316,7 +334,7 @@ std::string Sema::getDeletedOrUnavailableSuffix(const FunctionDecl *FD) { /// if so, it checks that the requirements of the sentinel are /// satisfied. void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, - Expr **args, unsigned numArgs) { + ArrayRef<Expr *> Args) { const SentinelAttr *attr = D->getAttr<SentinelAttr>(); if (!attr) return; @@ -370,14 +388,14 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, // If there aren't enough arguments for all the formal parameters, // the sentinel, and the args after the sentinel, complain. - if (numArgs < numFormalParams + numArgsAfterSentinel + 1) { + if (Args.size() < numFormalParams + numArgsAfterSentinel + 1) { Diag(Loc, diag::warn_not_enough_argument) << D->getDeclName(); - Diag(D->getLocation(), diag::note_sentinel_here) << calleeType; + Diag(D->getLocation(), diag::note_sentinel_here) << int(calleeType); return; } // Otherwise, find the sentinel expression. - Expr *sentinelExpr = args[numArgs - numArgsAfterSentinel - 1]; + Expr *sentinelExpr = Args[Args.size() - numArgsAfterSentinel - 1]; if (!sentinelExpr) return; if (sentinelExpr->isValueDependent()) return; if (Context.isSentinelNullExpr(sentinelExpr)) return; @@ -398,12 +416,12 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, NullValue = "(void*) 0"; if (MissingNilLoc.isInvalid()) - Diag(Loc, diag::warn_missing_sentinel) << calleeType; + Diag(Loc, diag::warn_missing_sentinel) << int(calleeType); else Diag(MissingNilLoc, diag::warn_missing_sentinel) - << calleeType + << int(calleeType) << FixItHint::CreateInsertion(MissingNilLoc, ", " + NullValue); - Diag(D->getLocation(), diag::note_sentinel_here) << calleeType; + Diag(D->getLocation(), diag::note_sentinel_here) << int(calleeType); } SourceRange Sema::getExprRange(Expr *E) const { @@ -725,6 +743,17 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) { /// when we're in an unevaluated context. Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) { if (Ty->isIncompleteType()) { + // C++11 [expr.call]p7: + // After these conversions, if the argument does not have arithmetic, + // enumeration, pointer, pointer to member, or class type, the program + // is ill-formed. + // + // Since we've already performed array-to-pointer and function-to-pointer + // decay, the only such type in C++ is cv void. This also handles + // initializer lists as variadic arguments. + if (Ty->isVoidType()) + return VAK_Invalid; + if (Ty->isObjCObjectType()) return VAK_Invalid; return VAK_Valid; @@ -747,35 +776,50 @@ Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) { if (getLangOpts().ObjCAutoRefCount && Ty->isObjCLifetimeType()) return VAK_Valid; - return VAK_Invalid; + + if (Ty->isObjCObjectType()) + return VAK_Invalid; + + // FIXME: In C++11, these cases are conditionally-supported, meaning we're + // permitted to reject them. We should consider doing so. + return VAK_Undefined; } -bool Sema::variadicArgumentPODCheck(const Expr *E, VariadicCallType CT) { +void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) { // Don't allow one to pass an Objective-C interface to a vararg. - const QualType & Ty = E->getType(); + const QualType &Ty = E->getType(); + VarArgKind VAK = isValidVarArgType(Ty); // Complain about passing non-POD types through varargs. - switch (isValidVarArgType(Ty)) { + switch (VAK) { case VAK_Valid: break; + case VAK_ValidInCXX11: - DiagRuntimeBehavior(E->getLocStart(), 0, + DiagRuntimeBehavior( + E->getLocStart(), 0, PDiag(diag::warn_cxx98_compat_pass_non_pod_arg_to_vararg) - << E->getType() << CT); + << E->getType() << CT); break; - case VAK_Invalid: { - if (Ty->isObjCObjectType()) - return DiagRuntimeBehavior(E->getLocStart(), 0, - PDiag(diag::err_cannot_pass_objc_interface_to_vararg) - << Ty << CT); - return DiagRuntimeBehavior(E->getLocStart(), 0, - PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) - << getLangOpts().CPlusPlus11 << Ty << CT); - } + case VAK_Undefined: + DiagRuntimeBehavior( + E->getLocStart(), 0, + PDiag(diag::warn_cannot_pass_non_pod_arg_to_vararg) + << getLangOpts().CPlusPlus11 << Ty << CT); + break; + + case VAK_Invalid: + if (Ty->isObjCObjectType()) + DiagRuntimeBehavior( + E->getLocStart(), 0, + PDiag(diag::err_cannot_pass_objc_interface_to_vararg) + << Ty << CT); + else + Diag(E->getLocStart(), diag::err_cannot_pass_to_vararg) + << isa<InitListExpr>(E) << Ty << CT; + break; } - // c++ rules are enforced elsewhere. - return false; } /// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but @@ -805,7 +849,7 @@ ExprResult Sema::DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, // Diagnostics regarding non-POD argument types are // emitted along with format string checking in Sema::CheckFunctionCall(). - if (isValidVarArgType(E->getType()) == VAK_Invalid) { + if (isValidVarArgType(E->getType()) == VAK_Undefined) { // Turn this into a trap. CXXScopeSpec SS; SourceLocation TemplateKWLoc; @@ -1230,25 +1274,23 @@ Sema::ActOnGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - MultiTypeArg ArgTypes, - MultiExprArg ArgExprs) { + ArrayRef<ParsedType> ArgTypes, + ArrayRef<Expr *> ArgExprs) { unsigned NumAssocs = ArgTypes.size(); assert(NumAssocs == ArgExprs.size()); - ParsedType *ParsedTypes = ArgTypes.data(); - Expr **Exprs = ArgExprs.data(); - TypeSourceInfo **Types = new TypeSourceInfo*[NumAssocs]; for (unsigned i = 0; i < NumAssocs; ++i) { - if (ParsedTypes[i]) - (void) GetTypeFromParser(ParsedTypes[i], &Types[i]); + if (ArgTypes[i]) + (void) GetTypeFromParser(ArgTypes[i], &Types[i]); else Types[i] = 0; } ExprResult ER = CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc, - ControllingExpr, Types, Exprs, - NumAssocs); + ControllingExpr, + llvm::makeArrayRef(Types, NumAssocs), + ArgExprs); delete [] Types; return ER; } @@ -1258,9 +1300,10 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, - TypeSourceInfo **Types, - Expr **Exprs, - unsigned NumAssocs) { + ArrayRef<TypeSourceInfo *> Types, + ArrayRef<Expr *> Exprs) { + unsigned NumAssocs = Types.size(); + assert(NumAssocs == Exprs.size()); if (ControllingExpr->getType()->isPlaceholderType()) { ExprResult result = CheckPlaceholderExpr(ControllingExpr); if (result.isInvalid()) return ExprError(); @@ -1328,8 +1371,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, if (IsResultDependent) return Owned(new (Context) GenericSelectionExpr( Context, KeyLoc, ControllingExpr, - llvm::makeArrayRef(Types, NumAssocs), - llvm::makeArrayRef(Exprs, NumAssocs), + Types, Exprs, DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack)); SmallVector<unsigned, 1> CompatIndices; @@ -1352,7 +1394,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, Diag(ControllingExpr->getLocStart(), diag::err_generic_sel_multi_match) << ControllingExpr->getSourceRange() << ControllingExpr->getType() << (unsigned) CompatIndices.size(); - for (SmallVector<unsigned, 1>::iterator I = CompatIndices.begin(), + for (SmallVectorImpl<unsigned>::iterator I = CompatIndices.begin(), E = CompatIndices.end(); I != E; ++I) { Diag(Types[*I]->getTypeLoc().getBeginLoc(), diag::note_compat_assoc) @@ -1384,8 +1426,7 @@ Sema::CreateGenericSelectionExpr(SourceLocation KeyLoc, return Owned(new (Context) GenericSelectionExpr( Context, KeyLoc, ControllingExpr, - llvm::makeArrayRef(Types, NumAssocs), - llvm::makeArrayRef(Exprs, NumAssocs), + Types, Exprs, DefaultLoc, RParenLoc, ContainsUnexpandedParameterPack, ResultIndex)); } @@ -1421,7 +1462,8 @@ static ExprResult BuildCookedLiteralOperatorCall(Sema &S, Scope *Scope, LookupResult R(S, OpName, UDSuffixLoc, Sema::LookupOrdinaryName); if (S.LookupLiteralOperator(Scope, R, llvm::makeArrayRef(ArgTy, Args.size()), - /*AllowRawAndTemplate*/false) == Sema::LOLR_Error) + /*AllowRaw*/false, /*AllowTemplate*/false, + /*AllowStringTemplate*/false) == Sema::LOLR_Error) return ExprError(); return S.BuildLiteralOperatorCall(R, OpNameInfo, Args, LitEndLoc); @@ -1446,36 +1488,39 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks, for (unsigned i = 0; i != NumStringToks; ++i) StringTokLocs.push_back(StringToks[i].getLocation()); - QualType StrTy = Context.CharTy; - if (Literal.isWide()) - StrTy = Context.getWCharType(); - else if (Literal.isUTF16()) - StrTy = Context.Char16Ty; - else if (Literal.isUTF32()) - StrTy = Context.Char32Ty; - else if (Literal.isPascal()) - StrTy = Context.UnsignedCharTy; - + QualType CharTy = Context.CharTy; StringLiteral::StringKind Kind = StringLiteral::Ascii; - if (Literal.isWide()) + if (Literal.isWide()) { + CharTy = Context.getWideCharType(); Kind = StringLiteral::Wide; - else if (Literal.isUTF8()) + } else if (Literal.isUTF8()) { Kind = StringLiteral::UTF8; - else if (Literal.isUTF16()) + } else if (Literal.isUTF16()) { + CharTy = Context.Char16Ty; Kind = StringLiteral::UTF16; - else if (Literal.isUTF32()) + } else if (Literal.isUTF32()) { + CharTy = Context.Char32Ty; Kind = StringLiteral::UTF32; + } else if (Literal.isPascal()) { + CharTy = Context.UnsignedCharTy; + } + QualType CharTyConst = CharTy; // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings) - StrTy.addConst(); + CharTyConst.addConst(); // Get an array type for the string, according to C99 6.4.5. This includes // the nul terminator character as well as the string length for pascal // strings. - StrTy = Context.getConstantArrayType(StrTy, + QualType StrTy = Context.getConstantArrayType(CharTyConst, llvm::APInt(32, Literal.GetNumStringChars()+1), - ArrayType::Normal, 0); + ArrayType::Normal, 0); + + // OpenCL v1.1 s6.5.3: a string literal is in the constant address space. + if (getLangOpts().OpenCL) { + StrTy = Context.getAddrSpaceQualType(StrTy, LangAS::opencl_constant); + } // Pass &StringTokLocs[0], StringTokLocs.size() to factory! StringLiteral *Lit = StringLiteral::Create(Context, Literal.GetString(), @@ -1498,12 +1543,57 @@ Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks, // 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()); + + DeclarationName OpName = + Context.DeclarationNames.getCXXLiteralOperatorName(UDSuffix); + DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc); + OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc); + + QualType ArgTy[] = { + Context.getArrayDecayedType(StrTy), SizeType + }; + + LookupResult R(*this, OpName, UDSuffixLoc, LookupOrdinaryName); + switch (LookupLiteralOperator(UDLScope, R, ArgTy, + /*AllowRaw*/false, /*AllowTemplate*/false, + /*AllowStringTemplate*/true)) { + + case LOLR_Cooked: { + llvm::APInt Len(Context.getIntWidth(SizeType), Literal.GetNumStringChars()); + IntegerLiteral *LenArg = IntegerLiteral::Create(Context, Len, SizeType, + StringTokLocs[0]); + Expr *Args[] = { Lit, LenArg }; + + return BuildLiteralOperatorCall(R, OpNameInfo, Args, StringTokLocs.back()); + } + + case LOLR_StringTemplate: { + TemplateArgumentListInfo ExplicitArgs; + + unsigned CharBits = Context.getIntWidth(CharTy); + bool CharIsUnsigned = CharTy->isUnsignedIntegerType(); + llvm::APSInt Value(CharBits, CharIsUnsigned); + + TemplateArgument TypeArg(CharTy); + TemplateArgumentLocInfo TypeArgInfo(Context.getTrivialTypeSourceInfo(CharTy)); + ExplicitArgs.addArgument(TemplateArgumentLoc(TypeArg, TypeArgInfo)); + + for (unsigned I = 0, N = Lit->getLength(); I != N; ++I) { + Value = Lit->getCodeUnit(I); + TemplateArgument Arg(Context, Value, CharTy); + TemplateArgumentLocInfo ArgInfo; + ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo)); + } + return BuildLiteralOperatorCall(R, OpNameInfo, None, StringTokLocs.back(), + &ExplicitArgs); + } + case LOLR_Raw: + case LOLR_Template: + llvm_unreachable("unexpected literal operator lookup result"); + case LOLR_Error: + return ExprError(); + } + llvm_unreachable("unexpected literal operator lookup result"); } ExprResult @@ -1519,7 +1609,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, ExprResult Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, const DeclarationNameInfo &NameInfo, - const CXXScopeSpec *SS, NamedDecl *FoundD) { + const CXXScopeSpec *SS, NamedDecl *FoundD, + const TemplateArgumentListInfo *TemplateArgs) { if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) if (const FunctionDecl *Callee = dyn_cast<FunctionDecl>(D)) { @@ -1536,14 +1627,28 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, bool refersToEnclosingScope = (CurContext != D->getDeclContext() && - D->getDeclContext()->isFunctionOrMethod()); - - DeclRefExpr *E = DeclRefExpr::Create(Context, - SS ? SS->getWithLocInContext(Context) - : NestedNameSpecifierLoc(), - SourceLocation(), - D, refersToEnclosingScope, - NameInfo, Ty, VK, FoundD); + D->getDeclContext()->isFunctionOrMethod()) || + (isa<VarDecl>(D) && + cast<VarDecl>(D)->isInitCapture()); + + DeclRefExpr *E; + if (isa<VarTemplateSpecializationDecl>(D)) { + VarTemplateSpecializationDecl *VarSpec = + cast<VarTemplateSpecializationDecl>(D); + + E = DeclRefExpr::Create( + Context, + SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(), + VarSpec->getTemplateKeywordLoc(), D, refersToEnclosingScope, + NameInfo.getLoc(), Ty, VK, FoundD, TemplateArgs); + } else { + assert(!TemplateArgs && "No template arguments for non-variable" + " template specialization referrences"); + E = DeclRefExpr::Create( + Context, + SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(), + SourceLocation(), D, refersToEnclosingScope, NameInfo, Ty, VK, FoundD); + } MarkDeclRefReferenced(E); @@ -1553,7 +1658,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, E->getLocStart()); if (Level != DiagnosticsEngine::Ignored) - getCurFunction()->recordUseOfWeak(E); + recordUseOfEvaluatedWeak(E); } // Just in case we're building an illegal pointer-to-member. @@ -1602,7 +1707,7 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id, bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs, - llvm::ArrayRef<Expr *> Args) { + ArrayRef<Expr *> Args) { DeclarationName Name = R.getLookupName(); unsigned diagnostic = diag::err_undeclared_var_use; @@ -1722,10 +1827,14 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC))) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); + bool DroppedSpecifier = + Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; R.setLookupName(Corrected.getCorrection()); - if (NamedDecl *ND = Corrected.getCorrectionDecl()) { + bool AcceptableWithRecovery = false; + bool AcceptableWithoutRecovery = false; + NamedDecl *ND = Corrected.getCorrectionDecl(); + if (ND) { if (Corrected.isOverloaded()) { OverloadCandidateSet OCS(R.getNameLoc()); OverloadCandidateSet::iterator Best; @@ -1743,63 +1852,49 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, Args, OCS); } switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) { - case OR_Success: - ND = Best->Function; - break; - default: - break; + case OR_Success: + ND = Best->Function; + Corrected.setCorrectionDecl(ND); + break; + default: + // FIXME: Arbitrarily pick the first declaration for the note. + Corrected.setCorrectionDecl(ND); + break; } } R.addDecl(ND); - if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { - if (SS.isEmpty()) - Diag(R.getNameLoc(), diagnostic_suggest) << Name << CorrectedQuotedStr - << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr); - else - Diag(R.getNameLoc(), diag::err_no_member_suggest) - << Name << computeDeclContext(SS, false) << CorrectedQuotedStr - << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - unsigned diag = isa<ImplicitParamDecl>(ND) - ? diag::note_implicit_param_decl - : diag::note_previous_decl; - - Diag(ND->getLocation(), diag) - << CorrectedQuotedStr; - - // Tell the callee to try to recover. - return false; - } - - if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) { - // FIXME: If we ended up with a typo for a type name or - // Objective-C class name, we're in trouble because the parser - // is in the wrong place to recover. Suggest the typo - // correction, but don't make it a fix-it since we're not going - // to recover well anyway. - if (SS.isEmpty()) - Diag(R.getNameLoc(), diagnostic_suggest) - << Name << CorrectedQuotedStr; - else - Diag(R.getNameLoc(), diag::err_no_member_suggest) - << Name << computeDeclContext(SS, false) << CorrectedQuotedStr - << SS.getRange(); - - // Don't try to recover; it won't work. - return true; - } + AcceptableWithRecovery = + isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND); + // FIXME: If we ended up with a typo for a type name or + // Objective-C class name, we're in trouble because the parser + // is in the wrong place to recover. Suggest the typo + // correction, but don't make it a fix-it since we're not going + // to recover well anyway. + AcceptableWithoutRecovery = + isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); } else { // FIXME: We found a keyword. Suggest it, but don't provide a fix-it // because we aren't able to recover. + AcceptableWithoutRecovery = true; + } + + if (AcceptableWithRecovery || AcceptableWithoutRecovery) { + unsigned NoteID = (Corrected.getCorrectionDecl() && + isa<ImplicitParamDecl>(Corrected.getCorrectionDecl())) + ? diag::note_implicit_param_decl + : diag::note_previous_decl; if (SS.isEmpty()) - Diag(R.getNameLoc(), diagnostic_suggest) << Name << CorrectedQuotedStr; + diagnoseTypo(Corrected, PDiag(diagnostic_suggest) << Name, + PDiag(NoteID), AcceptableWithRecovery); else - Diag(R.getNameLoc(), diag::err_no_member_suggest) - << Name << computeDeclContext(SS, false) << CorrectedQuotedStr - << SS.getRange(); - return true; + diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) + << Name << computeDeclContext(SS, false) + << DroppedSpecifier << SS.getRange(), + PDiag(NoteID), AcceptableWithRecovery); + + // Tell the callee whether to try to recover. + return !AcceptableWithRecovery; } } R.clear(); @@ -1824,10 +1919,10 @@ ExprResult Sema::ActOnIdExpression(Scope *S, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, - CorrectionCandidateCallback *CCC) { + CorrectionCandidateCallback *CCC, + bool IsInlineAsmIdentifier) { assert(!(IsAddressOfOperand && HasTrailingLParen) && "cannot be direct & operand and have a trailing lparen"); - if (SS.isInvalid()) return ExprError(); @@ -1918,6 +2013,7 @@ ExprResult Sema::ActOnIdExpression(Scope *S, bool ADL = UseArgumentDependentLookup(SS, R, HasTrailingLParen); 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 && !getLangOpts().CPlusPlus) { @@ -1930,16 +2026,32 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (R.empty()) { // In Microsoft mode, if we are inside a template class member function // whose parent class has dependent base classes, 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 the type dependent base classes. + // an identifier, then assume the identifier is a member of a dependent + // base class. The goal is to postpone name lookup to instantiation time + // to be able to search into the type dependent base classes. + // FIXME: If we want 100% compatibility with MSVC, we will have delay all + // unqualified name lookup. Any name lookup during template parsing means + // clang might find something that MSVC doesn't. For now, we only handle + // the common case of members of a dependent base class. if (getLangOpts().MicrosoftMode) { CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext); - if (MD && MD->getParent()->hasAnyDependentBases()) - return ActOnDependentIdExpression(SS, TemplateKWLoc, NameInfo, - IsAddressOfOperand, TemplateArgs); + if (MD && MD->isInstance() && MD->getParent()->hasAnyDependentBases()) { + assert(SS.isEmpty() && "qualifiers should be already handled"); + QualType ThisType = MD->getThisType(Context); + // Since the 'this' expression is synthesized, we don't need to + // perform the double-lookup check. + NamedDecl *FirstQualifierInScope = 0; + return Owned(CXXDependentScopeMemberExpr::Create( + Context, /*This=*/0, ThisType, /*IsArrow=*/true, + /*Op=*/SourceLocation(), SS.getWithLocInContext(Context), + TemplateKWLoc, FirstQualifierInScope, NameInfo, TemplateArgs)); + } } + // Don't diagnose an empty lookup for inline assmebly. + if (IsInlineAsmIdentifier) + return ExprError(); + CorrectionCandidateCallback DefaultValidator; if (DiagnoseEmptyLookup(S, SS, R, CCC ? *CCC : DefaultValidator)) return ExprError(); @@ -2001,15 +2113,27 @@ ExprResult Sema::ActOnIdExpression(Scope *S, MightBeImplicitMember = true; else MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl()) || - isa<IndirectFieldDecl>(R.getFoundDecl()); + isa<IndirectFieldDecl>(R.getFoundDecl()) || + isa<MSPropertyDecl>(R.getFoundDecl()); if (MightBeImplicitMember) return BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs); } - if (TemplateArgs || TemplateKWLoc.isValid()) + if (TemplateArgs || TemplateKWLoc.isValid()) { + + // In C++1y, if this is a variable template id, then check it + // in BuildTemplateIdExpr(). + // The single lookup result must be a variable template declaration. + if (Id.getKind() == UnqualifiedId::IK_TemplateId && Id.TemplateId && + Id.TemplateId->Kind == TNK_Var_template) { + assert(R.getAsSingle<VarTemplateDecl>() && + "There should only be one declaration found."); + } + return BuildTemplateIdExpr(SS, TemplateKWLoc, R, ADL, TemplateArgs); + } return BuildDeclarationNameExpr(SS, R, ADL); } @@ -2139,6 +2263,14 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, return ExprError(); MarkAnyDeclReferenced(Loc, IV, true); + if (!IV->getBackingIvarReferencedInAccessor()) { + // Mark this ivar 'referenced' in this method, if it is a backing ivar + // of a property and current method is one of its property accessor. + const ObjCPropertyDecl *PDecl; + const ObjCIvarDecl *BIV = GetIvarBackingPropertyAccessor(CurMethod, PDecl); + if (BIV && BIV == IV) + IV->setBackingIvarReferencedInAccessor(true); + } ObjCMethodFamily MF = CurMethod->getMethodFamily(); if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize && @@ -2155,7 +2287,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S, DiagnosticsEngine::Level Level = Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, Loc); if (Level != DiagnosticsEngine::Ignored) - getCurFunction()->recordUseOfWeak(Result); + recordUseOfEvaluatedWeak(Result); } if (CurContext->isClosure()) Diag(Loc, diag::warn_implicitly_retains_self) @@ -2289,9 +2421,8 @@ Sema::PerformObjectMemberConversion(Expr *From, // x = 17; // error: ambiguous base subobjects // Derived1::x = 17; // okay, pick the Base subobject of Derived1 // } - if (Qualifier) { + if (Qualifier && Qualifier->getAsType()) { QualType QType = QualType(Qualifier->getAsType(), 0); - assert(!QType.isNull() && "lookup done with dependent qualifier?"); assert(QType->isRecordType() && "lookup done with non-record type"); QualType QRecordType = QualType(QType->getAs<RecordType>(), 0); @@ -2400,7 +2531,7 @@ bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, // turn off ADL anyway). if (isa<UsingShadowDecl>(D)) D = cast<UsingShadowDecl>(D)->getTargetDecl(); - else if (D->getDeclContext()->isFunctionOrMethod()) + else if (D->getLexicalDeclContext()->isFunctionOrMethod()) return false; // C++0x [basic.lookup.argdep]p3: @@ -2477,10 +2608,9 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, } /// \brief Complete semantic analysis for a reference to the given declaration. -ExprResult -Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, - const DeclarationNameInfo &NameInfo, - NamedDecl *D, NamedDecl *FoundD) { +ExprResult Sema::BuildDeclarationNameExpr( + const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl *D, + NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs) { assert(D && "Cannot refer to a NULL declaration"); assert(!isa<FunctionTemplateDecl>(D) && "Cannot refer unambiguously to a function template"); @@ -2492,8 +2622,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) { // Specifically diagnose references to class templates that are missing // a template argument list. - Diag(Loc, diag::err_template_decl_ref) - << Template << SS.getRange(); + Diag(Loc, diag::err_template_decl_ref) << (isa<VarTemplateDecl>(D) ? 1 : 0) + << Template << SS.getRange(); Diag(Template->getLocation(), diag::note_template_decl_here); return ExprError(); } @@ -2583,6 +2713,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, } case Decl::Var: + case Decl::VarTemplateSpecialization: + case Decl::VarTemplatePartialSpecialization: // In C, "extern void blah;" is valid and is an r-value. if (!getLangOpts().CPlusPlus && !type.hasQualifiers() && @@ -2680,32 +2812,23 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, break; } - return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS, FoundD); + return BuildDeclRefExpr(VD, type, valueKind, NameInfo, &SS, FoundD, + TemplateArgs); } } -ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { - PredefinedExpr::IdentType IT; - - switch (Kind) { - default: llvm_unreachable("Unknown simple primary expr!"); - case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2] - case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break; - case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break; - case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break; - } - - // Pre-defined identifiers are of type char[x], where x is the length of the - // string. - - Decl *currentDecl = getCurFunctionOrMethodDecl(); - // Blocks and lambdas can occur at global scope. Don't emit a warning. - if (!currentDecl) { - if (const BlockScopeInfo *BSI = getCurBlock()) - currentDecl = BSI->TheDecl; - else if (const LambdaScopeInfo *LSI = getCurLambda()) - currentDecl = LSI->CallOperator; - } +ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc, + PredefinedExpr::IdentType IT) { + // Pick the current block, lambda, captured statement or function. + Decl *currentDecl = 0; + if (const BlockScopeInfo *BSI = getCurBlock()) + currentDecl = BSI->TheDecl; + else if (const LambdaScopeInfo *LSI = getCurLambda()) + currentDecl = LSI->CallOperator; + else if (const CapturedRegionScopeInfo *CSI = getCurCapturedRegion()) + currentDecl = CSI->TheCapturedDecl; + else + currentDecl = getCurFunctionOrMethodDecl(); if (!currentDecl) { Diag(Loc, diag::ext_predef_outside_function); @@ -2713,21 +2836,39 @@ ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { } QualType ResTy; - if (cast<DeclContext>(currentDecl)->isDependentContext()) { + if (cast<DeclContext>(currentDecl)->isDependentContext()) ResTy = Context.DependentTy; - } else { + else { + // Pre-defined identifiers are of type char[x], where x is the length of + // the string. unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length(); llvm::APInt LengthI(32, Length + 1); if (IT == PredefinedExpr::LFunction) - ResTy = Context.WCharTy.withConst(); + ResTy = Context.WideCharTy.withConst(); else ResTy = Context.CharTy.withConst(); ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0); } + return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT)); } +ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) { + PredefinedExpr::IdentType IT; + + switch (Kind) { + default: llvm_unreachable("Unknown simple primary expr!"); + case tok::kw___func__: IT = PredefinedExpr::Func; break; // [C99 6.4.2.2] + case tok::kw___FUNCTION__: IT = PredefinedExpr::Function; break; + case tok::kw___FUNCDNAME__: IT = PredefinedExpr::FuncDName; break; // [MS] + case tok::kw_L__FUNCTION__: IT = PredefinedExpr::LFunction; break; + case tok::kw___PRETTY_FUNCTION__: IT = PredefinedExpr::PrettyFunction; break; + } + + return BuildPredefinedExpr(Loc, IT); +} + ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) { SmallString<16> CharBuffer; bool Invalid = false; @@ -2742,7 +2883,7 @@ ExprResult Sema::ActOnCharacterConstant(const Token &Tok, Scope *UDLScope) { QualType Ty; if (Literal.isWide()) - Ty = Context.WCharTy; // L'x' -> wchar_t in C and C++. + Ty = Context.WideCharTy; // L'x' -> wchar_t in C and C++. else if (Literal.isUTF16()) Ty = Context.Char16Ty; // u'x' -> char16_t in C11 and C++11. else if (Literal.isUTF32()) @@ -2872,11 +3013,14 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { DeclarationNameInfo OpNameInfo(OpName, UDSuffixLoc); OpNameInfo.setCXXLiteralOperatorNameLoc(UDSuffixLoc); + SourceLocation TokLoc = Tok.getLocation(); + // 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, CookedTy, - /*AllowRawAndTemplate*/true)) { + /*AllowRaw*/true, /*AllowTemplate*/true, + /*AllowStringTemplate*/false)) { case LOLR_Error: return ExprError(); @@ -2887,19 +3031,17 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } else { llvm::APInt ResultVal(Context.getTargetInfo().getLongLongWidth(), 0); if (Literal.GetIntegerValue(ResultVal)) - Diag(Tok.getLocation(), diag::warn_integer_too_large); + Diag(Tok.getLocation(), diag::err_integer_too_large); Lit = IntegerLiteral::Create(Context, ResultVal, CookedTy, Tok.getLocation()); } - return BuildLiteralOperatorCall(R, OpNameInfo, Lit, - Tok.getLocation()); + return BuildLiteralOperatorCall(R, OpNameInfo, Lit, TokLoc); } 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.withConst(), llvm::APInt(32, Length + 1), @@ -2910,7 +3052,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { return BuildLiteralOperatorCall(R, OpNameInfo, Lit, TokLoc); } - case LOLR_Template: + 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'>() @@ -2925,11 +3067,12 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { TemplateArgumentLocInfo ArgInfo; ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo)); } - return BuildLiteralOperatorCall(R, OpNameInfo, None, Tok.getLocation(), + return BuildLiteralOperatorCall(R, OpNameInfo, None, TokLoc, &ExplicitArgs); } - - llvm_unreachable("unexpected literal operator lookup result"); + case LOLR_StringTemplate: + llvm_unreachable("unexpected literal operator lookup result"); + } } Expr *Res; @@ -2980,8 +3123,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { llvm::APInt ResultVal(MaxWidth, 0); if (Literal.GetIntegerValue(ResultVal)) { - // If this value didn't fit into uintmax_t, warn and force to ull. - Diag(Tok.getLocation(), diag::warn_integer_too_large); + // If this value didn't fit into uintmax_t, error and force to ull. + Diag(Tok.getLocation(), diag::err_integer_too_large); Ty = Context.UnsignedLongLongTy; assert(Context.getTypeSize(Ty) == ResultVal.getBitWidth() && "long long is not intmax_t?"); @@ -3103,6 +3246,10 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T, SourceLocation Loc, SourceRange ArgRange, UnaryExprOrTypeTrait TraitKind) { + // Invalid types must be hard errors for SFINAE in C++. + if (S.LangOpts.CPlusPlus) + return true; + // C99 6.5.3.4p1: if (T->isFunctionType() && (TraitKind == UETT_SizeOf || TraitKind == UETT_AlignOf)) { @@ -3185,6 +3332,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E, ExprTy = E->getType(); assert(!ExprTy->isReferenceType()); + if (ExprTy->isFunctionType()) { + Diag(E->getExprLoc(), diag::err_sizeof_alignof_function_type) + << ExprKind << E->getSourceRange(); + return true; + } + if (CheckObjCTraitOperandConstraints(*this, ExprTy, E->getExprLoc(), E->getSourceRange(), ExprKind)) return true; @@ -3258,6 +3411,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType, ExprKind, ExprRange)) return true; + if (ExprType->isFunctionType()) { + Diag(OpLoc, diag::err_sizeof_alignof_function_type) + << ExprKind << ExprRange; + return true; + } + if (CheckObjCTraitOperandConstraints(*this, ExprType, OpLoc, ExprRange, ExprKind)) return true; @@ -3487,7 +3646,8 @@ static bool checkArithmeticOnObjCPointer(Sema &S, SourceLocation opLoc, Expr *op) { assert(op->getType()->isObjCObjectPointerType()); - if (S.LangOpts.ObjCRuntime.allowsPointerArithmetic()) + if (S.LangOpts.ObjCRuntime.allowsPointerArithmetic() && + !S.LangOpts.ObjCSubscriptingLegacyRuntime) return false; S.Diag(opLoc, diag::err_arithmetic_nonfragile_interface) @@ -3592,15 +3752,10 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, // Use custom logic if this should be the pseudo-object subscript // expression. - if (!LangOpts.ObjCRuntime.isSubscriptPointerArithmetic()) + if (!LangOpts.isSubscriptPointerArithmetic()) return BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, 0, 0); ResultType = PTy->getPointeeType(); - if (!LangOpts.ObjCRuntime.allowsPointerArithmetic()) { - Diag(LLoc, diag::err_subscript_nonfragile_interface) - << ResultType << BaseExpr->getSourceRange(); - return ExprError(); - } } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) { // Handle the uncommon case of "123[Ptr]". BaseExpr = RHSExp; @@ -3612,7 +3767,7 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, BaseExpr = RHSExp; IndexExpr = LHSExp; ResultType = PTy->getPointeeType(); - if (!LangOpts.ObjCRuntime.allowsPointerArithmetic()) { + if (!LangOpts.isSubscriptPointerArithmetic()) { Diag(LLoc, diag::err_subscript_nonfragile_interface) << ResultType << BaseExpr->getSourceRange(); return ExprError(); @@ -3720,7 +3875,7 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, InstantiatingTemplate Inst(*this, CallLoc, Param, MutiLevelArgList.getInnermost()); - if (Inst) + if (Inst.isInvalid()) return ExprError(); ExprResult Result; @@ -3795,12 +3950,71 @@ Sema::getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(FDecl)) if (Method->isInstance()) return VariadicMethod; - } + } else if (Fn && Fn->getType() == Context.BoundMemberTy) + return VariadicMethod; return VariadicFunction; } return VariadicDoesNotApply; } +namespace { +class FunctionCallCCC : public FunctionCallFilterCCC { +public: + FunctionCallCCC(Sema &SemaRef, const IdentifierInfo *FuncName, + unsigned NumArgs, bool HasExplicitTemplateArgs) + : FunctionCallFilterCCC(SemaRef, NumArgs, HasExplicitTemplateArgs), + FunctionName(FuncName) {} + + virtual bool ValidateCandidate(const TypoCorrection &candidate) { + if (!candidate.getCorrectionSpecifier() || + candidate.getCorrectionAsIdentifierInfo() != FunctionName) { + return false; + } + + return FunctionCallFilterCCC::ValidateCandidate(candidate); + } + +private: + const IdentifierInfo *const FunctionName; +}; +} + +static TypoCorrection TryTypoCorrectionForCall(Sema &S, + DeclarationNameInfo FuncName, + ArrayRef<Expr *> Args) { + FunctionCallCCC CCC(S, FuncName.getName().getAsIdentifierInfo(), + Args.size(), false); + if (TypoCorrection Corrected = + S.CorrectTypo(FuncName, Sema::LookupOrdinaryName, + S.getScopeForContext(S.CurContext), NULL, CCC)) { + if (NamedDecl *ND = Corrected.getCorrectionDecl()) { + if (Corrected.isOverloaded()) { + OverloadCandidateSet OCS(FuncName.getLoc()); + OverloadCandidateSet::iterator Best; + for (TypoCorrection::decl_iterator CD = Corrected.begin(), + CDEnd = Corrected.end(); + CD != CDEnd; ++CD) { + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*CD)) + S.AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none), Args, + OCS); + } + switch (OCS.BestViableFunction(S, FuncName.getLoc(), Best)) { + case OR_Success: + ND = Best->Function; + Corrected.setCorrectionDecl(ND); + break; + default: + break; + } + } + if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { + return Corrected; + } + } + } + return TypoCorrection(); +} + /// ConvertArgumentsForCall - Converts the arguments specified in /// Args/NumArgs to the parameter types of the function FDecl with /// function prototype Proto. Call is the call expression itself, and @@ -3811,7 +4025,7 @@ bool Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, FunctionDecl *FDecl, const FunctionProtoType *Proto, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RParenLoc, bool IsExecConfig) { // Bail out early if calling a builtin with custom typechecking. @@ -3833,9 +4047,23 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, // If too few arguments are available (and we don't have default // arguments for the remaining parameters), don't make the call. - if (NumArgs < NumArgsInProto) { - if (NumArgs < MinArgs) { - if (MinArgs == 1 && FDecl && FDecl->getParamDecl(0)->getDeclName()) + if (Args.size() < NumArgsInProto) { + if (Args.size() < MinArgs) { + MemberExpr *ME = dyn_cast<MemberExpr>(Fn); + TypoCorrection TC; + if (FDecl && (TC = TryTypoCorrectionForCall( + *this, DeclarationNameInfo(FDecl->getDeclName(), + (ME ? ME->getMemberLoc() + : Fn->getLocStart())), + Args))) { + unsigned diag_id = + MinArgs == NumArgsInProto && !Proto->isVariadic() + ? diag::err_typecheck_call_too_few_args_suggest + : diag::err_typecheck_call_too_few_args_at_least_suggest; + diagnoseTypo(TC, PDiag(diag_id) << FnKind << MinArgs + << static_cast<unsigned>(Args.size()) + << Fn->getSourceRange()); + } else if (MinArgs == 1 && FDecl && FDecl->getParamDecl(0)->getDeclName()) Diag(RParenLoc, MinArgs == NumArgsInProto && !Proto->isVariadic() ? diag::err_typecheck_call_too_few_args_one : diag::err_typecheck_call_too_few_args_at_least_one) @@ -3846,10 +4074,11 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, ? diag::err_typecheck_call_too_few_args : diag::err_typecheck_call_too_few_args_at_least) << FnKind - << MinArgs << NumArgs << Fn->getSourceRange(); + << MinArgs << static_cast<unsigned>(Args.size()) + << Fn->getSourceRange(); // Emit the location of the prototype. - if (FDecl && !FDecl->getBuiltinID() && !IsExecConfig) + if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig) Diag(FDecl->getLocStart(), diag::note_callee_decl) << FDecl; @@ -3860,29 +4089,44 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, // If too many are passed and not variadic, error on the extras and drop // them. - if (NumArgs > NumArgsInProto) { + if (Args.size() > NumArgsInProto) { if (!Proto->isVariadic()) { - if (NumArgsInProto == 1 && FDecl && FDecl->getParamDecl(0)->getDeclName()) + TypoCorrection TC; + if (FDecl && (TC = TryTypoCorrectionForCall( + *this, DeclarationNameInfo(FDecl->getDeclName(), + Fn->getLocStart()), + Args))) { + unsigned diag_id = + MinArgs == NumArgsInProto && !Proto->isVariadic() + ? diag::err_typecheck_call_too_many_args_suggest + : diag::err_typecheck_call_too_many_args_at_most_suggest; + diagnoseTypo(TC, PDiag(diag_id) << FnKind << NumArgsInProto + << static_cast<unsigned>(Args.size()) + << Fn->getSourceRange()); + } else if (NumArgsInProto == 1 && FDecl && + FDecl->getParamDecl(0)->getDeclName()) Diag(Args[NumArgsInProto]->getLocStart(), MinArgs == NumArgsInProto ? diag::err_typecheck_call_too_many_args_one : diag::err_typecheck_call_too_many_args_at_most_one) << FnKind - << FDecl->getParamDecl(0) << NumArgs << Fn->getSourceRange() + << FDecl->getParamDecl(0) << static_cast<unsigned>(Args.size()) + << Fn->getSourceRange() << SourceRange(Args[NumArgsInProto]->getLocStart(), - Args[NumArgs-1]->getLocEnd()); + Args.back()->getLocEnd()); else Diag(Args[NumArgsInProto]->getLocStart(), MinArgs == NumArgsInProto ? diag::err_typecheck_call_too_many_args : diag::err_typecheck_call_too_many_args_at_most) << FnKind - << NumArgsInProto << NumArgs << Fn->getSourceRange() + << NumArgsInProto << static_cast<unsigned>(Args.size()) + << Fn->getSourceRange() << SourceRange(Args[NumArgsInProto]->getLocStart(), - Args[NumArgs-1]->getLocEnd()); + Args.back()->getLocEnd()); // Emit the location of the prototype. - if (FDecl && !FDecl->getBuiltinID() && !IsExecConfig) + if (!TC && FDecl && !FDecl->getBuiltinID() && !IsExecConfig) Diag(FDecl->getLocStart(), diag::note_callee_decl) << FDecl; @@ -3895,7 +4139,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, VariadicCallType CallType = getVariadicCallType(FDecl, Proto, Fn); Invalid = GatherArgumentsForCall(Call->getLocStart(), FDecl, - Proto, 0, Args, NumArgs, AllArgs, CallType); + Proto, 0, Args, AllArgs, CallType); if (Invalid) return true; unsigned TotalNumArgs = AllArgs.size(); @@ -3909,15 +4153,15 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, const FunctionProtoType *Proto, unsigned FirstProtoArg, - Expr **Args, unsigned NumArgs, - SmallVector<Expr *, 8> &AllArgs, + ArrayRef<Expr *> Args, + SmallVectorImpl<Expr *> &AllArgs, VariadicCallType CallType, bool AllowExplicit, bool IsListInitialization) { unsigned NumArgsInProto = Proto->getNumArgs(); - unsigned NumArgsToCheck = NumArgs; + unsigned NumArgsToCheck = Args.size(); bool Invalid = false; - if (NumArgs != NumArgsInProto) + if (Args.size() != NumArgsInProto) // Use default arguments for missing arguments NumArgsToCheck = NumArgsInProto; unsigned ArgIx = 0; @@ -3927,7 +4171,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, Expr *Arg; ParmVarDecl *Param; - if (ArgIx < NumArgs) { + if (ArgIx < Args.size()) { Arg = Args[ArgIx++]; if (RequireCompleteType(Arg->getLocStart(), @@ -3941,15 +4185,25 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, Param = FDecl->getParamDecl(i); // Strip the unbridged-cast placeholder expression off, if applicable. + bool CFAudited = false; if (Arg->getType() == Context.ARCUnbridgedCastTy && FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() && (!Param || !Param->hasAttr<CFConsumedAttr>())) Arg = stripARCUnbridgedCast(Arg); + else if (getLangOpts().ObjCAutoRefCount && + FDecl && FDecl->hasAttr<CFAuditedTransferAttr>() && + (!Param || !Param->hasAttr<CFConsumedAttr>())) + CFAudited = true; InitializedEntity Entity = Param ? InitializedEntity::InitializeParameter(Context, Param, ProtoArgType) : InitializedEntity::InitializeParameter(Context, ProtoArgType, Proto->isArgConsumed(i)); + + // Remember that parameter belongs to a CF audited API. + if (CFAudited) + Entity.setParameterCFAudited(); + ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(), Owned(Arg), @@ -3988,7 +4242,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, // return __unknown_anytype aren't *really* variadic. if (Proto->getResultType() == Context.UnknownAnyTy && FDecl && FDecl->isExternC()) { - for (unsigned i = ArgIx; i != NumArgs; ++i) { + for (unsigned i = ArgIx, e = Args.size(); i != e; ++i) { QualType paramType; // ignored ExprResult arg = checkUnknownAnyArg(CallLoc, Args[i], paramType); Invalid |= arg.isInvalid(); @@ -3997,7 +4251,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, // Otherwise do argument promotion, (C99 6.5.2.2p7). } else { - for (unsigned i = ArgIx; i != NumArgs; ++i) { + for (unsigned i = ArgIx, e = Args.size(); i != e; ++i) { ExprResult Arg = DefaultVariadicArgumentPromotion(Args[i], CallType, FDecl); Invalid |= Arg.isInvalid(); @@ -4006,7 +4260,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, } // Check for array bounds violations. - for (unsigned i = ArgIx; i != NumArgs; ++i) + for (unsigned i = ArgIx, e = Args.size(); i != e; ++i) CheckArrayAccess(Args[i]); } return Invalid; @@ -4014,6 +4268,8 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, static void DiagnoseCalleeStaticArrayParam(Sema &S, ParmVarDecl *PVD) { TypeLoc TL = PVD->getTypeSourceInfo()->getTypeLoc(); + if (DecayedTypeLoc DTL = TL.getAs<DecayedTypeLoc>()) + TL = DTL.getOriginalLoc(); if (ArrayTypeLoc ATL = TL.getAs<ArrayTypeLoc>()) S.Diag(PVD->getLocation(), diag::note_callee_static_array) << ATL.getLocalSourceRange(); @@ -4188,8 +4444,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, // Determine whether this is a call to an object (C++ [over.call.object]). if (Fn->getType()->isRecordType()) return Owned(BuildCallToObjectOfClassType(S, Fn, LParenLoc, - ArgExprs.data(), - ArgExprs.size(), RParenLoc)); + ArgExprs, RParenLoc)); if (Fn->getType() == Context.UnknownAnyTy) { ExprResult result = rebuildUnknownAnyFunction(*this, Fn); @@ -4198,8 +4453,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, } if (Fn->getType() == Context.BoundMemberTy) { - return BuildCallToMemberFunction(S, Fn, LParenLoc, ArgExprs.data(), - ArgExprs.size(), RParenLoc); + return BuildCallToMemberFunction(S, Fn, LParenLoc, ArgExprs, RParenLoc); } } @@ -4212,11 +4466,11 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, OverloadExpr *ovl = find.Expression; if (isa<UnresolvedLookupExpr>(ovl)) { UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(ovl); - return BuildOverloadedCallExpr(S, Fn, ULE, LParenLoc, ArgExprs.data(), - ArgExprs.size(), RParenLoc, ExecConfig); + return BuildOverloadedCallExpr(S, Fn, ULE, LParenLoc, ArgExprs, + RParenLoc, ExecConfig); } else { - return BuildCallToMemberFunction(S, Fn, LParenLoc, ArgExprs.data(), - ArgExprs.size(), RParenLoc); + return BuildCallToMemberFunction(S, Fn, LParenLoc, ArgExprs, + RParenLoc); } } } @@ -4240,9 +4494,8 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, else if (isa<MemberExpr>(NakedFn)) NDecl = cast<MemberExpr>(NakedFn)->getMemberDecl(); - return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs.data(), - ArgExprs.size(), RParenLoc, ExecConfig, - IsExecConfig); + return BuildResolvedCallExpr(Fn, NDecl, LParenLoc, ArgExprs, RParenLoc, + ExecConfig, IsExecConfig); } ExprResult @@ -4283,6 +4536,19 @@ ExprResult Sema::ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, RParenLoc)); } +/// ActOnConvertVectorExpr - create a new convert-vector expression from the +/// provided arguments. +/// +/// __builtin_convertvector( value, dst type ) +/// +ExprResult Sema::ActOnConvertVectorExpr(Expr *E, ParsedType ParsedDestTy, + SourceLocation BuiltinLoc, + SourceLocation RParenLoc) { + TypeSourceInfo *TInfo; + GetTypeFromParser(ParsedDestTy, &TInfo); + return SemaConvertVectorExpr(E, TInfo, BuiltinLoc, RParenLoc); +} + /// BuildResolvedCallExpr - Build a call to a resolved expression, /// i.e. an expression not of \p OverloadTy. The expression should /// unary-convert to an expression of function-pointer or @@ -4292,7 +4558,7 @@ ExprResult Sema::ActOnAsTypeExpr(Expr *E, ParsedType ParsedDestTy, ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, SourceLocation RParenLoc, Expr *Config, bool IsExecConfig) { FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(NDecl); @@ -4318,17 +4584,12 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, CallExpr *TheCall; if (Config) TheCall = new (Context) CUDAKernelCallExpr(Context, Fn, - cast<CallExpr>(Config), - llvm::makeArrayRef(Args,NumArgs), - Context.BoolTy, - VK_RValue, + cast<CallExpr>(Config), Args, + Context.BoolTy, VK_RValue, RParenLoc); else - TheCall = new (Context) CallExpr(Context, Fn, - llvm::makeArrayRef(Args, NumArgs), - Context.BoolTy, - VK_RValue, - RParenLoc); + TheCall = new (Context) CallExpr(Context, Fn, Args, Context.BoolTy, + VK_RValue, RParenLoc); // Bail out early if calling a builtin with custom typechecking. if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID)) @@ -4391,8 +4652,8 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT); if (Proto) { - if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs, - RParenLoc, IsExecConfig)) + if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, RParenLoc, + IsExecConfig)) return ExprError(); } else { assert(isa<FunctionNoProtoType>(FuncT) && "Unknown FunctionType!"); @@ -4401,11 +4662,11 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // Check if we have too few/too many template arguments, based // on our knowledge of the function definition. const FunctionDecl *Def = 0; - if (FDecl->hasBody(Def) && NumArgs != Def->param_size()) { + if (FDecl->hasBody(Def) && Args.size() != Def->param_size()) { Proto = Def->getType()->getAs<FunctionProtoType>(); - if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) + if (!Proto || !(Proto->isVariadic() && Args.size() >= Def->param_size())) Diag(RParenLoc, diag::warn_call_wrong_number_of_arguments) - << (NumArgs > Def->param_size()) << FDecl << Fn->getSourceRange(); + << (Args.size() > Def->param_size()) << FDecl << Fn->getSourceRange(); } // If the function we're calling isn't a function prototype, but we have @@ -4415,7 +4676,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, } // Promote the arguments (C99 6.5.2.2p6). - for (unsigned i = 0; i != NumArgs; i++) { + for (unsigned i = 0, e = Args.size(); i != e; i++) { Expr *Arg = Args[i]; if (Proto && i < Proto->getNumArgs()) { @@ -4456,7 +4717,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // Check for sentinels if (NDecl) - DiagnoseSentinelCalls(NDecl, LParenLoc, Args, NumArgs); + DiagnoseSentinelCalls(NDecl, LParenLoc, Args); // Do special checking on direct calls to functions. if (FDecl) { @@ -4466,7 +4727,10 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, if (BuiltinID) return CheckBuiltinFunctionCall(BuiltinID, TheCall); } else if (NDecl) { - if (CheckBlockCall(NDecl, TheCall, Proto)) + if (CheckPointerCall(NDecl, TheCall, Proto)) + return ExprError(); + } else { + if (CheckOtherCall(TheCall, Proto)) return ExprError(); } @@ -4476,7 +4740,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, ExprResult Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty, SourceLocation RParenLoc, Expr *InitExpr) { - assert((Ty != 0) && "ActOnCompoundLiteral(): missing type"); + assert(Ty && "ActOnCompoundLiteral(): missing type"); // FIXME: put back this assert when initializers are worked out. //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression"); @@ -4522,7 +4786,10 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, LiteralExpr = Result.get(); bool isFileScope = getCurFunctionOrMethodDecl() == 0; - if (isFileScope) { // 6.5.2.5p3 + if (isFileScope && + !LiteralExpr->isTypeDependent() && + !LiteralExpr->isValueDependent() && + !literalType->isDependentType()) { // 6.5.2.5p3 if (CheckForConstantInitializer(LiteralExpr, literalType)) return ExprError(); } @@ -5108,9 +5375,11 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, QualType lhptee, rhptee; // Get the pointee types. + bool IsBlockPointer = false; if (const BlockPointerType *LHSBTy = LHSTy->getAs<BlockPointerType>()) { lhptee = LHSBTy->getPointeeType(); rhptee = RHSTy->castAs<BlockPointerType>()->getPointeeType(); + IsBlockPointer = true; } else { lhptee = LHSTy->castAs<PointerType>()->getPointeeType(); rhptee = RHSTy->castAs<PointerType>()->getPointeeType(); @@ -5152,7 +5421,10 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS, // The pointer types are compatible. QualType ResultTy = CompositeTy.withCVRQualifiers(MergedCVRQual); - ResultTy = S.Context.getPointerType(ResultTy); + if (IsBlockPointer) + ResultTy = S.Context.getBlockPointerType(ResultTy); + else + ResultTy = S.Context.getPointerType(ResultTy); LHS = S.ImpCastExprToType(LHS.take(), ResultTy, CK_BitCast); RHS = S.ImpCastExprToType(RHS.take(), ResultTy, CK_BitCast); @@ -5266,28 +5538,26 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, VK = VK_RValue; OK = OK_Ordinary; + // First, check the condition. Cond = UsualUnaryConversions(Cond.take()); if (Cond.isInvalid()) return QualType(); - LHS = UsualUnaryConversions(LHS.take()); - if (LHS.isInvalid()) + if (checkCondition(*this, Cond.get())) return QualType(); - RHS = UsualUnaryConversions(RHS.take()); - if (RHS.isInvalid()) + + // Now check the two expressions. + if (LHS.get()->getType()->isVectorType() || + RHS.get()->getType()->isVectorType()) + return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); + + UsualArithmeticConversions(LHS, RHS); + if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); QualType CondTy = Cond.get()->getType(); QualType LHSTy = LHS.get()->getType(); QualType RHSTy = RHS.get()->getType(); - // first, check the condition. - if (checkCondition(*this, Cond.get())) - return QualType(); - - // Now check the two expressions. - if (LHSTy->isVectorType() || RHSTy->isVectorType()) - return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); - // 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. (OpenCL v1.1 s6.3.i) @@ -5297,12 +5567,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // If both operands have arithmetic type, do the usual arithmetic conversions // to find a common type: C99 6.5.15p3,5. - if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) { - UsualArithmeticConversions(LHS, RHS); - if (LHS.isInvalid() || RHS.isInvalid()) - return QualType(); + if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) return LHS.get()->getType(); - } // If both operands are the same structure or union type, the result is that // type. @@ -5638,7 +5904,14 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, Expr *commonExpr = 0; if (LHSExpr == 0) { commonExpr = CondExpr; - + // Lower out placeholder types first. This is important so that we don't + // try to capture a placeholder. This happens in few cases in C++; such + // as Objective-C++'s dictionary subscripting syntax. + if (commonExpr->hasPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(commonExpr); + if (!result.isUsable()) return ExprError(); + commonExpr = result.take(); + } // We usually want to apply unary conversions *before* saving, except // in the special case of a C++ l-value conditional. if (!(getLangOpts().CPlusPlus @@ -6248,7 +6521,8 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Sema::AssignConvertType Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, - bool Diagnose) { + bool Diagnose, + bool DiagnoseCFAudited) { if (getLangOpts().CPlusPlus) { if (!LHSType->isRecordType() && !LHSType->isAtomicType()) { // C++ 5.17p3: If the left operand is not of class type, the @@ -6290,12 +6564,14 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, // C99 6.5.16.1p1: the left operand is a pointer and the right is // a null pointer constant. - if ((LHSType->isPointerType() || - LHSType->isObjCObjectPointerType() || - LHSType->isBlockPointerType()) - && RHS.get()->isNullPointerConstant(Context, - Expr::NPC_ValueDependentIsNull)) { - RHS = ImpCastExprToType(RHS.take(), LHSType, CK_NullToPointer); + if ((LHSType->isPointerType() || LHSType->isObjCObjectPointerType() || + LHSType->isBlockPointerType()) && + RHS.get()->isNullPointerConstant(Context, + Expr::NPC_ValueDependentIsNull)) { + CastKind Kind; + CXXCastPath Path; + CheckPointerConversion(RHS.get(), LHSType, Kind, Path, false); + RHS = ImpCastExprToType(RHS.take(), LHSType, Kind, VK_RValue, &Path); return Compatible; } @@ -6321,9 +6597,14 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, // so that we can use references in built-in functions even in C. // The getNonReferenceType() call makes sure that the resulting expression // does not have reference type. - if (result != Incompatible && RHS.get()->getType() != LHSType) - RHS = ImpCastExprToType(RHS.take(), - LHSType.getNonLValueExprType(Context), Kind); + if (result != Incompatible && RHS.get()->getType() != LHSType) { + QualType Ty = LHSType.getNonLValueExprType(Context); + Expr *E = RHS.take(); + if (getLangOpts().ObjCAutoRefCount) + CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion, + DiagnoseCFAudited); + RHS = ImpCastExprToType(E, Ty, Kind); + } return result; } @@ -6402,12 +6683,19 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, return LHSType; } } - if (EltTy->isRealFloatingType() && RHSType->isScalarType() && - RHSType->isRealFloatingType()) { - int order = Context.getFloatingTypeOrder(EltTy, RHSType); - if (order > 0) - RHS = ImpCastExprToType(RHS.take(), EltTy, CK_FloatingCast); - if (order >= 0) { + if (EltTy->isRealFloatingType() && RHSType->isScalarType()) { + if (RHSType->isRealFloatingType()) { + int order = Context.getFloatingTypeOrder(EltTy, RHSType); + if (order > 0) + RHS = ImpCastExprToType(RHS.take(), EltTy, CK_FloatingCast); + if (order >= 0) { + RHS = ImpCastExprToType(RHS.take(), LHSType, CK_VectorSplat); + if (swapped) std::swap(RHS, LHS); + return LHSType; + } + } + if (RHSType->isIntegralType(Context)) { + RHS = ImpCastExprToType(RHS.take(), EltTy, CK_IntegralToFloating); RHS = ImpCastExprToType(RHS.take(), LHSType, CK_VectorSplat); if (swapped) std::swap(RHS, LHS); return LHSType; @@ -6480,11 +6768,12 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, return InvalidOperands(Loc, LHS, RHS); // Check for division by zero. - if (IsDiv && - RHS.get()->isNullPointerConstant(Context, - Expr::NPC_ValueDependentIsNotNull)) - DiagRuntimeBehavior(Loc, RHS.get(), PDiag(diag::warn_division_by_zero) - << RHS.get()->getSourceRange()); + llvm::APSInt RHSValue; + if (IsDiv && !RHS.get()->isValueDependent() && + RHS.get()->EvaluateAsInt(RHSValue, Context) && RHSValue == 0) + DiagRuntimeBehavior(Loc, RHS.get(), + PDiag(diag::warn_division_by_zero) + << RHS.get()->getSourceRange()); return compType; } @@ -6509,10 +6798,12 @@ QualType Sema::CheckRemainderOperands( return InvalidOperands(Loc, LHS, RHS); // Check for remainder by zero. - if (RHS.get()->isNullPointerConstant(Context, - Expr::NPC_ValueDependentIsNotNull)) - DiagRuntimeBehavior(Loc, RHS.get(), PDiag(diag::warn_remainder_by_zero) - << RHS.get()->getSourceRange()); + llvm::APSInt RHSValue; + if (!RHS.get()->isValueDependent() && + RHS.get()->EvaluateAsInt(RHSValue, Context) && RHSValue == 0) + DiagRuntimeBehavior(Loc, RHS.get(), + PDiag(diag::warn_remainder_by_zero) + << RHS.get()->getSourceRange()); return compType; } @@ -6685,12 +6976,63 @@ static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc, // 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) + Self.Diag(OpLoc, diag::note_string_plus_scalar_silence) << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&") << FixItHint::CreateReplacement(SourceRange(OpLoc), "[") << FixItHint::CreateInsertion(EndLoc, "]"); } else - Self.Diag(OpLoc, diag::note_string_plus_int_silence); + Self.Diag(OpLoc, diag::note_string_plus_scalar_silence); +} + +/// \brief Emit a warning when adding a char literal to a string. +static void diagnoseStringPlusChar(Sema &Self, SourceLocation OpLoc, + Expr *LHSExpr, Expr *RHSExpr) { + const DeclRefExpr *StringRefExpr = + dyn_cast<DeclRefExpr>(LHSExpr->IgnoreImpCasts()); + const CharacterLiteral *CharExpr = + dyn_cast<CharacterLiteral>(RHSExpr->IgnoreImpCasts()); + if (!StringRefExpr) { + StringRefExpr = dyn_cast<DeclRefExpr>(RHSExpr->IgnoreImpCasts()); + CharExpr = dyn_cast<CharacterLiteral>(LHSExpr->IgnoreImpCasts()); + } + + if (!CharExpr || !StringRefExpr) + return; + + const QualType StringType = StringRefExpr->getType(); + + // Return if not a PointerType. + if (!StringType->isAnyPointerType()) + return; + + // Return if not a CharacterType. + if (!StringType->getPointeeType()->isAnyCharacterType()) + return; + + ASTContext &Ctx = Self.getASTContext(); + SourceRange DiagRange(LHSExpr->getLocStart(), RHSExpr->getLocEnd()); + + const QualType CharType = CharExpr->getType(); + if (!CharType->isAnyCharacterType() && + CharType->isIntegerType() && + llvm::isUIntN(Ctx.getCharWidth(), CharExpr->getValue())) { + Self.Diag(OpLoc, diag::warn_string_plus_char) + << DiagRange << Ctx.CharTy; + } else { + Self.Diag(OpLoc, diag::warn_string_plus_char) + << DiagRange << CharExpr->getType(); + } + + // Only print a fixit for str + char, not for char + str. + if (isa<CharacterLiteral>(RHSExpr->IgnoreImpCasts())) { + SourceLocation EndLoc = Self.PP.getLocForEndOfToken(RHSExpr->getLocEnd()); + Self.Diag(OpLoc, diag::note_string_plus_scalar_silence) + << FixItHint::CreateInsertion(LHSExpr->getLocStart(), "&") + << FixItHint::CreateReplacement(SourceRange(OpLoc), "[") + << FixItHint::CreateInsertion(EndLoc, "]"); + } else { + Self.Diag(OpLoc, diag::note_string_plus_scalar_silence); + } } /// \brief Emit error when two pointers are incompatible. @@ -6719,9 +7061,11 @@ QualType Sema::CheckAdditionOperands( // C99 6.5.6 if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); - // Diagnose "string literal" '+' int. - if (Opc == BO_Add) + // Diagnose "string literal" '+' int and string '+' "char literal". + if (Opc == BO_Add) { diagnoseStringPlusInt(*this, Loc, LHS.get(), RHS.get()); + diagnoseStringPlusChar(*this, Loc, LHS.get(), RHS.get()); + } // handle the common case first (both operands are arithmetic). if (!compType.isNull() && compType->isArithmeticType()) { @@ -6846,6 +7190,18 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, LHS.get(), RHS.get())) return QualType(); + // The pointee type may have zero size. As an extension, a structure or + // union may have zero size or an array may have zero length. In this + // case subtraction does not make sense. + if (!rpointee->isVoidType() && !rpointee->isFunctionType()) { + CharUnits ElementSize = Context.getTypeSizeInChars(rpointee); + if (ElementSize.isZero()) { + Diag(Loc,diag::warn_sub_ptr_zero_size_types) + << rpointee.getUnqualifiedType() + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + } + } + if (CompLHSTy) *CompLHSTy = LHS.get()->getType(); return Context.getPointerDiffType(); } @@ -7234,6 +7590,65 @@ static void diagnoseObjCLiteralComparison(Sema &S, SourceLocation Loc, } } +static void diagnoseLogicalNotOnLHSofComparison(Sema &S, ExprResult &LHS, + ExprResult &RHS, + SourceLocation Loc, + unsigned OpaqueOpc) { + // This checking requires bools. + if (!S.getLangOpts().Bool) return; + + // Check that left hand side is !something. + UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS.get()->IgnoreImpCasts()); + if (!UO || UO->getOpcode() != UO_LNot) return; + + // Only check if the right hand side is non-bool arithmetic type. + if (RHS.get()->getType()->isBooleanType()) return; + + // Make sure that the something in !something is not bool. + Expr *SubExpr = UO->getSubExpr()->IgnoreImpCasts(); + if (SubExpr->getType()->isBooleanType()) return; + + // Emit warning. + S.Diag(UO->getOperatorLoc(), diag::warn_logical_not_on_lhs_of_comparison) + << Loc; + + // First note suggest !(x < y) + SourceLocation FirstOpen = SubExpr->getLocStart(); + SourceLocation FirstClose = RHS.get()->getLocEnd(); + FirstClose = S.getPreprocessor().getLocForEndOfToken(FirstClose); + if (FirstClose.isInvalid()) + FirstOpen = SourceLocation(); + S.Diag(UO->getOperatorLoc(), diag::note_logical_not_fix) + << FixItHint::CreateInsertion(FirstOpen, "(") + << FixItHint::CreateInsertion(FirstClose, ")"); + + // Second note suggests (!x) < y + SourceLocation SecondOpen = LHS.get()->getLocStart(); + SourceLocation SecondClose = LHS.get()->getLocEnd(); + SecondClose = S.getPreprocessor().getLocForEndOfToken(SecondClose); + if (SecondClose.isInvalid()) + SecondOpen = SourceLocation(); + S.Diag(UO->getOperatorLoc(), diag::note_logical_not_silence_with_parens) + << FixItHint::CreateInsertion(SecondOpen, "(") + << FixItHint::CreateInsertion(SecondClose, ")"); +} + +// Get the decl for a simple expression: a reference to a variable, +// an implicit C++ field reference, or an implicit ObjC ivar reference. +static ValueDecl *getCompareDecl(Expr *E) { + if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E)) + return DR->getDecl(); + if (ObjCIvarRefExpr* Ivar = dyn_cast<ObjCIvarRefExpr>(E)) { + if (Ivar->isFreeIvar()) + return Ivar->getDecl(); + } + if (MemberExpr* Mem = dyn_cast<MemberExpr>(E)) { + if (Mem->isImplicitAccess()) + return Mem->getMemberDecl(); + } + return 0; +} + // C99 6.5.8, C++ [expr.rel] QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned OpaqueOpc, @@ -7254,11 +7669,13 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, Expr *RHSStripped = RHS.get()->IgnoreParenImpCasts(); checkEnumComparison(*this, Loc, LHS.get(), RHS.get()); + diagnoseLogicalNotOnLHSofComparison(*this, LHS, RHS, Loc, OpaqueOpc); if (!LHSType->hasFloatingRepresentation() && !(LHSType->isBlockPointerType() && IsRelational) && !LHS.get()->getLocStart().isMacroID() && - !RHS.get()->getLocStart().isMacroID()) { + !RHS.get()->getLocStart().isMacroID() && + ActiveTemplateInstantiations.empty()) { // For non-floating point types, check for self-comparisons of the form // x == x, x != x, x < x, etc. These always evaluate to a constant, and // often indicate logic errors in the program. @@ -7269,37 +7686,34 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, // obvious cases in the definition of the template anyways. The idea is to // warn when the typed comparison operator will always evaluate to the same // result. - if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LHSStripped)) { - if (DeclRefExpr* DRR = dyn_cast<DeclRefExpr>(RHSStripped)) { - if (DRL->getDecl() == DRR->getDecl() && - !IsWithinTemplateSpecialization(DRL->getDecl())) { - DiagRuntimeBehavior(Loc, 0, PDiag(diag::warn_comparison_always) - << 0 // self- - << (Opc == BO_EQ - || Opc == BO_LE - || Opc == BO_GE)); - } else if (LHSType->isArrayType() && RHSType->isArrayType() && - !DRL->getDecl()->getType()->isReferenceType() && - !DRR->getDecl()->getType()->isReferenceType()) { - // what is it always going to eval to? - char always_evals_to; - switch(Opc) { - case BO_EQ: // e.g. array1 == array2 - always_evals_to = 0; // false - break; - case BO_NE: // e.g. array1 != array2 - always_evals_to = 1; // true - break; - default: - // best we can say is 'a constant' - always_evals_to = 2; // e.g. array1 <= array2 - break; - } - DiagRuntimeBehavior(Loc, 0, PDiag(diag::warn_comparison_always) - << 1 // array - << always_evals_to); + ValueDecl *DL = getCompareDecl(LHSStripped); + ValueDecl *DR = getCompareDecl(RHSStripped); + if (DL && DR && DL == DR && !IsWithinTemplateSpecialization(DL)) { + DiagRuntimeBehavior(Loc, 0, PDiag(diag::warn_comparison_always) + << 0 // self- + << (Opc == BO_EQ + || Opc == BO_LE + || Opc == BO_GE)); + } else if (DL && DR && LHSType->isArrayType() && RHSType->isArrayType() && + !DL->getType()->isReferenceType() && + !DR->getType()->isReferenceType()) { + // what is it always going to eval to? + char always_evals_to; + switch(Opc) { + case BO_EQ: // e.g. array1 == array2 + always_evals_to = 0; // false + break; + case BO_NE: // e.g. array1 != array2 + always_evals_to = 1; // true + break; + default: + // best we can say is 'a constant' + always_evals_to = 2; // e.g. array1 <= array2 + break; } - } + DiagRuntimeBehavior(Loc, 0, PDiag(diag::warn_comparison_always) + << 1 // array + << always_evals_to); } if (isa<CastExpr>(LHSStripped)) @@ -7333,21 +7747,9 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, } // C99 6.5.8p3 / C99 6.5.9p4 - if (LHS.get()->getType()->isArithmeticType() && - RHS.get()->getType()->isArithmeticType()) { - UsualArithmeticConversions(LHS, RHS); - if (LHS.isInvalid() || RHS.isInvalid()) - return QualType(); - } - else { - LHS = UsualUnaryConversions(LHS.take()); - if (LHS.isInvalid()) - return QualType(); - - RHS = UsualUnaryConversions(RHS.take()); - if (RHS.isInvalid()) - return QualType(); - } + UsualArithmeticConversions(LHS, RHS); + if (LHS.isInvalid() || RHS.isInvalid()) + return QualType(); LHSType = LHS.get()->getType(); RHSType = RHS.get()->getType(); @@ -7534,12 +7936,20 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS, diagnoseDistinctPointerComparison(*this, Loc, LHS, RHS, /*isError*/false); } - if (LHSIsNull && !RHSIsNull) - LHS = ImpCastExprToType(LHS.take(), RHSType, + if (LHSIsNull && !RHSIsNull) { + Expr *E = LHS.take(); + if (getLangOpts().ObjCAutoRefCount) + CheckObjCARCConversion(SourceRange(), RHSType, E, CCK_ImplicitConversion); + LHS = ImpCastExprToType(E, RHSType, RPT ? CK_BitCast :CK_CPointerToObjCPointerCast); - else - RHS = ImpCastExprToType(RHS.take(), LHSType, + } + else { + Expr *E = RHS.take(); + if (getLangOpts().ObjCAutoRefCount) + CheckObjCARCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion); + RHS = ImpCastExprToType(E, LHSType, LPT ? CK_BitCast :CK_CPointerToObjCPointerCast); + } return ResultTy; } if (LHSType->isObjCObjectPointerType() && @@ -7651,7 +8061,8 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, // For non-floating point types, check for self-comparisons of the form // 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 (!LHSType->hasFloatingRepresentation() && + ActiveTemplateInstantiations.empty()) { if (DeclRefExpr* DRL = dyn_cast<DeclRefExpr>(LHS.get()->IgnoreParenImpCasts())) if (DeclRefExpr* DRR @@ -7806,28 +8217,6 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] return Context.BoolTy; } -/// IsReadonlyProperty - Verify that otherwise a valid l-value expression -/// is a read-only property; return true if so. A readonly property expression -/// depends on various declarations and thus must be treated specially. -/// -static bool IsReadonlyProperty(Expr *E, Sema &S) { - const ObjCPropertyRefExpr *PropExpr = dyn_cast<ObjCPropertyRefExpr>(E); - if (!PropExpr) return false; - if (PropExpr->isImplicitProperty()) return false; - - 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 IsReadonlyMessage(Expr *E, Sema &S) { const MemberExpr *ME = dyn_cast<MemberExpr>(E); if (!ME) return false; @@ -7858,9 +8247,14 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) { 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()) + DeclContext *DC = S.CurContext, *Prev = 0; + while (DC != var->getDeclContext()) { + Prev = DC; DC = DC->getParent(); + } + // Unless we have an init-capture, we've gone one step too far. + if (!var->isInitCapture()) + DC = Prev; return (isa<BlockDecl>(DC) ? NCCK_Block : NCCK_Lambda); } @@ -7871,9 +8265,7 @@ static bool CheckForModifiableLvalue(Expr *E, SourceLocation Loc, Sema &S) { 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 (IsLV == Expr::MLV_ClassTemporary && IsReadonlyMessage(E, S)) + if (IsLV == Expr::MLV_ClassTemporary && IsReadonlyMessage(E, S)) IsLV = Expr::MLV_InvalidMessageExpression; if (IsLV == Expr::MLV_Valid) return false; @@ -7956,7 +8348,6 @@ 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_ReadonlyProperty: case Expr::MLV_NoSetterProperty: llvm_unreachable("readonly properties should be processed differently"); case Expr::MLV_InvalidMessageExpression: @@ -8163,6 +8554,10 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, } // Increment of bool sets it to true, but is deprecated. S.Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange(); + } else if (S.getLangOpts().CPlusPlus && ResType->isEnumeralType()) { + // Error on enum increments and decrements in C++ mode + S.Diag(OpLoc, diag::err_increment_decrement_enum) << IsInc << ResType; + return QualType(); } else if (ResType->isRealType()) { // OK! } else if (ResType->isPointerType()) { @@ -8186,6 +8581,9 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, IsInc, IsPrefix); } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) { // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 ) + } else if(S.getLangOpts().OpenCL && ResType->isVectorType() && + ResType->getAs<VectorType>()->getElementType()->isIntegerType()) { + // OpenCL V1.2 6.3 says dec/inc ops operate on integer vector types. } else { S.Diag(OpLoc, diag::err_typecheck_illegal_increment_decrement) << ResType << int(IsInc) << Op->getSourceRange(); @@ -8289,43 +8687,50 @@ 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, ExprResult &OrigOp, - SourceLocation OpLoc) { +QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { if (const BuiltinType *PTy = OrigOp.get()->getType()->getAsPlaceholderType()){ if (PTy->getKind() == BuiltinType::Overload) { - if (!isa<OverloadExpr>(OrigOp.get()->IgnoreParens())) { - assert(cast<UnaryOperator>(OrigOp.get()->IgnoreParens())->getOpcode() - == UO_AddrOf); - S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof_addrof_function) + Expr *E = OrigOp.get()->IgnoreParens(); + if (!isa<OverloadExpr>(E)) { + assert(cast<UnaryOperator>(E)->getOpcode() == UO_AddrOf); + Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof_addrof_function) << OrigOp.get()->getSourceRange(); return QualType(); } - - return S.Context.OverloadTy; + + OverloadExpr *Ovl = cast<OverloadExpr>(E); + if (isa<UnresolvedMemberExpr>(Ovl)) + if (!ResolveSingleFunctionTemplateSpecialization(Ovl)) { + Diag(OpLoc, diag::err_invalid_form_pointer_member_function) + << OrigOp.get()->getSourceRange(); + return QualType(); + } + + return Context.OverloadTy; } if (PTy->getKind() == BuiltinType::UnknownAny) - return S.Context.UnknownAnyTy; + return Context.UnknownAnyTy; if (PTy->getKind() == BuiltinType::BoundMember) { - S.Diag(OpLoc, diag::err_invalid_form_pointer_member_function) + Diag(OpLoc, diag::err_invalid_form_pointer_member_function) << OrigOp.get()->getSourceRange(); return QualType(); } - OrigOp = S.CheckPlaceholderExpr(OrigOp.take()); + OrigOp = CheckPlaceholderExpr(OrigOp.take()); if (OrigOp.isInvalid()) return QualType(); } if (OrigOp.get()->isTypeDependent()) - return S.Context.DependentTy; + return Context.DependentTy; assert(!OrigOp.get()->getType()->isPlaceholderType()); // Make sure to ignore parentheses in subsequent checks Expr *op = OrigOp.get()->IgnoreParens(); - if (S.getLangOpts().C99) { + if (getLangOpts().C99) { // Implement C99-only parts of addressof rules. if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) { if (uOp->getOpcode() == UO_Deref) @@ -8337,28 +8742,28 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, // expressions here, but the result of one is always an lvalue anyway. } ValueDecl *dcl = getPrimaryDecl(op); - Expr::LValueClassification lval = op->ClassifyLValue(S.Context); + Expr::LValueClassification lval = op->ClassifyLValue(Context); unsigned AddressOfError = AO_No_Error; if (lval == Expr::LV_ClassTemporary || lval == Expr::LV_ArrayTemporary) { - bool sfinae = (bool)S.isSFINAEContext(); - S.Diag(OpLoc, S.isSFINAEContext() ? diag::err_typecheck_addrof_temporary - : diag::ext_typecheck_addrof_temporary) + bool sfinae = (bool)isSFINAEContext(); + Diag(OpLoc, isSFINAEContext() ? diag::err_typecheck_addrof_temporary + : diag::ext_typecheck_addrof_temporary) << op->getType() << op->getSourceRange(); if (sfinae) return QualType(); // Materialize the temporary as an lvalue so that we can take its address. - OrigOp = op = new (S.Context) - MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true); + OrigOp = op = new (Context) + MaterializeTemporaryExpr(op->getType(), OrigOp.take(), true, 0); } else if (isa<ObjCSelectorExpr>(op)) { - return S.Context.getPointerType(op->getType()); + return Context.getPointerType(op->getType()); } else if (lval == Expr::LV_MemberFunction) { // If it's an instance method, make a member pointer. // The expression must have exactly the form &A::foo. // 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) + Diag(OpLoc, diag::err_invalid_form_pointer_member_function) << OrigOp.get()->getSourceRange(); return QualType(); } @@ -8367,25 +8772,29 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, // The id-expression was parenthesized. if (OrigOp.get() != DRE) { - S.Diag(OpLoc, diag::err_parens_pointer_member_function) + Diag(OpLoc, diag::err_parens_pointer_member_function) << OrigOp.get()->getSourceRange(); // The method was named without a qualifier. } else if (!DRE->getQualifier()) { if (MD->getParent()->getName().empty()) - S.Diag(OpLoc, diag::err_unqualified_pointer_member_function) + Diag(OpLoc, diag::err_unqualified_pointer_member_function) << op->getSourceRange(); else { SmallString<32> Str; StringRef Qual = (MD->getParent()->getName() + "::").toStringRef(Str); - S.Diag(OpLoc, diag::err_unqualified_pointer_member_function) + Diag(OpLoc, diag::err_unqualified_pointer_member_function) << op->getSourceRange() << FixItHint::CreateInsertion(op->getSourceRange().getBegin(), Qual); } } - return S.Context.getMemberPointerType(op->getType(), - S.Context.getTypeDeclType(MD->getParent()).getTypePtr()); + // Taking the address of a dtor is illegal per C++ [class.dtor]p2. + if (isa<CXXDestructorDecl>(MD)) + Diag(OpLoc, diag::err_typecheck_addrof_dtor) << op->getSourceRange(); + + return Context.getMemberPointerType(op->getType(), + Context.getTypeDeclType(MD->getParent()).getTypePtr()); } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) { // C99 6.5.3.2p1 // The operand must be either an l-value or a function designator @@ -8394,7 +8803,7 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, if (isa<PseudoObjectExpr>(op)) { AddressOfError = AO_Property_Expansion; } else { - S.Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) + Diag(OpLoc, diag::err_typecheck_invalid_lvalue_addrof) << op->getType() << op->getSourceRange(); return QualType(); } @@ -8412,11 +8821,11 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &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.getLangOpts().CPlusPlus) { + !getLangOpts().CPlusPlus) { AddressOfError = AO_Register_Variable; } } else if (isa<FunctionTemplateDecl>(dcl)) { - return S.Context.OverloadTy; + return Context.OverloadTy; } else if (isa<FieldDecl>(dcl) || isa<IndirectFieldDecl>(dcl)) { // Okay: we can take the address of a field. // Could be a pointer to member, though, if there is an explicit @@ -8425,16 +8834,16 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, DeclContext *Ctx = dcl->getDeclContext(); if (Ctx && Ctx->isRecord()) { if (dcl->getType()->isReferenceType()) { - S.Diag(OpLoc, - diag::err_cannot_form_pointer_to_member_of_reference_type) + Diag(OpLoc, + diag::err_cannot_form_pointer_to_member_of_reference_type) << dcl->getDeclName() << dcl->getType(); return QualType(); } while (cast<RecordDecl>(Ctx)->isAnonymousStructOrUnion()) Ctx = Ctx->getParent(); - return S.Context.getMemberPointerType(op->getType(), - S.Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr()); + return Context.getMemberPointerType(op->getType(), + Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr()); } } } else if (!isa<FunctionDecl>(dcl) && !isa<NonTypeTemplateParmDecl>(dcl)) @@ -8442,7 +8851,7 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, } if (AddressOfError != AO_No_Error) { - diagnoseAddressOfInvalidType(S, OpLoc, op, AddressOfError); + diagnoseAddressOfInvalidType(*this, OpLoc, op, AddressOfError); return QualType(); } @@ -8450,13 +8859,13 @@ static QualType CheckAddressOfOperand(Sema &S, ExprResult &OrigOp, // Taking the address of a void variable is technically illegal, but we // allow it in cases which are otherwise valid. // Example: "extern void x; void* y = &x;". - S.Diag(OpLoc, diag::ext_typecheck_addrof_void) << op->getSourceRange(); + Diag(OpLoc, diag::ext_typecheck_addrof_void) << op->getSourceRange(); } // If the operand has type "type", the result has type "pointer to type". if (op->getType()->isObjCObjectType()) - return S.Context.getObjCObjectPointerType(op->getType()); - return S.Context.getPointerType(op->getType()); + return Context.getObjCObjectPointerType(op->getType()); + return Context.getPointerType(op->getType()); } /// CheckIndirectionOperand - Type check unary indirection (prefix '*'). @@ -8630,7 +9039,20 @@ static void checkObjCPointerIntrospection(Sema &S, ExprResult &L, ExprResult &R, // looks for code trying to introspect into tagged pointers, which // code should generally never do. if (ObjCPointerExpr && isa<IntegerLiteral>(OtherExpr->IgnoreParenCasts())) { - S.Diag(OpLoc, diag::warn_objc_pointer_masking) + unsigned Diag = diag::warn_objc_pointer_masking; + // Determine if we are introspecting the result of performSelectorXXX. + const Expr *Ex = ObjCPointerExpr->IgnoreParenCasts(); + // Special case messages to -performSelector and friends, which + // can return non-pointer values boxed in a pointer value. + // Some clients may wish to silence warnings in this subcase. + if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(Ex)) { + Selector S = ME->getSelector(); + StringRef SelArg0 = S.getNameForSlot(0); + if (SelArg0.startswith("performSelector")) + Diag = diag::warn_objc_pointer_masking_performSelector; + } + + S.Diag(OpLoc, Diag) << ObjCPointerExpr->getSourceRange(); } } @@ -9149,7 +9571,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, Opc == UO_PreDec); break; case UO_AddrOf: - resultType = CheckAddressOfOperand(*this, Input, OpLoc); + resultType = CheckAddressOfOperand(Input, OpLoc); break; case UO_Deref: { Input = DefaultFunctionArrayLvalueConversion(Input.take()); @@ -9167,9 +9589,6 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, if (resultType->isArithmeticType() || // C99 6.5.3.3p1 resultType->isVectorType()) break; - else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6-7 - resultType->isEnumeralType()) - break; else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6 Opc == UO_Plus && resultType->isPointerType()) @@ -9392,7 +9811,7 @@ ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo". ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, LabelDecl *TheDecl) { - TheDecl->setUsed(); + TheDecl->markUsed(Context); // Create the AST node. The address of a label always has type 'void*'. return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl, Context.getPointerType(Context.VoidTy))); @@ -9657,9 +10076,15 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, // If the member was found in a base class, introduce OffsetOfNodes for // the base class indirections. - CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, - /*DetectVirtual=*/false); + CXXBasePaths Paths; if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) { + if (Paths.getDetectedVirtual()) { + Diag(OC.LocEnd, diag::err_offsetof_field_of_virtual_base) + << MemberDecl->getDeclName() + << SourceRange(BuiltinLoc, RParenLoc); + return ExprError(); + } + CXXBasePath &Path = Paths.front(); for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end(); B != BEnd; ++B) @@ -9715,6 +10140,7 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, ExprObjectKind OK = OK_Ordinary; QualType resType; bool ValueDependent = false; + bool CondIsTrue = false; if (CondExpr->isTypeDependent() || CondExpr->isValueDependent()) { resType = Context.DependentTy; ValueDependent = true; @@ -9727,9 +10153,10 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, if (CondICE.isInvalid()) return ExprError(); CondExpr = CondICE.take(); + CondIsTrue = condEval.getZExtValue(); // If the condition is > zero, then the AST type is the same as the LSHExpr. - Expr *ActiveExpr = condEval.getZExtValue() ? LHSExpr : RHSExpr; + Expr *ActiveExpr = CondIsTrue ? LHSExpr : RHSExpr; resType = ActiveExpr->getType(); ValueDependent = ActiveExpr->isValueDependent(); @@ -9738,7 +10165,7 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, } return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, - resType, VK, OK, RPLoc, + resType, VK, OK, RPLoc, CondIsTrue, resType->isDependentType(), ValueDependent)); } @@ -9750,6 +10177,17 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, /// ActOnBlockStart - This callback is invoked when a block literal is started. void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) { BlockDecl *Block = BlockDecl::Create(Context, CurContext, CaretLoc); + + if (LangOpts.CPlusPlus) { + Decl *ManglingContextDecl; + if (MangleNumberingContext *MCtx = + getCurrentMangleNumberContext(Block->getDeclContext(), + ManglingContextDecl)) { + unsigned ManglingNumber = MCtx->getManglingNumber(Block); + Block->setBlockMangling(ManglingNumber, ManglingContextDecl); + } + } + PushBlockScope(CurScope, Block); CurContext->addDecl(Block); if (CurScope) @@ -9822,13 +10260,6 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, CurBlock->TheDecl->setIsVariadic(isVariadic); - // Don't allow returning a objc interface by value. - if (RetTy->isObjCObjectType()) { - Diag(ParamInfo.getLocStart(), - diag::err_object_cannot_be_passed_returned_by_value) << 0 << RetTy; - return; - } - // Context.DependentTy is used as a placeholder for a missing block // return type. TODO: what should we do with declarators like: // ^ * { ... } @@ -9876,11 +10307,7 @@ void Sema::ActOnBlockArguments(SourceLocation CaretLoc, Declarator &ParamInfo, // Finally we can process decl attributes. ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo); - // Put the parameter variables in scope. We can bail out immediately - // if we don't have any. - if (Params.empty()) - return; - + // Put the parameter variables in scope. for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(), E = CurBlock->TheDecl->param_end(); AI != E; ++AI) { (*AI)->setOwningFunction(CurBlock->TheDecl); @@ -9942,7 +10369,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, if (Cap.isThisCapture()) continue; BlockDecl::Capture NewCap(Cap.getVariable(), Cap.isBlockCapture(), - Cap.isNested(), Cap.getCopyExpr()); + Cap.isNested(), Cap.getInitExpr()); Captures.push_back(NewCap); } BSI->TheDecl->setCaptures(Context, Captures.begin(), Captures.end(), @@ -9973,11 +10400,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.TypeQuals = 0; // FIXME: silently? EPI.ExtInfo = Ext; - BlockTy = - Context.getFunctionType(RetTy, - ArrayRef<QualType>(FPT->arg_type_begin(), - FPT->getNumArgs()), - EPI); + BlockTy = Context.getFunctionType(RetTy, FPT->getArgTypes(), EPI); } // If we don't have a function type, just build one from nothing. @@ -10007,7 +10430,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, computeNRVO(Body, getCurBlock()); BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy); - const AnalysisBasedWarnings::Policy &WP = AnalysisWarnings.getDefaultPolicy(); + AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result); // If the block isn't obviously global, i.e. it captures anything at @@ -10145,7 +10568,8 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) { } static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, - Expr *SrcExpr, FixItHint &Hint) { + Expr *SrcExpr, FixItHint &Hint, + bool &IsNSString) { if (!SemaRef.getLangOpts().ObjC1) return; @@ -10159,6 +10583,7 @@ static void MakeObjCStringLiteralFixItHint(Sema& SemaRef, QualType DstType, const ObjCInterfaceDecl *ID = PT->getInterfaceDecl(); if (!ID || !ID->getIdentifier()->isStr("NSString")) return; + IsNSString = true; } // Ignore any parens, implicit casts (should only be @@ -10192,6 +10617,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, ConversionFixItGenerator ConvHints; bool MayHaveConvFixit = false; bool MayHaveFunctionDiff = false; + bool IsNSString = false; switch (ConvTy) { case Compatible: @@ -10209,8 +10635,11 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, MayHaveConvFixit = true; break; case IncompatiblePointer: - MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint); - DiagKind = diag::ext_typecheck_convert_incompatible_pointer; + MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString); + DiagKind = + (Action == AA_Passing_CFAudited ? + diag::err_arc_typecheck_convert_incompatible_pointer : + diag::ext_typecheck_convert_incompatible_pointer); CheckInferredResultType = DstType->isObjCObjectPointerType() && SrcType->isObjCObjectPointerType(); if (Hint.isNull() && !CheckInferredResultType) { @@ -10220,6 +10649,8 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, SrcType = SrcType.getUnqualifiedType(); DstType = DstType.getUnqualifiedType(); } + else if (IsNSString && !Hint.isNull()) + DiagKind = diag::warn_missing_atsign_prefix; MayHaveConvFixit = true; break; case IncompatiblePointerSign: @@ -10302,6 +10733,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, case AA_Returning: case AA_Passing: + case AA_Passing_CFAudited: case AA_Converting: case AA_Sending: case AA_Casting: @@ -10312,7 +10744,10 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, } PartialDiagnostic FDiag = PDiag(DiagKind); - FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange(); + if (Action == AA_Passing_CFAudited) + FDiag << FirstType << SecondType << SrcExpr->getSourceRange(); + else + FDiag << FirstType << SecondType << Action << SrcExpr->getSourceRange(); // If we can fix the conversion, suggest the FixIts. assert(ConvHints.isNull() || Hint.isNull()); @@ -10394,112 +10829,52 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, // have a single non-explicit conversion function to an integral or // unscoped enumeration type ExprResult Converted; - if (!Diagnoser.Suppress) { - class CXX11ConvertDiagnoser : public ICEConvertDiagnoser { - public: - CXX11ConvertDiagnoser() : ICEConvertDiagnoser(false, true) { } - - virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, - QualType T) { - return S.Diag(Loc, diag::err_ice_not_integral) << T; - } - - virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, - SourceLocation Loc, - QualType T) { - return S.Diag(Loc, diag::err_ice_incomplete_type) << T; - } - - virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S, - SourceLocation Loc, - QualType T, - QualType ConvTy) { - return S.Diag(Loc, diag::err_ice_explicit_conversion) << T << ConvTy; - } - - virtual DiagnosticBuilder noteExplicitConv(Sema &S, - CXXConversionDecl *Conv, - QualType ConvTy) { - return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here) - << ConvTy->isEnumeralType() << ConvTy; - } - - virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, - QualType T) { - return S.Diag(Loc, diag::err_ice_ambiguous_conversion) << T; - } - - virtual DiagnosticBuilder noteAmbiguous(Sema &S, - CXXConversionDecl *Conv, - QualType ConvTy) { - return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here) - << ConvTy->isEnumeralType() << ConvTy; - } - - virtual DiagnosticBuilder diagnoseConversion(Sema &S, - SourceLocation Loc, - QualType T, - QualType ConvTy) { - return DiagnosticBuilder::getEmpty(); - } - } ConvertDiagnoser; + class CXX11ConvertDiagnoser : public ICEConvertDiagnoser { + public: + CXX11ConvertDiagnoser(bool Silent) + : ICEConvertDiagnoser(/*AllowScopedEnumerations*/false, + Silent, true) {} + + virtual SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, + QualType T) { + return S.Diag(Loc, diag::err_ice_not_integral) << T; + } - Converted = ConvertToIntegralOrEnumerationType(DiagLoc, E, - ConvertDiagnoser, - /*AllowScopedEnumerations*/ false); - } else { - // The caller wants to silently enquire whether this is an ICE. Don't - // produce any diagnostics if it isn't. - class SilentICEConvertDiagnoser : public ICEConvertDiagnoser { - public: - SilentICEConvertDiagnoser() : ICEConvertDiagnoser(true, true) { } - - virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, - QualType T) { - return DiagnosticBuilder::getEmpty(); - } - - virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, - SourceLocation Loc, - QualType T) { - return DiagnosticBuilder::getEmpty(); - } - - virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S, - SourceLocation Loc, - QualType T, - QualType ConvTy) { - return DiagnosticBuilder::getEmpty(); - } - - virtual DiagnosticBuilder noteExplicitConv(Sema &S, - CXXConversionDecl *Conv, - QualType ConvTy) { - return DiagnosticBuilder::getEmpty(); - } - - virtual DiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, - QualType T) { - return DiagnosticBuilder::getEmpty(); - } - - virtual DiagnosticBuilder noteAmbiguous(Sema &S, - CXXConversionDecl *Conv, - QualType ConvTy) { - return DiagnosticBuilder::getEmpty(); - } - - virtual DiagnosticBuilder diagnoseConversion(Sema &S, - SourceLocation Loc, - QualType T, - QualType ConvTy) { - return DiagnosticBuilder::getEmpty(); - } - } ConvertDiagnoser; - - Converted = ConvertToIntegralOrEnumerationType(DiagLoc, E, - ConvertDiagnoser, false); - } + virtual SemaDiagnosticBuilder diagnoseIncomplete( + Sema &S, SourceLocation Loc, QualType T) { + return S.Diag(Loc, diag::err_ice_incomplete_type) << T; + } + + virtual SemaDiagnosticBuilder diagnoseExplicitConv( + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) { + return S.Diag(Loc, diag::err_ice_explicit_conversion) << T << ConvTy; + } + + virtual SemaDiagnosticBuilder noteExplicitConv( + Sema &S, CXXConversionDecl *Conv, QualType ConvTy) { + return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here) + << ConvTy->isEnumeralType() << ConvTy; + } + + virtual SemaDiagnosticBuilder diagnoseAmbiguous( + Sema &S, SourceLocation Loc, QualType T) { + return S.Diag(Loc, diag::err_ice_ambiguous_conversion) << T; + } + + virtual SemaDiagnosticBuilder noteAmbiguous( + Sema &S, CXXConversionDecl *Conv, QualType ConvTy) { + return S.Diag(Conv->getLocation(), diag::note_ice_conversion_here) + << ConvTy->isEnumeralType() << ConvTy; + } + + virtual SemaDiagnosticBuilder diagnoseConversion( + Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) { + llvm_unreachable("conversion functions are permitted"); + } + } ConvertDiagnoser(Diagnoser.Suppress); + + Converted = PerformContextualImplicitConversion(DiagLoc, E, + ConvertDiagnoser); if (Converted.isInvalid()) return Converted; E = Converted.take(); @@ -10647,21 +11022,30 @@ void Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, ReuseLambdaContextDecl_t, bool IsDecltype) { - Decl *LambdaContextDecl = ExprEvalContexts.back().LambdaContextDecl; - PushExpressionEvaluationContext(NewContext, LambdaContextDecl, IsDecltype); + Decl *ClosureContextDecl = ExprEvalContexts.back().ManglingContextDecl; + PushExpressionEvaluationContext(NewContext, ClosureContextDecl, IsDecltype); } void Sema::PopExpressionEvaluationContext() { ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); if (!Rec.Lambdas.empty()) { - if (Rec.isUnevaluated()) { - // C++11 [expr.prim.lambda]p2: - // A lambda-expression shall not appear in an unevaluated operand - // (Clause 5). + if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) { + unsigned D; + if (Rec.isUnevaluated()) { + // C++11 [expr.prim.lambda]p2: + // A lambda-expression shall not appear in an unevaluated operand + // (Clause 5). + D = diag::err_lambda_unevaluated_operand; + } else { + // C++1y [expr.const]p2: + // A conditional-expression e is a core constant expression unless the + // evaluation of e, following the rules of the abstract machine, would + // evaluate [...] a lambda-expression. + D = diag::err_lambda_in_constant_expression; + } for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I) - Diag(Rec.Lambdas[I]->getLocStart(), - diag::err_lambda_unevaluated_operand); + Diag(Rec.Lambdas[I]->getLocStart(), D); } else { // Mark the capture expressions odr-used. This was deferred // during lambda expression creation. @@ -10874,7 +11258,8 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { if (!AlreadyInstantiated || Func->isConstexpr()) { if (isa<CXXRecordDecl>(Func->getDeclContext()) && - cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass()) + cast<CXXRecordDecl>(Func->getDeclContext())->isLocalClass() && + ActiveTemplateInstantiations.size()) PendingLocalImplicitInstantiations.push_back( std::make_pair(Func, PointOfInstantiation)); else if (Func->isConstexpr()) @@ -10908,14 +11293,14 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) { UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(), Loc)); } - // Normally the must current decl is marked used while processing the use and + // Normally the most current decl is marked used while processing the use and // any subsequent decls are marked used by decl merging. This fails with // template instantiation since marking can happen at the end of the file // and, because of the two phase lookup, this function is called with at // decl in the middle of a decl chain. We loop to maintain the invariant // that once a decl is used, all decls after it are also used. for (FunctionDecl *F = Func->getMostRecentDecl();; F = F->getPreviousDecl()) { - F->setUsed(true); + F->markUsed(Context); if (F == Func) break; } @@ -10967,36 +11352,251 @@ diagnoseUncapturableValueReference(Sema &S, SourceLocation loc, // capture. } -/// \brief Capture the given variable in the captured region. -static ExprResult captureInCapturedRegion(Sema &S, CapturedRegionScopeInfo *RSI, - VarDecl *Var, QualType FieldType, - QualType DeclRefType, - SourceLocation Loc, - bool RefersToEnclosingLocal) { - // The current implemention assumes that all variables are captured - // by references. Since there is no capture by copy, no expression evaluation - // will be needed. - // - RecordDecl *RD = RSI->TheRecordDecl; + +static bool isVariableAlreadyCapturedInScopeInfo(CapturingScopeInfo *CSI, VarDecl *Var, + bool &SubCapturesAreNested, + QualType &CaptureType, + QualType &DeclRefType) { + // Check whether we've already captured it. + if (CSI->CaptureMap.count(Var)) { + // If we found a capture, any subcaptures are nested. + SubCapturesAreNested = 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(); + return true; + } + return false; +} - FieldDecl *Field - = FieldDecl::Create(S.Context, RD, Loc, Loc, 0, FieldType, - S.Context.getTrivialTypeSourceInfo(FieldType, Loc), - 0, false, ICIS_NoInit); - Field->setImplicit(true); - Field->setAccess(AS_private); - RD->addDecl(Field); +// Only block literals, captured statements, and lambda expressions can +// capture; other scopes don't work. +static DeclContext *getParentOfCapturingContextOrNull(DeclContext *DC, VarDecl *Var, + SourceLocation Loc, + const bool Diagnose, Sema &S) { + if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC) || isLambdaCallOperator(DC)) + return getLambdaAwareParentOfDeclContext(DC); + else { + if (Diagnose) + diagnoseUncapturableValueReference(S, Loc, Var, DC); + } + return 0; +} - Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, - DeclRefType, VK_LValue, Loc); - Var->setReferenced(true); - Var->setUsed(true); +// Certain capturing entities (lambdas, blocks etc.) are not allowed to capture +// certain types of variables (unnamed, variably modified types etc.) +// so check for eligibility. +static bool isVariableCapturable(CapturingScopeInfo *CSI, VarDecl *Var, + SourceLocation Loc, + const bool Diagnose, Sema &S) { + + bool IsBlock = isa<BlockScopeInfo>(CSI); + bool IsLambda = isa<LambdaScopeInfo>(CSI); + + // 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 (Diagnose) { + S.Diag(Loc, diag::err_lambda_capture_anonymous_var); + S.Diag(Var->getLocation(), diag::note_declared_at); + } + return false; + } + + // Prohibit variably-modified types; they're difficult to deal with. + if (Var->getType()->isVariablyModifiedType()) { + if (Diagnose) { + if (IsBlock) + S.Diag(Loc, diag::err_ref_vm_type); + else + S.Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName(); + S.Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return false; + } + // Prohibit structs with flexible array members too. + // We cannot capture what is in the tail end of the struct. + if (const RecordType *VTTy = Var->getType()->getAs<RecordType>()) { + if (VTTy->getDecl()->hasFlexibleArrayMember()) { + if (Diagnose) { + if (IsBlock) + S.Diag(Loc, diag::err_ref_flexarray_type); + else + S.Diag(Loc, diag::err_lambda_capture_flexarray_type) + << Var->getDeclName(); + S.Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return false; + } + } + const bool HasBlocksAttr = Var->hasAttr<BlocksAttr>(); + // Lambdas and captured statements are not allowed to capture __block + // variables; they don't support the expected semantics. + if (HasBlocksAttr && (IsLambda || isa<CapturedRegionScopeInfo>(CSI))) { + if (Diagnose) { + S.Diag(Loc, diag::err_capture_block_variable) + << Var->getDeclName() << !IsLambda; + S.Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return false; + } - return Ref; + return true; } -/// \brief Capture the given variable in the given lambda expression. -static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, +// Returns true if the capture by block was successful. +static bool captureInBlock(BlockScopeInfo *BSI, VarDecl *Var, + SourceLocation Loc, + const bool BuildAndDiagnose, + QualType &CaptureType, + QualType &DeclRefType, + const bool Nested, + Sema &S) { + Expr *CopyExpr = 0; + bool ByRef = false; + + // Blocks are not allowed to capture arrays. + if (CaptureType->isArrayType()) { + if (BuildAndDiagnose) { + S.Diag(Loc, diag::err_ref_array_type); + S.Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return false; + } + + // Forbid the block-capture of autoreleasing variables. + if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) { + if (BuildAndDiagnose) { + S.Diag(Loc, diag::err_arc_autoreleasing_capture) + << /*block*/ 0; + S.Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return false; + } + const bool HasBlocksAttr = Var->hasAttr<BlocksAttr>(); + 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 (S.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)) + S.FinalizeVarWithDestructor(Var, Record); + + // Enter a new evaluation context to insulate the copy + // full-expression. + EnterExpressionEvaluationContext scope(S, S.PotentiallyEvaluated); + + // 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 (S.Context) DeclRefExpr(Var, Nested, + DeclRefType.withConst(), + VK_LValue, Loc); + + ExprResult Result + = S.PerformCopyInitialization( + InitializedEntity::InitializeBlock(Var->getLocation(), + CaptureType, 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(); + } + } + } + } + + // Actually capture the variable. + if (BuildAndDiagnose) + BSI->addCapture(Var, HasBlocksAttr, ByRef, Nested, Loc, + SourceLocation(), CaptureType, CopyExpr); + + return true; + +} + + +/// \brief Capture the given variable in the captured region. +static bool captureInCapturedRegion(CapturedRegionScopeInfo *RSI, + VarDecl *Var, + SourceLocation Loc, + const bool BuildAndDiagnose, + QualType &CaptureType, + QualType &DeclRefType, + const bool RefersToEnclosingLocal, + Sema &S) { + + // By default, capture variables by reference. + bool ByRef = true; + // Using an LValue reference type is consistent with Lambdas (see below). + CaptureType = S.Context.getLValueReferenceType(DeclRefType); + Expr *CopyExpr = 0; + if (BuildAndDiagnose) { + // The current implementation assumes that all variables are captured + // by references. Since there is no capture by copy, no expression evaluation + // will be needed. + // + RecordDecl *RD = RSI->TheRecordDecl; + + FieldDecl *Field + = FieldDecl::Create(S.Context, RD, Loc, Loc, 0, CaptureType, + S.Context.getTrivialTypeSourceInfo(CaptureType, Loc), + 0, false, ICIS_NoInit); + Field->setImplicit(true); + Field->setAccess(AS_private); + RD->addDecl(Field); + + CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, + DeclRefType, VK_LValue, Loc); + Var->setReferenced(true); + Var->markUsed(S.Context); + } + + // Actually capture the variable. + if (BuildAndDiagnose) + RSI->addCapture(Var, /*isBlock*/false, ByRef, RefersToEnclosingLocal, Loc, + SourceLocation(), CaptureType, CopyExpr); + + + return true; +} + +/// \brief Create a field within the lambda class for the variable +/// being captured. Handle Array captures. +static ExprResult addAsFieldToClosureType(Sema &S, + LambdaScopeInfo *LSI, VarDecl *Var, QualType FieldType, QualType DeclRefType, SourceLocation Loc, @@ -11032,7 +11632,7 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, DeclRefType, VK_LValue, Loc); Var->setReferenced(true); - Var->setUsed(true); + Var->markUsed(S.Context); // When the field has array type, create index variables for each // dimension of the array. We use these index variables to subscript @@ -11088,7 +11688,8 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, SmallVector<InitializedEntity, 4> Entities; Entities.reserve(1 + IndexVariables.size()); Entities.push_back( - InitializedEntity::InitializeLambdaCapture(Var, Field, Loc)); + InitializedEntity::InitializeLambdaCapture(Var->getIdentifier(), + Field->getType(), Loc)); for (unsigned I = 0, N = IndexVariables.size(); I != N; ++I) Entities.push_back(InitializedEntity::InitializeElement(S.Context, 0, @@ -11113,127 +11714,207 @@ static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, return Result; } -bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, + + +/// \brief Capture the given variable in the lambda. +static bool captureInLambda(LambdaScopeInfo *LSI, + VarDecl *Var, + SourceLocation Loc, + const bool BuildAndDiagnose, + QualType &CaptureType, + QualType &DeclRefType, + const bool RefersToEnclosingLocal, + const Sema::TryCaptureKind Kind, + SourceLocation EllipsisLoc, + const bool IsTopScope, + Sema &S) { + + // Determine whether we are capturing by reference or by value. + bool ByRef = false; + if (IsTopScope && Kind != Sema::TryCapture_Implicit) { + ByRef = (Kind == Sema::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 = S.Context.getLValueReferenceType(DeclRefType); + } else { + // 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) { + S.Diag(Loc, diag::err_arc_autoreleasing_capture) << /*lambda*/ 1; + S.Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + } + return false; + } + + if (S.RequireNonAbstractType(Loc, CaptureType, + diag::err_capture_of_abstract_type)) + return false; + } + + // Capture this variable in the lambda. + Expr *CopyExpr = 0; + if (BuildAndDiagnose) { + ExprResult Result = addAsFieldToClosureType(S, LSI, Var, + CaptureType, DeclRefType, Loc, + RefersToEnclosingLocal); + 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) + LSI->addCapture(Var, /*IsBlock=*/false, ByRef, RefersToEnclosingLocal, + Loc, EllipsisLoc, CaptureType, CopyExpr); + + return true; +} + + +bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation ExprLoc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, - QualType &DeclRefType) { + QualType &DeclRefType, + const unsigned *const FunctionScopeIndexToStopAt) { bool Nested = false; DeclContext *DC = CurContext; - if (Var->getDeclContext() == DC) return true; - if (!Var->hasLocalStorage()) return true; + const unsigned MaxFunctionScopesIndex = FunctionScopeIndexToStopAt + ? *FunctionScopeIndexToStopAt : FunctionScopes.size() - 1; + // We need to sync up the Declaration Context with the + // FunctionScopeIndexToStopAt + if (FunctionScopeIndexToStopAt) { + unsigned FSIndex = FunctionScopes.size() - 1; + while (FSIndex != MaxFunctionScopesIndex) { + DC = getLambdaAwareParentOfDeclContext(DC); + --FSIndex; + } + } - bool HasBlocksAttr = Var->hasAttr<BlocksAttr>(); + + // If the variable is declared in the current context (and is not an + // init-capture), there is no need to capture it. + if (!Var->isInitCapture() && Var->getDeclContext() == DC) return true; + if (!Var->hasLocalStorage()) return true; // 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. + // capture of that variable. We start from the innermost capturing-entity + // (the DC) and ensure that all intervening capturing-entities + // (blocks/lambdas etc.) between the innermost capturer and the variable`s + // declcontext can either capture the variable or have already captured + // the variable. CaptureType = Var->getType(); DeclRefType = CaptureType.getNonReferenceType(); bool Explicit = (Kind != TryCapture_Implicit); - unsigned FunctionScopesIndex = FunctionScopes.size() - 1; + unsigned FunctionScopesIndex = MaxFunctionScopesIndex; do { // Only block literals, captured statements, and lambda expressions can // capture; other scopes don't work. - DeclContext *ParentDC; - if (isa<BlockDecl>(DC) || isa<CapturedDecl>(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; - } + DeclContext *ParentDC = getParentOfCapturingContextOrNull(DC, Var, + ExprLoc, + BuildAndDiagnose, + *this); + if (!ParentDC) return true; + + FunctionScopeInfo *FSI = FunctionScopes[FunctionScopesIndex]; + CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FSI); - 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(); + if (isVariableAlreadyCapturedInScopeInfo(CSI, Var, Nested, CaptureType, + DeclRefType)) break; - } - - bool IsBlock = isa<BlockScopeInfo>(CSI); - bool IsLambda = isa<LambdaScopeInfo>(CSI); - - // 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 we are instantiating a generic lambda call operator body, + // we do not want to capture new variables. What was captured + // during either a lambdas transformation or initial parsing + // should be used. + if (isGenericLambdaCallOperatorSpecialization(DC)) { 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 - Diag(Loc, diag::err_lambda_capture_vm_type) << Var->getDeclName(); - Diag(Var->getLocation(), diag::note_previous_decl) - << Var->getDeclName(); - } - return true; - } - // Prohibit structs with flexible array members too. - // We cannot capture what is in the tail end of the struct. - if (const RecordType *VTTy = Var->getType()->getAs<RecordType>()) { - if (VTTy->getDecl()->hasFlexibleArrayMember()) { - if (BuildAndDiagnose) { - if (IsBlock) - Diag(Loc, diag::err_ref_flexarray_type); - else - Diag(Loc, diag::err_lambda_capture_flexarray_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(); + LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI); + if (LSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None) { + Diag(ExprLoc, diag::err_lambda_impcap) << Var->getDeclName(); + Diag(Var->getLocation(), diag::note_previous_decl) + << Var->getDeclName(); + Diag(LSI->Lambda->getLocStart(), diag::note_lambda_decl); + } else + diagnoseUncapturableValueReference(*this, ExprLoc, Var, DC); } return true; } - + // Certain capturing entities (lambdas, blocks etc.) are not allowed to capture + // certain types of variables (unnamed, variably modified types etc.) + // so check for eligibility. + if (!isVariableCapturable(CSI, Var, ExprLoc, BuildAndDiagnose, *this)) + return true; + if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_None && !Explicit) { - // No capture-default + // No capture-default, and this is not an explicit capture + // so cannot capture this variable. if (BuildAndDiagnose) { - Diag(Loc, diag::err_lambda_impcap) << Var->getDeclName(); + Diag(ExprLoc, 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); + // FIXME: If we error out because an outer lambda can not implicitly + // capture a variable that an inner lambda explicitly captures, we + // should have the inner lambda do the explicit capture - because + // it makes for cleaner diagnostics later. This would purely be done + // so that the diagnostic does not misleadingly claim that a variable + // can not be captured by a lambda implicitly even though it is captured + // explicitly. Suggestion: + // - create const bool VariableCaptureWasInitiallyExplicit = Explicit + // at the function head + // - cache the StartingDeclContext - this must be a lambda + // - captureInLambda in the innermost lambda the variable. } return true; } @@ -11243,203 +11924,37 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, 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; + // Walk back down the scope stack, (e.g. from outer lambda to inner lambda) + // computing the type of the capture at each step, checking type-specific + // requirements, and adding captures if requested. + // If the variable had already been captured previously, we start capturing + // at the lambda nested within that one. + for (unsigned I = ++FunctionScopesIndex, N = MaxFunctionScopesIndex + 1; 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(); - } + if (BlockScopeInfo *BSI = dyn_cast<BlockScopeInfo>(CSI)) { + if (!captureInBlock(BSI, Var, ExprLoc, + BuildAndDiagnose, CaptureType, + DeclRefType, Nested, *this)) 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); - - // Enter a new evaluation context to insulate the copy - // full-expression. - EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated); - - // 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, Nested, - 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; - } - - if (CapturedRegionScopeInfo *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) { - // By default, capture variables by reference. - bool ByRef = true; - // Using an LValue reference type is consistent with Lambdas (see below). - CaptureType = Context.getLValueReferenceType(DeclRefType); - - Expr *CopyExpr = 0; - if (BuildAndDiagnose) { - ExprResult Result = captureInCapturedRegion(*this, RSI, Var, - CaptureType, DeclRefType, - Loc, Nested); - if (!Result.isInvalid()) - CopyExpr = Result.take(); - } - - // Actually capture the variable. - if (BuildAndDiagnose) - CSI->addCapture(Var, /*isBlock*/false, ByRef, Nested, Loc, - SourceLocation(), CaptureType, CopyExpr); + } else if (CapturedRegionScopeInfo *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) { + if (!captureInCapturedRegion(RSI, Var, ExprLoc, + BuildAndDiagnose, CaptureType, + DeclRefType, Nested, *this)) + return true; 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 { - // 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(); - } + LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI); + if (!captureInLambda(LSI, Var, ExprLoc, + BuildAndDiagnose, CaptureType, + DeclRefType, Nested, Kind, EllipsisLoc, + /*IsTopScope*/I == N - 1, *this)) return true; - } - } - - // Capture this variable in the lambda. - Expr *CopyExpr = 0; - if (BuildAndDiagnose) { - ExprResult Result = captureInLambda(*this, LSI, Var, CaptureType, - DeclRefType, Loc, - Nested); - 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(); + Nested = true; } - - // Add the capture. - if (BuildAndDiagnose) - CSI->addCapture(Var, /*IsBlock=*/false, ByRef, Nested, Loc, - EllipsisLoc, CaptureType, CopyExpr); - Nested = true; } - return false; } @@ -11449,7 +11964,7 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, QualType DeclRefType; return tryCaptureVariable(Var, Loc, Kind, EllipsisLoc, /*BuildAndDiagnose=*/true, CaptureType, - DeclRefType); + DeclRefType, 0); } QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) { @@ -11458,28 +11973,36 @@ QualType Sema::getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc) { // Determine whether we can capture this variable. if (tryCaptureVariable(Var, Loc, TryCapture_Implicit, SourceLocation(), - /*BuildAndDiagnose=*/false, CaptureType, DeclRefType)) + /*BuildAndDiagnose=*/false, CaptureType, + DeclRefType, 0)) 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.UndefinedButUsed[Var->getCanonicalDecl()]; - if (old.isInvalid()) old = Loc; - } - SemaRef.tryCaptureVariable(Var, Loc); - Var->setUsed(true); +// If either the type of the variable or the initializer is dependent, +// return false. Otherwise, determine whether the variable is a constant +// expression. Use this if you need to know if a variable that might or +// might not be dependent is truly a constant expression. +static inline bool IsVariableNonDependentAndAConstantExpression(VarDecl *Var, + ASTContext &Context) { + + if (Var->getType()->isDependentType()) + return false; + const VarDecl *DefVD = 0; + Var->getAnyInitializer(DefVD); + if (!DefVD) + return false; + EvaluatedStmt *Eval = DefVD->ensureEvaluatedStmt(); + Expr *Init = cast<Expr>(Eval->Value); + if (Init->isValueDependent()) + return false; + return IsVariableAConstantExpression(Var, Context); } + 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 @@ -11487,6 +12010,22 @@ void Sema::UpdateMarkingForLValueToRValue(Expr *E) { // is immediately applied." This function handles the lvalue-to-rvalue // conversion part. MaybeODRUseExprs.erase(E->IgnoreParens()); + + // If we are in a lambda, check if this DeclRefExpr or MemberExpr refers + // to a variable that is a constant expression, and if so, identify it as + // a reference to a variable that does not involve an odr-use of that + // variable. + if (LambdaScopeInfo *LSI = getCurLambda()) { + Expr *SansParensExpr = E->IgnoreParens(); + VarDecl *Var = 0; + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SansParensExpr)) + Var = dyn_cast<VarDecl>(DRE->getFoundDecl()); + else if (MemberExpr *ME = dyn_cast<MemberExpr>(SansParensExpr)) + Var = dyn_cast<VarDecl>(ME->getMemberDecl()); + + if (Var && IsVariableNonDependentAndAConstantExpression(Var, Context)) + LSI->markVariableExprAsNonODRUsed(SansParensExpr); + } } ExprResult Sema::ActOnConstantExpression(ExprResult Res) { @@ -11517,46 +12056,105 @@ void Sema::CleanupVarDeclMarking() { llvm_unreachable("Unexpcted expression"); } - MarkVarDeclODRUsed(*this, Var, Loc); + MarkVarDeclODRUsed(Var, Loc, *this, /*MaxFunctionScopeIndex Pointer*/ 0); } 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) { + assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E)) && + "Invalid Expr argument to DoMarkVarDeclReferenced"); 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) { + // If the context is not PotentiallyEvaluated and not Unevaluated + // (i.e PotentiallyEvaluatedIfUsed) do not bother to consider variables + // in this context for odr-use unless we are within a lambda. + // If we don't know whether the context is potentially evaluated or not + // (for e.g., if we're in a generic lambda), we want to add a potential + // capture and eventually analyze for odr-use. + // We should also be able to analyze certain constructs in a non-generic + // lambda setting for potential odr-use and capture violation: + // template<class T> void foo(T t) { + // auto L = [](int i) { return t; }; + // } + // + if (!IsPotentiallyEvaluatedContext(SemaRef)) { + + if (SemaRef.isUnevaluatedContext()) return; + + const bool refersToEnclosingScope = + (SemaRef.CurContext != Var->getDeclContext() && + Var->getDeclContext()->isFunctionOrMethod()); + if (!refersToEnclosingScope) return; + + if (LambdaScopeInfo *const LSI = SemaRef.getCurLambda()) { + // If a variable could potentially be odr-used, defer marking it so + // until we finish analyzing the full expression for any lvalue-to-rvalue + // or discarded value conversions that would obviate odr-use. + // Add it to the list of potential captures that will be analyzed + // later (ActOnFinishFullExpr) for eventual capture and odr-use marking + // unless the variable is a reference that was initialized by a constant + // expression (this will never need to be captured or odr-used). + const bool IsConstantExpr = IsVariableNonDependentAndAConstantExpression( + Var, SemaRef.Context); + assert(E && "Capture variable should be used in an expression."); + if (!IsConstantExpr || !Var->getType()->isReferenceType()) + LSI->addPotentialCapture(E->IgnoreParens()); + } + return; + } + + VarTemplateSpecializationDecl *VarSpec = + dyn_cast<VarTemplateSpecializationDecl>(Var); + assert(!isa<VarTemplatePartialSpecializationDecl>(Var) && + "Can't instantiate a partial template specialization."); + + // Implicit instantiation of static data members, static data member + // templates of class templates, and variable template specializations. + // Delay instantiations of variable templates, except for those + // that could be used in a constant expression. + TemplateSpecializationKind TSK = Var->getTemplateSpecializationKind(); + if (isTemplateInstantiation(TSK)) { + bool TryInstantiating = TSK == TSK_ImplicitInstantiation; + + if (TryInstantiating && !isa<VarTemplateSpecializationDecl>(Var)) { + if (Var->getPointOfInstantiation().isInvalid()) { // This is a modification of an existing AST node. Notify listeners. if (ASTMutationListener *L = SemaRef.getASTMutationListener()) L->StaticDataMemberInstantiated(Var); - MSInfo->setPointOfInstantiation(Loc); + } else if (!Var->isUsableInConstantExpressions(SemaRef.Context)) + // Don't bother trying to instantiate it again, unless we might need + // its initializer before we get to the end of the TU. + TryInstantiating = false; + } + + if (Var->getPointOfInstantiation().isInvalid()) + Var->setTemplateSpecializationKind(TSK, Loc); + + if (TryInstantiating) { + SourceLocation PointOfInstantiation = Var->getPointOfInstantiation(); + bool InstantiationDependent = false; + bool IsNonDependent = + VarSpec ? !TemplateSpecializationType::anyDependentTemplateArguments( + VarSpec->getTemplateArgsInfo(), InstantiationDependent) + : true; + + // Do not instantiate specializations that are still type-dependent. + if (IsNonDependent) { + if (Var->isUsableInConstantExpressions(SemaRef.Context)) { + // Do not defer instantiations of variables which could be used in a + // constant expression. + SemaRef.InstantiateVariableDefinition(PointOfInstantiation, Var); + } else { + SemaRef.PendingInstantiations + .push_back(std::make_pair(Var, PointOfInstantiation)); + } } - 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 satisfies // the requirements for appearing in a constant expression (5.19) and, if // it is an object, the lvalue-to-rvalue conversion (4.1) @@ -11565,14 +12163,16 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc, // Note that we use the C++11 definition everywhere because nothing in // C++03 depends on whether we get the C++03 version correct. The second // part does not apply to references, since they are not objects. - const VarDecl *DefVD; - if (E && !isa<ParmVarDecl>(Var) && - Var->isUsableInConstantExpressions(SemaRef.Context) && - Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE()) { + if (E && IsVariableAConstantExpression(Var, SemaRef.Context)) { + // A reference initialized by a constant expression can never be + // odr-used, so simply ignore it. + // But a non-reference might get odr-used if it doesn't undergo + // an lvalue-to-rvalue or is discarded, so track it. if (!Var->getType()->isReferenceType()) SemaRef.MaybeODRUseExprs.insert(E); - } else - MarkVarDeclODRUsed(SemaRef, Var, Loc); + } + else + MarkVarDeclODRUsed(Var, Loc, SemaRef, /*MaxFunctionScopeIndex ptr*/0); } /// \brief Mark a variable referenced, and check whether it is odr-used @@ -11889,7 +12489,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) { Selector Sel = ME->getSelector(); // self = [<foo> init...] - if (isSelfExpr(Op->getLHS()) && Sel.getNameForSlot(0).startswith("init")) + if (isSelfExpr(Op->getLHS()) && ME->getMethodFamily() == OMF_init) diagnostic = diag::warn_condition_is_idiomatic_assignment; // <foo> = [<bar> nextObject] @@ -12204,15 +12804,49 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) { assert(E->getObjectKind() == OK_Ordinary); // Rebuild the function type, replacing the result type with DestType. - if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FnType)) - DestType = - S.Context.getFunctionType(DestType, - ArrayRef<QualType>(Proto->arg_type_begin(), - Proto->getNumArgs()), - Proto->getExtProtoInfo()); - else + const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FnType); + if (Proto) { + // __unknown_anytype(...) is a special case used by the debugger when + // it has no idea what a function's signature is. + // + // We want to build this call essentially under the K&R + // unprototyped rules, but making a FunctionNoProtoType in C++ + // would foul up all sorts of assumptions. However, we cannot + // simply pass all arguments as variadic arguments, nor can we + // portably just call the function under a non-variadic type; see + // the comment on IR-gen's TargetInfo::isNoProtoCallVariadic. + // However, it turns out that in practice it is generally safe to + // call a function declared as "A foo(B,C,D);" under the prototype + // "A foo(B,C,D,...);". The only known exception is with the + // Windows ABI, where any variadic function is implicitly cdecl + // regardless of its normal CC. Therefore we change the parameter + // types to match the types of the arguments. + // + // This is a hack, but it is far superior to moving the + // corresponding target-specific code from IR-gen to Sema/AST. + + ArrayRef<QualType> ParamTypes = Proto->getArgTypes(); + SmallVector<QualType, 8> ArgTypes; + if (ParamTypes.empty() && Proto->isVariadic()) { // the special case + ArgTypes.reserve(E->getNumArgs()); + for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { + Expr *Arg = E->getArg(i); + QualType ArgType = Arg->getType(); + if (E->isLValue()) { + ArgType = S.Context.getLValueReferenceType(ArgType); + } else if (E->isXValue()) { + ArgType = S.Context.getRValueReferenceType(ArgType); + } + ArgTypes.push_back(ArgType); + } + ParamTypes = ArgTypes; + } + DestType = S.Context.getFunctionType(DestType, ParamTypes, + Proto->getExtProtoInfo()); + } else { DestType = S.Context.getFunctionNoProtoType(DestType, FnType->getExtInfo()); + } // Rebuild the appropriate pointer-to-function type. switch (Kind) { @@ -12345,6 +12979,8 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) { return ExprError(); } + // Modifying the declaration like this is friendly to IR-gen but + // also really dangerous. VD->setType(DestType); E->setType(Type); E->setValueKind(ValueKind); |