diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 38 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 4 |
5 files changed, 47 insertions, 44 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 0c25e01787c1..b8e7ede2716c 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -6523,6 +6523,12 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, if (!stackE) return; // Nothing suspicious was found. + // Parameters are initalized in the calling scope, so taking the address + // of a parameter reference doesn't need a warning. + for (auto *DRE : refVars) + if (isa<ParmVarDecl>(DRE->getDecl())) + return; + SourceLocation diagLoc; SourceRange diagRange; if (refVars.empty()) { @@ -6546,6 +6552,13 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, } else if (isa<AddrLabelExpr>(stackE)) { // address of label. S.Diag(diagLoc, diag::warn_ret_addr_label) << diagRange; } else { // local temporary. + // If there is an LValue->RValue conversion, then the value of the + // reference type is used, not the reference. + if (auto *ICE = dyn_cast<ImplicitCastExpr>(RetValExp)) { + if (ICE->getCastKind() == CK_LValueToRValue) { + return; + } + } S.Diag(diagLoc, diag::warn_ret_local_temp_addr_ref) << lhsType->isReferenceType() << diagRange; } @@ -7776,6 +7789,12 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, unsigned OriginalWidth = Value.getBitWidth(); unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); + if (Value.isSigned() && Value.isNegative()) + if (UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit)) + if (UO->getOpcode() == UO_Minus) + if (isa<IntegerLiteral>(UO->getSubExpr())) + OriginalWidth = Value.getMinSignedBits(); + if (OriginalWidth <= FieldWidth) return false; @@ -9372,7 +9391,8 @@ void Sema::CheckUnsequencedOperations(Expr *E) { void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc, bool IsConstexpr) { CheckImplicitConversions(E, CheckLoc); - CheckUnsequencedOperations(E); + if (!E->isInstantiationDependent()) + CheckUnsequencedOperations(E); if (!IsConstexpr && !E->isValueDependent()) CheckForIntOverflow(E); } diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 2cd00f8218a6..b7a968e09d4d 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -961,32 +961,26 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda( QualType Sema::getCurrentThisType() { DeclContext *DC = getFunctionLevelDeclContext(); QualType ThisTy = CXXThisTypeOverride; + if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(DC)) { if (method && method->isInstance()) ThisTy = method->getThisType(Context); } - if (ThisTy.isNull()) { - if (isGenericLambdaCallOperatorSpecialization(CurContext) && - CurContext->getParent()->getParent()->isRecord()) { - // This is a generic lambda call operator that is being instantiated - // within a default initializer - so use the enclosing class as 'this'. - // There is no enclosing member function to retrieve the 'this' pointer - // from. - - // FIXME: This looks wrong. If we're in a lambda within a lambda within a - // default member initializer, we need to recurse up more parents to find - // the right context. Looks like we should be walking up to the parent of - // the closure type, checking whether that is itself a lambda, and if so, - // recursing, until we reach a class or a function that isn't a lambda - // call operator. And we should accumulate the constness of *this on the - // way. - - QualType ClassTy = Context.getTypeDeclType( - cast<CXXRecordDecl>(CurContext->getParent()->getParent())); - // There are no cv-qualifiers for 'this' within default initializers, - // per [expr.prim.general]p4. - ThisTy = Context.getPointerType(ClassTy); - } + + if (ThisTy.isNull() && isLambdaCallOperator(CurContext) && + !ActiveTemplateInstantiations.empty()) { + + assert(isa<CXXRecordDecl>(DC) && + "Trying to get 'this' type from static method?"); + + // This is a lambda call operator that is being instantiated as a default + // initializer. DC must point to the enclosing class type, so we can recover + // the 'this' type from it. + + QualType ClassTy = Context.getTypeDeclType(cast<CXXRecordDecl>(DC)); + // There are no cv-qualifiers for 'this' within default initializers, + // per [expr.prim.general]p4. + ThisTy = Context.getPointerType(ClassTy); } // If we are within a lambda's call operator, the cv-qualifiers of 'this' diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 1b8410d7f4b9..8a2bf929dfc0 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -355,8 +355,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange, TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params, - const bool IsConstexprSpecified) { + ArrayRef<ParmVarDecl *> Params) { QualType MethodType = MethodTypeInfo->getType(); TemplateParameterList *TemplateParams = getGenericLambdaTemplateParameterList(getCurLambda(), *this); @@ -393,7 +392,7 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class, MethodType, MethodTypeInfo, SC_None, /*isInline=*/true, - IsConstexprSpecified, + /*isConstExpr=*/false, EndLoc); Method->setAccess(AS_public); @@ -878,9 +877,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, MethodTyInfo, KnownDependent, Intro.Default); - CXXMethodDecl *Method = - startLambdaDefinition(Class, Intro.Range, MethodTyInfo, EndLoc, Params, - ParamInfo.getDeclSpec().isConstexprSpecified()); + CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range, + MethodTyInfo, EndLoc, Params); if (ExplicitParams) CheckCXXDefaultArguments(Method); @@ -1599,17 +1597,6 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, CaptureInits, ArrayIndexVars, ArrayIndexStarts, EndLoc, ContainsUnexpandedParameterPack); - // If the lambda expression's call operator is not explicitly marked constexpr - // and we are not in a dependent context, analyze the call operator to infer - // its constexpr-ness, supressing diagnostics while doing so. - if (getLangOpts().CPlusPlus1z && !CallOperator->isInvalidDecl() && - !CallOperator->isConstexpr() && - !Class->getDeclContext()->isDependentContext()) { - TentativeAnalysisScope DiagnosticScopeGuard(*this); - CallOperator->setConstexpr( - CheckConstexprFunctionDecl(CallOperator) && - CheckConstexprFunctionBody(CallOperator, CallOperator->getBody())); - } if (!CurContext->isDependentContext()) { switch (ExprEvalContexts.back().Context) { diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index b025a397edca..40d6e910f1fb 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -5975,8 +5975,12 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, SmallVector<Expr *, 16> ConvertedArgs; bool InitializationFailed = false; + // Ignore any variadic parameters. Converting them is pointless, since the + // user can't refer to them in the enable_if condition. + unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size()); + // Convert the arguments. - for (unsigned I = 0, E = Args.size(); I != E; ++I) { + for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) { ExprResult R; if (I == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) && !cast<CXXMethodDecl>(Function)->isStatic() && diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 36859f61d387..7224eef848de 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -10222,9 +10222,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition( Class, E->getIntroducerRange(), NewCallOpTSI, E->getCallOperator()->getLocEnd(), - NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(), - E->getCallOperator()->isConstexpr()); - + NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams()); LSI->CallOperator = NewCallOperator; getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); |