aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaChecking.cpp22
-rw-r--r--lib/Sema/SemaExprCXX.cpp38
-rw-r--r--lib/Sema/SemaLambda.cpp21
-rw-r--r--lib/Sema/SemaOverload.cpp6
-rw-r--r--lib/Sema/TreeTransform.h4
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);